new strategy, but still not working
This commit is contained in:
157
day17/copy.go
157
day17/copy.go
@@ -1,157 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import ("math"; "errors"; "strconv"; "strings"; "fmt"; "os")
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
func check(err error) { if err != nil { panic(err) } }
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
type Computer struct {
|
|
||||||
pc uint
|
|
||||||
ra uint
|
|
||||||
rb uint
|
|
||||||
rc uint
|
|
||||||
mem []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewComputer(input string) *Computer {
|
|
||||||
registers := strings.Split(input, "\n\n")[0]
|
|
||||||
memory := strings.Split(strings.Split(input, "\n\n")[1], " ")[1]
|
|
||||||
|
|
||||||
lines := strings.Split(registers, "\n")
|
|
||||||
ra, err := strconv.Atoi(strings.TrimSpace(strings.Split(lines[0], ":")[1]))
|
|
||||||
check(err)
|
|
||||||
rb, err := strconv.Atoi(strings.TrimSpace(strings.Split(lines[1], ":")[1]))
|
|
||||||
check(err)
|
|
||||||
rc, err := strconv.Atoi(strings.TrimSpace(strings.Split(lines[2], ":")[1]))
|
|
||||||
check(err)
|
|
||||||
|
|
||||||
mem := make([]byte, 0)
|
|
||||||
for _, str := range strings.Split(memory, ",") {
|
|
||||||
num, err := strconv.Atoi(str)
|
|
||||||
check(err)
|
|
||||||
mem = append(mem, byte(num))
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Computer{
|
|
||||||
pc: 0,
|
|
||||||
ra: uint(ra),
|
|
||||||
rb: uint(rb),
|
|
||||||
rc: uint(rc),
|
|
||||||
mem: mem,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) literalop() uint {
|
|
||||||
// current literal operator
|
|
||||||
return uint(c.mem[c.pc + 1])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) comboop() uint {
|
|
||||||
// current combo operator
|
|
||||||
val := uint(c.mem[c.pc + 1])
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case val == 4: val = c.ra
|
|
||||||
case val == 5: val = c.rb
|
|
||||||
case val == 6: val = c.rc
|
|
||||||
case val == 7: panic("invalid program")
|
|
||||||
}
|
|
||||||
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) adv(op uint) uint {
|
|
||||||
// division
|
|
||||||
numerator := c.ra
|
|
||||||
denominator := math.Pow(2, float64(op))
|
|
||||||
return uint(float64(numerator) / float64(denominator))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) bxl(op uint) uint {
|
|
||||||
// bitwise xor
|
|
||||||
return c.rb ^ op
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) bst(op uint) uint {
|
|
||||||
// mod 8
|
|
||||||
return op % 8
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) jnz(op uint) {
|
|
||||||
// jump if non zero
|
|
||||||
if c.ra == 0 {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
c.pc = op - 2
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) bxc() uint {
|
|
||||||
// bitwise xor
|
|
||||||
return c.rb ^ c.rc
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) tick() (int, error) {
|
|
||||||
// returns an error if the program halts
|
|
||||||
if c.pc >= uint(len(c.mem)) { return -1, errors.New("halted") }
|
|
||||||
|
|
||||||
instr := c.mem[c.pc]
|
|
||||||
out := -1
|
|
||||||
switch {
|
|
||||||
case instr == 0: c.ra = c.adv(c.comboop())
|
|
||||||
case instr == 1: c.rb = c.bxl(c.literalop())
|
|
||||||
case instr == 2: c.rb = c.bst(c.comboop())
|
|
||||||
case instr == 3: c.jnz(c.literalop())
|
|
||||||
case instr == 4: c.rb = c.bxc()
|
|
||||||
case instr == 5: out = int(c.comboop() % 8)
|
|
||||||
case instr == 6: c.rb = c.adv(c.comboop())
|
|
||||||
case instr == 7: c.rc = c.adv(c.comboop())
|
|
||||||
}
|
|
||||||
|
|
||||||
c.pc += 2
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) returns_its_source() bool {
|
|
||||||
i := 0
|
|
||||||
for {
|
|
||||||
out, err := c.tick()
|
|
||||||
|
|
||||||
if err != nil { return false }
|
|
||||||
if out != -1 {
|
|
||||||
if byte(out) != c.mem[i] { return false }
|
|
||||||
i++
|
|
||||||
if i == len(c.mem) { return true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// never reached
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Computer) restore(ra uint) {
|
|
||||||
c.pc = 0
|
|
||||||
c.ra = ra
|
|
||||||
c.rb = 0
|
|
||||||
c.rc = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
func main() {
|
|
||||||
dat, err := os.ReadFile("data.txt")
|
|
||||||
check(err)
|
|
||||||
input := strings.TrimSpace(string(dat))
|
|
||||||
|
|
||||||
comp := NewComputer(input)
|
|
||||||
|
|
||||||
for i := range 1000000000 {
|
|
||||||
comp.restore(uint(i))
|
|
||||||
if comp.returns_its_source() {
|
|
||||||
fmt.Println(i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
107
day17/reversed.go
Normal file
107
day17/reversed.go
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func reverseSlice(slice []uint) {
|
||||||
|
for i, j := 0, len(slice)-1; i < j; i, j = i+1, j-1 {
|
||||||
|
slice[i], slice[j] = slice[j], slice[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func compressedProgram(ra uint) []uint {
|
||||||
|
out := make([]uint, 0)
|
||||||
|
|
||||||
|
var A, B uint
|
||||||
|
A = ra
|
||||||
|
|
||||||
|
for {
|
||||||
|
B = ((A % 8) ^ 2) ^ 7 ^ (A >> ((A % 8) ^ 2))
|
||||||
|
A = A >> 3
|
||||||
|
|
||||||
|
out = append(out, B%8)
|
||||||
|
|
||||||
|
if A == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func reversedProgram(out []uint) uint {
|
||||||
|
reverseSlice(out)
|
||||||
|
A := uint(0)
|
||||||
|
|
||||||
|
for _, o := range out {
|
||||||
|
|
||||||
|
// find next n bits so that o is returned
|
||||||
|
n := 2
|
||||||
|
searching := true
|
||||||
|
for searching {
|
||||||
|
n++
|
||||||
|
|
||||||
|
// for every combination of n bits
|
||||||
|
for i := range 1 << n {
|
||||||
|
A_ := (A << n) + uint(i)
|
||||||
|
|
||||||
|
//fmt.Println("add", i, "as binary with", n, "bits")
|
||||||
|
//fmt.Println("old", strconv.FormatUint(uint64(A), 2))
|
||||||
|
//fmt.Println("new", strconv.FormatUint(uint64(A_), 2))
|
||||||
|
|
||||||
|
if o == ((A_%8)^2)^7^(A_>>((A_%8)^2))%8 {
|
||||||
|
A = A_
|
||||||
|
//fmt.Println("valid")
|
||||||
|
//fmt.Println("yields", compressedProgram(A))
|
||||||
|
searching = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Println("invalid")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return A
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
fmt.Println(input)
|
||||||
|
|
||||||
|
a := uint64(0)
|
||||||
|
for _, elem := range input {
|
||||||
|
|
||||||
|
expected_d := elem ^ 7
|
||||||
|
for b := range 8 {
|
||||||
|
e := uint64(b ^ 2)
|
||||||
|
c := (((a << 3) | uint64(b)) >> (e)) % 8
|
||||||
|
actual_d := c ^ e
|
||||||
|
if uint64(expected_d) == actual_d {
|
||||||
|
fmt.Println(b)
|
||||||
|
fmt.Println(e)
|
||||||
|
fmt.Println(c)
|
||||||
|
a = a << 3
|
||||||
|
a = a | uint64(b)
|
||||||
|
fmt.Println(strconv.FormatUint(a, 2))
|
||||||
|
fmt.Println(a, 2)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
fmt.Println(a)
|
||||||
|
//fmt.Println(strconv.FormatUint(a, 2))
|
||||||
|
*/
|
||||||
|
|
||||||
|
//fmt.Println(compressedProgram(41644071))
|
||||||
|
|
||||||
|
input := []uint{2, 4, 1, 2, 7, 5, 1, 7, 4, 4, 0, 3, 5, 5, 3, 0}
|
||||||
|
fmt.Println("-- input: ", input, "--")
|
||||||
|
ra := reversedProgram(input)
|
||||||
|
fmt.Println("-- ra: ", ra, "--")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user