I think that the difficulty in the question revolves around the word “clock”, because of which I have been thinking about two hands for too long :)
The similarity between the “clocks” is similar to the fact that it can be defined by the sequence of separation of the “hands”; in the example question, the differences are 1,2,1,1,2. However, the main problem areas are pleasantly avoided in this very simple case ...
Packing: for example. in normal time, hours located at a distance of 4.6 and 11.1 are 2,
A few hands: for example. A 4-hour watch with 8 points can have hands at 1,2,5,6 and 1,4,5,8 giving a separation of 1,3,1 or 3,1,3, but they are rotationally identical!
When thinking of a watch with a large number of hands, you can imagine that sequences of hand breaks cannot simply be matched or sorted.
So, we measure all the spaces between the hands - the above four-hand example will be 1,3,1,3 and 3,1,3,1 (for this, I just add the first element at the end of the array), and then try to match this with previous patterns. We save unique templates along with an invoice for each of them.
Pattern comparison tries to compare arrays, then rotates the array one element and tries again (which eats a lot of time!)
In the end, we simply summarize the combinations for each account.
The current code gets a score of 90 points, only a failure for a couple of tests due to a timeout. I'm sure someone with a better understanding of Javascript could shave a few hundred milliseconds.
Here's the output: https://codility.com/demo/results/demo9GZ7VW-V63/
and here is the code:
// compare 2 arrays - assumes they are the same length function compareArrays( a1, a2 ) { for( var i=0; i<a1.length; i++) if( a1[i] != a2[i] ){ return false; } return true; } // compare newpos[] with positions[][] // - rotates newpos[] to attempt match // returns: index of match or -1 if no match // function comparePositions(positions,newpos) { for(var ipos=0; ipos<positions.length; ipos++){ for( i=0; i<newpos.length; i++){ if( compareArrays(positions[ipos],newpos)) return ipos; newpos.push(newpos.shift()); //rotate array } } return -1; } function solution(A, P) { var idx,diff,halfP=P/2; var highestCount=0; var highestIndex=0; var positions = []; var counts=[]; A.forEach(function(clock) { var position = []; // sort 'hands' in ascending order clock.sort(function(a, b) { return a - b }); // duplicate start point on end clock.push(clock[0]); // create array of distances between hands, wrapping around clock for(idx=1; idx<clock.length;idx++){ diff= Math.abs(clock[idx] - clock[idx-1]); position.push((diff>halfP)?P-diff:diff); } idx= comparePositions(positions,position); if( idx < 0 ){ positions.push(position); // new pattern counts.push(1); }else{ counts[idx]++; // count old pattern } }); // sum the combinations of counts for each position type var sum=0; for(idx=0; idx<counts.length; idx++){ count=counts[idx]; sum+= (count > 2) ? (count * (count-1))/2 : count-1; } return sum; }