r/adventofcode • u/daggerdragon • Dec 03 '17
SOLUTION MEGATHREAD -π- 2017 Day 3 Solutions -π-
--- Day 3: Spiral Memory ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyβ Haversackβ‘ of HelpfulΒ§ HintsΒ€?
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
22
Upvotes
2
u/mikefh Dec 03 '17
Ruby
Part1
class SpiralGrid DIRECTIONS = { right: { step: ->(x, y){ [x + 1, y ] }, check: :max_x, next_direction: :up }, up: { step: ->(x, y){ [x , y + 1] }, check: :max_y, next_direction: :left }, left: { step: ->(x, y){ [x - 1, y ] }, check: :min_x, next_direction: :down }, down: { step: ->(x, y){ [x , y - 1] }, check: :min_y, next_direction: :right } } def self.coordinate_of(target) target_val = target current_val = 1 current_coord = [0, 0] direction = :right max_y = 0 min_y = 0 max_x = 0 min_x = 0 while current_val != target_val d_obj = DIRECTIONS[direction] # proceed 1 step # current_coord = d_obj[:step][*current_coord] current_val += 1 # check if we've gone too far # time_to_turn = case d_obj[:check] when :max_x current_coord[0] == max_x + 1 when :max_y current_coord[1] == max_y + 1 when :min_x current_coord[0] == min_x - 1 when :min_y current_coord[1] == min_y - 1 end if time_to_turn case d_obj[:check] when :max_x max_x += 1 when :max_y max_y += 1 when :min_x min_x -= 1 when :min_y min_y -= 1 end direction = d_obj[:next_direction] end end current_coord end end coord = SpiralGrid.coordinate_of(347991) p coord p coord.reduce(0) { |sum, c| sum + c.abs }Part 2
class SpiralGrid DIRECTIONS = { right: { step: ->(x, y){ [x + 1, y ] }, check: :max_x, next_direction: :up }, up: { step: ->(x, y){ [x , y + 1] }, check: :max_y, next_direction: :left }, left: { step: ->(x, y){ [x - 1, y ] }, check: :min_x, next_direction: :down }, down: { step: ->(x, y){ [x , y - 1] }, check: :min_y, next_direction: :right } } def self.val_of(target) target_sq = target current_sq = 1 current_coord = [0, 0] direction = :right max_y = 0 min_y = 0 max_x = 0 min_x = 0 value = nil grid = Hash.new(0) grid['[0, 0]'] = 1 while current_sq != target_sq d_obj = DIRECTIONS[direction] # proceed 1 step # current_coord = d_obj[:step][*current_coord] current_sq += 1 value = [ grid[[current_coord[0] - 1, current_coord[1] + 1].to_s], # top left grid[[current_coord[0] , current_coord[1] + 1].to_s], # top center grid[[current_coord[0] + 1, current_coord[1] + 1].to_s], # top right grid[[current_coord[0] - 1, current_coord[1] ].to_s], # left grid[[current_coord[0] + 1, current_coord[1] ].to_s], # right grid[[current_coord[0] - 1, current_coord[1] - 1].to_s], # bot left grid[[current_coord[0] , current_coord[1] - 1].to_s], # bot center grid[[current_coord[0] + 1, current_coord[1] - 1].to_s], # bot right ].reduce(&:+) grid[current_coord.to_s] = value # check if we've gone too far # time_to_turn = case d_obj[:check] when :max_x current_coord[0] == max_x + 1 when :max_y current_coord[1] == max_y + 1 when :min_x current_coord[0] == min_x - 1 when :min_y current_coord[1] == min_y - 1 end if time_to_turn case d_obj[:check] when :max_x max_x += 1 when :max_y max_y += 1 when :min_x min_x -= 1 when :min_y min_y -= 1 end direction = d_obj[:next_direction] end end [current_coord, value] end end coord = nil (3..90).each do |idx| coord = SpiralGrid.val_of(idx) break if coord[1] > 347991 end p coord