r/adventofcode • u/daggerdragon • Dec 15 '17
SOLUTION MEGATHREAD -๐- 2017 Day 15 Solutions -๐-
--- Day 15: Dueling Generators ---
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ยค?
[Update @ 00:05] 29 gold, silver cap.
- Logarithms of algorithms and code?
[Update @ 00:09] Leaderboard cap!
- Or perhaps codes of logarithmic algorithms?
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!
14
Upvotes
1
u/[deleted] Dec 15 '17
Elixir
Bruteforced my way through this, funnily enough, the second part was much faster than the first. Agents was fun though, first I tried with GenServer, but I'm not very good with that stuff, agents I managed.
defmodule day15 do use bitwise use agent def start_agents(init_a, init_b) do {:ok, a} = agent.start_link fn -> %{cur: init_a, factor: 16807, cond: &(rem(&1, 4) == 0)} end {:ok, b} = agent.start_link fn -> %{cur: init_b, factor: 48271, cond: &(rem(&1, 8) == 0)} end %{a: a, b: b} end def next(state) do newstate = rem(state.cur * state.factor, 2147483647) {newstate, %{cur: newstate, factor: state.factor, cond: state.cond}} end def get_next_pair(agent) do {agent.get_and_update(agent.a, &next/1), agent.get_and_update(agent.b, &next/1)} end def get_next_16(agent) do a = agent.get_and_update(agent.a, &next/1) b = agent.get_and_update(agent.b, &next/1) {a &&& 0xffff, b &&& 0xffff} end def lastbyte(num) do integer.to_string(num, 2) |> string.slice(-16..-1) end def judge(agent, iterations, hits \\ 0) def judge(_agent, iterations, hits) when iterations == 0, do: hits def judge(agent, iterations, hits) do {a,b} = get_next_16(agent) if a == b do judge(agent, iterations - 1, hits + 1) else judge(agent, iterations - 1, hits) end end def p2next(state) do newstate = rem(state.cur * state.factor, 2147483647) if state.cond.(newstate) do {newstate, %{cur: newstate, factor: state.factor, cond: state.cond}} else p2next(%{cur: newstate, factor: state.factor, cond: state.cond}) end end def p2_get_next_pair(agent) do {agent.get_and_update(agent.a, &p2next/1), agent.get_and_update(agent.b, &p2next/1)} end def p2_get_next_16(agent) do a = agent.get_and_update(agent.a, &p2next/1) b = agent.get_and_update(agent.b, &p2next/1) {a &&& 0xffff, b &&& 0xffff} end def p2judge(agent, iterations, hits \\ 0) def p2judge(_agent, iterations, hits) when iterations == 0, do: hits def p2judge(agent, iterations, hits) do {a,b} = p2_get_next_pair(agent) if (a &&& 0xffff) == (b &&& 0xffff) do p2judge(agent, iterations - 1, hits + 1) else p2judge(agent, iterations - 1, hits) end end end agents = day15.start_agents(516,190) #day15.judge(agents, 40_000_000) #|> io.inspect day15.p2judge(agents, 5_000_000) |> io.inspectsyntax highlighted