From 6b37eaf6dfa15b143c7ce587d2c03e64e176b6a5 Mon Sep 17 00:00:00 2001 From: Dory Date: Tue, 17 Dec 2024 12:37:35 -0800 Subject: [PATCH] better d17 --- day17/d17p2.swift | 130 ++++++++++++++++++++++++---------------------- 1 file changed, 69 insertions(+), 61 deletions(-) diff --git a/day17/d17p2.swift b/day17/d17p2.swift index 1752287..c816f11 100644 --- a/day17/d17p2.swift +++ b/day17/d17p2.swift @@ -10,11 +10,6 @@ import Foundation 6 bdv: A / 2^OP -> B 7 cdv: A / 2^OP -> C -adv 1 // A = A / 2 -out A // print(A % 8) -jnz 0 // loop while A != 0 - - 2,4, 1,1, 7,5, 1,5, 4,0, 5,5, 0,3, 3,0 bst 4 // B = A % 8 bxl 1 // B = B xor 1 @@ -27,54 +22,16 @@ jnz 0 // loop while A != 0 */ extension RangeReplaceableCollection where Self: StringProtocol { - func paddingToLeft(upTo length: Int, using element: Element = " ") -> SubSequence { - return repeatElement(element, count: Swift.max(0, length-count)) + suffix(Swift.max(count, count-length)) - } -} - -let prog = [2,4, 1,1, 7,5, 1,5, 4,0, 5,5, 0,3, 3,0] - -var A0 = -1 -var Asuffixlen = 16 -var Asuffixes = [0b0110111010111101, 0b0110111110111101] -var maxLen = 0 -aLoop: while true { - A0 += 1 - for suffix in Asuffixes { - //var A = A0 // do this at the beginning to find the suffixes - let Ax = (A0 << Asuffixlen) | suffix - var A = Ax - var B = 0 - var C = 0 - progLoop: for i in 0..> B // 3 - B = B ^ 5 // 4 - B = B ^ C // 5 - // print(B % 8, terminator: ",") - if B % 8 != prog[i] { - if i >= maxLen { - maxLen = i - print(String(Ax, radix: 2).paddingToLeft(upTo: 64) + - " (\(i)) \(prog.prefix(i))") - } - continue aLoop - } - A = A >> 3 - if A == 0 { - if i == prog.count - 1 { - print(Ax) - break aLoop - } - continue aLoop - } - } + func padLeft(to length: Int, using e: Element = " ") -> SubSequence { + return repeatElement(e, + count: Swift.max(0, length-count)) + + suffix(Swift.max(count, count-length) + ) } } /* -Loop 1 +printout 2 B1 = A%8 | B2 | C3 | B4 | B5 = B4^C3 = xxxxx010 | A? ---------+-----+------+-----+-----------------------+------------ 000 | 001 | A>>1 | 100 | 100^(A>>1) = xxxxx010 | ...xxxx001x (❌) @@ -85,16 +42,67 @@ B1 = A%8 | B2 | C3 | B4 | B5 = B4^C3 = xxxxx010 | A? 101 | 100 | A>>4 | 001 | 001^(A>>4) = xxxxx010 | ...x011x101 110 | 111 | A>>7 | 010 | 010^(A>>7) = xxxxx010 | .000xxxx110 111 | 110 | A>>6 | 011 | 011^(A>>6) = xxxxx010 | ..001xxx111 - -Loop 2 -B1 = A%8 | B2 | C3 | B4 | B5 = B4^C3 = xxxxx100 | A? ----------+-----+------+-----+-----------------------+--------- - 000 | 001 | A>>1 | 100 | 100^(A>>1) = xxxxx100 | ...xxxx0000 - 001 | 000 | A | 101 | 101^A = xxxxx100 | ...xxxxx001 - 010 | 011 | A>>3 | 110 | 110^(A>>3) = xxxxx100 | ...xx010010 - 011 | 010 | A>>2 | 111 | 111^(A>>2) = xxxxx100 | ...xxx011xx (❌) - 100 | 101 | A>>5 | 000 | 000^(A>>5) = xxxxx100 | 010xx100 - 101 | 100 | A>>4 | 001 | 001^(A>>4) = xxxxx100 | 0011x101 - 110 | 111 | A>>7 | 010 | 010^(A>>7) = xxxxx100 | 0xxxx110 - 111 | 110 | A>>6 | 011 | 011^(A>>6) = xxxxx100 | 01xxx111 */ + +struct Register : Comparable, CustomStringConvertible { + let value: Int + let mask: Int + var description: String { + var s: String = "" + var (v, m) = (value, mask) + while v != 0 || m != 0 { + s = ((m&1 == 0) ? "x" : String(v&1)) + s + v >>= 1 + m >>= 1 + } + return String(s.padLeft(to: 64, using: "x")) + } + static func < (lhs: Register, rhs: Register) -> Bool { + return (lhs.value & lhs.mask) < (rhs.value & rhs.mask) + } + static func == (lhs: Register, rhs: Register) -> Bool { + return (lhs.value & lhs.mask) == (rhs.value & rhs.mask) + } + var dec: Int { return value & mask } + + func combine(with b: Register) -> Register? { + if self.value & self.mask & b.mask == b.value & self.mask & b.mask { + return Register( + value: (self.value & self.mask) | (b.value & b.mask), + mask: self.mask | b.mask + ) + } + return nil + } + static func >> (lhs: Register, rhs: Int) -> Register { + return Register(value: lhs.value >> rhs, mask: lhs.mask >> rhs) + } + static func << (lhs: Register, rhs: Int) -> Register { + return Register(value: lhs.value << rhs, mask: lhs.mask << rhs) + } +} + +func possibleAs(fromB5 b5Suffix: Int) -> [Register] { + let choices: [Register] = (0b000...0b111).compactMap { aSuffix in + let aShift = aSuffix ^ 1 + let b4 = aShift ^ 5 + let a = Register(value: (b4^b5Suffix) << aShift, mask: 0b111 << aShift) + return a.combine(with: Register(value: aSuffix, mask: 0b111)) + } + return choices.sorted() +} + +func findA(from a: Register, _ outputs: [Int]) -> [Register] { + if outputs.count == 0 { return [a] } + let As = possibleAs(fromB5: outputs[0]).compactMap { a.combine(with: $0) } + return As.flatMap { a in + findA(from: a >> 3, Array(outputs.dropFirst())).compactMap { nextA in + a.combine(with: nextA << 3) + } + }.sorted() +} + +let prog = [2,4, 1,1, 7,5, 1,5, 4,0, 5,5, 0,3, 3,0] +let res = findA(from: Register(value: 0, mask: 0), prog) +print(res) +print(res[0].dec)