this repo has no description
1# Day 04 2 3```elixir 4Mix.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 17rolls = 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 34defmodule 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 48end 49``` 50 51## Part 1 52 53```elixir 54Enum.count(rolls, &PaperRolls.free?(&1, rolls)) 55``` 56 57## Part 2 58 59```elixir 60cleaned = 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 75MapSet.size(rolls) - MapSet.size(cleaned) 76``` 77 78<!-- livebook:{"offset":1486,"stamp":{"token":"XCP.deDYlsmx1l6_24twLKmjhZpjVr-zKpCk4kKaQFxGe1gppbfdc-7UyFIZxpcR_jVCGfX6vDlmYQ7ACpVB7bxafYi0X3Avsi-upj46ogSc5zRBoDdxStrGLSLdSmW_EsudIg","version":2}} -->