this repo has no description
at master 4.2 kB view raw
1<!-- livebook:{"persist_outputs":true} --> 2 3# Day 17 4 5```elixir 6Mix.install([:kino_aoc]) 7``` 8 9## Section 10 11<!-- livebook:{"attrs":"eyJhc3NpZ25fdG8iOiJwdXp6bGVfaW5wdXQiLCJkYXkiOiIxNyIsInNlc3Npb25fc2VjcmV0IjoiQURWRU5UX09GX0NPREVfU0VTU0lPTiIsInllYXIiOiIyMDI0In0","chunks":null,"kind":"Elixir.KinoAOC.HelperCell","livebook_object":"smart_cell"} --> 12 13```elixir 14{:ok, puzzle_input} = 15 KinoAOC.download_puzzle("2024", "17", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION")) 16``` 17 18<!-- livebook:{"output":true} --> 19 20``` 21{:ok, 22 "Register A: 66245665\nRegister B: 0\nRegister C: 0\n\nProgram: 2,4,1,7,7,5,1,7,4,6,0,3,5,5,3,0"} 23``` 24 25```elixir 26defmodule Computer do 27 @instructions ~w[adv bxl bst jnz bxc out bdv cdv]a 28 |> Enum.with_index() 29 |> Map.new(fn {name, ins} -> {ins, name} end) 30 31 def load(opcodes) do 32 opcodes 33 |> Enum.chunk_every(2) 34 |> Enum.map(fn [opcode, op] -> 35 {@instructions[opcode], op} 36 end) 37 |> List.to_tuple() 38 end 39 40 def process(program, reg) do 41 reg = Map.merge(%{a: 0, b: 0, c: 0}, Map.new(reg)) 42 do_process(program, 0, reg, []) 43 end 44 45 defp do_process(program, idx, _reg, out) when idx >= tuple_size(program) do 46 Enum.reverse(out) 47 end 48 49 defp do_process(program, idx, reg, out) do 50 ins = elem(program, idx) 51 52 case compute(ins, reg) do 53 new_reg when is_map(new_reg) -> 54 do_process(program, idx + 1, new_reg, out) 55 56 {:out, op} -> 57 do_process(program, idx + 1, reg, [op | out]) 58 59 {:jump, op} -> 60 do_process(program, op, reg, out) 61 end 62 end 63 64 def compute({:adv, op}, reg), 65 do: %{reg | a: div(reg.a, 2 ** combo(op, reg))} 66 67 def compute({:bdv, op}, reg), 68 do: %{reg | b: div(reg.a, 2 ** combo(op, reg))} 69 70 def compute({:cdv, op}, reg), 71 do: %{reg | c: div(reg.a, 2 ** combo(op, reg))} 72 73 def compute({:bxl, op}, reg), 74 do: %{reg | b: Bitwise.bxor(reg.b, op)} 75 76 def compute({:bxc, _op}, reg), 77 do: %{reg | b: Bitwise.bxor(reg.b, reg.c)} 78 79 def compute({:bst, op}, reg), 80 do: %{reg | b: Bitwise.band(combo(op, reg), 0b111)} 81 82 def compute({:out, op}, reg), 83 do: {:out, Bitwise.band(combo(op, reg), 0b111)} 84 85 def compute({:jnz, op}, reg) do 86 if reg.a != 0 do 87 {:jump, op} 88 else 89 reg 90 end 91 end 92 93 defp combo(v, _) when v in 0..3, do: v 94 defp combo(4, %{a: a}), do: a 95 defp combo(5, %{b: b}), do: b 96 defp combo(6, %{c: c}), do: c 97end 98``` 99 100<!-- livebook:{"output":true} --> 101 102``` 103{:module, Computer, <<70, 79, 82, 49, 0, 0, 21, ...>>, {:combo, 2}} 104``` 105 106```elixir 107[ 108 "Register A: " <> a, 109 "Register B: " <> b, 110 "Register C: " <> c, 111 "Program: " <> raw_code 112] = String.split(puzzle_input, "\n", trim: true) 113 114reg = %{ 115 a: String.to_integer(a), 116 b: String.to_integer(b), 117 c: String.to_integer(c) 118} |> dbg() 119 120code = 121 raw_code 122 |> String.split(",") 123 |> Enum.map(&String.to_integer/1) 124 125program = Computer.load(code) 126``` 127 128<!-- livebook:{"output":true} --> 129 130``` 131%{a: 66245665, b: 0, c: 0} 132``` 133 134<!-- livebook:{"output":true} --> 135 136``` 137{{:bst, 4}, {:bxl, 7}, {:cdv, 5}, {:bxl, 7}, {:bxc, 6}, {:adv, 3}, {:out, 5}, {:jnz, 0}} 138``` 139 140## Part 1 141 142```elixir 143out = Computer.process(program, reg) 144``` 145 146<!-- livebook:{"output":true} --> 147 148``` 149[1, 4, 6, 1, 6, 4, 3, 0, 3] 150``` 151 152```elixir 153IO.puts(Enum.join(out, ",")) 154``` 155 156<!-- livebook:{"output":true} --> 157 158``` 1591,4,6,1,6,4,3,0,3 160``` 161 162<!-- livebook:{"output":true} --> 163 164``` 165:ok 166``` 167 168## Part 2 169 170```elixir 171defmodule Quine do 172 def find(program, target) do 173 do_find(program, Enum.reverse(target), Enum.to_list(0..7)) 174 end 175 176 def do_find(_program, [], out), do: out 177 178 def do_find(program, [n | rest], out) do 179 potential = 180 for a <- out, 181 i <- 0..7, 182 hd(Computer.process(program, a: a * 8 + i)) == n, 183 do: a * 8 + i 184 185 do_find(program, rest, potential) 186 end 187end 188``` 189 190<!-- livebook:{"output":true} --> 191 192``` 193{:module, Quine, <<70, 79, 82, 49, 0, 0, 10, ...>>, {:do_find, 3}} 194``` 195 196```elixir 197Quine.find(program, code) |> Enum.min() 198``` 199 200<!-- livebook:{"output":true} --> 201 202``` 203265061364597659 204``` 205 206<!-- livebook:{"offset":4021,"stamp":{"token":"XCP.PwUWTErrjClVJj6ZS87ZLrfbzleELwxqD__HBvfB1y_Yc633Wj72_Jigo2Z3T7V2ONi1nVguQ_AE_NSyLCF5sjSmWldUKuW294o_wsQqiM_gKhXOjSLzJOnslN9iIEFIEww","version":2}} -->