Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

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.()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment