this repo has no description

chore: cleanup 09.2022

+36 -100
+36 -100
2022/day09.livemd
··· 39 39 40 40 {dir, String.to_integer(steps)} 41 41 end) 42 + |> Enum.flat_map(fn {dir, steps} -> List.duplicate(dir, steps) end) 42 43 ``` 43 44 44 45 <!-- livebook:{"output":true} --> 45 46 46 47 ``` 47 - [ 48 - {"L", 1}, 49 - {"R", 1}, 50 - {"L", 1}, 51 - {"U", 1}, 52 - {"R", 2}, 53 - {"U", 1}, 54 - {"D", 2}, 55 - {"R", 2}, 56 - {"U", 1}, 57 - {"D", 2}, 58 - {"U", 2}, 59 - {"L", 2}, 60 - {"D", 1}, 61 - {"U", 1}, 62 - {"D", 2}, 63 - {"L", 2}, 64 - {"D", 1}, 65 - {"L", 2}, 66 - {"D", 2}, 67 - {"L", 1}, 68 - {"U", 2}, 69 - {"R", 2}, 70 - {"L", 1}, 71 - {"D", 2}, 72 - {"L", 2}, 73 - {"R", 2}, 74 - {"D", 2}, 75 - {"L", 1}, 76 - {"U", 1}, 77 - {"R", 1}, 78 - {"U", 1}, 79 - {"L", 1}, 80 - {"D", 1}, 81 - {"R", 1}, 82 - {"U", 2}, 83 - {"D", 2}, 84 - {"R", 1}, 85 - {"U", 1}, 86 - {"R", 1}, 87 - {"L", 1}, 88 - {"U", 1}, 89 - {"R", 1}, 90 - {"D", 1}, 91 - {"L", 1}, 92 - {"U", 1}, 93 - {"R", 1}, 94 - {"D", 1}, 95 - {"U", 1}, 96 - {"D", ...}, 97 - {...}, 98 - ... 99 - ] 48 + ["L", "R", "L", "U", "R", "R", "U", "D", "D", "R", "R", "U", "D", "D", "U", "U", "L", "L", "D", "U", 49 + "D", "D", "L", "L", "D", "L", "L", "D", "D", "L", "U", "U", "R", "R", "L", "D", "D", "L", "L", "R", 50 + "R", "D", "D", "L", "U", "R", "U", "L", "D", "R", ...] 100 51 ``` 101 52 102 53 ```elixir 103 54 defmodule Rope do 55 + @enforce_keys [:segments] 56 + defstruct [:segments] 57 + 104 58 @start %{x: 0, y: 0} 105 59 106 - defstruct segments: [%{x: 0, y: 0}, %{x: 0, y: 0}] 107 - 108 60 def new(length), 109 61 do: %__MODULE__{segments: List.duplicate(@start, length + 1)} 110 62 63 + def run(rope, moves) do 64 + {_rope, tail_positions} = 65 + Enum.reduce(moves, {rope, MapSet.new([Rope.last(rope)])}, fn dir, {rope, acc} -> 66 + new_rope = Rope.move(rope, dir) 67 + 68 + {new_rope, MapSet.put(acc, Rope.last(new_rope))} 69 + end) 70 + 71 + MapSet.size(tail_positions) 72 + end 73 + 111 74 def last(%__MODULE__{segments: list}), do: List.last(list) 112 75 113 76 def move(%__MODULE__{segments: [%{x: x, y: y} | tails]}, dir) do 114 77 head = 115 78 case dir do 116 - "U" -> %{x: x + 1, y: y} 117 - "D" -> %{x: x - 1, y: y} 118 - "L" -> %{x: x, y: y + 1} 119 - "R" -> %{x: x, y: y - 1} 79 + "L" -> %{x: x + 1, y: y} 80 + "R" -> %{x: x - 1, y: y} 81 + "U" -> %{x: x, y: y + 1} 82 + "D" -> %{x: x, y: y - 1} 120 83 end 121 84 122 - segments = move_tails([head | tails]) 123 - 124 - %__MODULE__{segments: segments} 85 + %__MODULE__{segments: move_tails([head | tails])} 125 86 end 126 87 127 88 defp move_tails([]), do: [] ··· 132 93 when abs(head.x - tail.x) < 2 and abs(head.y - tail.y) < 2, 133 94 do: rope 134 95 135 - defp move_tails([head, tail | rest]) 136 - when abs(head.y - tail.y) < 2, 137 - do: [head | move_tails([%{x: head.x - sgn(head.x - tail.x), y: head.y} | rest])] 138 - 139 - defp move_tails([head, tail | rest]) 140 - when abs(head.x - tail.x) < 2, 141 - do: [head | move_tails([%{x: head.x, y: head.y - sgn(head.y - tail.y)} | rest])] 142 - 143 - defp move_tails([head, tail | rest]), 144 - do: [ 145 - head 146 - | move_tails([%{x: head.x - sgn(head.x - tail.x), y: head.y - sgn(head.y - tail.y)} | rest]) 147 - ] 96 + defp move_tails([head, tail | rest]) do 97 + {dx, dy} = step(head, tail) 98 + [head | move_tails([%{x: head.x - dx, y: head.y - dy} | rest])] 99 + end 148 100 149 101 def sgn(0), do: 0 150 102 def sgn(n) when n < 0, do: -1 151 103 def sgn(_), do: 1 104 + 105 + defp step(%{x: x1, y: y1}, %{x: x2, y: y2}) do 106 + {sgn(div(x1 - x2, 2)), sgn(div(y1 - y2, 2))} 107 + end 152 108 end 153 109 ``` 154 110 155 111 <!-- livebook:{"output":true} --> 156 112 157 113 ``` 158 - {:module, Rope, <<70, 79, 82, 49, 0, 0, 21, ...>>, {:sgn, 1}} 114 + {:module, Rope, <<70, 79, 82, 49, 0, 0, 23, ...>>, {:step, 2}} 159 115 ``` 160 116 161 - ```elixir 162 - rope = Rope.new(1) 163 - 164 - {_rope, tail_positions} = 165 - moves 166 - |> Enum.flat_map(fn {dir, steps} -> List.duplicate(dir, steps) end) 167 - |> Enum.reduce({rope, MapSet.new([Rope.last(rope)])}, fn dir, {rope, acc} -> 168 - new_rope = Rope.move(rope, dir) 169 - 170 - {new_rope, MapSet.put(acc, Rope.last(new_rope))} 171 - end) 117 + ## Task 1 172 118 173 - MapSet.size(tail_positions) 119 + ```elixir 120 + Rope.run(Rope.new(1), moves) 174 121 ``` 175 122 176 123 <!-- livebook:{"output":true} --> ··· 182 129 ## Task 2 183 130 184 131 ```elixir 185 - rope = Rope.new(9) 186 - 187 - {_rope, tail_positions} = 188 - moves 189 - |> Enum.flat_map(fn {dir, steps} -> List.duplicate(dir, steps) end) 190 - |> Enum.reduce({rope, MapSet.new([Rope.last(rope)])}, fn dir, {rope, acc} -> 191 - new_rope = Rope.move(rope, dir) 192 - 193 - {new_rope, MapSet.put(acc, Rope.last(new_rope))} 194 - end) 195 - 196 - MapSet.size(tail_positions) 132 + Rope.run(Rope.new(9), moves) 197 133 ``` 198 134 199 135 <!-- livebook:{"output":true} -->