This commit is contained in:
Adam Millerchip 2021-12-26 22:10:19 +09:00
parent 675985e57d
commit bd4acc8f17
30 changed files with 5699 additions and 0 deletions

995
2018/day1/input Normal file
View file

@ -0,0 +1,995 @@
-4
+9
+6
+8
+3
+14
+11
+7
-12
+4
-15
+2
-12
-4
+15
-8
-16
-4
+14
-11
-19
-2
+15
-4
-5
-1
+15
-8
+1
+10
+7
+18
+1
+10
+11
+17
-16
+4
-12
+14
+9
+6
+7
+10
+14
+7
+6
-3
+19
+18
+4
+16
+17
+11
+9
+7
-8
-1
-5
-12
-7
+4
-5
+2
+4
+3
+20
-19
+18
+12
+14
+5
-14
+7
-19
-20
+6
-3
+7
+15
+12
+11
+15
+2
+3
-17
-18
+1
+13
-3
+14
-1
-8
-9
-12
+15
-8
+10
+11
+15
+4
+6
+16
+1
+3
+13
-6
+14
-3
-12
-12
+14
+6
-10
+20
+5
+18
+11
+3
+17
+2
-9
-17
-14
+2
+9
+11
-2
+14
+5
-7
+18
-6
-9
-9
-10
-12
-16
-1
+14
-15
-9
-2
-6
-11
-14
-11
-19
+11
-12
-18
-5
+11
+18
+17
-5
-19
+14
+11
-2
-14
+17
+8
+3
+12
-9
+1
+23
+7
-12
+24
+10
-2
+6
+20
-16
-17
+19
-7
+11
+14
+21
-18
+1
+4
+8
-2
-5
-12
-13
+7
+19
+2
+8
+9
+8
+2
+17
+15
+18
+18
+18
-2
-13
-18
-12
-1
+17
-14
-15
+8
+20
+9
-7
+11
-15
-16
-11
-9
+11
+19
+15
+4
+15
+9
-3
+5
-18
+6
+17
+15
-8
-13
+16
+8
+17
+2
+18
+2
+2
+4
-10
+11
-3
+8
+2
+3
-12
+6
+12
-1
+21
-13
-17
-10
+13
-6
-18
-4
-6
-5
+18
-20
-6
-7
-17
-6
-18
+9
+16
+14
+10
+16
+1
-4
+1
+15
-9
-5
-4
-7
-7
-1
+13
-15
-1
-22
-19
+10
-8
-5
+16
-12
+17
+7
+4
-7
+4
+6
+5
-2
-1
+20
-8
-3
+7
-47
-10
+19
-27
-3
+13
-26
+1
+8
-30
-14
+3
+17
-16
-2
-11
+14
-8
-7
-10
-8
+20
+23
+26
+12
-25
-88
+4
+1
-29
-5
+16
-19
+15
+19
-27
-8
-18
-9
-12
-10
+14
-13
-14
-10
-21
-14
+6
-1
+21
+14
+6
+21
-2
+17
+20
-5
+17
-4
-14
-9
-11
-14
+17
+20
+10
+20
-80
+15
-27
-42
+7
-18
+14
-4
-16
-3
+10
-8
-25
-14
-3
+24
+3
+18
-35
+54
+29
-35
+63
+4
-119
-24
-57508
+1
-10
-10
-17
-8
-9
+4
-7
+19
+2
+19
+8
-16
-19
-2
+5
+2
+10
+11
-6
-18
+11
-17
-17
+12
+4
-2
-17
-5
+7
-18
-14
-3
-18
-16
+18
-1
-10
-8
-13
+12
-4
-9
+6
+11
-5
+9
+13
+16
+15
-5
+10
+13
-19
-16
-13
+5
-12
+8
+1
+14
+23
-1
+17
-15
-19
-9
+8
-2
+19
-13
-15
+2
+12
-15
-16
-20
-2
+14
+6
-1
-1
-3
-9
-3
-15
+6
+4
-8
+9
-14
-10
+9
-15
-16
-3
-18
-9
+18
-8
-16
-18
+14
+17
+9
+12
-7
+2
+15
+12
-7
-11
+13
+8
+5
+2
+10
-19
-12
-20
+10
+7
+19
-8
-7
+19
-18
-15
-9
-12
-18
+2
+12
+10
-5
+7
-15
+1
-11
-18
-8
-16
-16
+13
-19
-10
-5
-5
-18
+13
+3
+16
+17
+15
+19
-11
+15
-12
+2
+17
+17
-16
-15
+5
+20
-12
+5
+2
+7
+15
-6
-17
+18
-20
-8
-15
-18
-1
-20
-5
+18
-11
-15
+2
-15
-15
+8
-18
+1
+1
+5
+5
+11
+5
+15
+16
+19
-4
-7
-5
+8
-2
-19
+7
-6
+19
+17
+9
+2
+1
-15
-2
-6
-12
+19
-16
-9
+4
-3
+21
+6
+27
+14
-22
+18
+12
+18
+13
-10
+8
-13
-6
+10
-12
-17
-38
+21
-19
+18
-23
-7
+17
+8
+59
+3
-19
+22
+17
+15
+5
+24
+13
+15
+8
+18
-17
+16
+16
+20
+1
+7
-16
-15
+2
-18
-9
+1
+13
+5
-17
+22
-13
-21
-12
-4
+20
-31
-12
-34
+10
+2
+20
+22
-28
-19
-19
-2
+133
+17
-10
+18
-10
+6
+20
-10
+3
+11
+14
-5
+3
+20
+11
-9
-12
-1
-3
-19
+12
+14
+8
+12
+2
+18
+7
-19
+11
-22
+13
-9
+15
-13
+1
+20
+14
-9
+11
-18
+13
-21
-20
-16
+7
-14
+12
-1
+8
-16
-16
-13
+7
-3
+19
-22
-10
+6
+1
+16
+4
-1
-12
-16
-10
+29
+8
+18
-9
+11
+18
-6
-2
+4
-3
-8
-9
+21
+13
-23
-26
-22
-9
-24
-11
+2
-18
-42
+13
+46
-96
-7
-9
-131
-6
-21
+11
-18
+14
+28
-18
-11
-18
-48
+7
+69
+9
-24
-15
+46
-10
+137
-57522
+5
+4
+3
+16
-3
-18
+3
-9
-10
+11
+12
-8
-18
-18
-4
+18
+19
-4
-19
-19
+4
-15
+3
-16
-2
+12
+16
+9
+10
+13
+1
+21
+17
+18
+5
-4
-2
+15
+13
+2
+7
-19
+1
-16
-7
-10
+18
+12
-21
-7
+3
+16
+14
-13
+17
+2
+7
-2
-10
-17
+9
-5
+14
+13
+7
+15
-13
+1
-13
+16
-2
-5
-7
+15
+13
-8
-1
+18
+16
-15
-7
+11
+10
+16
-12
+15
-16
-14
+8
-16
-4
-4
-19
-17
-4
+18
+1
+14
-9
-15
+19
+8
+19
+14
+20
-14
+1
-18
+4
-3
+2
-20
+10
-2
+1
-3
-2
-3
+12
+6
+6
+11
+17
-7
+20
-16
+5
+6
-39
-26
-31
-29
+2
-19
+18
-6
-16
+14
+4
-19
+18
-14
-1
-10
-4
-17
+6
+17
+1
+1
-12
+21
-12
+16
-12
+16
-27
+22
-2
+30
+1
-3
+7
+23
-9
+20
+34
-142
-7
+5
+16
-23
-9
+7
-2
+12
-15
-4
-19
-16
+15
+13
+4
+4
-16
-7
+10
+17
-6
-15
+11
-5
-8
-18
+115524

5
2018/day1/part1.exs Normal file
View file

@ -0,0 +1,5 @@
File.stream!("input")
|> Stream.map(&String.trim/1)
|> Stream.map(&String.to_integer/1)
|> Enum.sum()
|> IO.puts()

27
2018/day1/part2.exs Normal file
View file

@ -0,0 +1,27 @@
defmodule Part2 do
def mark_seen(change, {prev_freq, seen}) do
freq = prev_freq + change
marked_freq = {freq, MapSet.member?(seen, freq)}
acc = {freq, MapSet.put(seen, freq)}
{[marked_freq], acc}
end
def run do
File.stream!("input")
|> Stream.map(&String.trim/1)
# Trying to work out why can't cycle over the stream
# Can't reproduce with this
# Stream.cycle([1]) |> Stream.transform(0, fn one, prev -> {[prev + one], prev + one} end) |> Enum.find(fn x -> x == 25 end)
# So maybe it's because a combination of the accumulator in the stream and Enum.find
|> Stream.map(&String.to_integer/1)
|> Stream.cycle()
|> Stream.transform({0, MapSet.new([0])}, &mark_seen/2)
|> Enum.find(fn {_freq, seen} -> seen end)
|> elem(0)
|> IO.puts()
end
end
Part2.run()

91
2018/day10/day10.exs Normal file
View file

@ -0,0 +1,91 @@
defmodule Star do
defstruct [:pos_x, :pos_y, :vel_x, :vel_y]
def move_all(stars, secs) do
Enum.map(stars, &move(&1, secs))
end
def move(star, secs) do
%Star{star | pos_x: star.pos_x + star.vel_x * secs, pos_y: star.pos_y + star.vel_y * secs}
end
end
defmodule Day10 do
@input_pattern ~r/=< ?(-?\d+), ?(-?\d+)>.*=< ?(-?\d+), ?(-?\d+)>/
def parse_line(line) do
[pos_x, pos_y, v_x, v_y] =
Regex.run(@input_pattern, line, capture: :all_but_first)
|> Enum.map(&String.to_integer/1)
%Star{pos_x: pos_x, pos_y: pos_y, vel_x: v_x, vel_y: v_y}
end
def init do
File.stream!("input")
|> Enum.map(&parse_line/1)
end
# Start with the first star, then compare all the others to find the extremities
def bounding_box([%Star{pos_x: x, pos_y: y} | _] = stars) do
Enum.reduce(stars, {x, y, x, y}, fn star, {min_x, min_y, max_x, max_y} ->
{
min(star.pos_x, min_x),
min(star.pos_y, min_y),
max(star.pos_x, max_x),
max(star.pos_y, max_y)
}
end)
end
def draw(stars) do
starfield = MapSet.new(stars, fn star -> {star.pos_x, star.pos_y} end)
{min_x, min_y, max_x, max_y} = bounding_box(stars)
grid =
for y <- min_y..max_y, x <- min_x..max_x do
eol = if x === max_x, do: "\n", else: ""
char = if MapSet.member?(starfield, {x, y}), do: "#", else: " "
char <> eol
end
Enum.join(grid)
end
def aligned?(stars) do
starfield = MapSet.new(stars, fn star -> {star.pos_x, star.pos_y} end)
Enum.all?(stars, &aligned?(&1, starfield))
end
def aligned?(star, starfield) do
neighbours = [
{star.pos_x - 1, star.pos_y - 1},
{star.pos_x - 1, star.pos_y},
{star.pos_x - 1, star.pos_y + 1},
{star.pos_x, star.pos_y - 1},
{star.pos_x, star.pos_y + 1},
{star.pos_x + 1, star.pos_y - 1},
{star.pos_x + 1, star.pos_y},
{star.pos_x + 1, star.pos_y + 1}
]
Enum.any?(neighbours, &MapSet.member?(starfield, &1))
end
def wait_for_alignment(stars, count) do
if aligned?(stars) do
{stars, count}
else
stars |> Star.move_all(1) |> wait_for_alignment(count + 1)
end
end
def go do
{stars, count} = init() |> wait_for_alignment(0)
IO.puts(draw(stars))
IO.puts("#{count} seconds")
end
end
Day10.go()

374
2018/day10/input Normal file
View file

@ -0,0 +1,374 @@
position=<-20620, -41485> velocity=< 2, 4>
position=<-51844, 41770> velocity=< 5, -4>
position=<-51817, -20670> velocity=< 5, 2>
position=< 21000, 52179> velocity=<-2, -5>
position=< 21051, 31360> velocity=<-2, -3>
position=< 41859, -41487> velocity=<-4, 4>
position=< 41830, 31361> velocity=<-4, -3>
position=<-51817, -51895> velocity=< 5, 5>
position=<-51836, -41484> velocity=< 5, 4>
position=< 21032, -51887> velocity=<-2, 5>
position=<-31003, -41482> velocity=< 3, 4>
position=< 52261, -51890> velocity=<-5, 5>
position=<-51836, 10547> velocity=< 5, -1>
position=< 10614, -10259> velocity=<-1, 1>
position=<-10194, 41776> velocity=< 1, -4>
position=<-10186, 10550> velocity=< 1, -1>
position=< 31431, -51892> velocity=<-3, 5>
position=<-51804, 52175> velocity=< 5, -5>
position=< 10601, 52183> velocity=<-1, -5>
position=<-51812, 10548> velocity=< 5, -1>
position=< 10633, 20959> velocity=<-1, -2>
position=<-41417, -41480> velocity=< 4, 4>
position=< 10628, 31360> velocity=<-1, -3>
position=<-10160, -20666> velocity=< 1, 2>
position=<-51793, -20673> velocity=< 5, 2>
position=<-41430, -41485> velocity=< 4, 4>
position=< 21032, -20670> velocity=<-2, 2>
position=<-30987, -51891> velocity=< 3, 5>
position=< 52280, -31080> velocity=<-5, 3>
position=<-30995, -10266> velocity=< 3, 1>
position=<-10177, -51888> velocity=< 1, 5>
position=<-30995, 10551> velocity=< 3, -1>
position=< 21028, 20961> velocity=<-2, -2>
position=< 31412, -51895> velocity=<-3, 5>
position=< 31467, -10260> velocity=<-3, 1>
position=< 31407, -51895> velocity=<-3, 5>
position=< 10636, 41773> velocity=<-1, -4>
position=< 31418, -51892> velocity=<-3, 5>
position=<-20620, 41773> velocity=< 2, -4>
position=<-10163, -10265> velocity=< 1, 1>
position=<-20594, -10264> velocity=< 2, 1>
position=< 52266, -10262> velocity=<-5, 1>
position=< 52223, 52178> velocity=<-5, -5>
position=< 21019, -20666> velocity=<-2, 2>
position=<-20620, 20958> velocity=< 2, -2>
position=< 21016, 20960> velocity=<-2, -2>
position=< 10593, -10259> velocity=<-1, 1>
position=< 21045, 31365> velocity=<-2, -3>
position=< 10609, 10548> velocity=<-1, -1>
position=< 21016, -20666> velocity=<-2, 2>
position=< 10598, -10265> velocity=<-1, 1>
position=<-41394, 20955> velocity=< 4, -2>
position=<-20612, -10262> velocity=< 2, 1>
position=<-30987, -41489> velocity=< 3, 4>
position=< 52261, 31361> velocity=<-5, -3>
position=< 31408, 31364> velocity=<-3, -3>
position=<-10181, -31076> velocity=< 1, 3>
position=<-20625, -10268> velocity=< 2, 1>
position=< 41846, 10551> velocity=<-4, -1>
position=<-20588, -31074> velocity=< 2, 3>
position=<-41407, 31364> velocity=< 4, -3>
position=<-20577, 41767> velocity=< 2, -4>
position=< 21040, 31361> velocity=<-2, -3>
position=<-20586, -51892> velocity=< 2, 5>
position=<-41386, 31364> velocity=< 4, -3>
position=< 21001, 20953> velocity=<-2, -2>
position=<-51797, -20671> velocity=< 5, 2>
position=<-20620, -41484> velocity=< 2, 4>
position=< 31433, -51887> velocity=<-3, 5>
position=< 10617, 31363> velocity=<-1, -3>
position=< 10598, 52175> velocity=<-1, -5>
position=<-41413, -51891> velocity=< 4, 5>
position=<-41386, -10260> velocity=< 4, 1>
position=<-51846, -20671> velocity=< 5, 2>
position=< 52273, -51892> velocity=<-5, 5>
position=<-51836, -51896> velocity=< 5, 5>
position=<-20596, 20959> velocity=< 2, -2>
position=< 41814, 31360> velocity=<-4, -3>
position=< 10620, -31073> velocity=<-1, 3>
position=<-41438, 31360> velocity=< 4, -3>
position=< 21060, 31361> velocity=<-2, -3>
position=<-20628, -41487> velocity=< 2, 4>
position=<-10185, -51896> velocity=< 1, 5>
position=<-31022, -20671> velocity=< 3, 2>
position=< 31407, 10551> velocity=<-3, -1>
position=< 41830, -51887> velocity=<-4, 5>
position=< 52263, 52177> velocity=<-5, -5>
position=<-41413, -10267> velocity=< 4, 1>
position=< 10653, -10260> velocity=<-1, 1>
position=<-20628, -31074> velocity=< 2, 3>
position=< 41830, -51892> velocity=<-4, 5>
position=<-51822, 20953> velocity=< 5, -2>
position=< 52221, 52181> velocity=<-5, -5>
position=<-20583, -41488> velocity=< 2, 4>
position=<-51813, -31082> velocity=< 5, 3>
position=< 41822, 52175> velocity=<-4, -5>
position=<-41442, -41482> velocity=< 4, 4>
position=<-10172, -31078> velocity=< 1, 3>
position=<-10178, -10263> velocity=< 1, 1>
position=<-51797, 31360> velocity=< 5, -3>
position=< 10650, 31364> velocity=<-1, -3>
position=<-51798, 10550> velocity=< 5, -1>
position=< 31444, -51893> velocity=<-3, 5>
position=< 21008, -51888> velocity=<-2, 5>
position=<-51792, -31078> velocity=< 5, 3>
position=<-30991, 20960> velocity=< 3, -2>
position=< 10606, -10263> velocity=<-1, 1>
position=<-41429, 31363> velocity=< 4, -3>
position=< 41843, 20960> velocity=<-4, -2>
position=< 31423, -51896> velocity=<-3, 5>
position=<-20586, 20957> velocity=< 2, -2>
position=< 21002, -20675> velocity=<-2, 2>
position=< 21056, 20953> velocity=<-2, -2>
position=< 31420, 10549> velocity=<-3, -1>
position=< 21029, 31365> velocity=<-2, -3>
position=< 21048, 20955> velocity=<-2, -2>
position=< 31463, -10264> velocity=<-3, 1>
position=<-31007, -41489> velocity=< 3, 4>
position=<-20595, -20675> velocity=< 2, 2>
position=<-51849, -20673> velocity=< 5, 2>
position=< 41856, -10264> velocity=<-4, 1>
position=<-31011, -20671> velocity=< 3, 2>
position=<-31033, 41767> velocity=< 3, -4>
position=<-10165, 20956> velocity=< 1, -2>
position=<-41418, -20667> velocity=< 4, 2>
position=< 21024, 41775> velocity=<-2, -4>
position=<-20572, 10547> velocity=< 2, -1>
position=<-41383, 52181> velocity=< 4, -5>
position=<-31022, 20956> velocity=< 3, -2>
position=< 31415, -51889> velocity=<-3, 5>
position=<-10184, -51887> velocity=< 1, 5>
position=<-41418, 10548> velocity=< 4, -1>
position=< 52238, 10555> velocity=<-5, -1>
position=<-41439, 10546> velocity=< 4, -1>
position=< 21013, -51887> velocity=<-2, 5>
position=< 52247, 41767> velocity=<-5, -4>
position=<-20599, -51895> velocity=< 2, 5>
position=< 41823, 31364> velocity=<-4, -3>
position=<-41394, 41773> velocity=< 4, -4>
position=<-41394, 10547> velocity=< 4, -1>
position=<-31027, -51893> velocity=< 3, 5>
position=< 31420, 10554> velocity=<-3, -1>
position=< 52258, -10267> velocity=<-5, 1>
position=< 52277, -20672> velocity=<-5, 2>
position=< 10601, -41488> velocity=<-1, 4>
position=< 52258, 31362> velocity=<-5, -3>
position=<-31031, -31078> velocity=< 3, 3>
position=<-30987, -31073> velocity=< 3, 3>
position=<-30990, 41775> velocity=< 3, -4>
position=< 31432, -41489> velocity=<-3, 4>
position=<-31001, 41767> velocity=< 3, -4>
position=<-20588, -20675> velocity=< 2, 2>
position=<-20591, 41769> velocity=< 2, -4>
position=<-31003, 20953> velocity=< 3, -2>
position=<-51793, 52178> velocity=< 5, -5>
position=<-41410, 31361> velocity=< 4, -3>
position=<-20580, 31369> velocity=< 2, -3>
position=<-20594, 31360> velocity=< 2, -3>
position=< 41855, -41487> velocity=<-4, 4>
position=<-10173, 20954> velocity=< 1, -2>
position=< 21016, 20954> velocity=<-2, -2>
position=< 41843, -51888> velocity=<-4, 5>
position=< 52241, -51887> velocity=<-5, 5>
position=<-51816, -31082> velocity=< 5, 3>
position=<-31035, -20666> velocity=< 3, 2>
position=< 41857, 31366> velocity=<-4, -3>
position=< 41814, -51896> velocity=<-4, 5>
position=< 31439, 20957> velocity=<-3, -2>
position=< 21036, 31366> velocity=<-2, -3>
position=<-20615, -41488> velocity=< 2, 4>
position=< 10634, -20674> velocity=<-1, 2>
position=< 52269, 20958> velocity=<-5, -2>
position=<-41441, -20671> velocity=< 4, 2>
position=<-30995, -20670> velocity=< 3, 2>
position=< 41872, -20672> velocity=<-4, 2>
position=< 52222, 31364> velocity=<-5, -3>
position=<-41434, 20956> velocity=< 4, -2>
position=< 41814, 10554> velocity=<-4, -1>
position=< 41833, -41480> velocity=<-4, 4>
position=<-31007, 31368> velocity=< 3, -3>
position=< 10609, -41481> velocity=<-1, 4>
position=<-51844, 41769> velocity=< 5, -4>
position=< 41814, 31361> velocity=<-4, -3>
position=< 41818, 20957> velocity=<-4, -2>
position=< 41859, -51888> velocity=<-4, 5>
position=< 31455, -20667> velocity=<-3, 2>
position=< 21045, 10549> velocity=<-2, -1>
position=< 10609, 10550> velocity=<-1, -1>
position=<-20628, 10552> velocity=< 2, -1>
position=<-41431, -20671> velocity=< 4, 2>
position=< 41858, 52181> velocity=<-4, -5>
position=< 10595, 20953> velocity=<-1, -2>
position=<-10208, 20960> velocity=< 1, -2>
position=<-51817, 10553> velocity=< 5, -1>
position=<-20568, -31074> velocity=< 2, 3>
position=< 52241, 10555> velocity=<-5, -1>
position=< 31452, 41774> velocity=<-3, -4>
position=< 41865, -41485> velocity=<-4, 4>
position=< 10638, -31080> velocity=<-1, 3>
position=<-20571, 31364> velocity=< 2, -3>
position=<-41394, 31363> velocity=< 4, -3>
position=< 31407, 10546> velocity=<-3, -1>
position=< 41870, 31366> velocity=<-4, -3>
position=< 21040, -31074> velocity=<-2, 3>
position=< 10614, -20666> velocity=<-1, 2>
position=<-51801, 52182> velocity=< 5, -5>
position=<-31027, 41767> velocity=< 3, -4>
position=< 31415, -20671> velocity=<-3, 2>
position=<-51817, -41481> velocity=< 5, 4>
position=< 31452, 52177> velocity=<-3, -5>
position=< 21027, -20675> velocity=<-2, 2>
position=<-31035, 20957> velocity=< 3, -2>
position=<-51814, -31077> velocity=< 5, 3>
position=<-20569, 41769> velocity=< 2, -4>
position=< 21013, -51889> velocity=<-2, 5>
position=< 21033, -51892> velocity=<-2, 5>
position=<-10173, -20669> velocity=< 1, 2>
position=<-20596, 41770> velocity=< 2, -4>
position=< 21027, 52183> velocity=<-2, -5>
position=<-41418, -31076> velocity=< 4, 3>
position=< 52264, 52179> velocity=<-5, -5>
position=< 21048, 10551> velocity=<-2, -1>
position=< 52221, 20956> velocity=<-5, -2>
position=<-51793, 20954> velocity=< 5, -2>
position=<-30999, 10550> velocity=< 3, -1>
position=< 41827, -31075> velocity=<-4, 3>
position=<-41423, 10555> velocity=< 4, -1>
position=< 52272, 41771> velocity=<-5, -4>
position=< 21008, 52180> velocity=<-2, -5>
position=<-20595, -31078> velocity=< 2, 3>
position=<-10178, -51890> velocity=< 1, 5>
position=< 21013, 10548> velocity=<-2, -1>
position=<-51793, -41483> velocity=< 5, 4>
position=<-51808, 10547> velocity=< 5, -1>
position=< 21050, -41489> velocity=<-2, 4>
position=<-20599, -41481> velocity=< 2, 4>
position=<-51833, 31367> velocity=< 5, -3>
position=<-51817, -31082> velocity=< 5, 3>
position=<-30995, 31364> velocity=< 3, -3>
position=< 31455, 10546> velocity=<-3, -1>
position=< 31433, 41776> velocity=<-3, -4>
position=<-30995, -10264> velocity=< 3, 1>
position=<-51849, -51889> velocity=< 5, 5>
position=<-31026, 20957> velocity=< 3, -2>
position=< 31468, 31360> velocity=<-3, -3>
position=< 31449, -51893> velocity=<-3, 5>
position=<-41397, 20959> velocity=< 4, -2>
position=<-10181, 10549> velocity=< 1, -1>
position=< 10638, -10268> velocity=<-1, 1>
position=< 41843, -10262> velocity=<-4, 1>
position=<-10189, 52183> velocity=< 1, -5>
position=< 41859, -51893> velocity=<-4, 5>
position=< 41819, -51893> velocity=<-4, 5>
position=< 31431, -10263> velocity=<-3, 1>
position=<-51793, 52179> velocity=< 5, -5>
position=< 10593, -10263> velocity=<-1, 1>
position=< 21040, 31369> velocity=<-2, -3>
position=< 10649, -10267> velocity=<-1, 1>
position=< 41875, -10268> velocity=<-4, 1>
position=<-20600, 10554> velocity=< 2, -1>
position=< 31468, 20953> velocity=<-3, -2>
position=<-31019, 20958> velocity=< 3, -2>
position=<-20624, -51892> velocity=< 2, 5>
position=< 41842, 20953> velocity=<-4, -2>
position=<-20599, -41480> velocity=< 2, 4>
position=< 10645, -51896> velocity=<-1, 5>
position=<-10216, 52175> velocity=< 1, -5>
position=< 21024, 31363> velocity=<-2, -3>
position=< 41870, 10551> velocity=<-4, -1>
position=<-20572, -20672> velocity=< 2, 2>
position=<-20583, 31369> velocity=< 2, -3>
position=<-20586, 31363> velocity=< 2, -3>
position=<-20596, 10549> velocity=< 2, -1>
position=< 31436, 41772> velocity=<-3, -4>
position=<-41418, 20960> velocity=< 4, -2>
position=<-10205, -51889> velocity=< 1, 5>
position=< 10649, -31074> velocity=<-1, 3>
position=< 10622, 20959> velocity=<-1, -2>
position=< 52274, -10268> velocity=<-5, 1>
position=< 52222, -51896> velocity=<-5, 5>
position=< 52266, -31077> velocity=<-5, 3>
position=< 41854, -10259> velocity=<-4, 1>
position=< 31463, -20670> velocity=<-3, 2>
position=< 21045, 10552> velocity=<-2, -1>
position=<-10197, 20955> velocity=< 1, -2>
position=< 31431, -51892> velocity=<-3, 5>
position=< 52250, -10262> velocity=<-5, 1>
position=< 41830, -20672> velocity=<-4, 2>
position=<-20596, -51887> velocity=< 2, 5>
position=<-10203, -41480> velocity=< 1, 4>
position=< 41850, 52174> velocity=<-4, -5>
position=< 10628, 52179> velocity=<-1, -5>
position=<-30986, 31360> velocity=< 3, -3>
position=<-20591, -31074> velocity=< 2, 3>
position=< 52234, -51887> velocity=<-5, 5>
position=<-20604, -51891> velocity=< 2, 5>
position=< 10593, 41768> velocity=<-1, -4>
position=< 31439, 31362> velocity=<-3, -3>
position=< 41859, -51892> velocity=<-4, 5>
position=<-10205, 31369> velocity=< 1, -3>
position=<-31027, 10548> velocity=< 3, -1>
position=< 10633, 10548> velocity=<-1, -1>
position=< 21028, 20953> velocity=<-2, -2>
position=< 21016, 20959> velocity=<-2, -2>
position=< 31434, -10263> velocity=<-3, 1>
position=<-10192, 10555> velocity=< 1, -1>
position=< 52234, 31366> velocity=<-5, -3>
position=< 41822, 31363> velocity=<-4, -3>
position=< 41838, -51895> velocity=<-4, 5>
position=<-31007, 20958> velocity=< 3, -2>
position=<-41402, 31362> velocity=< 4, -3>
position=< 52229, 41769> velocity=<-5, -4>
position=< 10641, -41482> velocity=<-1, 4>
position=<-51804, -41484> velocity=< 5, 4>
position=< 41827, 20962> velocity=<-4, -2>
position=<-10208, -31080> velocity=< 1, 3>
position=< 41826, 41771> velocity=<-4, -4>
position=< 21041, -10266> velocity=<-2, 1>
position=<-51808, -51895> velocity=< 5, 5>
position=<-51841, 41774> velocity=< 5, -4>
position=<-20596, 41774> velocity=< 2, -4>
position=< 41866, 31364> velocity=<-4, -3>
position=< 31407, -20672> velocity=<-3, 2>
position=< 10643, -20671> velocity=<-1, 2>
position=< 41865, 10546> velocity=<-4, -1>
position=<-51792, 10551> velocity=< 5, -1>
position=<-30977, -10262> velocity=< 3, 1>
position=< 31436, 41775> velocity=<-3, -4>
position=< 31443, 20960> velocity=<-3, -2>
position=<-30977, 10549> velocity=< 3, -1>
position=<-31022, -31082> velocity=< 3, 3>
position=<-41434, -41488> velocity=< 4, 4>
position=<-20604, -31074> velocity=< 2, 3>
position=< 52261, 31367> velocity=<-5, -3>
position=< 21029, 20960> velocity=<-2, -2>
position=< 10625, 52174> velocity=<-1, -5>
position=<-41433, 41771> velocity=< 4, -4>
position=< 52269, 20954> velocity=<-5, -2>
position=< 10625, 41768> velocity=<-1, -4>
position=< 41830, 20959> velocity=<-4, -2>
position=< 31431, -10266> velocity=<-3, 1>
position=<-20572, 41774> velocity=< 2, -4>
position=< 52265, -20668> velocity=<-5, 2>
position=< 10595, -41485> velocity=<-1, 4>
position=<-20580, -10264> velocity=< 2, 1>
position=< 52270, -10268> velocity=<-5, 1>
position=<-31019, 31362> velocity=< 3, -3>
position=< 31439, -10262> velocity=<-3, 1>
position=<-20618, 20957> velocity=< 2, -2>
position=<-41407, 31364> velocity=< 4, -3>
position=< 41814, -31080> velocity=<-4, 3>
position=<-10208, -20673> velocity=< 1, 2>
position=< 31412, -20673> velocity=<-3, 2>
position=< 31463, 52183> velocity=<-3, -5>
position=<-30983, -51896> velocity=< 3, 5>
position=< 31447, 10553> velocity=<-3, -1>
position=< 41843, -51895> velocity=<-4, 5>
position=< 31447, -10259> velocity=<-3, 1>
position=<-41438, -31082> velocity=< 4, 3>
position=< 10593, -31078> velocity=<-1, 3>
position=<-30985, 10546> velocity=< 3, -1>
position=<-31027, -41487> velocity=< 3, 4>
position=< 21026, 52174> velocity=<-2, -5>
position=<-51809, 52178> velocity=< 5, -5>
position=<-41429, -10267> velocity=< 4, 1>
position=< 52256, 10551> velocity=<-5, -1>
position=< 52277, 41769> velocity=<-5, -4>
position=<-31000, 41767> velocity=< 3, -4>
position=<-20583, -51887> velocity=< 2, 5>
position=<-20594, 10550> velocity=< 2, -1>
position=<-41393, 20953> velocity=< 4, -2>
position=< 21002, -20671> velocity=<-2, 2>
position=<-10200, 41776> velocity=< 1, -4>
position=< 52258, 31369> velocity=<-5, -3>

93
2018/day11/day11.exs Normal file
View file

@ -0,0 +1,93 @@
defmodule Day11 do
@serial 7511
@size 300
def hundreds(lvl) when lvl < 100, do: 0
def hundreds(lvl) do
[_units, _tens, hundreds | _] = Integer.digits(lvl) |> Enum.reverse()
hundreds
end
def power_level(x, y, serial) do
rack_id = x + 10
rack_id |> Kernel.*(y) |> Kernel.+(serial) |> Kernel.*(rack_id) |> hundreds() |> Kernel.-(5)
end
def grid(serial \\ @serial) do
for x <- 1..@size, y <- 1..@size, into: %{} do
{{x, y}, power_level(x, y, serial)}
end
end
def total_power(x, y, grid) do
for x <- x..(x + 2), y <- y..(y + 2) do
grid[{x, y}]
end
|> Enum.sum()
end
def find_largest_3x3(grid) do
for x <- 1..(@size - 2), y <- 1..(@size - 2) do
{{x, y}, total_power(x, y, grid)}
end
|> Enum.max_by(fn {_, power} -> power end)
end
def part1 do
{{x, y}, power} = grid() |> find_largest_3x3()
"#{x},#{y} (total power #{power})"
end
# Entry point
def largest_total_power_at(x, y, grid) do
size = 1
power = grid[{x, y}]
largest_total_power_at(x, y, grid, size, power, size, power)
end
# Terminating condition, square size has reached the edge of the grid
def largest_total_power_at(x, y, _grid, size, _power, max_size, max_power)
when x + size > @size or y + size > @size do
{x, y, max_size, max_power}
end
# Calculate extra power for square of size + 1 and take the max of the two
def largest_total_power_at(x, y, grid, size, power, max_size, max_power) do
new_x = x + size
new_y = y + size
new_row = for row_x <- x..new_x, do: grid[{row_x, new_y}]
# Minus 1 to avoid counting the corner twice
new_col = for col_y <- y..(new_y - 1), do: grid[{new_x, col_y}]
new_power = Enum.sum([power | new_row ++ new_col])
new_size = size + 1
{max_size, max_power} =
if new_power > max_power do
{new_size, new_power}
else
{max_size, max_power}
end
largest_total_power_at(x, y, grid, new_size, new_power, max_size, max_power)
end
# Still very slow, managed to avoid recalculating larger squares, but still recalculates
# smaller squares that are a subset of a larger square we already calculated.
# Could fix it, but 300x300 completes in a few mins.. maybe will come back to this
# I Wonder if replacing all the comprehensions with reduce would have a strong effect
def part2 do
grid = grid()
{x, y, size, power} =
for x <- 1..@size, IO.inspect(301 - x), y <- 1..@size do
largest_total_power_at(x, y, grid)
end
|> Enum.max_by(fn {_x, _y, _size, power} -> power end)
"Part 2 Answer: #{x},#{y},#{size} (power: #{power})"
end
end
IO.puts(Day11.part1())
IO.puts(Day11.part2())

101
2018/day12/day12.exs Normal file
View file

@ -0,0 +1,101 @@
defmodule Day12 do
defmodule Parser do
def parse(filename) when is_binary(filename) do
File.open!(filename, [:utf8], &parse/1)
end
def parse(file) do
IO.read(file, String.length("initial state: "))
state = file |> IO.read(:line) |> String.trim() |> String.to_charlist() |> Enum.with_index()
IO.read(file, :line)
{state, parse_spec(file)}
end
def parse_spec(file), do: parse_spec(file, IO.read(file, :line), %{})
def parse_spec(_file, :eof, spec), do: spec
def parse_spec(file, line, spec) do
[pattern, <<result::utf8>>] = ~r/(.{5}) => (.)/ |> Regex.run(line, capture: :all_but_first)
parse_spec(
file,
IO.read(file, :line),
Map.put(spec, String.to_charlist(pattern), result)
)
end
end
def evolve(input, _spec, 0, _previous), do: input
def evolve(input, spec, generations, previous) do
next = generation(input, spec)
IO.inspect("#{generations}: #{next |> visualise}")
if stable?(next, input) do
# Stable state, so we can just add the remaining generation count to the index numbers and finish early
next = Enum.map(next, fn {pot, idx} -> {pot, idx + generations - 1} end)
evolve(next, spec, 0, input)
else
evolve(next, spec, generations - 1, input)
end
end
def stable?(next, prev), do: visualise(next) === visualise(prev)
def generation(input, spec) do
input |> pad |> propagate(spec) |> strip
end
def propagate([a, b, c, d, e | rest], spec) do
{_, pot} = c
pattern = visualise([a, b, c, d, e])
[{Map.get(spec, pattern), pot} | propagate([b, c, d, e | rest], spec)]
end
def propagate(rest, _spec) when length(rest) == 4, do: []
# Pads with 4 empty pots. If the spec contained ..... => #, would need to pad with 5
def pad(list) do
list |> Enum.reverse() |> pad_rear |> Enum.reverse() |> pad_front
end
def pad_front([{?., _}, {?., _}, {?., _}, {?., _} | _] = done), do: done
def pad_front([{_, i} | _] = list), do: pad_front([{?., i - 1} | list])
def pad_rear([{?., _}, {?., _}, {?., _}, {?., _} | _] = done), do: done
def pad_rear([{_, i} | _] = list), do: pad_rear([{?., i + 1} | list])
# Removes leading and trailing empty pots
def strip([{?., _}]), do: []
def strip([{?., _} | list]), do: strip(list)
def strip([{?#, _} | _] = list), do: strip_tl(Enum.reverse(list))
def strip_tl([{?., _} | list]), do: strip_tl(list)
def strip_tl(list), do: Enum.reverse(list)
def visualise(input) do
Enum.map(input, fn {x, _i} -> x end)
end
def part1 do
{input, spec} = Parser.parse("input")
evolve(input, spec, 20, [])
|> Enum.filter(fn {plant, _} -> plant === ?# end)
|> Enum.map(fn {_, pot} -> pot end)
|> Enum.sum()
end
def part2 do
{input, spec} = Parser.parse("input")
evolve(input, spec, 50_000_000_000, [])
|> Enum.filter(fn {plant, _} -> plant === ?# end)
|> Enum.map(fn {_, pot} -> pot end)
|> Enum.sum()
end
end
part1 = Day12.part1()
part2 = Day12.part2()
IO.puts("part 1: #{part1}")
IO.puts("part 2: #{part2}")

34
2018/day12/input Normal file
View file

@ -0,0 +1,34 @@
initial state: #.##.##.##.##.......###..####..#....#...#.##...##.#.####...#..##..###...##.#..#.##.#.#.#.#..####..#
..### => .
##..# => #
#..## => .
.#..# => .
#.##. => .
#.... => .
##... => #
#...# => .
###.# => #
##.## => .
....# => .
..##. => #
..#.. => .
##.#. => .
.##.# => #
#..#. => #
.##.. => #
###.. => #
.###. => #
##### => #
####. => .
.#.#. => .
...#. => #
#.### => .
.#... => #
.#### => .
#.#.# => #
...## => .
..... => .
.#.## => #
..#.# => #
#.#.. => #

179
2018/day13/day13.exs Normal file
View file

@ -0,0 +1,179 @@
defmodule Day13 do
defmodule Cart do
defstruct dir: nil, turn: :left
end
defmodule Parser do
# track pieces
# | - / \ +
# Carts
# ^ v < >
# Inital cart = straight track underneath
# Sample input:
# /->-\
# | | /----\
# | /-+--+-\ |
# | | | | v |
# \-+-/ \-+--/
# \------/
def parse_file(filename) do
rows =
File.read!(filename)
|> String.split("\n")
|> Enum.map(&String.to_charlist/1)
{_, track, carts} =
Enum.reduce(rows, {0, %{}, %{}}, fn row, {row_idx, track, carts} ->
{_, _, track, carts} = Enum.reduce(row, {row_idx, 0, track, carts}, &parse_char/2)
{row_idx + 1, track, carts}
end)
{track, carts}
end
defp parse_char(?\s, {row_idx, col_idx, track, carts}) do
{row_idx, col_idx + 1, track, carts}
end
defp parse_char(cart, args) when cart in '^v<>', do: parse_cart(cart, args)
defp parse_char(track, args) when track in '|-/\\+', do: parse_track(track, args)
defp parse_cart(?^, {row_idx, col_idx, track, carts}) do
carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :up})
parse_track(?|, {row_idx, col_idx, track, carts})
end
defp parse_cart(?v, {row_idx, col_idx, track, carts}) do
carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :down})
parse_track(?|, {row_idx, col_idx, track, carts})
end
defp parse_cart(?<, {row_idx, col_idx, track, carts}) do
carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :left})
parse_track(?-, {row_idx, col_idx, track, carts})
end
defp parse_cart(?>, {row_idx, col_idx, track, carts}) do
carts = Map.put(carts, {row_idx, col_idx}, %Cart{dir: :right})
parse_track(?-, {row_idx, col_idx, track, carts})
end
defp parse_track(char, {row_idx, col_idx, track, carts}) do
track = Map.put(track, {row_idx, col_idx}, <<char::utf8>>)
{row_idx, col_idx + 1, track, carts}
end
end
# Plan:
# Build a giant coordinate map containing what piece of track is at a coordinate
# (spaces with no track can be skipped)
# Build a separate map of carts
# Carts should contain their location, dir, and next turn
# -> Sort the map each tick to determine cart order
# For a tick, go through each cart and update it's location (key), dir, and next turn
# - if there's a collision, we can stop early and return the location
def sort(carts) do
Enum.sort(carts, fn {{row1, col1}, _}, {{row2, col2}, _} ->
cond do
row1 < row2 -> true
row1 == row2 -> col1 <= col2
row1 > row2 -> false
end
end)
end
def next_pos(row, col, %Cart{dir: :up}), do: {row - 1, col}
def next_pos(row, col, %Cart{dir: :down}), do: {row + 1, col}
def next_pos(row, col, %Cart{dir: :left}), do: {row, col - 1}
def next_pos(row, col, %Cart{dir: :right}), do: {row, col + 1}
def turn(cart, track) when track in ["-", "|"], do: cart
def turn(%Cart{dir: :left} = cart, "/"), do: %Cart{cart | dir: :down}
def turn(%Cart{dir: :right} = cart, "/"), do: %Cart{cart | dir: :up}
def turn(%Cart{dir: :up} = cart, "/"), do: %Cart{cart | dir: :right}
def turn(%Cart{dir: :down} = cart, "/"), do: %Cart{cart | dir: :left}
def turn(%Cart{dir: :left} = cart, "\\"), do: %Cart{cart | dir: :up}
def turn(%Cart{dir: :right} = cart, "\\"), do: %Cart{cart | dir: :down}
def turn(%Cart{dir: :up} = cart, "\\"), do: %Cart{cart | dir: :left}
def turn(%Cart{dir: :down} = cart, "\\"), do: %Cart{cart | dir: :right}
def turn(%Cart{dir: :left, turn: :left}, "+"), do: %Cart{dir: :down, turn: :straight}
def turn(%Cart{dir: :left, turn: :straight}, "+"), do: %Cart{dir: :left, turn: :right}
def turn(%Cart{dir: :left, turn: :right}, "+"), do: %Cart{dir: :up, turn: :left}
def turn(%Cart{dir: :right, turn: :left}, "+"), do: %Cart{dir: :up, turn: :straight}
def turn(%Cart{dir: :right, turn: :straight}, "+"), do: %Cart{dir: :right, turn: :right}
def turn(%Cart{dir: :right, turn: :right}, "+"), do: %Cart{dir: :down, turn: :left}
def turn(%Cart{dir: :up, turn: :left}, "+"), do: %Cart{dir: :left, turn: :straight}
def turn(%Cart{dir: :up, turn: :straight}, "+"), do: %Cart{dir: :up, turn: :right}
def turn(%Cart{dir: :up, turn: :right}, "+"), do: %Cart{dir: :right, turn: :left}
def turn(%Cart{dir: :down, turn: :left}, "+"), do: %Cart{dir: :right, turn: :straight}
def turn(%Cart{dir: :down, turn: :straight}, "+"), do: %Cart{dir: :down, turn: :right}
def turn(%Cart{dir: :down, turn: :right}, "+"), do: %Cart{dir: :left, turn: :left}
def crashed?(pos, unmoved_carts, moved_carts) do
Map.get(unmoved_carts, pos) || Map.get(moved_carts, pos)
end
def tick([], _unmoved_carts, moved_carts, _track), do: {:tock, moved_carts}
def tick([{{row, col}, cart} | sorted_carts], unmoved_carts, moved_carts, track) do
# This cart is no longer unmoved (so it can't crash into itself)
unmoved_carts = Map.delete(unmoved_carts, {row, col})
next_pos = next_pos(row, col, cart)
if crashed?(next_pos, unmoved_carts, moved_carts) do
{:boom, next_pos}
else
next_track = Map.fetch!(track, next_pos)
moved_cart = turn(cart, next_track)
tick(sorted_carts, unmoved_carts, Map.put(moved_carts, next_pos, moved_cart), track)
end
end
def find_collision(track, carts) do
case tick(sort(carts), carts, %{}, track) do
{:tock, carts} -> find_collision(track, carts)
{:boom, {row, col}} -> "#{col},#{row}"
end
end
def part1 do
{track, carts} = Parser.parse_file("input")
find_collision(track, carts)
end
# Part 2.
# Instead of stopping on a crash, we should instead remove the two carts that crashed.
# Terminating condition is when there is only one cart left.
def tick2([], _unmoved_carts, moved_carts, _track), do: moved_carts
def tick2([{{row, col}, cart} | sorted_carts], unmoved_carts, moved_carts, track) do
unmoved_carts = Map.delete(unmoved_carts, {row, col})
next_pos = next_pos(row, col, cart)
if crashed?(next_pos, unmoved_carts, moved_carts) do
unmoved_carts = Map.delete(unmoved_carts, next_pos)
moved_carts = Map.delete(moved_carts, next_pos)
# Could have deleted an unmoved, so need to re-sort the remaining carts to process
tick2(sort(unmoved_carts), unmoved_carts, moved_carts, track)
else
next_track = Map.fetch!(track, next_pos)
moved_cart = turn(cart, next_track)
tick2(sorted_carts, unmoved_carts, Map.put(moved_carts, next_pos, moved_cart), track)
end
end
def find_last_cart(track, carts), do: find_last_cart(track, carts, sort(carts))
def find_last_cart(_track, _carts, [{{row, col}, _cart}]), do: "#{col},#{row}"
def find_last_cart(track, carts, sorted_carts) do
find_last_cart(track, tick2(sorted_carts, carts, %{}, track))
end
def part2 do
{track, carts} = Parser.parse_file("input")
find_last_cart(track, carts)
end
end

150
2018/day13/input Normal file
View file

@ -0,0 +1,150 @@
/--------------------------------------------------------------------------------------------------------\
| /--------------------------------------------------\ /----------------------------+\
| | | | /------------------------++-----\
/-------------------------\ | /+--------------------------------------------------+----\ | | || |
| /---------------------+--+----++-\ /------------------------------------+----+-------------+---+--------------------\ || |
| | /+--+----++-+-----------+-----\ /+----+-------------+--\| /------------+---++----\|
| /+--------------------++--+----++-+-----------+----\| || | | || /-----+------------+-\ || ||
/------+--++--------------------++\ | || | /----+----++-----------------------------++----+-------------+--++\| | | | || ||
| | || /----------------+++-+----++-+------+----+----++--------------------\ || | | |||| | | | || ||
| | || | ||| | || | | | || /----------+--------++----+-------------+--++++-----+---------\ | | || ||
| | || | ||| | || | | |/---++---------+----------+--------++----+-------------+--++++-----+---------+--+-+-++--\ ||
|/-----+--++---+---\ ||| | || | | || || /-----+----------+--------++----+-------------+--++++-----+----\ | | | || | ||
|| | || | | ||| | /--++-+------+----++---++---+-----+----------+--------++--<-+-------------+--++++-----+--\ |/---+--+-+-++--+\||
|| | || | | ||| | | \+-+------+----++---++---+-----+----------+--------++----/ | |||| | | || | | | || ||||
|| | || | | ||| | | | | | /-++---++---+-----+----------+--------++----------------\ | |||| | | || | | | || ||||
|| | || | | ||| | | | | | | || || | | /+--------++----------------+-+--++++-----+--+-++--\| | | || ||||
|| | || /+---+------------+++-+-+---+\| | | || || | | ||/-------++----------------+-+--++++---\ | | || || | | || ||||
|| \--++--++---+------------+/| | | ||| | | || || | | ||| || | | |||| | | | || || | | || ||||
|| || || | | | \-+---+++------+--+-++---++---+-----+---------+++-------++----------------+-+--++++---+-+--+-++--++--+-+-/| ||||
|| /----++--++---+------------+-+---+---+++------+--+-++---++---+---\ | /-------+++-\ || | | |||| | | | || || | ^ | ||||
|| | || || | \-+---+---+++------+--+-++---+/ | | | | ||| | \+----------------+-+--/||| | | | || || | | | ||||
|| | || || | /---------+--\| ||| | /+-++---+----+---+-+-+-------+++-+------+----------------+-+---+++---+-+-\| || || | | | ||||
|| | || || | | | /++---+++---\ | || ||/--+----+---+-+-+-------+++-+------+------------\ | | ||| | | || |\--++--+-+--+--+/||
|| | || || | | | ||| /+++---+--+-++-+++--+\ | | | | ||| | | | | | ||| | | || | || | | | | ||
|| | /--++--++---+----+---------+-+++--++++---+--+-++-+++--++---+---+-+-+-------+++-+------+----\ | | | ||| | | || | || | | | | ||
|| | | || || |/---+---------+-+++--++++---+--+-++-+++--++-\ | | | | ||| | | | | | | ||| | | || | || | | | | ||
|| | | || |\---++---+---------+-+++--++++---+--+-++-+++--++-+-+---+-+-+-------+/| | | | | | | ||| | | || | || | | | | ||
|| | | || | || | /--+-+++--++++---+--+-++-+++--++-+\| | | | | | | /--+----+-------+---+-+---+++---+-+\|| | || | | | | ||
|| \-+--++--+----++---+------+--+-+++--++++---+--+-++-+++--++-+++---/ | | /--+-+-+---+--+-\ | | | \---+++---+-++++-+---++--+-+--/ | ||
|| | || /+----++---+------+--+-+++--++++---+--+-++-+++--++-+++-----+-+----+-\| | | | | | | | | ||| | |||| | || | | | ||
|| | || || || | | | ||| |||| | | || ||| || ||| | | | || | | | | | | /-----+---+--\ ||| | |||| | || | | | ||
|| | || || || | | | ||| |||| | | |^ ||| || ||| | | | || | | | | | | | v | | ||| | |||| | || | | | ||
|| | || || /-++---+------+--+-+++--++++--\| | || ||| || ||| | | | || | | | | | | | | | | ||| | |||| | || | | | ||
|| | || || | || | | | ||| |||| || | || ||| ||/+++-----+-+----+-++-+\| | |/+--+-+-----+\ | | ||| | |||| | || | | | ||
|| | || || | || | | | ||| |||| || | || ||| |||||| \-+----+-++-+++---+--+++--+-+-----++--+--+--+++---+-++++-+---+/ | | | ||
||/----+--++-++--+-++\ | | | ||| |||| || | || ||| |||||| | | || ||| | ||| | | || | | ||| | |||| | | | | | ||
||| | || || | ||| | | | ||| |||| || | || ||| |||||| | | || ||| | ||| | | v| | |/-+++---+-++++-+---+---+-+-----+\||
||| | || || | ||| | | | ||| |||| || | || ||| |||||| | | || \++---+--+++--+-+-----++--+--++-+++---/ |||| | | | | ||||
||| | || || v ||| | | | ||| |||| || | || ||| |||||| | | || || | ||| | | || | || ||| |||| | | | | ||||
||| | || || | ||| | | | ||| |||| || | || ||| |||||| /---+----+-++--++---+--+++--+-+--<--++--+--++-+++-\ |||| | | | | ||||
||| | || || | ||| | | | |||/-++++--++--+-++-+++--++++++---+---+----+-++--++---+--+++--+-+-----++-\| || ||| | |||| | | | | ||||
||| | || || | ||| | | | |||| |||| || | || ||| /++++++---+---+----+-++--++---+--+++--+-+---\ || || || ||| | |||| | | | | ||||
||| | || || | ||| | | | |||| |||| || | \+-+++-+++++++---+---+----+-++--++---+--+++--+-+---+-++-++--++-+++-+---++/| | | | | ||||
||| | \+-++--+-+++--+------+--+-++++-++++--++--+--+-+++-+/||||| | | /-+-++--++---+--+++--+-+---+-++-++--++-+++-+---++-+-+-<-+---+\| ||||
/+++----+---+-++--+-+++--+------+--+-++++-++++--++--+--+-+++-+-+++++---+---+--+-+-++--++---+--+++--+-+-\ | || || || ||| | || | | | ||| ||||
|||| | | || | ||| | | | |||| |||| || | | ||| | ||||| | | | | || || | ||| | | | | || || || ||\-+---++-+-+-<-+---++/ ||||
|||| | | \+--+-+++--+------+--+-++++-++++--++--+--+-+++-+-+++++<--+---+--+-+-/| || | ||| | | | | || || || || | || | | | || ||||
||||/---+---+--+--+-+++--+------+-\| |||| |||| ||/-+--+-+++-+-+++++---+---+--+-+--+--++---+--+++--+-+-+-+-++-++--++-++--+---++-+-+---+---++--\ ||||
|||||/--+---+--+--+-+++--+------+-++-++++-++++--+++-+\ | ||| | ||||| /-+--<+--+-+--+--++--\| ||| | | | | || || || || | || | | | || | ||||
|||||| | | | | ||| | | || |||| |||| ||| || | ||| | ||||| | | | | | | || |\--+++--+-+-+-+-++-++--++-++--+---+/ | | | || | ||||
|||||| | \--+--+-+++--+------+-++-++++-+++/ ||| || | |\+-+-+++++-+-+---+--+-+--+--++--+---+++--+-+-+-+-++-++--++-++--+---+--+-+---+---++--+---/|||
|||||| | | /+-+++--+------+-++-++++-+++---+++-++-+-+-+-+-+++++-+-+---+--+-+--+--++--+---+++\ | | | | || || || || | | | | | || | |||
|||||| | | || ||| | | ||/++++-+++---+++-++-+-+-+-+-+++++-+-+---+--+-+--+--++--+---++++-+-+-+-+-++-++--++\|| | | | | | || | |||
|||||| | | || ||| | | ||||||| ||| ||| || | | | \-+++++-+-+---+--+-+--+--++--+---++++-+-+-+-//++-++--+++++\ | | | | | || | |||
|\++++--+------+-++-+++--+------+-+/||||| ||| ||| || | | | ||||| | | \--+-+--+--+/ | |||| | | | ||| || |||||| | | | | | || | |||
| |||| | | || ||| | | | ||||| ||| ||| || | | | ||||| | | /----+-+--+--+---+---++++-+-+-+--+++-++\ |||||| | | | | | || | |||
| |||| | | || ||| | |/+-+++++-+++---+++-++-+-+-+---+++++-+-+-+---\| | | | | |||| | | | ||| ||| |||||| | | | | | || | |||
| |||| | | || ||| | ||| ||||| |\+---+++-++-+-+-+---+++++-+-+-+---++-+--+--+---+---/||| | | | ||| ||| |||||| | | | | | || | |||
| |||| | | || ||| | ||| ||||| |/+---+++-++-+-+-+---+++++-+-+-+---++-+--+--+---+----+++-+-+-+\ ||| ||| |||||| | | | | | || | |||
| ||||/-+------+-++\||| | /--+++-+++++-+++-\ ||| || | |/+---+++++-+-+-+---++-+--+--+---+----+++-+-+-++-+++-+++-++++++-+---+--+-+---+---++--+-\ |||
| ||||| | | |||||| | | ||| ||||| ||| | ||| || | ||| ||||| | | | || | | | | ||| |/+-++-+++-+++-++++++-+---+--+-+-\ | || | | |||
|/+++++-+------+-++++++--+---+--+++-+++++-+++-+-+++-++-+-+++---+++++-+-+-+---++-+--+-\| | ||| ||| || ||| ||| |||||| | | | | | | || | | |||
||v|||| | | |||||| | | ||| |||||/+++-+-+++-++-+-+++---+++++-+-+-+---++-+--+-++---+----+++-+++-++-+++-+++-++++++-+---+--+-+-+-+---++-\| | |||
||||||| \------+-++++++--+---+--+++-+++++++++-+-+++-++-+-+++---+++++-+-+-+---++-+--+-++---+----+++-/|| || ||| ||| |||||| | | | | | | || || | |||
||||||| | |||||| | | ||| ||||||||| | ||| || | ||| /-+++++-+-+-+---++-+--+-++--\| |||/-++-++-+++\||| |||||| | | | | | | || || | |||
||\++++--------+-+++/|| | | ||| ||||||||| | ||| \+-+-+++-+-+++++-+-+-+---++-+--+-++--++----++++-++-++-+++++++-++++/| | | | | | | || || | |||
|| |||| /------+-+++-++--+---+--+++-+++++++++-+-+++--+-+-+++-+-+++++-+-+\| || | | || || |||| || || ||||||| |||| | | | | | | | || || | |||
|| |||| | | ||| || | | ||| ||||||||| | ||| | | ||\-+-+++++-+-+++---++-+--+-++--++----++++-++-++-+/||||| |||| | | | | | | | || || | |||
|| |||| | | ||| || | | ||| ||||||||| | ||| | | || | ||||| | ||| || | | || || |||| || || | ||||| |||| | | \--+-+-+-+---++-++-+--+/|
||/++++-+------+-+++-++--+---+--+++-+++++++++-+-+++--+-+-++--+-+++++\| ||| || | | || ||/---++++-++-++\| ||||| |||| | | | | | | || || | | |
||||||| | | ||| || | | ||| |||||||||/+-+++--+-+-++--+-+++++++-+++---++-+--+-++--+++--\|||| || |||| ||||| |||| | | | | | | || || | | |
||||||| | | ||| || | | /+++-+++++++++++-+++--+-+-++--+-+++++++-+++---++-+--+-++--+++--+++++-++-++++-+++++-++++-+-+-\ | | | | || || | | |
||||||| | | |\+-++--+---+-++++-+++++++++++-/|| | | \+--+-+++++++-+++---++-+--+-++--+++--+++++-++-++++-+++++-++++-+-+-+----+-+-+-+---/| || | | |
||||||| | | | | || | | |||| ||||||||||| || | | | | ||||||| ||| || | | || ||| ||||| || |||| ||||| |||| | | | | | | | | || | | |
||||||| | | | | || | | |||| ||||||||||| || | \--+--+-+++++++-+++---++-+--+-++--+++--+++++-++-++++-+++/| |||| | | | | | | | | || | | |
|||||||/+------+-+-+-++\ | | |||| ||||||||||| || | | | ||||||| ||\---++-+--+-++--+++--+++++-++-++++-+++-/ |||| |/+-+----+-+-+-+----+-++-+-\| |
||||||||| | | | ||| | | |||| ||||||||||| || | | | ||||||| || || | | || ||| ||||| || |||| ||| |||| ||| | | | | | | || | || |
||||||||| | | | ||| | /+-++++-+++++++++++--++--+----+--+-+++++++-++----++-+--+-++--+++--+++++-++-++++-+++---++++-+++-+----+-+\| | | || | || |
||||||||| | | | ||| | || |||| ||||||||||| || | | | ||||||| || || \--+-++--+++--++/|| || |||| ||| |||| ||| | | ||| | | || | || |
||||||||| | | | ||| | |\-++++-++++++++++/ || | /--+--+-+++++++-++----++----+-++--+++--++-++-++-++++-+++---++++-+++-+----+-+++-+-\ | || | || |
||||||||| | | | ||| | | |||| |||||||||| || | | | | ||||||| || || | || ||| || || || |||| ||| |||| ||| | | ||| | | | || | || |
||||||||| | | | ||| | | |||| |||||||||| || | | | | ||||||| \+----++----+-++--+++--++-++-++-++++-+++---++++-++/ | | ||| | | | || | || |
||||||||| | | | ||| | | |||| |||||||||| ||/-+-+--+--+-+++++++--+----++----+-++--+++\ |\-++-++-++++-/|| |||| || | | ||| | | | || | || |
||||||||| | | | ||| | | |||| |||||||||| ||| | | | | ||||||| | || | || |||| | || || |||| || |||| || | | ||| | | | || | || |
||||||||| | | | ||| | | |||| |||||||||\---+++-+-+--+--+-+++++++--+----++----+-++--++++-/ || || |||| || |||| || | | ||| | | | || | || |
||||||||| | | | ||| | | |||| ||||||||| ||| | |/-+--+-+++++++--+-\ || | || |||| || || |||| || |||\-++--+----+-+++-+-+--+-++-+-++-/
||||||||| | | | ||| |/-+--++++-+++++++++----+++-+-++-+--+-+++++++--+-+--++--\ | || |||| || || |||| || ||| || | | ||| | | | || | ||
||||||||| | | | ||| \+-+--++++-++/|||\++----+++-+-++-+--+-/|||||| | | || | | || ||||/---++-++-++++--++---+++\ || | | ||| | | | || | ||
||||||||| | | | ||| | |/-++++-++-+++-++----+++-+-++-+--+--++++++--+-+--++--+-+-++--+++++---++-++-++++--++---++++-++--+\ | ||| | | | || | ||
||||||||\------+-+-+-+++--+-++-++++-++-+++-++----+++-+-++-+--+--++++++--/ | || | | || ||||| || || |||| || /++++-++--++---+-+++-+-+--+-++\| ||
|||||||| /---+-+-+-+++--+-++-++++-++-+++-++----+++-+-++-+--+--++++++----+--++--+-+\|| ||||| || || ||^| || ||||| || || | ||| | | | |||| ||
|||||||| /+---+-+-+-+++--+-++-++++-++-+++-++----+++-+-++-+--+\ |||||\----+--++--+-++++--+/||| || || |||| || ||||| || || | ||| | | | |||| ||
|||||\++--++---+-+-+-+++--+-++-++++-++-+++-++----+++-/ || |/-++-+++++-----+--++--+-++++--+-+++---++-++-++++--++--+++++-++\ || | ||| | | | |||| ||
||||| || || | | | ||| | || |||| || ||| || ||| || || || ||||| | || | \+++--+-+++---++-++-++++--++--+++++-+++-++---+-+++-/ | | |||| ||
||||| || || | |/+-+++--+-++-++++-++-+++\|| ||| || || || ||||| | || | ||| | ||| || \+-++++--++--+++++-+++-++---+-++/ | | |||| ||
||||| || || | ||| ||| | || |||| || |||||| ||| || || || ||||| | || | ||| | ||| /-++--+-++++--++--+++++-+++-++--\| || | | |||| ||
||||| || || | ||| ||| | || |||| || |||||| |\+---++-++-++-+++++-----+--++--+--+++--+-+++-+-++--+-++++--++--+++++-+++-++--++-++----+--+-+/|| ||
\++++-++--++---+-+++-+++--+-++-++++-++-++++++----+-+---++-++-++-+++++-----+--++--+--+++--+-+++-+-++--+-/||| || ||||| ||| || || || | | | || ||
|||| \+--++---+-++/ ||| | || |||| || |||||| | | || || || ||||| | || | ||| | ||| | || | ||| || ||||| ||| || || || | | | || ||
|||| |/-++---+-++--+++--+-++-++++-++-++++++---\| | || || || ||||| | || | ||| | ||| | || | ||| || ||||| ||| || || || | | | || ||
|||| || || | || ||| | || |||| || |||||| || | || || || ||||| | |\--+--+++--+-+++-+-++--+--+++--++--+++++-+++-++--++-++----+--/ | || ||
|||| || || | || ||| | || |||| || |||||| || | || || || ||||| | | | ||| | ||| | || | ||| || \++++-+++-++--++-++----+----+-/| ||
|||| || || | || ||| | || |||| || |||||| || | || ||/++-+++++-----+--+---+--+++--+-+++-+-++--+--+++--++---++++-+++\|| || || | | | ||
|||| || || | || ||| | |\-++++-++-++++++---++-+---++-+++++-+++++-----+--+---+--+++--+-+++-+-++--+--+++--++---++++-+++++/ || || | | | ||
|||| || || | || ||| | | |||| || |||||| || | || ||||| ||||| | | | ||| | ||| | || | ||| || |||| ||||| || || | | | ||
|||| || || | || ||| | | |||| || ||||\+---++-+---++-+++++-+++++-----+--+---+--+++--+-+++-+-++--+--/|| || |||| |\+++---++-++----+----+--+-/|
|||| || || | || ||| | | |||| |\-++++-+---+/ | /-++-+++++\||||| | | | ||| | ||| | || | || || |||| | ||| || || | | | |
|||| || |\---+-++--+++--+-+--++++-+--++++-+---+--+-+-++-+++++++++++-----+--+---+--/|| | ||| | || |/--++--++\ |||| | ||| || || | | | |
|||| || | | || ||| | | |||| | \+++-+---+--+-+-++-+++++++++++-----+--+---+---++--+-+++-+-++--++--++--+++--++++-+-+++---+/ || | | | |
|||| || | | || ||| | | |||| | ||| | | | | || \++++++++++-----+--+---+---++--+-+++-+-++--++--++--+++--++++-+-+++---+--++----+----+--/ |
|||| || | | || ||| | | |||| | \++-+---+--+-+-++--++++++++++-----+--+---+---++--+-+++-+-++--++--++--+/| |||| | ||| | || | | |
|||| || | | || ||| \-+--++++-+----++-+---+--+-+-++--++++++++++-----+--+---/ || | ||| \-++--++--++--+-+--++++-+-+++---/ || | | |
|||| || | | || ||| | ||||/+----++-+---+--+-+-++--++++++++++-----+--+-------++--+-+++---++--++--++-\| | |||| | ||| || | | |
|||| || \----+-++--+++----+--++++++----++-+---+--+-+-++--+++/|\++++-----+--+-------+/ | ||| || || || || | |||| | ||| || | | |
|||| || | || ||| | |||||| || | | | | || ||| | |||| | | | | ||| || || || || | |||| | ||| || | | |
|||| || | || ||| | |||||| || | | | | || ||| | |||| | | | | ||| || || || || | |||| | ||| || | | |
|||| || | || ||| | |||||| || | | | | || ||| | |||| | | | | ||| || || || || |/-++++-+-+++------++----+----+\ |
|||| || | || ||| | |\++++----++-+---+--+-+-++--+++-+-+/|| | | | | ||| || || || || || |||| | ||| || | || |
|||| || \-++--+++----+--+-++++----++-/ | | | || ||| | | \+-----+--+-------+---+-+++---++--++--++-++-++-++++-+-+++------/| | || |
|||| || || ||| | | |||| || | | \-++--+++-/ | | | | | | ||| || || || || || |||| | ||| | | || |
|||| || || /+++----+--+-++++----++-----+--+---++--+++---+--+-\ | | |/--+-+++---++--++--++-++-++-++++-+-+++-------+----+----++-\ |
|||| || || |||| | | |||| || | | || ||| | | | | | || | ||\>--++--++--++-++-++-+++/ | ||| | | || | |
|||| || || |||| | | ||\+----++-----+--+---++--+++---+--+-+---+--+-------++--+-++----++--++--++-/| || ||| | ||| | | || | |
|||| || || |||| | | || | || | | \+--+++---+--+-+---+--+-------++--+-++----++--++--++--+-++-+++--+-+++-------+----/ /--++-+--+\
|||| || || |||| | \-++-+----++-----+--+----+--+++---+--+-+---+--+-------++--+-++----++--++--++--+-++-+++--+-++/ | | || | ||
|||| || || |||| | ||/+----++-----+--+----+--+++---+--+-+---+--+------\|| | || || || || | || ||| | || | | || | ||
|||| || || |\++----+----++++----++-----+--+----+--+++---/ | | | | ||| | || || || |\--+-++-+++--/ || | | || | ||
|||| || || | || | |||| || | | | ||| | | | | ||| | || || || | | || ||| || | | || | ||
|||| || |\-+-++----+----++++----+/ | | | ||| | | | | ||| |/++----++--++--+---+-++-+++----++--------+-\ | || | ||
||\+--++--------+--+-/| | |||| /--+-----\| | | ||| | | | | ||| |||| || || | | || ||| || | | | || | ||
|| | || | | | | |||| | | || | | ||| | | | | ||| |||| || || | | || ||| || | | | || | ||
|| | || | | | | /--++++-+--+-----++--+----+--+++------+<+---+\ | ||| |||| || || | | |\-+++----++--------+-+----+--+/ | ||
|| | || v | | | | \+++-+--+-----++--+----+--+++------+-+---++-/ ||| |||| || \+--+---+-+--/|| || | | | | | ||
\+-+--++--------+--+--+----+-+---+++-+--+-----++--+----+--+++------+-+---++--------+/| |||| || | | | | || || | | | | | ||
| | || | | | | | ||| | | || | | ||| | | || | | ||\+----++---+--/ | | || || | | \--+--+--+/
| | |\--------+--+--+----+-+---+++-+--+-----+/ \----+--+++------+-+---++--------+-+--++-/ || | | | || || | | | | |
| | | | | | | | ||\-+--+-----+--------+--+++------+-+---++--------+-+--++------++---+------+-+---+/ || | | | | |
| | | | | | | | || | \-----+--------+--+++------+-+---++--------+-+--++------++---+------+-+---+-----++--------+-+-------/ | |
| | | \--+--+----+-+---++--+--------+--------+--+++------+-+---++--------+-+--++------/| | | | | || | | | |
| | | | | \-+---++--+--------+--------+--+++------+-+---++--------+-+--++-------+---+------+-+---+-----++--------/ | | |
| | | | | \---++--+--------+--------+--+++------+-+---+/ | | || | \------+-/ | || | | |
| | | \--+----------++--+--------+--------+--+++------+-/ | | | || | | | || | | |
| | | | || | | | \++------+-----+---------+-+--++-------+----------+-----+-----/| | | |
\-+--+---------------+----------++--+--------+--------+---++------/ | | | || | | | | | | |
\--+--------------<+----------/\--+--------+--------+---++------------+---------/ | || | | \------+----------+----------+--/
| | | | \---++------------/ \--++-------+----------+------------+----------+----------/
| | \--------/ || || \----------/ | |
| | \+---------------------------++-------------------------------/ |
\---------------/ | || |
\---------------------------/\------------------------------------------/

6
2018/day13/test Normal file
View file

@ -0,0 +1,6 @@
/->-\
| | /----\
| /-+--+-\ |
| | | | v |
\-+-/ \-+--/
\------/

7
2018/day13/test2 Normal file
View file

@ -0,0 +1,7 @@
/>-<\
| |
| /<+-\
| | | v
\>+</ |
| ^
\<->/

155
2018/day14/day14.exs Normal file
View file

@ -0,0 +1,155 @@
defmodule Day14 do
# Cyclical linked list
# Use a map, with a ref as the key.
# Each element contains the value, and next pointer
# Keep two pointers for the current recipies
defmodule Recipe do
defstruct ~w/score next/a
end
defmodule State do
defstruct ~w/recipes first_elf second_elf last target count target_count last_seq desired_sequence/a
end
def init(target_count) do
desired_sequence =
target_count
|> Integer.to_string()
|> String.split("", trim: true)
|> Enum.map(&String.to_integer/1)
|> List.to_tuple()
last_seq =
(for(_i <- 1..(tuple_size(desired_sequence) - 2), do: nil) ++ [3, 7])
|> List.to_tuple()
first_elf = System.unique_integer()
second_elf = System.unique_integer()
%State{
first_elf: first_elf,
second_elf: second_elf,
last: second_elf,
target: nil,
target_count: target_count,
count: 2,
desired_sequence: desired_sequence,
last_seq: last_seq,
recipes: %{
first_elf => %Recipe{score: 3, next: second_elf},
second_elf => %Recipe{score: 7, next: first_elf}
}
}
end
def combine_recipes(a, b) do
(a + b)
|> Integer.to_string()
|> String.split("", trim: true)
|> Enum.map(&String.to_integer/1)
end
def append_score(score, %{last: prev_last, recipes: recipes} = state) do
last_seq =
state.last_seq
|> Tuple.delete_at(0)
|> Tuple.append(score)
last = System.unique_integer()
updated_recipes =
recipes
|> Map.put(prev_last, %Recipe{recipes[prev_last] | next: last})
|> Map.put(last, %Recipe{score: score, next: recipes[prev_last].next})
state = %State{
state
| last: last,
recipes: updated_recipes,
count: state.count + 1
}
state =
if state.count === state.target_count do
%State{state | target: last}
else
state
end
if state.last_seq === state.desired_sequence do
state
else
%State{state | last_seq: last_seq}
end
end
def next_recipe(current, 0, _recipes), do: current
def next_recipe(current, steps, recipes) do
next_recipe(recipes[current].next, steps - 1, recipes)
end
def next_recipes(%{first_elf: first_elf, second_elf: second_elf, recipes: recipes} = state) do
%State{
state
| first_elf: next_recipe(first_elf, recipes[first_elf].score + 1, recipes),
second_elf: next_recipe(second_elf, recipes[second_elf].score + 1, recipes)
}
end
# Set the target pointer when the target count is reached
def set_target(%{count: target, last: last} = state, target), do: %State{state | target: last}
def set_target(state, _target), do: state
def compute_recipes(%{count: count, target_count: target} = state) when count >= target + 10,
do: state
def compute_recipes(%{first_elf: elf1, second_elf: elf2, recipes: recipes} = state) do
combine_recipes(recipes[elf1].score, recipes[elf2].score)
|> Enum.reduce(state, &append_score/2)
|> next_recipes()
|> compute_recipes()
end
def next_ten_scores(_recipes, _current, scores, 10), do: scores
def next_ten_scores(recipes, current, scores, count) do
next = recipes[current].next
scores = scores <> Integer.to_string(recipes[next].score)
next_ten_scores(recipes, next, scores, count + 1)
end
def part1 do
state = init(330_121) |> compute_recipes()
next_ten_scores(state.recipes, state.target, "", 0)
end
# Part 2
# Produce recipes until the last 6 are the puzzle input
# Then the answer is the count before those 6
def find_sequence(%{desired_sequence: desired, last_seq: desired, count: count}) do
count - tuple_size(desired)
end
def find_sequence(%{first_elf: elf1, second_elf: elf2, recipes: recipes} = state) do
if rem(state.count, 100_000) == 0 do
IO.puts((state.last_seq |> Tuple.to_list() |> Enum.join()) <> " (#{state.count})")
end
combine_recipes(recipes[elf1].score, recipes[elf2].score)
|> Enum.reduce(state, &append_score/2)
|> next_recipes()
|> find_sequence()
end
# TODO both 1245 and the actual answer are +1. Fix.
def part2 do
IO.puts("tests...")
init(51589) |> find_sequence |> IO.puts()
init(1245) |> find_sequence |> IO.puts()
init(92510) |> find_sequence |> IO.puts()
init(59414) |> find_sequence |> IO.puts()
IO.puts("answer: (after about 20M items)...")
init(330_121) |> find_sequence
end
end

250
2018/day2/input Normal file
View file

@ -0,0 +1,250 @@
kbqwtcvzgumhpwelrnaxydpfuj
kbqwtcvzgsmhpoelryaxydiqij
kbqwpcvzssmhpoelgnaxydifuj
kbqgtcvxgsmhpoalrnaxydifuj
kbqwtcvygsmhpoelrnaxydiaut
kbqwtcvjgsmhpoelrnawydzfuj
kbqftcvzgsmhpoeprnaxydifus
rbqwtcgzgsxhpoelrnaxydifuj
kbqwtlvzgvmhpoelrnaxkdifuj
kbqwtcvzgsmhpolqrnaxydifub
kbqbtcqzgsmhposlrnaxydifuj
kbqwmcvzgswhpoelxnaxydifuj
kbqwtyvzgsmhkoelrnsxydifuj
khqwtcvzgsmhqoelinaxydifuj
koqwtcvzcsmhpoelrnaxydizuj
kbqwtcvzlsmhpoezrnaxydmfuj
kbqwtcvzdsmhpoelrjaxydifij
kbqwtcvzgsmhpoelrncxyjifuk
kbtwtcvzgsmhpoelonaxydiwuj
kbqwfcrzgsmhpoelrnaeydifuj
kbqutcvkgsmhpoelrnfxydifuj
kbqwtcvzgsmvvoelrnaxydihuj
kbqwtcvzhymhpoelrnaxydifyb
kbqctcvzgumhpoalrnaxydifuj
kuqktcvzgsmhpoelrnaxydieuj
kbqwtcvzgsmvpozlrnaxydifmj
kbqwtcvzgsmhpojlraaxydiouj
kbqwtcvzgmmhpoelknaxydizuj
kbwwtcvzgsmhpoefrnaxydifij
kbqwucvzgsmhpoelvnahydifuj
kbqwtcvzpsmhpgelrqaxydifuj
kblqtcvzgsmhpoeirnaxydifuj
kbqwtcvzgsmhpovlrnabydifum
kbqwwcvzgsmhpoelrnaoydnfuj
kyqwdcvzgsmhpoelrnaxfdifuj
kbqftcvzgsmxpoelknaxydifuj
kbqwtsvzksmhpoelqnaxydifuj
kbqwtcvzgsmhplelrnauydifux
kbqytcvzgsmhpkelrnaxydefuj
kbqwtcvzgsmjjoelrlaxydifuj
kbqvtcvzgsmhpoelnnaxydafuj
kbqwtcvzgsjhioelrnaxpdifuj
kbqptcvpgsmhpoelrnaxydiful
kbqwjcazgimhpoelrnaxydifuj
kbqxtcvzgwmhpaelrnaxydifuj
kbqwtcezgsmhqoelrnaxydifub
kbqwtcvzgsmhooelynaxydifuf
kbqwtwvzgsmkpoelrnaxrdifuj
nbqwtcvugsmhpoelrnzxydifuj
kbvwqcvzgsmhpoelsnaxydifuj
kbqwtcyzjsmhpoelrnaxymifuj
kbqwtcvzgsmhpoclrnaxykzfuj
kbbwtcvzgsmhyodlrnaxydifuj
kbwwtcvzgsmytoelrnaxydifuj
kbmwtcczgpmhpoelrnaxydifuj
ubqwtcvzgsmmpoblrnaxydifuj
kbqwtcvzgrmhpoelrnaxnrifuj
kbqwhcvzgsmhpoelynaaydifuj
kbqwtcvzgsmtpoelrcpxydifuj
kdqwtchzgsmhpoelrmaxydifuj
qbqrncvzgsmhpoelrnaxydifuj
kbqwtcvzghshpoelrnaxodifuj
kbqwhcvzgsmhpoelknaxydiwuj
ebqwtcvzgsmhpoelrotxydifuj
kbqwacvzusmhpoelryaxydifuj
kbqwtcvggsmhpoelrnaxygifyj
kbqwtcvzgsmhpoelrnaxycwfuo
kzqwzcvzgsmhpoelrxaxydifuj
khqwtcvzgsmhpoelrnaxldifyj
kbqwtbtzgsmhpoelrnaxydifud
gbqwtcvzgqmhpoelrnaxydifrj
kbqdtqvzgwmhpoelrnaxydifuj
kbqwscvzgsmhpoelrpaxypifuj
kmqwtcdzgsmhpoelenaxydifuj
klqwtcvvgsmhpoelrfaxydifuj
kbuwtcvzgsmhpoelrtaxyuifuj
kbqwtcvrgomhpoelrnaxydijuj
kbqwtgvzgsmhzoelrnpxydifuj
kbqltcvzgsmhooeljnaxydifuj
kbqwtcvzgbmxpoelrnaxydivuj
kbqdtcmzgsmhpoelrnaxydmfuj
kbqwtcazgsmhpoplrnacydifuj
kbqztcvegsmhpoelrnvxydifuj
kbqwtcvzgsmhpoecrnaxydzfsj
kbqwtcvzgsmepoelrnaqydifuf
kbqwtcqzgsmhpoelrnoxydivuj
kbqwtcvzgsmhpoeylnaxydhfuj
kbqwtcvfgsmhpoelrnaxgdifyj
kbqwtcvzgsmhnbelrnaxyfifuj
kbqwtcvzgsmhpoelrnaxbdffmj
kwqwtcvogtmhpoelrnaxydifuj
kdqwtcvzggyhpoelrnaxydifuj
kbqwtuvzgtmhpoelrnaxydifxj
kbqctdvzcsmhpoelrnaxydifuj
kbqwtcvzgsmhpoblrniyydifuj
kbqwucvzzsmhpoelrnvxydifuj
kbqwtcvzgslzpoelrnaxydiruj
kbqwtdmzgsmhpwelrnaxydifuj
kbqwtcvzgsmhpoilrnaxqiifuj
kbqwtcvzgsmhpgelrnaxydisnj
kbdwtqvzgsmhpoelrnaxydivuj
kbqvtdvzgsmhpoelrjaxydifuj
kfqwtcvzgsmhpoeurnyxydifuj
kbqwtcvzgsmhpoglrnaxqkifuj
kbqwtcvrgsmhpoelrnajydifnj
xbqwpcvzgjmhpoelrnaxydifuj
kbqwtcvzgsmhpoelrdaxvdihuj
kbuwtcvzssmhpoklrnaxydifuj
kbqwtcvzgqmhpoelrnzxydifbj
kbqwtcvzgsmhsoeoknaxydifuj
kfqltcvzgsmhpoelrnaxydifnj
qbqwtsvzgsmhpoelrnaxodifuj
kbqwwevzgsmypoelrnaxydifuj
kbqwtcuzgimhpoelrnaxydffuj
kxqwlcvzgsmhpoelrnaxyrifuj
nbqwtcvzgsmhpoelryaxyiifuj
kbqwtcvzgsmhhoxlreaxydifuj
mbqwtcvzfsmxpoelrnaxydifuj
kbqwttvzgsmhpoeqrnaxidifuj
kbqwtcvzgamhpielrnaxyiifuj
rfqwtcvzgsmhpoelrnaxydifun
kbpwtqvzgsmbpoelrnaxydifuj
kbqwtcvzgsmhpoqlroaxydifua
hbqwtcvzksmhpoelrnaxydbfuj
kaqutcvzgsmhpoelrnaxydiiuj
kbqctcvzgsnhpoelrcaxydifuj
kbqwtnvzgsmhpoelrnaxydqfoj
kbqwtcvzhsmhpoelrnaxydifyb
ubqwtcvcgsmhooelrnaxydifuj
kbqwtcvrgsmhpoelrnaxtdivuj
kbqwtcvzgsmhplelrnmxydifaj
ebqwlcvzghmhpoelrnaxydifuj
hbqwtcvzgsmhpoelrnaqyeifuj
kbqstcvzgsmeprelrnaxydifuj
kbqwtcvogsthpoelrnnxydifuj
ybqwtcvzgdmhpoelrnaxydufuj
kbqutcvzgsmhpoelrnaxydifgx
kbqwtcvzgsmhpozlunadydifuj
kkqwtcvzgsmhpuefrnaxydifuj
kbqrtcvzgsmhpoelrnaxcdifuq
kbqwtcvzjsmupoelrnaxydiluj
kbqwmcvzgsuhpoelrnaxydifhj
kbqwfcvzgsmhpoelrnaxydkzuj
kbqatcvzgsdhpoeyrnaxydifuj
kbtwtcvzusmhpoelrxaxydifuj
kbqwtcwzgsmhpoelrnaxysofuj
kbqqtcvmgsmhpoevrnaxydifuj
kbqwjcvzgsmhpoelrnaxydhuuj
mbdwtcvzgsmhpoelqnaxydifuj
kbqwtcvlgsmhpoelrdaxydifaj
kbqwtcvzgsmmpoelrlaxydnfuj
kbqwtchfggmhpoelrnaxydifuj
kbqqtcvzgsyhpoelrnaxyoifuj
knqwtcvzqsmupoelrnaxydifuj
kdqdtcvzgsmhpoelrnaxydmfuj
kbqwtcvzgsmhptelrnawyhifuj
kbqwtcvzgrmhpoeqrnaxydifuw
kbnxtcvzgsmhpoelrnauydifuj
kbqwacvsgsmhpoelrnaxydifgj
kbqwtcvzgsmhpperrnaxydifuc
gbqwtcvzgsqhxoelrnaxydifuj
kbqwtcvzgsmhpoeljgaxydifwj
kbqktcvzgsmhpotlrnatydifuj
bbqwtcvzgsmhpoilrnaxydjfuj
kbqwecvdgsmhpoelrnaxypifuj
keqwtcvzgemhpotlrnaxydifuj
kbqptcvzgsmvpoelrnaxydixuj
kbqwbctzgsmhpoelrnaxydifup
kbqwtcvzgszhpbelrnzxydifuj
mbqwtcvtgsmhpoeyrnaxydifuj
kbqwtcvzgsmhqcelrhaxydifuj
kbqotcvzgsmhooelrnazydifuj
kbqwtcvzgsmhpoelmpaxyiifuj
kbqwtcvwgsmypoclrnaxydifuj
kbqwtcvsgskhpoelrnaxykifuj
kbqwtcvzgszvpoelrnwxydifuj
kbqwtcvzgsmhpoejonaxydrfuj
kbqwtcvzgsmhkoelrnazyqifuj
kbzwtzvzgsmhptelrnaxydifuj
kbqwtcdzgsmhptelrnaxydiduj
kbqwtcvzgamhpoelrnakyzifuj
kbqwtcvzgsmhpoeonnaxydifxj
kbqwtcvzgsmhpoeranaxydifej
kbqwscvzgsmhpoelunaxydimuj
cbqwtcvzgsmhpoelrdaxydefuj
vbqwtcjzgsmhpoelrnaxydifua
kmqwtcvzksmhpoeljnaxydifuj
kbqwtcvzgsmppojlrnasydifuj
kaqwtcvfgsmhpoelrnaxydiauj
khqwccvzgsmhpoelrnaxydifud
vbqwtcvzrsmhpoelrhaxydifuj
kuqwtcvzgsmhpoelgnaiydifuj
kbqwtcvzdsmhpbelvnaxydifuj
kbowtcvzgnmhpoelrfaxydifuj
kbqwtcvsgsmhfoejrnaxydifuj
kbqwtcvzgskhtoelrnxxydifuj
kbqwtcvzgtmhpoevrnaxydivuj
bbqptcgzgsmhpoelrnaxydifuj
kbqwtpvzgsmnpoelhnaxydifuj
kbqwtovzgsmmpoelrnaxydifuw
kbqwtcvzgsihpwelrnaxydsfuj
kbqwtcvzggmhpollrnaxydifsj
kbqwtcjzgsmhpoelrnaxyxifub
ebqwtcvzgsmzpoelrnaaydifuj
kbqwtcvzusmhpoelrnqxydijuj
obqwtcvzgsghpoelrnaxydifkj
kbrwtcvzmdmhpoelrnaxydifuj
kbqwtcvzxsmhpoblrnhxydifuj
kbqwacvzgsahpoelrnaxydiguj
kyqwtcvzgsmipoelrnlxydifuj
kbbwtcvzgsmhboelpnaxydifuj
kbqwtcvzgsmhpoelrnaxhdosuj
kbqwtgvzgxmhpoelrnaxyrifuj
pbqwtsvzgsmhpoelrnabydifuj
kbqrtcvzgsmhpsblrnaxydifuj
kbqwtcvzgsmhpoexrnaaycifuj
kbqxtcvzgsjhkoelrnaxydifuj
kbqwtcvzgsmhpxelrnaxydifby
lbxwtcvzgsmdpoelrnaxydifuj
kbqwtcczgsmhpoklrnzxydifuj
zbqwtcvzgsmhpoelrbaxydifui
krqwtcvzbsmhpoelrjaxydifuj
kbkwtcvzgsmhpoelrnaxydiacj
kbqwtcvzgszhpseprnaxydifuj
kbxwtcvzxsmhpoesrnaxydifuj
kbqwdcvzgsmhpoelrbaxygifuj
kbqwthkzgsmhhoelrnaxydifuj
klqwtchzgamhpoelrnaxydifuj
obqwtcvzgsvcpoelrnaxydifuj
kblwtcvzgsmhpoelrnanydifuw
kbqwtrvzgsmhpoelynaxydifug
kbqwtcvzgsmhcoelmnaxydkfuj
kbqwtcvzgsmhpotlqoaxydifuj
kaqatcvzgsmhpoelrnaxyiifuj
kbqttcvwgsmhpoelrnaxydifgj
kpqwtcvzgsmhpwelynaxydifuj
kbqwucvzgsmhpyelrnaxyxifuj
kbqwucvzgsmhprelrnaxyfifuj
kbqwthvzgsmhphelrnaxylifuj
kbqwtcvzosmhdoelrnaxwdifuj
kbqwtxvsgsphpoelrnaxydifuj
koqwtcvfghmhpoelrnaxydifuj
kbtwicvzpsmhpoelrnaxydifuj
kbawtcvzgsmhmoelrnaxyiifuj
kbqwtcvzgslhpbelrnaxydifuk
kbqttcvzgsmypoelrnaxydifua
kbqwtcvrgqmhpnelrnaxydifuj
kbqwtcvzghmhpoekpnaxydifuj
kbqwtcvzgsmupoelrnaxidifui
kbqwtcvzgsmhpbelrnaxrdifux

33
2018/day2/part1.exs Normal file
View file

@ -0,0 +1,33 @@
defmodule Part1 do
def increment_freq(char, freq_map) do
Map.update(freq_map, char, 1, &(&1 + 1))
end
def to_freq_map(str) do
str
|> String.to_charlist()
|> Enum.reduce(%{}, &increment_freq/2)
end
def contains_frequency?(freq_map, freq) do
Map.values(freq_map) |> Enum.member?(freq)
end
def count_twos_and_threes(freq_map, {twos, threes}) do
twos = if contains_frequency?(freq_map, 2), do: twos + 1, else: twos
threes = if contains_frequency?(freq_map, 3), do: threes + 1, else: threes
{twos, threes}
end
def run do
{twos, threes} =
File.stream!("input")
|> Stream.map(&String.trim/1)
|> Stream.map(&to_freq_map/1)
|> Enum.reduce({0, 0}, &count_twos_and_threes/2)
IO.puts("#{twos} * #{threes} = #{twos * threes}")
end
end
Part1.run()

30
2018/day2/part2.exs Normal file
View file

@ -0,0 +1,30 @@
defmodule Part2 do
def count_diffs(str1, str2) do
Stream.zip(String.to_charlist(str1), String.to_charlist(str2))
|> Enum.count(fn {a, b} -> a !== b end)
end
def common_chars(str1, str2) do
Stream.zip(String.to_charlist(str1), String.to_charlist(str2))
|> Stream.filter(fn {a, b} -> a === b end)
|> Enum.map(fn {a, _b} -> a end)
end
def run do
boxes = File.stream!("input") |> Enum.map(&String.trim/1)
diffs =
for box <- boxes, other_box <- boxes -- [box] do
{box, count_diffs(box, other_box)}
end
[str1, str2] =
diffs
|> Enum.filter(fn {_box, diff} -> diff === 1 end)
|> Enum.map(fn {box, 1} -> box end)
IO.puts(common_chars(str1, str2))
end
end
Part2.run()

57
2018/day3/day3.exs Normal file
View file

@ -0,0 +1,57 @@
defmodule Coord do
defstruct [:x, :y]
end
defmodule Claim do
defstruct id: nil, pos: %Coord{x: 0, y: 0}, len: %Coord{x: 0, y: 0}
@input_pattern ~r/#(\d+) @ (\d+),(\d+): (\d+)x(\d+)/
def new_from_str(str) do
[id, pos_x, pos_y, len_x, len_y] =
Regex.run(@input_pattern, str, capture: :all_but_first)
|> Enum.map(&String.to_integer/1)
%Claim{id: id, pos: %Coord{x: pos_x, y: pos_y}, len: %Coord{x: len_x, y: len_y}}
end
def all_coords(claim) do
x_coords = claim.pos.x..(claim.pos.x + claim.len.x - 1)
y_coords = claim.pos.y..(claim.pos.y + claim.len.y - 1)
for x <- x_coords, y <- y_coords, do: %Coord{x: x, y: y}
end
def unshared?(claim, unshared_inches) do
Enum.all?(all_coords(claim), &MapSet.member?(unshared_inches, &1))
end
end
defmodule Day3 do
def count_claim_inches(claim, count) do
Enum.reduce(Claim.all_coords(claim), count, fn coord, count ->
Map.update(count, coord, 1, &(&1 + 1))
end)
end
def part1 do
File.stream!("input")
|> Stream.map(&Claim.new_from_str/1)
|> Enum.reduce(%{}, &count_claim_inches/2)
|> Stream.filter(fn {_coord, count} -> count >= 2 end)
|> Enum.count()
end
def part2 do
all_claims = File.stream!("input") |> Enum.map(&Claim.new_from_str/1)
unshared_inches =
all_claims
|> Enum.reduce(%{}, &count_claim_inches/2)
|> Enum.filter(fn {_coord, count} -> count == 1 end)
|> MapSet.new(fn {coord, _count} -> coord end)
Enum.find(all_claims, &Claim.unshared?(&1, unshared_inches))
end
end
IO.puts("Part1 (number of square inches claimed multiple times): #{Day3.part1()}")
IO.puts("Part2 (id of only claim not overlapping with another): #{Day3.part2().id}")

1317
2018/day3/input Normal file

File diff suppressed because it is too large Load diff

97
2018/day4/day4.exs Normal file
View file

@ -0,0 +1,97 @@
defmodule Day4 do
@log_pattern ~r/\[(\d\d\d\d-\d\d-\d\d \d\d:\d\d)\] (.+)/
@guard_pattern ~r/Guard #(\d+) begins shift/
def parse_log_line(str) do
[date_str, entry] = Regex.run(@log_pattern, str, capture: :all_but_first)
{:ok, date} = NaiveDateTime.from_iso8601(date_str <> ":00")
{date, parse_entry(entry)}
end
def parse_entry("wakes up"), do: :wake
def parse_entry("falls asleep"), do: :sleep
def parse_entry(str) do
[id] = Regex.run(@guard_pattern, str, capture: :all_but_first)
{:arrive, String.to_integer(id)}
end
# [
# {~N[1518-02-18 00:08:00], :sleep, 131},
# {~N[1518-02-18 00:29:00], :wake, 131},
# ...
# ]
def parse_log() do
File.stream!("input")
|> Stream.map(&String.trim/1)
|> Stream.map(&parse_log_line/1)
|> Enum.sort(fn {d1, _}, {d2, _} -> NaiveDateTime.compare(d1, d2) === :lt end)
|> Enum.map_reduce(nil, fn
{date, {:arrive, id}}, _id -> {{date, :arrive, id}, id}
{date, entry}, id -> {{date, entry, id}, id}
end)
|> elem(0)
|> Enum.reject(fn {_date, event, _id} -> event === :arrive end)
end
def sleepy do
parse_log()
|> Enum.chunk_every(2)
|> Enum.map(fn [{sleep, _, _}, {wake, _, id}] ->
{id, div(NaiveDateTime.diff(wake, sleep), 60)}
end)
|> Enum.group_by(fn {id, _mins} -> id end, fn {_id, mins} -> mins end)
|> Enum.map(fn {id, mins} -> {id, Enum.sum(mins)} end)
|> Enum.max_by(fn {_id, mins} -> mins end)
|> elem(0)
end
def most_min_slept(guard_id) do
parse_log()
|> Enum.reject(fn {_date, _event, id} -> id !== guard_id end)
|> Enum.chunk_every(2)
|> Enum.map(fn [{sleep, _, _}, {wake, _, _}] -> sleep.minute..(wake.minute - 1) end)
|> Enum.reduce(%{}, fn range, freq_map ->
Enum.reduce(range, freq_map, fn minute, freq_map ->
Map.update(freq_map, minute, 1, &(&1 + 1))
end)
end)
|> Enum.max_by(fn {_minute, freq} -> freq end)
|> elem(0)
end
def part1 do
sleepy = sleepy()
most_min_slept = most_min_slept(sleepy)
IO.puts("Guard most often asleep: #{sleepy}")
IO.puts("Most mintutes that guard slept: #{most_min_slept}")
IO.puts("Part 1 answer: #{sleepy * most_min_slept}")
end
def most_sleepy_guard_in(guard_freq_map) do
Enum.max_by(guard_freq_map, fn {_id, freq} -> freq end)
end
def part2 do
{minute, {id, _freq}} =
parse_log()
|> Enum.chunk_every(2)
|> Enum.map(fn [{sleep, _, _}, {wake, _, id}] -> {id, sleep.minute..(wake.minute - 1)} end)
|> Enum.reduce(%{}, fn {id, range}, minute_map ->
Enum.reduce(range, minute_map, fn minute, minute_map ->
Map.update(minute_map, minute, %{id => 1}, fn guard_map ->
Map.update(guard_map, id, 1, &(&1 + 1))
end)
end)
end)
|> Enum.map(fn {minute, freq_map} -> {minute, most_sleepy_guard_in(freq_map)} end)
|> Enum.max_by(fn {_minute, {_id, freq}} -> freq end)
IO.puts("The guard that was most freequently alseep on the same minute: #{id}")
IO.puts("The minute that guard was most frequently asleep on: #{minute}")
IO.puts("Part 2 answer: #{id * minute}")
end
end
Day4.part1()
Day4.part2()

1106
2018/day4/input Normal file

File diff suppressed because it is too large Load diff

41
2018/day5/day5.exs Normal file
View file

@ -0,0 +1,41 @@
defmodule Day5 do
def upcase?(char), do: char in ?A..?Z
def same_letter?(c1, c2), do: String.upcase(<<c1::utf8>>) === String.upcase(<<c2::utf8>>)
def case_differs?(c1, c2), do: upcase?(c1) !== upcase?(c2)
def react?(c1, c2), do: same_letter?(c1, c2) && case_differs?(c1, c2)
# note: reverses the list - for part 1 doesn't seem to matter
def react(chars) do
Enum.reduce(chars, [], fn
curr, [] -> [curr]
curr, [prev | old] -> if react?(curr, prev), do: old, else: [curr, prev | old]
end)
end
def part1 do
File.read!("input")
|> String.trim()
|> String.to_charlist()
|> react()
|> length()
end
def part2 do
polymer =
File.read!("input")
|> String.trim()
|> String.to_charlist()
lengths =
for lower <- ?a..?z, upper = lower - 32 do
Enum.reject(polymer, &(&1 in [lower, upper]))
|> react()
|> length()
end
Enum.min(lengths)
end
end
IO.puts(Day5.part1())
IO.puts(Day5.part2())

1
2018/day5/input Normal file

File diff suppressed because one or more lines are too long

118
2018/day6/day6.exs Normal file
View file

@ -0,0 +1,118 @@
defmodule Area do
defstruct [:min_x, :min_y, :max_x, :max_y]
def all_coords(area) do
for x <- area.min_x..area.max_x, y <- area.min_y..area.max_y, do: {x, y}
end
def edge_coords(area) do
top_and_bottom = for x <- area.min_x..area.max_x, y <- [area.min_y, area.max_y], do: {x, y}
sides = for x <- [area.min_x, area.max_x], y <- (area.min_y + 1)..(area.max_y - 1), do: {x, y}
top_and_bottom ++ sides
end
end
defmodule Day6 do
def parse_danger_pt_list do
File.stream!("input")
|> Stream.map(&String.trim/1)
|> Stream.map(fn line -> String.split(line, ", ") |> Enum.map(&String.to_integer/1) end)
|> Enum.map(fn [x, y] -> {x, y} end)
end
def bounding_box(coords) do
{max_x, max_y} =
Enum.reduce(coords, {0, 0}, fn {x, y}, {max_x, max_y} ->
{max(x, max_x), max(y, max_y)}
end)
{min_x, min_y} =
Enum.reduce(coords, {max_x, max_y}, fn {x, y}, {min_x, min_y} ->
{min(x, min_x), min(y, min_y)}
end)
%Area{min_x: min_x, min_y: min_y, max_x: max_x, max_y: max_y}
end
def manhattan_distance({x1, y1}, {x2, y2}), do: abs(x2 - x1) + abs(y2 - y1)
# %{ grid_coordinate => {distance, dangerous_point} }
def proximity_grid_for(danger_pt, field) do
Area.all_coords(field)
|> Enum.map(fn coord -> {coord, {manhattan_distance(coord, danger_pt), [danger_pt]}} end)
|> Map.new()
end
def proximity_grid(danger_pts, field) do
empty_grid = Enum.map(danger_pts, fn danger_pt -> {danger_pt, {nil, []}} end) |> Map.new()
Enum.reduce(danger_pts, empty_grid, fn danger_pt, merged_grid ->
Map.merge(proximity_grid_for(danger_pt, field), merged_grid, fn
_grid_coord, {dist, [danger_pt]}, {_dist, []} ->
{dist, [danger_pt]}
_grid_coord, {dist1, [danger_pt]}, {dist2, _danger_pts} when dist1 < dist2 ->
{dist1, [danger_pt]}
_grid_coord, {dist1, _danger_pt}, {dist2, danger_pts} when dist2 < dist1 ->
{dist2, danger_pts}
_grid_coord, {dist1, [danger_pt]}, {dist2, danger_pts} when dist1 === dist2 ->
{dist1, [danger_pt | danger_pts]}
end)
end)
end
def find_infinite_danger_pts(proximity_grid, field) do
Enum.reduce(Area.edge_coords(field), MapSet.new(), fn coord, infinite_pts ->
with {_dist, [danger_pt]} <- proximity_grid[coord] do
MapSet.put(infinite_pts, danger_pt)
else
_ -> infinite_pts
end
end)
end
def remove_shared_and_infinite(proximity_grid, infinite_pts) do
proximity_grid
|> Enum.reject(fn {_, {_dist, danger_pts}} -> length(danger_pts) > 1 end)
|> Enum.reject(fn {_, {_dist, [danger_pt]}} -> MapSet.member?(infinite_pts, danger_pt) end)
|> Map.new()
end
def to_areas(proximity_grid) do
Enum.reduce(proximity_grid, %{}, fn {_coord, {_dist, [danger_pt]}}, areas ->
Map.update(areas, danger_pt, 1, &(&1 + 1))
end)
end
def part1 do
danger_pts = parse_danger_pt_list()
field = bounding_box(danger_pts)
proximity_grid = proximity_grid(danger_pts, field)
infinite_pts = find_infinite_danger_pts(proximity_grid, field)
remove_shared_and_infinite(proximity_grid, infinite_pts)
|> to_areas()
|> Map.values()
|> Enum.max()
end
def part2 do
danger_pts = parse_danger_pt_list()
danger_pts
|> bounding_box()
|> Area.all_coords()
|> Enum.map(fn coord ->
Enum.reduce(danger_pts, 0, fn danger_pt, dist ->
dist + manhattan_distance(coord, danger_pt)
end)
end)
|> Enum.filter(&(&1 < 10_000))
|> length()
end
end
IO.puts(Day6.part1())
IO.puts(Day6.part2())

50
2018/day6/input Normal file
View file

@ -0,0 +1,50 @@
80, 357
252, 184
187, 139
101, 247
332, 328
302, 60
196, 113
271, 201
334, 89
85, 139
327, 161
316, 352
343, 208
303, 325
316, 149
270, 319
318, 153
257, 332
306, 348
299, 358
172, 289
303, 349
271, 205
347, 296
220, 276
235, 231
133, 201
262, 355
72, 71
73, 145
310, 298
138, 244
322, 334
278, 148
126, 135
340, 133
311, 118
193, 173
319, 99
50, 309
160, 356
155, 195
61, 319
80, 259
106, 318
49, 169
134, 61
74, 204
337, 174
108, 287

125
2018/day7/day7.exs Normal file
View file

@ -0,0 +1,125 @@
defmodule Day7 do
def input_to_graph do
input_pattern = ~r/Step (\w) must be finished before step (\w) can begin./
File.stream!("input")
|> Enum.map(&Regex.run(input_pattern, &1, capture: :all_but_first))
|> Enum.reduce(%{}, fn [from, to], routes ->
Map.update(routes, from, [to], fn tos -> [to | tos] end)
end)
end
def count_predecessors(graph) do
Enum.reduce(graph, %{}, fn {step, _children}, counts ->
counts = Map.put_new(counts, step, 0)
count_predecessors(counts, counts[step], graph[step], graph)
end)
end
def count_predecessors(counts, _, nil, _), do: counts
def count_predecessors(counts, level, children, graph) do
child_lvl = level + 1
Enum.reduce(children, counts, fn child, counts ->
counts = Map.update(counts, child, child_lvl, fn existing -> max(existing, child_lvl) end)
count_predecessors(counts, counts[child], graph[child], graph)
end)
end
def resolve_steps(graph, steps) when map_size(graph) === 1 do
[{penultimate, ultimates}] = Map.to_list(graph)
Enum.reverse(steps) ++ [penultimate | Enum.sort(ultimates)]
end
def resolve_steps(graph, steps) do
before_counts = count_predecessors(graph)
[next | _] =
Enum.filter(before_counts, fn {_, count} -> count === 0 end)
|> Enum.map(fn {step, _count} -> step end)
|> Enum.sort()
resolve_steps(Map.delete(graph, next), [next | steps])
end
def time_for(step), do: hd(String.to_charlist(step)) - 5
def get_work({graph, counts, in_progress}) do
case Enum.filter(counts, fn {_, count} -> count === 0 end)
|> Enum.map(fn {step, _count} -> step end)
|> Enum.sort() do
[] ->
{nil, {graph, counts, in_progress}}
[step | _] ->
{{step, time_for(step)}, {graph, Map.delete(counts, step), [step | in_progress]}}
end
end
def get_work_done(completed_step, {graph, _counts, in_progress}) do
graph = Map.delete(graph, completed_step)
counts = count_predecessors(graph) |> Map.drop(in_progress)
get_work({graph, counts, in_progress})
end
def all_prerequisites_allocated?(graph, in_progress) do
map_size(Map.drop(graph, in_progress)) === 0
end
def tick(workers, graph, counts, in_progress, seconds) do
{workers, {graph, counts, _}} =
Enum.map_reduce(workers, {graph, counts, in_progress}, fn
nil, acc -> get_work(acc)
{step, 0}, acc -> get_work_done(step, acc)
{step, remaining}, acc -> {{step, remaining - 1}, acc}
end)
{workers, graph, counts, seconds + 1}
end
def finish_up(workers, counts, seconds) do
remaining_workers =
workers
|> Enum.filter(fn worker -> worker != nil end)
|> Enum.map(fn {_, time} -> time end)
|> Enum.max()
# This assumes the number of remaining jobs will not be greater than the remaining
# workers. That's probably a bad assumption so if the answer is wrong I'll
# come back and fix this.
if map_size(counts) > length(workers) do
raise("Number of final jobs greater than remaining workers")
end
remaining_queued = (counts |> Enum.map(fn {step, _} -> time_for(step) end) |> Enum.max()) + 1
seconds + remaining_workers + remaining_queued
end
def work(workers, graph, counts, seconds) do
in_progress =
workers
|> Enum.filter(fn worker -> worker != nil end)
|> Enum.map(fn {step, _} -> step end)
if all_prerequisites_allocated?(graph, in_progress) do
finish_up(workers, counts, seconds)
else
{workers, graph, counts, seconds} = tick(workers, graph, counts, in_progress, seconds)
work(workers, graph, counts, seconds)
end
end
def part1, do: input_to_graph() |> resolve_steps([]) |> Enum.join()
def part2 do
graph = input_to_graph()
counts = count_predecessors(graph)
workers = for _ <- 1..5, do: nil
work(workers, graph, counts, 0)
end
end
IO.puts(Day7.part1())
IO.puts(Day7.part2())

101
2018/day7/input Normal file
View file

@ -0,0 +1,101 @@
Step J must be finished before step H can begin.
Step N must be finished before step C can begin.
Step G must be finished before step P can begin.
Step M must be finished before step I can begin.
Step H must be finished before step X can begin.
Step B must be finished before step Y can begin.
Step C must be finished before step L can begin.
Step F must be finished before step I can begin.
Step V must be finished before step O can begin.
Step W must be finished before step Q can begin.
Step E must be finished before step L can begin.
Step U must be finished before step S can begin.
Step D must be finished before step K can begin.
Step Y must be finished before step X can begin.
Step T must be finished before step R can begin.
Step I must be finished before step K can begin.
Step A must be finished before step K can begin.
Step L must be finished before step X can begin.
Step Q must be finished before step S can begin.
Step S must be finished before step O can begin.
Step P must be finished before step Z can begin.
Step X must be finished before step R can begin.
Step Z must be finished before step O can begin.
Step O must be finished before step K can begin.
Step R must be finished before step K can begin.
Step J must be finished before step W can begin.
Step F must be finished before step V can begin.
Step A must be finished before step X can begin.
Step Z must be finished before step K can begin.
Step M must be finished before step O can begin.
Step X must be finished before step K can begin.
Step E must be finished before step K can begin.
Step J must be finished before step K can begin.
Step E must be finished before step Y can begin.
Step B must be finished before step Q can begin.
Step X must be finished before step Z can begin.
Step D must be finished before step L can begin.
Step N must be finished before step I can begin.
Step N must be finished before step B can begin.
Step V must be finished before step A can begin.
Step H must be finished before step R can begin.
Step N must be finished before step L can begin.
Step U must be finished before step O can begin.
Step A must be finished before step O can begin.
Step V must be finished before step Z can begin.
Step O must be finished before step R can begin.
Step Q must be finished before step P can begin.
Step F must be finished before step Q can begin.
Step P must be finished before step R can begin.
Step S must be finished before step X can begin.
Step J must be finished before step E can begin.
Step V must be finished before step P can begin.
Step M must be finished before step D can begin.
Step I must be finished before step S can begin.
Step Q must be finished before step O can begin.
Step M must be finished before step H can begin.
Step W must be finished before step X can begin.
Step D must be finished before step O can begin.
Step X must be finished before step O can begin.
Step Y must be finished before step Z can begin.
Step F must be finished before step L can begin.
Step V must be finished before step T can begin.
Step V must be finished before step E can begin.
Step Y must be finished before step A can begin.
Step I must be finished before step R can begin.
Step L must be finished before step O can begin.
Step U must be finished before step X can begin.
Step Q must be finished before step X can begin.
Step P must be finished before step X can begin.
Step G must be finished before step C can begin.
Step A must be finished before step L can begin.
Step M must be finished before step U can begin.
Step L must be finished before step S can begin.
Step S must be finished before step P can begin.
Step S must be finished before step K can begin.
Step F must be finished before step T can begin.
Step Q must be finished before step K can begin.
Step G must be finished before step M can begin.
Step G must be finished before step F can begin.
Step T must be finished before step Q can begin.
Step F must be finished before step Z can begin.
Step I must be finished before step Z can begin.
Step N must be finished before step X can begin.
Step J must be finished before step F can begin.
Step W must be finished before step E can begin.
Step M must be finished before step Z can begin.
Step G must be finished before step X can begin.
Step V must be finished before step U can begin.
Step P must be finished before step O can begin.
Step U must be finished before step R can begin.
Step G must be finished before step Z can begin.
Step F must be finished before step R can begin.
Step L must be finished before step R can begin.
Step F must be finished before step A can begin.
Step I must be finished before step O can begin.
Step D must be finished before step T can begin.
Step U must be finished before step L can begin.
Step B must be finished before step S can begin.
Step S must be finished before step Z can begin.
Step J must be finished before step N can begin.
Step H must be finished before step T can begin.

52
2018/day8/day8.exs Normal file
View file

@ -0,0 +1,52 @@
defmodule Day8 do
import Kernel, except: [node: 1]
def list, do: File.read!("input") |> String.split() |> Enum.map(&String.to_integer/1)
def node([child_count, data_count | rest]) do
{children, rest} = children(child_count, [], rest)
{data, rest} = Enum.split(rest, data_count)
{{data, children}, rest}
end
def children(0, acc, list), do: {Enum.reverse(acc), list}
def children(count, acc, list) do
{child, rest} = node(list)
children(count - 1, [child | acc], rest)
end
def sum_node({items, children}, sum) do
Enum.sum(items) + Enum.reduce(children, sum, &sum_node/2)
end
def part1 do
{tree, _} = node(list())
sum_node(tree, 0)
end
def select(nodes, indices) do
node_map =
nodes
|> Enum.with_index(1)
|> Map.new(fn {node, index} -> {index, node} end)
indices
|> Enum.map(&Map.get(node_map, &1))
|> Enum.reject(&(&1 === nil))
end
def value_node({items, []}), do: Enum.sum(items)
def value_node({items, children}) do
children |> select(items) |> Enum.map(&value_node/1) |> Enum.sum()
end
def part2 do
{tree, _} = node(list())
value_node(tree)
end
end
IO.puts(Day8.part1())
IO.puts(Day8.part2())

1
2018/day8/input Normal file

File diff suppressed because one or more lines are too long

102
2018/day9/day9.exs Normal file
View file

@ -0,0 +1,102 @@
defmodule Marble do
defstruct [:cw, :ccw]
end
defmodule Game do
defstruct [:current, :next, :circle, :players, :active, :scores, :marbles]
def start(players, marbles) do
game = %Game{
current: 0,
next: 1,
circle: %{0 => %Marble{ccw: 0, cw: 0}},
players: players,
active: 1,
scores: Map.new(1..players, &{&1, 0}),
marbles: marbles
}
play(game)
end
def next_turn(%Game{next: next, marbles: marbles} = game) when next > marbles do
game.scores |> Map.values() |> Enum.max()
end
def next_turn(%Game{players: players, active: active} = game) do
next = active + 1
next = if next <= players, do: next, else: 1
play(%Game{game | active: next})
end
def insert(circle, val, ccw, cw) do
circle
|> Map.put(val, %Marble{ccw: ccw, cw: cw})
|> Map.update!(ccw, &%Marble{&1 | cw: val})
|> Map.update!(cw, &%Marble{&1 | ccw: val})
end
def remove(circle, val, ccw, cw) do
circle
|> Map.delete(val)
|> Map.update!(ccw, &%Marble{&1 | cw: cw})
|> Map.update!(cw, &%Marble{&1 | ccw: ccw})
end
def find_remove(cw, circle, 1) do
remove = circle[cw].ccw
ccw = circle[remove].ccw
{remove, ccw, cw}
end
def find_remove(current, circle, dec) do
find_remove(circle[current].ccw, circle, dec - 1)
end
def play(%Game{current: current, next: val, circle: circle} = game) when rem(val, 23) == 0 do
# Find and remove the item 7 items over
{remove, ccw, cw} = find_remove(current, circle, 7)
circle = remove(circle, remove, ccw, cw)
# Update the player's score
scores = Map.update!(game.scores, game.active, &(&1 + val + remove))
game = %Game{game | current: cw, next: val + 1, circle: circle, scores: scores}
next_turn(game)
end
def play(%Game{current: current, next: val, circle: circle} = game) do
one = circle[current].cw
two = circle[one].cw
game = %Game{game | current: val, next: val + 1, circle: insert(circle, val, one, two)}
next_turn(game)
end
end
defmodule Day9 do
def part1 do
input = File.read!("input")
pattern = ~r/(\d+) players; last marble is worth (\d+) points/
[players, marbles] =
Regex.run(pattern, input, capture: :all_but_first)
|> Enum.map(&String.to_integer/1)
Game.start(players, marbles)
end
# Probably supposed to make this more efficient, but it still runs in 30 seconds...
def part2 do
input = File.read!("input")
pattern = ~r/(\d+) players; last marble is worth (\d+) points/
[players, marbles] =
Regex.run(pattern, input, capture: :all_but_first)
|> Enum.map(&String.to_integer/1)
Game.start(players, marbles * 100)
end
end
IO.puts(Day9.part1())
IO.puts(Day9.part2())

1
2018/day9/input Normal file
View file

@ -0,0 +1 @@
459 players; last marble is worth 71790 points