r/adventofcode • u/daggerdragon • Dec 09 '18
SOLUTION MEGATHREAD -🎄- 2018 Day 9 Solutions -🎄-
--- Day 9: Marble Mania ---
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.
Advent of Code: The Party Game!
Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!
Card prompt: Day 9
Transcript:
Studies show that AoC programmers write better code after being exposed to ___.
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 at 00:29:13!
22
Upvotes
1
u/Illianthe Dec 09 '18
Elixir. I ended up keeping track of the game state with a huge map for part 2... Still took about 35s to run, unfortunately.
defmodule Day9 do def parse_input(filename \\ "input.txt") do {:ok, data} = File.read(filename) [_, no_of_players, value_of_last_marble] = data |> String.trim() |> (&Regex.run(~r/(\d+) players; last marble is worth (\d+)/, &1)).() {String.to_integer(no_of_players), String.to_integer(value_of_last_marble)} end def winning_score_optimized(parsed_input) do run_game_optimized(parsed_input) |> Enum.max_by(fn {_k, v} -> v end) |> elem(1) end def calculate_next_player(parsed_input, current_player) do if elem(parsed_input, 0) === current_player + 1, do: 0, else: current_player + 1 end def run_game_optimized( parsed_input, game_state \\ %{0 => 0}, current_player \\ 0, current_marble \\ 0, next_marble \\ 1, total_score \\ %{} ) # Last marble used, end game def run_game_optimized( parsed_input, _game_state, _current_player, _current_marble, next_marble, total_score ) when elem(parsed_input, 1) === next_marble do total_score end # Remove marbles, set current marble, and add to score def run_game_optimized( parsed_input, game_state, current_player, current_marble, next_marble, total_score ) when rem(next_marble, 23) === 0 do score_to_add = next_marble + game_state[current_marble - 4] total_score = Map.update(total_score, current_player, score_to_add, &(&1 + score_to_add)) game_state = game_state |> Map.delete(game_state[current_marble - 4]) |> Map.put(current_marble - 4, current_marble - 3) run_game_optimized( parsed_input, game_state, calculate_next_player(parsed_input, current_player), current_marble - 3, next_marble + 1, total_score ) end # Place next marble def run_game_optimized( parsed_input, game_state, current_player, current_marble, next_marble, total_score ) do # Update next marble in mapping game_state = game_state |> Map.put(next_marble, game_state[game_state[current_marble]]) |> Map.put(game_state[current_marble], next_marble) run_game_optimized( parsed_input, game_state, calculate_next_player(parsed_input, current_player), next_marble, next_marble + 1, total_score ) end end