this repo has no description
1<!-- vim: syntax=markdown --> 2<!-- livebook:{"persist_outputs":true} --> 3 4# Advent of Code 2021 5 6## Setup 7 8```elixir 9Mix.install([]) 10``` 11 12```output 13:ok 14``` 15 16## Day 1 17 18### Load input 19 20```elixir 21stream = 22 File.stream!("day1.txt") 23 |> Stream.map(&String.to_integer(String.trim(&1))) 24``` 25 26```output 27#Stream<[ 28 enum: %File.Stream{ 29 line_or_bytes: :line, 30 modes: [:raw, :read_ahead, :binary], 31 path: "day1.txt", 32 raw: true 33 }, 34 funs: [#Function<47.58486609/1 in Stream.map/2>] 35]> 36``` 37 38### Task 1 39 40<!-- livebook:{"break_markdown":true} --> 41 42Compute count of consecutive increases 43 44```elixir 45stream 46|> Stream.chunk_every(2, 1, :discard) 47|> Enum.count(fn [a, b] -> a < b end) 48``` 49 50```output 511688 52``` 53 54### Task 2 55 56<!-- livebook:{"break_markdown":true} --> 57 58Compute count of consecutive increases of sums of trigrams. 59 60However we can notice, that if we have list like: 61 62$$ 63[a, b, c, d] 64$$ 65 66Then when we want to compare consecutive trigrams then we compare: 67 68$$ 69a + b + c < b + c + d \\ 70a < d 71$$ 72 73So we can traverse each 4 elements and then just compare first and last one 74instead of summing and then traversing it again. 75 76```elixir 77stream 78|> Stream.chunk_every(4, 1, :discard) 79|> Enum.count(fn [a, _, _, b] -> a < b end) 80``` 81 82```output 831728 84``` 85 86## Day 2 87 88### Load input 89 90We do parsing there, as it will help us with the latter tasks. Pattern matching 91is the simplest approach there, as input is in form of: 92 93``` 94forward 10 95up 20 96down 30 97``` 98 99We need to `trim/1` input to make sure that the last newline will not interrupt 100`String.to_integer/1` calls. 101 102```elixir 103stream = 104 File.stream!("day2.txt") 105 |> Stream.map(fn input -> 106 case String.trim(input) do 107 "forward " <> n -> {:forward, String.to_integer(n)} 108 "up " <> n -> {:up, String.to_integer(n)} 109 "down " <> n -> {:down, String.to_integer(n)} 110 end 111 end) 112``` 113 114```output 115#Stream<[ 116 enum: %File.Stream{ 117 line_or_bytes: :line, 118 modes: [:raw, :read_ahead, :binary], 119 path: "day2.txt", 120 raw: true 121 }, 122 funs: [#Function<47.58486609/1 in Stream.map/2>] 123]> 124``` 125 126### Task 1 127 128```elixir 129{h, d} = 130 stream 131 |> Enum.reduce({0, 0}, fn 132 {:forward, n}, {h, d} -> {h + n, d} 133 {:up, n}, {h, d} -> {h, d - n} 134 {:down, n}, {h, d} -> {h, d + n} 135 end) 136 137h * d 138``` 139 140```output 1411499229 142``` 143 144### Task 2 145 146```elixir 147{h, d, _} = 148 stream 149 |> Enum.reduce({0, 0, 0}, fn 150 {:forward, n}, {h, d, a} -> {h + n, d + a * n, a} 151 {:up, n}, {h, d, a} -> {h, d, a - n} 152 {:down, n}, {h, d, a} -> {h, d, a + n} 153 end) 154 155h * d 156``` 157 158```output 1591340836560 160``` 161 162## Day 3 163 164### Input 165 166```elixir 167stream = 168 File.stream!("day3.txt") 169 |> Enum.map(&String.trim/1) 170 |> Enum.map(&String.to_charlist/1) 171 172defmodule Day3 do 173 def count(list) do 174 Enum.reduce(list, List.duplicate(0, 12), fn input, acc -> 175 for {value, counter} <- Enum.zip(input, acc) do 176 case value do 177 ?1 -> counter + 1 178 ?0 -> counter 179 end 180 end 181 end) 182 end 183end 184``` 185 186```output 187{:module, Day3, <<70, 79, 82, 49, 0, 0, 7, ...>>, {:count, 1}} 188``` 189 190### Task 1 191 192```elixir 193half = div(length(stream), 2) 194 195{a, b} = 196 stream 197 |> Day3.count() 198 |> Enum.reduce({0, 0}, fn elem, {a, b} -> 199 if elem > half do 200 {a * 2 + 1, b * 2} 201 else 202 {a * 2, b * 2 + 1} 203 end 204 end) 205 206a * b 207``` 208 209```output 2103847100 211``` 212 213### Task 2 214 215```elixir 216defmodule Day3.Task2 do 217 def reduce(list, cb), do: reduce(list, 0, cb) 218 219 defp reduce([elem], _, _), do: elem 220 221 defp reduce(list, at, cb) do 222 counts = Day3.count(list) 223 224 half = div(length(list), 2) 225 count = Enum.at(counts, at) 226 227 bit = 228 cond do 229 count == half and cb.(count + 1, half) -> ?1 230 count != half and cb.(count, half) -> ?1 231 true -> ?0 232 end 233 234 reduce(Enum.filter(list, &(Enum.at(&1, at) == bit)), at + 1, cb) 235 end 236end 237 238co2 = List.to_integer(Day3.Task2.reduce(stream, &</2), 2) 239o2 = List.to_integer(Day3.Task2.reduce(stream, &>/2), 2) 240 241co2 * o2 242``` 243 244```output 2454105235 246```