this repo has no description
at master 2.0 kB view raw
1<!-- vim:set ft=markdown: --> 2 3<!-- livebook:{"persist_outputs":true} --> 4 5 6# Day 9 7 8## Setup 9 10```elixir 11Mix.install([ 12 {:nx, github: "elixir-nx/nx", sparse: "nx"}, 13 {:kino, github: "livebook-dev/kino"} 14]) 15``` 16 17```output 18:ok 19``` 20 21## Input 22 23```elixir 24input = 25 File.read!("day9.txt") 26 |> String.split("\n", trim: true) 27 |> Enum.map(&String.to_charlist(String.trim(&1))) 28 |> Nx.tensor(names: [:y, :x]) 29 |> Nx.subtract(?0) 30 |> Nx.add(1) 31 32{width, height} = shape = Nx.shape(input) 33``` 34 35```output 36{100, 100} 37``` 38 39## Task 1 40 41```elixir 42minima = fn padded, size, axis -> 43 shifted = Nx.slice_axis(padded, 0, size, axis) 44 x1 = Nx.less(input, shifted) 45 46 shifted = Nx.slice_axis(padded, 2, size, axis) 47 x2 = Nx.less(input, shifted) 48 49 Nx.logical_and(x1, x2) 50end 51 52padded = Nx.pad(input, 99, [{0, 0, 0}, {1, 1, 0}]) 53 54x = minima.(padded, width, :x) 55 56padded = Nx.pad(input, 99, [{1, 1, 0}, {0, 0, 0}]) 57 58y = minima.(padded, height, :y) 59 60minimas = Nx.logical_and(x, y) 61 62input 63|> Nx.multiply(minimas) 64|> Nx.sum() 65|> Nx.to_number() 66``` 67 68```output 69452 70``` 71 72## Task 2 73 74```elixir 75input 76|> Nx.equal(10) 77|> Nx.logical_not() 78|> Nx.select(Nx.iota(shape), 9999) 79|> Nx.to_flat_list() 80|> Enum.reject(&(&1 == 9999)) 81|> Enum.map(fn point -> {div(point, width), rem(point, width)} end) 82|> Enum.reduce([], fn {y, x} = point, basins -> 83 basin_left = Enum.find_index(basins, &({y, x - 1} in &1)) 84 basin_up = Enum.find_index(basins, &({y - 1, x} in &1)) 85 86 case {basin_left, basin_up} do 87 {nil, nil} -> 88 [MapSet.new([point]) | basins] 89 90 {idx, nil} -> 91 List.update_at(basins, idx, &MapSet.put(&1, point)) 92 93 {nil, idx} -> 94 List.update_at(basins, idx, &MapSet.put(&1, point)) 95 96 {idx, idx} -> 97 List.update_at(basins, idx, &MapSet.put(&1, point)) 98 99 {idx1, idx2} -> 100 {old, basins} = List.pop_at(basins, max(idx1, idx2)) 101 102 List.update_at(basins, min(idx1, idx2), &(&1 |> MapSet.union(old) |> MapSet.put(point))) 103 end 104end) 105|> Enum.map(&MapSet.size/1) 106|> Enum.sort(:desc) 107|> Enum.take(3) 108|> Enum.reduce(&*/2) 109``` 110 111```output 1121263735 113```