this post was submitted on 15 Dec 2024
14 points (93.8% liked)

Advent Of Code

979 readers
22 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
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

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

Day 15: Warehouse Woes

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] [email protected] 2 points 6 days ago* (last edited 6 days ago)

J

Nothing much to say about today's. I think I wrote basically the same code you'd write in Python, just with fewer characters, more of which are punctuation. I did learn a little bit more about how to use J's step debugger, and that / is specifically a right fold, so you can use it on a dyad with arguments of different types as long as the list argument is the left one.

data_file_name =: '15.data'
lines =: cutopen fread data_file_name
NB. instructions start with the first line not containing a # character
start_of_moves =: 0 i.~ '#' e."1 > lines
grid =: ,. > start_of_moves {. lines
start_row =: 1 i.~ '@' e."1 grid
start_col =: '@' i.~ start_row { grid
pos =: start_row, start_col
grid =: '.' ( start_of_moves }. lines
translate_move =: monad define"0
   if. y = '>' do. 0 1
   elseif. y = '^' do. _1 0
   elseif. y = '<' do. 0 _1
   elseif. y = 'v' do. 1 0
   else. 0 0 end.
)
moves =: translate_move move_instructions
NB. pos step move updates grid as needed and returns the new position
step =: dyad define"1 1
   new_pos =. x + y
   if. '#' = (< new_pos) { grid do. x  NB. obstructed by wall
   elseif. '.' = (< new_pos) { grid do. new_pos  NB. free to move
   else.  NB. it's 'O', need to push a stack
      p =. new_pos  NB. pointer to box at end of stack
      while. 'O' = (< p) { grid do. p =. p + y end.
      if. '#' = (< p) { grid do. x  NB. stack is blocked
      else.  NB. move stack
         grid =: 'O.' (< p ,: new_pos)} grid
         new_pos
      end.
   end.
)
score =: dyad define"0 2
   +/ ; ((<"0) 100 * i.#y) +&.> (< @: I. @: = & x)"1 y
)
final_pos =: step~/ |. pos , moves  NB. / is a right fold
result1 =: 'O' score grid

translate_cell =: monad define"0
   if. y = '#' do. '##'
   elseif. y = '.' do. '..'
   elseif. y = 'O' do. '[]'
   else. '@.' end.
)
grid2 =: (,/ @: translate_cell)"1 ,. > start_of_moves {. lines
start_row2 =: 1 i.~ '@' e."1 grid2
start_col2 =: '@' i.~ start_row { grid2
pos =: start_row2, start_col2
grid2 =: '.' (< pos)} grid2  NB. erase the @
NB. (grid; box_pos) try_push dir attempts to push the box at box_pos one
NB. cell in direction dir. box_pos can be either the left or right cell of
NB. the box. it returns (grid; success) where grid is the maybe-changed grid
NB. and success is whether the box moved. if any box that would be pushed
NB. cannot move, this box cannot move either and the grid does not change.
try_push =: dyad define"1 1
   'grid pos' =. x
   if. ']' = (< pos) { grid do. pos =. pos + 0 _1 end.  NB. make pos left cell
   source_cells =. pos ,: pos + 0 1
   if. 0 = {: y do.  NB. moving up or down
      target_cells =. (pos + y) ,: (pos + y + 0 1)  NB. cells we move into
   elseif. y -: 0 _1 do. target_cells =. 1 2 $ pos + y  NB. moving left
   else. target_cells =. 1 2 $ pos + y + 0 1 end.  NB. moving right
   NB. Have to check target cells one at a time because pushing a box up or
   NB. down may vacate the other target cell, or it may not
   trial_grid =. grid
   for_tc. target_cells do.
      NB. if a target cell is blocked by wall, fail
      if. '#' = (< tc) { trial_grid do. grid; 0 return.
      elseif. '[]' e.~ (< tc) { trial_grid do.
         'trial_grid success' =. (trial_grid; tc) try_push y
         if. -. success do. grid; 0 return. end.
      end.
   end.
   NB. at this point either target_cells are clear or we have returned failure,
   NB. so push the box
   grid =. '[]' (<"1 source_cells +"1 y)} '.' (<"1 source_cells)} trial_grid
   grid; 1
)
NB. (grid; pos) step2 move executes the move and returns new (grid; pos)
step2 =: dyad define"1 1
   'grid pos' =. x
   new_pos =. pos + y
   if. '#' = (< new_pos) { grid do. grid; pos  NB. obstructed by wall
   elseif. '.' = (< new_pos) { grid do. grid; new_pos  NB. free to move
   else.  NB. need to push a box
      'new_grid success' =. (grid; new_pos) try_push y
      if. success do. new_grid; new_pos else. grid; pos end.
   end.
)
'final_grid final_pos' =: > (step2~ &.>)/ (<"1 |. moves) , <(grid2; pos)
result2 =: '[' score final_grid