Skip to content

Commit

Permalink
day 17 part 2 solution, input specific but runs in some microseconds
Browse files Browse the repository at this point in the history
  • Loading branch information
aleche28 committed Dec 18, 2024
1 parent ceb064c commit 1ec3948
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 11 deletions.
Binary file modified solutions/alessio/day17/aoc17
Binary file not shown.
106 changes: 96 additions & 10 deletions solutions/alessio/day17/day17.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
"slices"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -34,13 +35,12 @@ func exec(opcode int, operand int, a *int, b *int, c *int) bool {
switch opcode {
case 0: // adv
opVal := getComboOpVal(operand, *a, *b, *c)
res := (*a) / (1 << opVal)
*a = res
(*a) = (*a) >> opVal
case 1: // bxl
(*b) = (*b) ^ operand
case 2: // bst
opVal := getComboOpVal(operand, *a, *b, *c)
(*b) = opVal % 8
(*b) = opVal & 7
case 3: // jnz
if (*a) != 0 {
return true
Expand All @@ -49,15 +49,13 @@ func exec(opcode int, operand int, a *int, b *int, c *int) bool {
(*b) = (*b) ^ (*c)
case 5: // out
opVal := getComboOpVal(operand, *a, *b, *c)
fmt.Printf("%d,", opVal%8)
fmt.Printf("%d,", opVal&7)
case 6: // bdv
opVal := getComboOpVal(operand, *a, *b, *c)
res := (*a) / (1 << opVal)
*b = res
(*b) = (*a) >> opVal
case 7: // cdv
opVal := getComboOpVal(operand, *a, *b, *c)
res := (*a) / (1 << opVal)
*c = res
(*c) = (*a) >> opVal
default:
panic("invalid opcode: " + string(opcode))
}
Expand Down Expand Up @@ -94,8 +92,95 @@ func part1(lines []string) {

}

func checkEquation(x byte, res byte) bool {
// it would be:
// ((x ^ 010) ^ ((a >> i) >> (x ^ 010)) ^ 011) & 111 = res
// but (a >> i) can be replaced with (a >> i) & 111, that is x
// because we just care about the last 3 bits of all this operations
// therefore the compacted equation is:
// ((x ^ 010) ^ (x >> (x ^ 010)) ^ 011) & 111 = res
this := ((x ^ 0b010) ^ (x >> (x ^ 0b010)) ^ 0b011) & 0b111
fmt.Println(this)
return this == res
}

func part2(lines []string) {
solve(lines)
results := []byte{2, 4, 1, 2, 7, 5, 4, 7, 1, 3, 5, 5, 0, 3, 3, 0}
a := 0
for i := 0; i <= 45; i += 3 {
res := results[i/3]
// x = ( a >> i ) & 111
// This extracts the 3 bits starting at position i in a's binary
// representation.
valid := false
for x := 0; x < 8; x++ {
if checkEquation(byte(x), res) {
a |= (x << i)
valid = true
break
}
}
if !valid {
panic("no valid x found for i=" + strconv.Itoa(i))
}
}
fmt.Println(a)
fmt.Println(1 << 45)
}

func part2gpt() {
// The given output sequence
results := []byte{2, 4, 1, 2, 7, 5, 4, 7, 1, 3, 5, 5, 0, 3, 3, 0}
a := 0

// Reconstruct a in reverse
shift := 0
for i := len(results) - 1; i >= 0; i-- {
b := int(results[i]) // b & 111 is the output
b ^= 0b011 // Reverse final XOR
c := a >> shift // Recompute c as the shifted part of a
b ^= c // Reverse second XOR
b ^= 0b010 // Reverse first XOR
a |= int(b) << shift // Add the reconstructed bits to a
shift += 3 // Shift by 3 bits for the next chunk
}

fmt.Printf("Reconstructed a: %d\n", a)
}

func outputSingleIteration(a int) byte {
b := a & 0b111
b ^= 0b010
c := a >> b
b ^= c
b ^= 0b011
return byte(b & 0b111)
}

func completeOutput(a int) []byte {
output := make([]byte, 0, 16)
for a > 0 {
output = append(output, outputSingleIteration(a))
a /= 8
}
return output
}

func part2b() {
output := []byte{2, 4, 1, 2, 7, 5, 4, 7, 1, 3, 5, 5, 0, 3, 3, 0}
tot := len(output)

a := 1
for i := 1; i <= tot; i++ {
for !slices.Equal(completeOutput(a), output[tot-i:]) {
a++
}
if i != tot {
a *= 8
}
}

fmt.Println(a)
}

func main() {
Expand All @@ -108,6 +193,7 @@ func main() {
part1(lines)
fmt.Printf("part1: %s\n", time.Since(start))
start = time.Now()
part2(lines)
part2b()
fmt.Printf("part2: %s\n", time.Since(start))
// part2gpt()
}
2 changes: 1 addition & 1 deletion solutions/alessio/day17/input17_def.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Register A: 35200350
Register A: 37221274271220
Register B: 0
Register C: 0

Expand Down
63 changes: 63 additions & 0 deletions solutions/alessio/day17/notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

2,4 1,2 7,5 4,7 1,3 5,5 0,3 3,0

primo giro:

b = a & 111
b = b ^ 010
c = a >> b
b = b ^ c
b = b ^ 011
(b & 111) == 2

b = (a & 111) ^ 010
c = a >> ((a & 111) ^ 010)
b = ((a & 111) ^ 010) ^ (a >> ((a & 111) ^ 010))
b = ((a & 111) ^ 010) ^ (a >> ((a & 111) ^ 010)) ^ 011
print(b & 111) => (((a & 111) ^ 010) ^ (a >> ((a & 111) ^ 010)) ^ 011) & 111 = 010
=> (x ^ (a >> x) ^ 011) & 111 = 010
=> x ^ (a >> x) ^ 011 = 010
=> x ^ (a >> x) = 001

secondo giro:

if a >> 3 != 0 (cioe' a >= 8) {
((((a >> 3)& 111) ^ 010) ^ ((a >> 3)>> (((a >> 3)& 111) ^ 010)) ^ 011) & 111 = 100
} else (cioe' a < 8) {
break
quindi, al secondo giro a >= 8 sicuramente
}

terzo giro:
if a >> 6 != 0 (cioe' a >= 64) {
((((a >> 6)& 111) ^ 010) ^ ((a >> 6)>> (((a >> 6)& 111) ^ 010)) ^ 011) & 111 = 001
} else {
break
quindi, anche ora al terzo giro >= 64 sicuramente
}

sicuramente a >= 2^15, inoltre posso mettere tante condizioni a sistema:
(((a & 111) ^ 010) ^ (a >> ((a & 111) ^ 010)) ^ 011) & 111 = 010
((((a >> 3)& 111) ^ 010) ^ ((a >> 3)>> (((a >> 3)& 111) ^ 010)) ^ 011) & 111 = 100
((((a >> 6)& 111) ^ 010) ^ ((a >> 6)>> (((a >> 6)& 111) ^ 010)) ^ 011) & 111 = 001
((((a >> 9)& 111) ^ 010) ^ ((a >> 9)>> (((a >> 9)& 111) ^ 010)) ^ 011) & 111 = 010
((((a >> 12)& 111) ^ 010) ^ ((a >> 12)>> (((a >> 12)& 111) ^ 010)) ^ 011) & 111 = 111
((((a >> 15)& 111) ^ 010) ^ ((a >> 15)>> (((a >> 15)& 111) ^ 010)) ^ 011) & 111 = 101
((((a >> 18)& 111) ^ 010) ^ ((a >> 18)>> (((a >> 18)& 111) ^ 010)) ^ 011) & 111 = 100
((((a >> 21)& 111) ^ 010) ^ ((a >> 21)>> (((a >> 21)& 111) ^ 010)) ^ 011) & 111 = 111
((((a >> 24)& 111) ^ 010) ^ ((a >> 24)>> (((a >> 24)& 111) ^ 010)) ^ 011) & 111 = 001
((((a >> 27)& 111) ^ 010) ^ ((a >> 27)>> (((a >> 27)& 111) ^ 010)) ^ 011) & 111 = 011
((((a >> 30)& 111) ^ 010) ^ ((a >> 30)>> (((a >> 30)& 111) ^ 010)) ^ 011) & 111 = 101
((((a >> 33)& 111) ^ 010) ^ ((a >> 33)>> (((a >> 33)& 111) ^ 010)) ^ 011) & 111 = 101
((((a >> 36)& 111) ^ 010) ^ ((a >> 36)>> (((a >> 36)& 111) ^ 010)) ^ 011) & 111 = 000
((((a >> 39)& 111) ^ 010) ^ ((a >> 39)>> (((a >> 39)& 111) ^ 010)) ^ 011) & 111 = 011
((((a >> 42)& 111) ^ 010) ^ ((a >> 42)>> (((a >> 42)& 111) ^ 010)) ^ 011) & 111 = 011
((((a >> 45)& 111) ^ 010) ^ ((a >> 45)>> (((a >> 45)& 111) ^ 010)) ^ 011) & 111 = 000

a >= 2^45

((x ^ 010) ^ (x >> (x ^ 010)) ^ 011) & 111 = 100

(((b ^ 010) ^ ((a >> 3)>> ((b ^ 010)) ^ 011) & 111 = 100
(((b ^ 010) ^ ((a >> (3 + (b ^ 010))) ^ 011) & 111 = 100
(((x ^ 010) ^ ((a >> i)>> (x ^ 010) ^ 011) & 111 = 100

0 comments on commit 1ec3948

Please sign in to comment.