Day 1
Mix.install([
{:finch, "~> 0.12.0"}
])
Helper functions
Finch.start_link(name: MyFinch)
download_fun = fn
{:status, 200}, acc -> acc
{:headers, _}, acc -> acc
{:data, data}, acc -> acc <> data
end
input_stream_fun = fn url ->
{:ok, data} = Finch.build(:get, url) |> Finch.stream(MyFinch, "", download_fun)
String.splitter(data, "\n", trim: true)
end
Part 1
How many easurements are larger than the previous measurement?
For example, there are 7 measurements that are larger than the previous measurement:
199 (N/A - no previous measurement)
200 (increased)
208 (increased)
210 (increased)
200 (decreased)
207 (increased)
240 (increased)
269 (increased)
260 (decreased)
263 (increased)
In this example, there are 7 measurements that are larger than the previous measurement.
Solution
str = """
199
200
208
210
200
207
240
269
260
263
"""
lines = String.split(str, "\n", trim: true)
IO.inspect(lines)
# Hold the previous value and compare it with the current value
# 199, nil
# 200, 199
# 208, 200
# ...
# To resolve this problem, we can use `Stream.transform/3`,
# which accepts an accumulator as a beginning,
# then transforms each stream element into a tuple `{new_stream, next_acc}`.
lines
|> Stream.map(&String.to_integer/1)
|> Stream.transform(
nil,
fn
line, nil -> {["#{line} (N/A - no previous measurement)"], line}
line, acc when line < acc -> {["#{line} (decreased)"], line}
line, acc when line > acc -> {["#{line} (increased)"], line}
end
)
|> Enum.to_list()
count_increases = fn enumerable ->
enumerable
|> Stream.transform(nil, fn
line, acc when line > acc -> {[1], line}
line, _ -> {[], line}
end)
|> Enum.sum()
end
"https://gist.githubusercontent.com/goofansu/5bc343a082119a26ae43f44cfc93a6c2/raw/e6565b3cf35200b8d2a323e86c6d0a664a057101/input"
|> input_stream_fun.()
|> Stream.map(&String.to_integer/1)
|> count_increases.()
Part 2
How many sums are larger than the previous sum?
199 A
200 A B
208 A B C
210 B C D
200 E C D
207 E F D
240 E F G
269 F G H
260 G H
263 H
For example, the sum of each three-measurement window is as follows:
A: 607 (N/A - no previous sum)
B: 618 (increased)
C: 618 (no change)
D: 617 (decreased)
E: 647 (increased)
F: 716 (increased)
G: 769 (increased)
H: 792 (increased)
In this example, there are 5 sums that are larger than the previous sum.
Solution
143, 0
147, 1
150, 2
[[143]]
[[143, 147], [147]]
[143, 147, 150], [147, 150], [150]]
# Sum every three numbers, but the next sum starts just from next number.
# Think of chunking the stream every n numbers with overlapping.
# So we can use `Stream.chunk_every/4`.
"https://gist.githubusercontent.com/goofansu/5bc343a082119a26ae43f44cfc93a6c2/raw/e6565b3cf35200b8d2a323e86c6d0a664a057101/input"
|> input_stream_fun.()
|> Stream.map(&String.to_integer/1)
|> Stream.chunk_every(3, 1, :discard)
|> Stream.map(&Enum.sum/1)
|> count_increases.()