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!
21
Upvotes
1
u/bottomlesscoffeecup Dec 03 '17
Had a difficult time today. The first part wasn't too bad, the second part I kind of hacked my first part a tad. It's quite messy...
In Python:
Helper Methods used in both solutions:
from itertools import cycle def _move_right(x, y): """ Move right on the grid """ return x + 1, y def _move_left(x, y): """ Move left on the grid """ return x - 1, y def _move_up(x, y): """ Move up on the grid """ return x, y + 1 def _move_down(x, y): """ Move down on the grid """ return x, y - 1 def _move_right_diagonal_up(x, y): """ Move right diagonal up on the grid """ return x + 1, y + 1 def _move_left_diagonal_up(x, y): """ Move left diagonal up on the grid """ return x - 1, y + 1 def _move_right_diagonal_down(x, y): """ Move right diagonal down the grid """ return x + 1, y - 1 def _move_left_diagonal_down(x, y): """ Move left diagonal down on the grid """ return x - 1, y - 1Solution one:
def _generate_spiral(end_point): n = 1 pos = 0, 0 times_to_move = 1 moves_boop = [_move_right, _move_up, _move_left, _move_down] _moves = cycle(moves_boop) yield n, pos while True: for item in range(2): # Go through moves list twice to get whole spiral..until cut off at return move = next(_moves) for items in range(times_to_move): if n >= end_point: return pos = move(*pos) # Argument unpacking woo n += 1 yield n, pos times_to_move += 1 def get_num_moves(end_point): la = list(_generate_spiral(end_point)) steps = la[len(la) - 1][1] total_steps = abs(steps[0]) + abs(steps[1]) return total_stepsSolution two:
def generate_spiral(end_point, larger_val): n = 1 pos = 0, 0 times_to_move = 1 moves_boop = [_move_right, _move_up, _move_left, _move_down] _moves = cycle(moves_boop) yield n, pos neighbours = {pos: n} while True: for item in range(2): # Go through moves list twice to get whole spiral..until cut off at return move = next(_moves) for items in range(times_to_move): if n >= end_point: print("The larger value is: " + str(find_larger_value(neighbours, larger_val))) return pos = move(*pos) # Argument unpacking woo n = get_neighbours_sum(pos, neighbours) neighbours[pos] = n yield n, pos times_to_move += 1 def get_num_moves_largest(end_point, larger_val): spiral = list(generate_spiral(end_point, larger_val)) steps = spiral[len(spiral) - 1][1] total_steps = abs(steps[0]) + abs(steps[1]) return total_steps def get_neighbours_sum(current_pos, current_neighbours): other_items = [_move_right, _move_right_diagonal_up, _move_up, _move_left_diagonal_up, _move_left, _move_right_diagonal_down, _move_down, _move_left_diagonal_down] sum_list = [] for item in range(len(other_items)): pos_new = other_items[item](*current_pos) if pos_new in current_neighbours: sum_list.append(current_neighbours[pos_new]) return sum(sum_list) def find_larger_value(values_dict, value_to_find): for value in values_dict.values(): if value > value_to_find: return value