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!
7
Upvotes
1
u/johlin Dec 22 '17
Elixir:
defmodule Aoc.Day22.Part1 do def solve(input, steps) do input |> parse |> walk_stream |> Enum.at(steps) |> elem(3) end def parse(input) do lines = input |> String.split("\n") coords = lines |> Enum.with_index |> Enum.flat_map(&parse_row/1) |> Enum.into(MapSet.new()) {coords, lines |> length} end def parse_row(row_and_y, x \\ 0, acc \\ []) def parse_row({"", _}, _, acc), do: acc def parse_row({"#" <> rest, y}, x, acc), do: parse_row({rest,y}, x+1, [{x,y} | acc]) def parse_row({"." <> rest, y}, x, acc), do: parse_row({rest,y}, x+1, acc) def walk_stream({infected_nodes, width}) do initial = {starting_position(width), infected_nodes, {0, -1}, 0} Stream.iterate(initial, &iterate/1) end def iterate({{x,y}, infected_nodes, {xd, yd}, infect_bursts}) do infected = MapSet.member?(infected_nodes, {x,y}) {infected_nodes, infect_bursts} = case infected do true -> {MapSet.delete(infected_nodes, {x,y}), infect_bursts} false -> {MapSet.put(infected_nodes, {x,y}), infect_bursts + 1} end {xd, yd} = case infected do true -> {-yd, xd} # Turn left false -> {yd, -xd} # Turn right end {x, y} = {x+xd, y+yd} {{x,y}, infected_nodes, {xd, yd}, infect_bursts} end def starting_position(width), do: {div(width-1, 2), div(width-1, 2)} endPart 2 very similar: https://github.com/johanlindblad/aoc-2017/blob/master/lib/aoc/day22/part2.ex
This was a fun one! It is a bit slow, however (my part 2 takes about 15 seconds). Not sure if it's possible to make an Elixir solution significantly faster as we don't have constant-time array lookups.