# NailingPlanks

A bit of a brain breaker. At the end, i didn’t use binary search for this one.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
function solution(A, B, C) { var result = -1, planks = [], nails = []; // sort the planks for( var i = 0; i < A.length; i++ ){ planks.push({ start: A[i], end: B[i] }); } planks.sort( (a, b) => a.start - b.start ); //now sort the nails, while retaining their original index; for( var i = 0; i < C.length; i++ ){ nails.push({ i: i, val: C[i] }); } nails.sort( (a, b) => a.val - b.val ); var nails_index = 0; for( var i = 0; i < planks.length; i++ ){ var nails_count = nails_index; while( nails_index < nails.length ){ // discard the nails that come before if( nails[nails_index].val < planks[i].start ){ nails_index++; } else if( nails[nails_index].val > planks[i].end ){ // as nails are sorted, every nail after this is to big.. return -1; } else{ break; } } if( i != 0 && planks[i].start === planks[i-1].start){ // planks have the same starting position continue; } // else var tmp_result = nails.length, tmp_index = nails_index; while( tmp_index < nails.length && planks[i].start <= nails[tmp_index].val && nails[tmp_index].val <= planks[i].end){ tmp_result = Math.min( tmp_result, nails[tmp_index].i ); tmp_index += 1; if (tmp_result <= result){ break; } } result = Math.max(result, tmp_result); } return result+1; } |

You are given two non-empty zero-indexed arrays A and B consisting of N integers. These arrays represent N planks. More precisely, A[K] is the start and B[K] the end of the K−th plank.

Next, you are given a non-empty zero-indexed array C consisting of M integers. This array represents M nails. More precisely, C[I] is the position where you can hammer in the I−th nail.

We say that a plank (A[K], B[K]) is nailed if there exists a nail C[I] such that A[K] ≤ C[I] ≤ B[K].

The goal is to find the minimum number of nails that must be used until all the planks are nailed. In other words, you should find a value J such that all planks will be nailed after using only the first J nails. More precisely, for every plank (A[K], B[K]) such that 0 ≤ K < N, there should exist a nail C[I] such that I < J and A[K] ≤ C[I] ≤ B[K].

For example, given arrays A, B such that:

A[0] = 1 B[0] = 4

A[1] = 4 B[1] = 5

A[2] = 5 B[2] = 9

A[3] = 8 B[3] = 10

four planks are represented: [1, 4], [4, 5], [5, 9] and [8, 10].

Given array C such that:

C[0] = 4

C[1] = 6

C[2] = 7

C[3] = 10

C[4] = 2

if we use the following nails:

0, then planks [1, 4] and [4, 5] will both be nailed.

0, 1, then planks [1, 4], [4, 5] and [5, 9] will be nailed.

0, 1, 2, then planks [1, 4], [4, 5] and [5, 9] will be nailed.

0, 1, 2, 3, then all the planks will be nailed.

Thus, four is the minimum number of nails that, used sequentially, allow all the planks to be nailed.

Write a function:

function solution(A, B, C);

that, given two non-empty zero-indexed arrays A and B consisting of N integers and a non-empty zero-indexed array C consisting of M integers, returns the minimum number of nails that, used sequentially, allow all the planks to be nailed.

If it is not possible to nail all the planks, the function should return −1.

For example, given arrays A, B, C such that:

A[0] = 1 B[0] = 4

A[1] = 4 B[1] = 5

A[2] = 5 B[2] = 9

A[3] = 8 B[3] = 10

C[0] = 4

C[1] = 6

C[2] = 7

C[3] = 10

C[4] = 2

the function should return 4, as explained above.

Assume that:

N and M are integers within the range [1..30,000];

each element of arrays A, B, C is an integer within the range [1..2*M];

A[K] ≤ B[K].

Complexity:

expected worst-case time complexity is O((N+M)*log(M));

expected worst-case space complexity is O(M), beyond input storage (not counting the storage required for input arguments).

Elements of input arrays can be modified.