this repo has no description

Day 04 od 2025

hauleth.dev 26bec5c3 b5ea05b3

verified
+78
+78
2025/day04.livemd
··· 1 + # Day 04 2 + 3 + ```elixir 4 + Mix.install([:kino_aoc]) 5 + ``` 6 + 7 + ## Setup 8 + 9 + <!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiI0Iiwic2Vzc2lvbl9zZWNyZXQiOiJBRFZFTlRfT0ZfQ09ERV9TRVNTSU9OIiwieWVhciI6IjIwMjUifQ","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} --> 10 + 11 + ```elixir 12 + {:ok, puzzle_input} = 13 + KinoAOC.download_puzzle("2025", "4", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION")) 14 + ``` 15 + 16 + ```elixir 17 + rolls = 18 + puzzle_input 19 + |> String.split("\n", trim: true) 20 + |> Enum.with_index() 21 + |> Enum.flat_map(fn {line, row} -> 22 + line 23 + |> String.to_charlist() 24 + |> Enum.with_index() 25 + |> Enum.filter(&(elem(&1, 0) == ?@)) 26 + |> Enum.map(&{elem(&1, 1), row}) 27 + end) 28 + |> MapSet.new() 29 + ``` 30 + 31 + ## Implementation 32 + 33 + ```elixir 34 + defmodule PaperRolls do 35 + def adjacent({x, y}) do 36 + for dx <- -1..1, 37 + dy <- -1..1, 38 + {dx, dy} != {0, 0}, 39 + do: {x + dx, y + dy} 40 + end 41 + 42 + def free?(pos, map) do 43 + pos 44 + |> adjacent() 45 + |> Enum.count(&(&1 in map)) 46 + |> then(&(&1 < 4)) 47 + end 48 + end 49 + ``` 50 + 51 + ## Part 1 52 + 53 + ```elixir 54 + Enum.count(rolls, &PaperRolls.free?(&1, rolls)) 55 + ``` 56 + 57 + ## Part 2 58 + 59 + ```elixir 60 + cleaned = 61 + Stream.repeatedly(fn -> [] end) 62 + |> Enum.reduce_while(rolls, fn _, acc -> 63 + removable = 64 + Enum.filter(acc, &PaperRolls.free?(&1, acc)) 65 + |> MapSet.new() 66 + 67 + case MapSet.difference(acc, removable) do 68 + ^acc -> {:halt, acc} 69 + remaining -> {:cont, remaining} 70 + end 71 + end) 72 + ``` 73 + 74 + ```elixir 75 + MapSet.size(rolls) - MapSet.size(cleaned) 76 + ``` 77 + 78 + <!-- livebook:{"offset":1486,"stamp":{"token":"XCP.deDYlsmx1l6_24twLKmjhZpjVr-zKpCk4kKaQFxGe1gppbfdc-7UyFIZxpcR_jVCGfX6vDlmYQ7ACpVB7bxafYi0X3Avsi-upj46ogSc5zRBoDdxStrGLSLdSmW_EsudIg","version":2}} -->