// Paste into the Ramda REPL at http://ramdajs.com/repl/ // NESW - doubly linked list, cyclical const compass = [[1, 1], [[0, 1], [[1, -1], [[0, -1]]]]] compass[1][1][1][1] = compass compass[1][2] = compass compass[1][1][2] = compass[1] compass[1][1][1][2] = compass[1][1] compass[2] = compass[1][1][1] const blocksLens = lensIndex( 2 ) // number of blocks to walk in current instruction const compassLens = lensIndex( 3 ) // access our compass in the accumulator // update the compass in the accumulator according to the direction we turned const turn = a => over( compassLens , ifElse( always( equals( 'R', head( a ) ) ) , view( lensIndex( 1 ) ) // turn right , view( lensIndex( 2 ) ) // turn left ) ) // shortcut to the compass value in the accumulator const viewCardLens = compose( view( lensIndex( 0 ) ), view( compassLens ) ) // create a lens to the x or y axis in the accumulator based on the current axis const viewAxisLens = compose( lensIndex, view( lensIndex( 0 ) ), viewCardLens ) // view the current compass sign (positive or negative) const viewSignLens = compose( view( lensIndex( 1 ) ), viewCardLens ) // add the current number of blocks * compass cardinal direction to previous blocks const move = compose( add, converge( multiply, [ view( blocksLens ), viewSignLens ] ) ) // update the number of blocks walked in the x or y axis const setPosition = a => converge( over, [ viewAxisLens, move ] )( a )( a ) const go = ( a, v ) => compose( setPosition , turn( v ) , set( blocksLens, parseInt( tail( v ), 10 ) ) )( a ) // The accumulator is: [ x blocks, y blocks, current blocks, compass ] compose( apply( ( a, b ) => add( Math.abs( a ), Math.abs( b ) ) ) , take( 2 ) , reduce( go, [ 0, 0, 0, compass ] ) , split( ', ' ) )( 'L3, R1, L4, L1, L2, R4, L3, L3, R2, R3, L5, R1, R3, L4, L1, L2, R2, R1, L4, L4, R2, L5, R3, R2, R1, L1, L2, R2, R2, L1, L1, R2, R1, L3, L5, R4, L3, R3, R3, L5, L190, L4, R4, R51, L4, R5, R5, R2, L1, L3, R1, R4, L3, R1, R3, L5, L4, R2, R5, R2, L1, L5, L1, L1, R78, L3, R2, L3, R5, L2, R2, R4, L1, L4, R1, R185, R3, L4, L1, L1, L3, R4, L4, L1, R5, L5, L1, R5, L1, R2, L5, L2, R4, R3, L2, R3, R1, L3, L5, L4, R3, L2, L4, L5, L4, R1, L1, R5, L2, R4, R2, R3, L1, L1, L4, L3, R4, L3, L5, R2, L5, L1, L1, R2, R3, L5, L3, L2, L1, L4, R4, R4, L2, R3, R1, L2, R1, L2, L2, R3, R3, L1, R4, L5, L3, R4, R4, R1, L2, L5, L3, R1, R4, L2, R5, R4, R2, L5, L3, R4, R1, L1, R5, L3, R1, R5, L2, R1, L5, L2, R2, L2, L3, R3, R3, R1' )