Day 14
# Note: when making the next template, something like this works well:
# `cat day04.livemd | sed 's/14/04/' > day04.livemd`
# When inspecting lists of numbers, use "charlists: :as_lists"
#
Mix.install([
# Join the string so a copy of dayN to dayM doesn't destroy it.
{:kino, "~> 0.1" <> "4.2"}
])
# Join the string so a copy of dayN to dayM doesn't destroy it.
IEx.Helpers.c("/Users/johnb/dev/2" <> "0" <> "2" <> "4adventOfCode/advent_of_code.ex")
alias AdventOfCode, as: AOC
alias Kino.Input
Installation and Data
input_example = Kino.Input.textarea("Example Data", monospace: true)
input_puzzleInput = Kino.Input.textarea("Puzzle Input", monospace: true)
input_source_select =
Kino.Input.select("Source", [{:example, "example"}, {:puzzle_input, "puzzle input"}])
data = fn ->
(Kino.Input.read(input_source_select) == :example &&
Kino.Input.read(input_example)) ||
Kino.Input.read(input_puzzleInput)
end
Solution
defmodule Day14 do
@parser ~r/p=(\d+),(\d+) v=(-?\d+),(-?\d+)/
def parse(text) do
text
|> AOC.as_single_lines()
|> Enum.map(fn line ->
[_px, _py, _vx, _vy] = Regex.scan(@parser, line)
|> List.flatten()
|> Enum.slice(1..-1//1)
|> Enum.map(&String.to_integer/1)
end)
end
def solve1(text) do
seconds = 100
robots = parse(text)
[space_x, space_y] = (Enum.count(robots) > 50) && [101, 103] || [11, 7]
final_positions = robots
|> Enum.map(fn [px, py, vx, vy] ->
new_x = rem(rem(px + seconds * vx, space_x) + space_x, space_x)
new_y = rem(rem(py + seconds * vy, space_y) + space_y, space_y)
[new_x, new_y]
end)
|> Enum.sort()
final_positions
|> Enum.reduce([0,0,0,0], fn [x, y], [q1,q2,q3,q4] ->
cond do
x < floor(space_x / 2) && y < floor(space_y / 2) ->
[q1+1,q2,q3,q4]
x >= ceil(space_x / 2) && y < floor(space_y / 2) ->
[q1,q2+1,q3,q4]
x < floor(space_x / 2) && y >= ceil(space_y / 2) ->
[q1,q2,q3+1,q4]
x >= ceil(space_x / 2) && y >= ceil(space_y / 2) ->
[q1,q2,q3,q4+1]
true ->
[q1,q2,q3,q4]
end
end)
|> Enum.reduce(1, fn q, acc -> q * acc end)
end
def format(robots, space_x, space_y, title) do
positions = robots
|> Enum.map(fn [x, y, _, _] -> [x,y] end)
space = for y <- 0..(space_y - 1) do
for x <- 0..(space_x - 1) do
([x,y] in positions) && "#" || "."
end
|> Enum.join()
end
|> Enum.join("\n")
"=== #{title} ===\n" <> space
end
def display(file, robots, space_x, space_y, title) do
IO.puts(file, format(robots, space_x, space_y, title))
robots
end
def step(robots, space_x, space_y) do
robots
|> Enum.map(fn [px, py, vx, vy] ->
[
rem(rem(px + vx, space_x) + space_x, space_x),
rem(rem(py + vy, space_y) + space_y, space_y),
vx, vy
]
end)
end
def solve2(text) do
seconds = 6587 # found iteratively from commented-out code below
robots = parse(text)
[space_x, space_y] = (Enum.count(robots) > 50) && [101, 103] || [11, 7]
tree_position = robots
|> Enum.map(fn [px, py, vx, vy] ->
[rem(rem(px + seconds * vx, space_x) + space_x, space_x),
rem(rem(py + seconds * vy, space_y) + space_y, space_y),
vx, vy]
end)
# {:ok, file} = File.open("6587.text", [:write])
IO.puts(format(tree_position, space_x, space_y, "6587"))
# display(file, tree_position, space_x, space_y, "#{seconds}")
# File.close(file)
IO.puts("closed file")
6587
# Original code used to find 6587
# robots = parse(text)
# [space_x, space_y] = (Enum.count(robots) > 50) && [101, 103] || [11, 7]
# # IO.puts(format(robots, space_x, space_y, "START"))
# # {:ok, file} = File.open("6587.text", [:write])
# IO.puts("START")
# 1..10_000
# |> Enum.reduce(robots, fn second, acc ->
# robots = step(acc, space_x, space_y)
# screen = format(robots, space_x, space_y, "#{second}")
# if screen =~ "##########" do
# IO.puts(screen)
# end
# # if second in 0..100 do
# # display(file, robots, space_x, space_y, "#{second}")
# # end
# robots
# end)
# # File.close(file)
# IO.puts("closed file")
end
end
# Example:
# p=0,4 v=3,-3
# p=6,3 v=-1,-3
# p=10,3 v=-1,2
# p=2,0 v=2,-1
# p=0,0 v=1,3
# p=3,0 v=-2,-2
# p=7,6 v=-1,-3
# p=3,0 v=-1,-2
# p=9,3 v=2,3
# p=7,3 v=-1,2
# p=2,4 v=2,-3
# p=9,5 v=-3,-3
data.()
|> Day14.solve1()
|> IO.inspect(label: "\n*** Part 1 solution (example: 12)")
# 211692000
data.()
|> Day14.solve2()
|> IO.inspect(label: "\n*** Part 2 solution (example: none)")
# 6587
# ....................................#................................................................
# ...........................#.........................................................................
# .....................................................................................................
# .................................#......###############################..............................
# ............#...........................#.............................#..............................
# ........................................#.............................#..........#...................
# ........................................#.............................#..............................
# ....................#...................#.............................#..............................
# ........................................#..............#..............#..............................
# ........................................#.............###.............#...................#..........
# ........................................#............#####............#..............................
# ......................................#.#...........#######...........#..............................
# ........................................#..........#########..........#..............................
# ........................................#............#####............#..............................
# .............#..........................#...........#######...........#...........#.........#........
# .....#..#...............................#..........#########..........#.....#........................
# .......#........#.......................#.........###########.........#..............................
# ........................................#........#############........#..............................
# .#...#..................................#..........#########..........#..............................
# ........................................#.........###########.........#.......#......................
# .................#......................#........#############........#..............................
# ......#......................#..........#.......###############.......#..............................
# #.......................................#......#################......#..............................
# ........................................#........#############........#....#.........................
# .....#..................................#.......###############.......#..............................
# ........................................#......#################......#..............................
# ........................................#.....###################.....#..............................
# .................#......................#....#####################....#...................#..........
# ........................................#.............###.............#..............................
# ..............#.........................#.............###.............#..............................
# ........................................#.............###.............#............#.................
# ........................................#.............................#..............................
# ........................................#.............................#..............................
# ........................................#.............................#...#..........................
# ........................................#.............................#............#.................
# ........................................###############################..............................
# ...........................#.........................................................................