Advent 2023 - Day 5
Mix.install([
{:kino, "~> 0.11.3"}
])
Section
input = Kino.Input.textarea("Please paste your input file")
[seeds | mappings] =
input
|> Kino.Input.read()
|> String.split("\n\n")
|> Enum.map(fn category ->
category
|> String.split(":")
|> Enum.at(1)
|> String.trim()
|> String.split("\n")
|> Enum.map(fn chain ->
chain
|> String.split(" ")
|> Enum.map(&Integer.parse/1)
|> Enum.map(&elem(&1, 0))
end)
end)
[
[[79, 14, 55, 13]],
[[50, 98, 2], ~c"420"],
[[0, 15, 37], [37, 52, 2], [39, 0, 15]],
[~c"15\b", [0, 11, 42], [42, 0, 7], [57, 7, 4]],
[[88, 18, 7], [18, 25, 70]],
[[45, 77, 23], [81, 45, 19], ~c"D@\r"],
[[0, 69, 1], [1, 0, 69]],
[~c"<8%", [56, 93, 4]]
]
seeds = List.flatten(seeds)
[79, 14, 55, 13]
mappings =
for mapping <- mappings do
for [dest, src, range] <- mapping do
{src..(src + range), dest - src}
end
end
[
[{98..100, -48}, {50..98, 2}],
[{15..52, -15}, {52..54, -15}, {0..15, 39}],
[{53..61, -4}, {11..53, -11}, {0..7, 42}, {7..11, 50}],
[{18..25, 70}, {25..95, -7}],
[{77..100, -32}, {45..64, 36}, {64..77, 4}],
[{69..70, -69}, {0..69, 1}],
[{56..93, 4}, {93..97, -37}]
]
Part 1
for seed <- seeds do
Enum.reduce(mappings, seed, fn mapping, value ->
map =
Enum.find(mapping, fn {range, _} ->
Enum.member?(range, value)
end)
if is_nil(map) do
value
else
{_, to_add} = map
value + to_add
end
end)
end
|> Enum.min()
35
Part 2
seed_ranges =
seeds
|> Enum.chunk_every(2)
|> Enum.map(fn [start, range] ->
start..(start + range - 1)
end)
[79..92, 55..67]
if we have: 30..50
outside range:
-
10..20 -> {nil, [30..50]}
-
60..80 -> {nil, [30..50]}
corner of range:
-
10..40 -> {30..40<-remap range, [41..50]<-leftover}
-
40..60 -> {40..50<-remap range, [30..39]<-leftover}
within_range:
-
35..45 -> {35..45<-remap range, [30..34,46..50]<-leftover}
entire_range:
-
30..50 -> {30..50<-remap range, []<-leftover}
-
0..100 -> {30..50<-remap range, []<-leftover}
defmodule Almanac do
# outside of range / disjoint
def dice(sl..sr//1 = src, ml..mr//1) when sr < ml or sl > mr, do: {nil, [src]}
# corner to the left
def dice(sl..sr//1, ml..mr//1) when sl >= ml and sr > mr, do: {sl..mr, [(mr + 1)..sr]}
# corner to the right
def dice(sl..sr//1, ml..mr//1) when sl < ml and sr <= mr, do: {ml..sr, [sl..(ml - 1)]}
# within range
def dice(sl..sr//1, ml..mr//1) when sl < ml and sr > mr,
do: {ml..mr, [sl..(ml - 1), (mr + 1)..sr]}
# entire range
def dice(sl..sr//1, ml..mr//1) when sl >= ml and sr <= mr, do: {sl..sr, []}
end
example = 30..50
# outside
{nil, [30..50]} = Almanac.dice(example, 10..20)
# corner to the left
{30..40, [41..50]} = Almanac.dice(example, 10..40)
# corner to the right
{40..50, [30..39]} = Almanac.dice(example, 40..60)
# within range
{35..45, [30..34, 46..50]} = Almanac.dice(example, 35..45)
# entire range
{30..50, []} = Almanac.dice(example, 30..50)
# also entire range
{30..50, []} = Almanac.dice(example, 0..100)
{30..50, []}
example = 50..150
Almanac.dice(example, 60..70)
{60..70, [50..59, 71..150]}
Almanac.dice(example, 100..120)
{100..120, [50..99, 121..150]}
for seed_range <- seed_ranges do
Enum.reduce(mappings, [seed_range], fn mapping, values ->
values
|> Enum.map(fn value ->
IO.puts("value")
IO.inspect(value)
Enum.map_reduce(mapping, [value], fn {range, to_add}, leftovers ->
leftovers
|> Enum.map(fn leftover ->
{to_be_mapped, leftover} = Almanac.dice(leftover, range)
end)
|> IO.inspect()
raise "fuck"
end)
mapping
|> Enum.map(fn {range, to_add} ->
IO.inspect("what")
IO.inspect(range)
IO.inspect(value)
map_first..map_last//_step = range
val_first..val_last//_step = value
first = if map_first < val_first, do: val_first, else: map_first
last = if map_last > val_last, do: val_last, else: map_last
first..last
# (first + to_add)..(last + to_add)
end)
end)
|> List.flatten()
|> IO.inspect()
raise "aaa"
end)
end
warning: variable "leftover" is unused (there is a variable with the same name in the context, use the pin operator (^) to match on it or prefix this variable with underscore if it is not meant to be used)
advent2023/day5.livemd#cell:auevw3s4pafeeggwj3ttbo6gjyez65mo:11
warning: variable "to_be_mapped" is unused (if the variable is not meant to be used, prefix it with an underscore)
advent2023/day5.livemd#cell:auevw3s4pafeeggwj3ttbo6gjyez65mo:11
warning: variable "to_add" is unused (if the variable is not meant to be used, prefix it with an underscore)
advent2023/day5.livemd#cell:auevw3s4pafeeggwj3ttbo6gjyez65mo:8
warning: variable "to_add" is unused (if the variable is not meant to be used, prefix it with an underscore)
advent2023/day5.livemd#cell:auevw3s4pafeeggwj3ttbo6gjyez65mo:19
value
79..92
[nil: [79..92]]