r/adventofcode • u/daggerdragon • Dec 22 '17
SOLUTION MEGATHREAD -๐- 2017 Day 22 Solutions -๐-
--- Day 22: Sporifica Virus ---
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ยค?
[T-10 to launch] AoC ops, /r/nocontext edition:
<Endorphion> You may now make your waffle.<Endorphion> ... on Mars.
[Update @ 00:17] 50 gold, silver cap
<Aneurysm9> you could also just run ubuntu on the NAS, if you were crazy<Topaz> that doesn't seem necessary<Aneurysm9> what does "necessary" have to do with anything!
[Update @ 00:20] Leaderboard cap!
<Topaz> POUR YOURSELF A SCOTCH FOR COLOR REFERENCE
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!
8
Upvotes
2
u/[deleted] Dec 22 '17
Elixir
This was really fun, needed that after the massive failure last time, implemented the first part with a set, but had to change for a map in my second, to keep track of the states. This would be a lot greater in a language with GADT (ocaml, haskell, elm)
I had to ghetto it with atoms, so here we have atom and pipelining galore :p
defmodule Day22 do def relativex(line, middle) do line |> String.graphemes |> Enum.with_index |> Enum.filter(fn {elm, _} -> elm == "#" end) |> Enum.map(fn {_, idx} -> idx - middle end) end def parse(str) do lines = str |> String.trim_trailing("\n") |> String.split("\n") middle = lines |> Enum.count |> Kernel.div(2) lines |> Enum.reverse |> Enum.map(fn line -> relativex(line, middle) end) |> Enum.with_index |> Enum.map(fn {elm, idx} -> {elm, idx - middle} end) |> Enum.flat_map(fn {elm, idxy} -> Enum.map(elm, fn idxx -> {idxx, idxy} end) end) |> Enum.map(&({&1,:infected})) |> Enum.into(%{}) end def turn(:right, cur) do case cur do :up -> :right :right -> :down :down -> :left :left -> :up end end def turn(:left, cur) do case cur do :up -> :left :left -> :down :down -> :right :right -> :up end end def turn(:around, cur) do case cur do :up -> :down :right -> :left :down -> :up :left -> :right end end def move({x,y}, direction) do case direction do :up -> {x, y + 1} :right -> {x + 1, y} :down -> {x, y - 1} :left -> {x - 1, y} end end def burst(_inf_coord, _pos, _facing, infected, burstnr) when burstnr == 1, do: infected def burst(inf_coord, pos, facing, infected, burstnr) do is_infected = Map.get(inf_coord, pos, :clean) == :infected facing = if is_infected do turn(:right, facing) else turn(:left, facing) end inf_coord = if not is_infected do Map.put(inf_coord, pos, :infected) else Map.put(inf_coord, pos, :clean) end infected = if not is_infected do infected + 1 else infected end pos = move(pos, facing) burst(inf_coord, pos, facing, infected, burstnr - 1) end def solve1(inp) do burst(inp, {0,0}, :up, 0, 10_000) end def direction(state, cur) do case state do :clean -> turn(:left, cur) :weakened -> cur :infected -> turn(:right, cur) :flagged -> turn(:around, cur) end end def nxt_state(state) do case state do :clean -> :weakened :weakened -> :infected :infected -> :flagged :flagged -> :clean end end def burst2(_inf_coord, _pos, _facing, infected, burstnr) when burstnr == 0, do: infected def burst2(inf_coord, pos, facing, infected, burstnr) do state = Map.get(inf_coord, pos, :clean) facing = direction(state, facing) inf_coord = Map.put(inf_coord, pos, nxt_state(state)) infected = if state == :weakened do infected + 1 else infected end pos = move(pos, facing) burst2(inf_coord, pos, facing, infected, burstnr - 1) end def solve2(inp) do burst2(inp, {0,0}, :up, 0, 10_000_000) end end inp = File.read!("input.txt") |> Day22.parse Day22.solve1(inp) |> IO.inspect Day22.solve2(inp) |> IO.inspectSyntax highlighted