Skip to content

Instantly share code, notes, and snippets.

@kurtmilam
Last active December 11, 2016 23:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurtmilam/db400c3b127dd8b7b2a794cc61278b84 to your computer and use it in GitHub Desktop.
Save kurtmilam/db400c3b127dd8b7b2a794cc61278b84 to your computer and use it in GitHub Desktop.
Advent of Code 2016, Puzzle #1: Using Ramda, doubly linked cyclical list and lenses
// 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' )
@kurtmilam
Copy link
Author

I packed the axis into the compass in revision 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment