diff --git a/2021/24/main.go b/2021/24/main.go index 44e9305..0b57112 100644 --- a/2021/24/main.go +++ b/2021/24/main.go @@ -1,331 +1,130 @@ package main import ( - aoc "AoC/2021/common" - "bufio" "fmt" - "strconv" - "strings" ) -type Operator byte -const ( - INP Operator = iota - ADD - ADDR - MUL - MULR - DIV - DIVR - MOD - MODR - EQL - EQLR -) +func step(w int, z int, a int, b int, pop bool) int { + temp := z -func (op Operator) String() string { - switch op { - case INP: - return "INP" - case ADD, ADDR: - return "ADD" - case MUL, MULR: - return "MUL" - case DIV, DIVR: - return "DIV" - case MOD, MODR: - return "MOD" - case EQL, EQLR: - return "EQL" - default: - return fmt.Sprintf("%d", int(op)) - } -} - -type Instruction struct { - op Operator - a int - b int -} - -func (i Instruction) String() string { - if i.op == INP { - return fmt.Sprintf("%v\t[%s]", i.op, registerToString(i.a)) + if pop { + // Pop value from stack + z /= 26 } - if i.op % 2 == 0 { - return fmt.Sprintf("%v\t[%s],\t[%s]", i.op, registerToString(i.a), registerToString(i.b)) + if (temp%26)+a != w { + // Push new value to stack + z *= 26 + z += w + b } - return fmt.Sprintf("%v\t[%s],\t %d", i.op, registerToString(i.a), i.b) -} - -type Memory [4]int - -func (m Memory) String() string { - return fmt.Sprintf("w: %d, x: %d, y: %d, z: %d", m[0], m[1], m[2], m[3]) -} - -type Stream struct { - stream []int - counter int -} - -func (s *Stream) Get() int { - if s.counter == len(s.stream) { - panic("End of stream reached") - } - - val := s.stream[s.counter] - s.counter++ - return val -} - -func NewStream(input string) Stream { - var s Stream - s.stream = make([]int, len(input)) - - for i, b := range input { - n, err := strconv.Atoi(string(b)) - if err != nil { - panic(err) - } - - if n == 0 { - panic("0 is not a valid input") - } - - s.stream[i] = n - } - - return s -} - -type Program []Instruction - -func (p Program) Execute(input string) Memory { - stream := NewStream(input) - var mem Memory - - for _, i := range p { - switch i.op { - case INP: - mem[i.a] = stream.Get() - case ADD: - mem[i.a] += i.b - case ADDR: - mem[i.a] += mem[i.b] - case MUL: - mem[i.a] *= i.b - case MULR: - mem[i.a] *= mem[i.b] - case DIV: - mem[i.a] /= i.b - case DIVR: - mem[i.a] /= mem[i.b] - case MOD: - mem[i.a] %= i.b - case MODR: - mem[i.a] %= mem[i.b] - case EQL: - val := 0 - if mem[i.a] == i.b { - val = 1 - } - mem[i.a] = val - case EQLR: - val := 0 - if mem[i.a] == mem[i.b] { - val = 1 - } - mem[i.a] = val - default: - panic("Unknown operator") - } - - // fmt.Println(mem) - } - - return mem -} - -func Compile(input *bufio.Scanner) Program { - var program Program - - for input.Scan() { - line := input.Text() - inst := strings.Split(line, " ") - - var instruction Instruction - - // Parse the operator - switch inst[0] { - case "inp": - instruction.op = INP - case "add": - instruction.op = ADD - case "mul": - instruction.op = MUL - case "div": - instruction.op = DIV - case "mod": - instruction.op = MOD - case "eql": - instruction.op = EQL - default: - panic("Unknown instruction") - } - - // Parse the first parameter, this is always a register - instruction.a = parseRegister(inst[1]) - - // All instructions, except INP, require a second parameter - if instruction.op != INP { - b := inst[2] - if val, err := strconv.Atoi(b); err == nil { - // If the parameter is a number we use that as the second parameter - instruction.b = val - } else { - // Otherwise the parameter is a register, so we parse it and set it to the register - instruction.b = parseRegister(b) - // We also increment the operator by one to indicate that the second parameter is a register - instruction.op++ - } - } - - program = append(program, instruction) - } - - return program -} - -func (p Program) Optimize() Program { - // previous := len(p) - for counter := 0; counter < 4; counter++ { - fmt.Printf("PRECOMP %d\n", counter) - p = p.precomp() - - fmt.Printf("QUASI %d\n", counter) - p = p.quasi() - - // if previous == len(p) { - // fmt.Println("Done optimizing") - // break - // } - - // previous = len(p) - } - - return p + return z } func main() { - challenge := aoc.New(2021, 24) + // for w1 := 1; w1 <= 9; w1++ { + // z1 := step(w1, 0, 14, 1, false) + // for w2 := 1; w2 <= 9; w2++ { + // z2 := step(w2, z1, 15, 7, false) + // for w3 := 1; w3 <= 9; w3++ { + // z3 := step(w3, z2, 15, 13, false) + // for w4 := 1; w4 <= 9; w4++ { + // z4 := step(w4, z3, -6, 10, true) + // for w5 := 1; w5 <= 9; w5++ { + // fmt.Println(w1, w2, w3, w4, w5) + // z5 := step(w5, z4, 14, 0, false) + // for w6 := 1; w6 <= 9; w6++ { + // z6 := step(w6, z5, -4, 13, true) + // for w7 := 1; w7 <= 9; w7++ { + // z7 := step(w7, z6, 15, 11, false) + // for w8 := 1; w8 <= 9; w8++ { + // z8 := step(w8, z7, 15, 6, false) + // for w9 := 1; w9 <= 9; w9++ { + // z9 := step(w9, z8, 11, 1, false) + // for w10 := 1; w10 <= 9; w10++ { + // z10 := step(w10, z9, 0, 7, true) + // for w11 := 1; w11 <= 9; w11++ { + // z11 := step(w11, z10, 0, 11, true) + // for w12 := 1; w12 <= 9; w12++ { + // z12 := step(w12, z11, -3, 14, true) + // for w13 := 1; w13 <= 9; w13++ { + // z13 := step(w13, z12, -9, 4, true) - // challenge.Test(`inp x -// mul x -1`, []int{-1, -1}) + // w14 := z13 - 9 + // if w14 <= 0 || w14 > 9 { + // continue + // } - // challenge.Test(`inp z -// inp x -// mul z 3 -// eql z x`, []int{-1, -1}) + // z14 := step(w14, z13, -9, 10, true) - // challenge.Test(`inp w -// add z w -// mod z 2 -// div w 2 -// add y w -// mod y 2 -// div w 2 -// add x w -// mod x 2 -// div w 2 -// mod w 2`, []int{-1, -1}) + // if z14 == 0 { + // fmt.Println("SOLUTION FOUND:", w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14) + // return + // } + // } + // } + // } + // } + // } + // } + // } + // } + // } + // } + // } + // } + // } - challenge.Test(`inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 14 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 1 -mul y x -add z y`, []int{-1, -1}) + for w1 := 1; w1 <= 9; w1++ { + z1 := step(w1, 0, 14, 1, false) + for w2 := 1; w2 <= 9; w2++ { + z2 := step(w2, z1, 15, 7, false) + for w3 := 1; w3 <= 9; w3++ { + z3 := step(w3, z2, 15, 13, false) + for w4 := 1; w4 <= 9; w4++ { + z4 := step(w4, z3, -6, 10, true) + for w5 := 1; w5 <= 9; w5++ { + fmt.Println(w1, w2, w3, w4, w5) + z5 := step(w5, z4, 14, 0, false) + for w6 := 1; w6 <= 9; w6++ { + z6 := step(w6, z5, -4, 13, true) + for w7 := 1; w7 <= 9; w7++ { + z7 := step(w7, z6, 15, 11, false) + for w8 := 1; w8 <= 9; w8++ { + z8 := step(w8, z7, 15, 6, false) + for w9 := 1; w9 <= 9; w9++ { + z9 := step(w9, z8, 11, 1, false) + for w10 := 1; w10 <= 9; w10++ { + z10 := step(w10, z9, 0, 7, true) + for w11 := 1; w11 <= 9; w11++ { + z11 := step(w11, z10, 0, 11, true) + for w12 := 1; w12 <= 9; w12++ { + z12 := step(w12, z11, -3, 14, true) + for w13 := 1; w13 <= 9; w13++ { + z13 := step(w13, z12, -9, 4, true) - challenge.Test(`inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 14 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 1 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 7 -mul y x -add z y`, []int{-1, -1}) + w14 := z13 - 9 + if w14 <= 0 || w14 > 9 { + continue + } - // challenge.Test(``, []int{-1, -1}) + z14 := step(w14, z13, -9, 10, true) - challenge.Solution(1, func (input *bufio.Scanner) int { - program := Compile(input) - - fmt.Println("ORIGINAL") - for _, i := range program { - fmt.Printf("%v\n", i) + if z14 == 0 { + fmt.Println("SOLUTION FOUND:", w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14) + return + } + } + } + } + } + } + } + } + } + } + } + } } - fmt.Println(len(program)) - - fmt.Println("OPTIMIZED") - opti := program.Optimize() - for _, i := range opti { - fmt.Printf("%v\n", i) - } - fmt.Println(len(opti)) - - str := "25579246899999" - fmt.Println(program.Execute(str)) - fmt.Println(opti.Execute(str)) - - // fmt.Println(mem) - - return 0 - }) - - challenge.Solution(2, func (input *bufio.Scanner) int { - return 0 - }) + } } diff --git a/2021/24/helper.go b/2021/24/old/helper.go similarity index 100% rename from 2021/24/helper.go rename to 2021/24/old/helper.go diff --git a/2021/24/old/main.go b/2021/24/old/main.go new file mode 100644 index 0000000..183a66f --- /dev/null +++ b/2021/24/old/main.go @@ -0,0 +1,322 @@ +package main + +import ( + aoc "AoC/2021/common" + "bufio" + "fmt" + "strconv" + "strings" +) + +type Operator byte +const ( + INP Operator = iota + ADD + ADDR + MUL + MULR + DIV + DIVR + MOD + MODR + EQL + EQLR +) + +func (op Operator) String() string { + switch op { + case INP: + return "INP" + case ADD, ADDR: + return "ADD" + case MUL, MULR: + return "MUL" + case DIV, DIVR: + return "DIV" + case MOD, MODR: + return "MOD" + case EQL, EQLR: + return "EQL" + default: + return fmt.Sprintf("%d", int(op)) + } +} + +type Instruction struct { + op Operator + a int + b int +} + +func (i Instruction) String() string { + if i.op == INP { + return fmt.Sprintf("%v\t[%s]", i.op, registerToString(i.a)) + } + + if i.op % 2 == 0 { + return fmt.Sprintf("%v\t[%s],\t[%s]", i.op, registerToString(i.a), registerToString(i.b)) + } + + return fmt.Sprintf("%v\t[%s],\t %d", i.op, registerToString(i.a), i.b) +} + +type Memory [4]int + +func (m Memory) String() string { + return fmt.Sprintf("w: %d, x: %d, y: %d, z: %d", m[0], m[1], m[2], m[3]) +} + +type Stream struct { + stream []int + counter int +} + +func (s *Stream) Get() int { + if s.counter == len(s.stream) { + panic("End of stream reached") + } + + val := s.stream[s.counter] + s.counter++ + return val +} + +func NewStream(input string) Stream { + var s Stream + s.stream = make([]int, len(input)) + + for i, b := range input { + n, err := strconv.Atoi(string(b)) + if err != nil { + panic(err) + } + + if n == 0 { + panic("0 is not a valid input") + } + + s.stream[i] = n + } + + return s +} + +type Program []Instruction + +func (p Program) ExecuteMem(input string, mem Memory) Memory { + stream := NewStream(input) + + for _, i := range p { + switch i.op { + case INP: + mem[i.a] = stream.Get() + case ADD: + mem[i.a] += i.b + case ADDR: + mem[i.a] += mem[i.b] + case MUL: + mem[i.a] *= i.b + case MULR: + mem[i.a] *= mem[i.b] + case DIV: + mem[i.a] /= i.b + case DIVR: + mem[i.a] /= mem[i.b] + case MOD: + mem[i.a] %= i.b + case MODR: + mem[i.a] %= mem[i.b] + case EQL: + val := 0 + if mem[i.a] == i.b { + val = 1 + } + mem[i.a] = val + case EQLR: + val := 0 + if mem[i.a] == mem[i.b] { + val = 1 + } + mem[i.a] = val + default: + panic("Unknown operator") + } + + // fmt.Println(mem) + } + + return mem +} + +func (p Program) Execute(input string) Memory { + var mem Memory + + return p.ExecuteMem(input, mem) +} + +func Compile(input *bufio.Scanner) Program { + var program Program + + for input.Scan() { + line := input.Text() + inst := strings.Split(line, " ") + + var instruction Instruction + + // Parse the operator + switch inst[0] { + case "inp": + instruction.op = INP + case "add": + instruction.op = ADD + case "mul": + instruction.op = MUL + case "div": + instruction.op = DIV + case "mod": + instruction.op = MOD + case "eql": + instruction.op = EQL + default: + panic("Unknown instruction") + } + + // Parse the first parameter, this is always a register + instruction.a = parseRegister(inst[1]) + + // All instructions, except INP, require a second parameter + if instruction.op != INP { + b := inst[2] + if val, err := strconv.Atoi(b); err == nil { + // If the parameter is a number we use that as the second parameter + instruction.b = val + } else { + // Otherwise the parameter is a register, so we parse it and set it to the register + instruction.b = parseRegister(b) + // We also increment the operator by one to indicate that the second parameter is a register + instruction.op++ + } + } + + program = append(program, instruction) + } + + return program +} + +func (p Program) Optimize() Program { + fmt.Printf("QUASI\n") + p, _ = p.quasi(false) + + fmt.Printf("PRECOMP\n") + p = p.precomp() + + return p +} + +// func (p Program) Solver() { +// // There should be a total of 14 blocks +// mem := [4]int{3, 0, 0, 0} +// for i := range p { +// if p[i].op == INP { +// end := len(p) +// for j := i+1; j < len(p); j++ { +// if p[j].op == INP { +// end = j +// break +// } +// } + +// tp := p[i+1:end] +// tp.Execute("", [4]int{w, 0, 0, 0})) + +// break +// } +// } +// } + +func step(w int, z int, a int, b int, pop bool) int { + temp := z + + if pop { + // Pop value from stack + z /= 26 + } + + if (temp % 26) + a != w { + // Push new value to stack + z *= 26 + z += w+b + } + + return z +} + +func reverse(w int, z int, a int, b int, pop bool) []int { + var valid []int + for zc := 0; zc < 1000; zc++ { + res := step(w, zc, a, b, pop) + if res == z { + valid = append(valid, zc) + } + } + + return valid +} + + +func main() { + challenge := aoc.New(2021, 24) + + challenge.Solution(1, func (input *bufio.Scanner) int { + program := Compile(input) + + mem := program.Execute("13579246899999") + fmt.Println(mem) + + w := []int{1, 3, 5, 7, 9, 2, 4, 6, 8, 9, 9, 9, 9, 9} + z := step(w[0], 0, 14, 1, false) + z = step(w[1], z, 15, 7, false) + z = step(w[2], z, 15, 13, false) + z = step(w[3], z, -6, 10, true) + z = step(w[4], z, 14, 0, false) + z = step(w[5], z, -4, 13, true) + z = step(w[6], z, 15, 11, false) + z = step(w[7], z, 15, 6, false) + z = step(w[8], z, 11, 1, false) + z = step(w[9], z, 0, 7, true) + z = step(w[10], z, 0, 11, true) + z = step(w[11], z, -3, 14, true) + z = step(w[12], z, -9, 4, true) + z = step(w[13], z, -9, 10, true) + fmt.Println(z) + + // solution := make(map[int]int) + for w := 1; w <= 9; w++ { + valid := reverse(w, 0, -9, 10, true) + fmt.Println(w, valid) + for _, v := range valid { + check := step(w, v, -9, 10, true) + + if check != 0 { + panic("CHECK FAILED") + } + } + } + + + for w := 1; w <= 9; w++ { + fmt.Println(w, reverse(w, w+9, -9, 4, true)) + } + + // for _, i := range program { + // fmt.Println(i) + // } + + return -1 + }) + + challenge.Solution(2, func (input *bufio.Scanner) int { + return 0 + }) +} diff --git a/2021/24/precomp.go b/2021/24/old/precomp.go similarity index 52% rename from 2021/24/precomp.go rename to 2021/24/old/precomp.go index 09b4b9c..dc3fe9c 100644 --- a/2021/24/precomp.go +++ b/2021/24/old/precomp.go @@ -1,5 +1,7 @@ package main +// import "fmt" + type RegisterState struct { value int last int @@ -18,49 +20,61 @@ func (p Program) precomp() Program { } for _, i := range p { + // fmt.Println(i) switch i.op { case INP: r[i.a].known = false np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case ADD: if r[i.a].known { r[i.a].value += i.b + // fmt.Printf("- \t%v\n", r) continue } np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case ADDR: if r[i.a].known && r[i.b].known { r[i.a].value += r[i.b].value + // fmt.Printf("- \t%v\n", r) continue } if r[i.a].known { - np = append(np, Instruction{MUL, i.a, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.a].value}) + if r[i.a].value - r[i.a].last != 0 { + np = append(np, Instruction{ADD, i.a, r[i.a].value - r[i.a].last}) + r[i.a].last = r[i.a].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } if r[i.b].known { - np = append(np, Instruction{MUL, i.b, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.b].value}) + if r[i.b].value - r[i.b].last != 0 { + np = append(np, Instruction{ADD, i.b, r[i.b].value - r[i.b].last}) + r[i.b].last = r[i.b].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } r[i.a].known = false + // fmt.Printf("- \t%v\n", r) np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case MUL: if i.b == 0 { r[i.a].value = 0 if !r[i.a].known { r[i.a].value = 0 + r[i.a].last = 0 r[i.a].known = true np = append(np, Instruction{MUL, i.a, 0}) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } + // fmt.Printf("- \t%v\n", r) continue } @@ -70,14 +84,17 @@ func (p Program) precomp() Program { if r[i.a].known { r[i.a].value *= i.b + // fmt.Printf("- \t%v\n", r) continue } np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case MULR: if r[i.a].known && r[i.a].value == 0 { r[i.a].value = 0 + // fmt.Printf("- \t%v\n", r) continue } @@ -85,9 +102,12 @@ func (p Program) precomp() Program { r[i.a].value = 0 if !r[i.a].known { r[i.a].value = 0 + r[i.a].last = 0 r[i.a].known = true np = append(np, Instruction{MUL, i.a, 0}) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } + // fmt.Printf("- \t%v\n", r) continue } @@ -97,25 +117,30 @@ func (p Program) precomp() Program { if r[i.a].known && r[i.b].known { r[i.a].value *= r[i.b].value + // fmt.Printf("- \t%v\n", r) continue } if r[i.a].known { - np = append(np, Instruction{MUL, i.a, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.a].value}) + if r[i.a].value - r[i.a].last != 0 { + np = append(np, Instruction{ADD, i.a, r[i.a].value - r[i.a].last}) + r[i.a].last = r[i.a].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } if r[i.b].known { - np = append(np, Instruction{MUL, i.b, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.b].value}) + if r[i.b].value - r[i.b].last != 0 { + np = append(np, Instruction{ADD, i.b, r[i.b].value - r[i.b].last}) + r[i.b].last = r[i.b].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } r[i.a].known = false + // fmt.Printf("- \t%v\n", r) np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case DIV: if i.b == 1 { @@ -124,14 +149,17 @@ func (p Program) precomp() Program { if r[i.a].known { r[i.a].value /= i.b + // fmt.Printf("- \t%v\n", r) continue } np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case DIVR: if r[i.a].known && r[i.a].value == 0 { r[i.a].value = 0 + // fmt.Printf("- \t%v\n", r) continue } @@ -141,34 +169,42 @@ func (p Program) precomp() Program { if r[i.a].known && r[i.b].known { r[i.a].value /= r[i.b].value + // fmt.Printf("- \t%v\n", r) continue } if r[i.a].known { - np = append(np, Instruction{MUL, i.a, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.a].value}) + if r[i.a].value - r[i.a].last != 0 { + np = append(np, Instruction{ADD, i.a, r[i.a].value - r[i.a].last}) + r[i.a].last = r[i.a].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } if r[i.b].known { - np = append(np, Instruction{MUL, i.b, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.b].value}) + if r[i.b].value - r[i.b].last != 0 { + np = append(np, Instruction{ADD, i.b, r[i.b].value - r[i.b].last}) + r[i.b].last = r[i.b].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } r[i.a].known = false + // fmt.Printf("- \t%v\n", r) np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case MOD: if i.b == -1 { r[i.a].value = 0 if !r[i.a].known { r[i.a].value = 0 + r[i.a].last = 0 r[i.a].known = true np = append(np, Instruction{MUL, i.a, 0}) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } + // fmt.Printf("- \t%v\n", r) continue } @@ -176,22 +212,28 @@ func (p Program) precomp() Program { r[i.a].value = 0 if !r[i.a].known { r[i.a].value = 0 + r[i.a].last = 0 r[i.a].known = true np = append(np, Instruction{MUL, i.a, 0}) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } + // fmt.Printf("- \t%v\n", r) continue } if r[i.a].known { r[i.a].value %= i.b + // fmt.Printf("- \t%v\n", r) continue } np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case MODR: if r[i.a].known && r[i.a].value == 0 { r[i.a].value = 0 + // fmt.Printf("- \t%v\n", r) continue } @@ -199,9 +241,12 @@ func (p Program) precomp() Program { r[i.a].value = 0 if !r[i.a].known { r[i.a].value = 0 + r[i.a].last = 0 r[i.a].known = true np = append(np, Instruction{MUL, i.a, 0}) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } + // fmt.Printf("- \t%v\n", r) continue } @@ -209,33 +254,41 @@ func (p Program) precomp() Program { r[i.a].value = 0 if !r[i.a].known { r[i.a].value = 0 + r[i.a].last = 0 r[i.a].known = true np = append(np, Instruction{MUL, i.a, 0}) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } + // fmt.Printf("- \t%v\n", r) continue } if r[i.a].known && r[i.b].known { r[i.a].value %= r[i.b].value + // fmt.Printf("- \t%v\n", r) continue } if r[i.a].known { - np = append(np, Instruction{MUL, i.a, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.a].value}) + if r[i.a].value - r[i.a].last != 0 { + np = append(np, Instruction{ADD, i.a, r[i.a].value - r[i.a].last}) + r[i.a].last = r[i.a].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } if r[i.b].known { - np = append(np, Instruction{MUL, i.b, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.b].value}) + if r[i.b].value - r[i.b].last != 0 { + np = append(np, Instruction{ADD, i.b, r[i.b].value - r[i.b].last}) + r[i.b].last = r[i.b].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } r[i.a].known = false + // fmt.Printf("- \t%v\n", r) np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case EQL: if r[i.a].known { @@ -244,19 +297,24 @@ func (p Program) precomp() Program { val = 1 } r[i.a].value = val + // fmt.Printf("- \t%v\n", r) continue } np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) case EQLR: if i.a == i.b { r[i.a].value = 1 if !r[i.a].known { r[i.a].value = 0 + r[i.a].last = 0 r[i.a].known = true np = append(np, Instruction{MUL, i.a, 0}) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } + // fmt.Printf("- \t%v\n", r) continue } @@ -266,25 +324,30 @@ func (p Program) precomp() Program { val = 1 } r[i.a].value = val + // fmt.Printf("- \t%v\n", r) continue } if r[i.a].known { - np = append(np, Instruction{MUL, i.a, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.a].value}) + if r[i.a].value - r[i.a].last != 0 { + np = append(np, Instruction{ADD, i.a, r[i.a].value - r[i.a].last}) + r[i.a].last = r[i.a].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } if r[i.b].known { - np = append(np, Instruction{MUL, i.b, 0}) - if r[i.b].value != 0 { - np = append(np, Instruction{ADD, i.b, r[i.b].value}) + if r[i.b].value - r[i.b].last != 0 { + np = append(np, Instruction{ADD, i.b, r[i.b].value - r[i.b].last}) + r[i.b].last = r[i.b].value + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } r[i.a].known = false + // fmt.Printf("- \t%v\n", r) np = append(np, i) + // fmt.Printf("- \t%v\n", np[len(np)-1]) } } diff --git a/2021/24/quasi.go b/2021/24/old/quasi.go similarity index 54% rename from 2021/24/quasi.go rename to 2021/24/old/quasi.go index 4a42321..78742a6 100644 --- a/2021/24/quasi.go +++ b/2021/24/old/quasi.go @@ -7,6 +7,12 @@ type RegisterQuasiState struct { max int } +type SubProgram struct { + program Program + min int + max int +} + func minv(a int, b int) int { if a < b { return a @@ -22,16 +28,27 @@ func maxv(a int, b int) int { } // This function will try to eliminate eql statements -func (p Program) quasi() Program { +func (p Program) quasi(prnt bool) (Program, []SubProgram) { var np Program + var sp []SubProgram var r [4]RegisterQuasiState + counter1 := 0 + counter2 := 0 broken := false - for _, i := range p { + for index, i := range p { if !broken { switch i.op { case INP: + counter2 = counter1 + counter1 = index + + sp = append(sp, SubProgram{p[counter2:counter1], r[3].min, r[3].max}) + + if prnt { + fmt.Println("") + } r[i.a].min = 1 r[i.a].max = 9 @@ -60,13 +77,35 @@ func (p Program) quasi() Program { r[i.a].min = minv(min1, minv(min2, minv(max1, max2))) r[i.a].max = maxv(min1, maxv(min2, maxv(max1, max2))) + case DIV: + r[i.a].min /= i.b + r[i.a].max /= i.b + + if r[i.a].min > r[i.a].max { + r[i.a].min, r[i.a].max = r[i.a].max, r[i.a].min + } + + case DIVR: + min1 := r[i.a].min / r[i.b].min + min2 := r[i.a].min / r[i.b].max + max1 := r[i.a].max / r[i.b].min + max2 := r[i.a].max / r[i.b].max + + r[i.a].min = minv(min1, minv(min2, minv(max1, max2))) + r[i.a].max = maxv(min1, maxv(min2, maxv(max1, max2))) + case EQL: if i.b < r[i.a].min || i.b > r[i.a].max { r[i.a].min = 0 r[i.a].max = 0 + if prnt { + fmt.Printf("- %v \t %v\n", i, r) + } np = append(np, Instruction{MUL, i.a, 0}) - fmt.Println("\tReplace EQL with mul 0") + if prnt { + fmt.Printf("+ %v\n", np[len(np)-1]) + } continue } @@ -79,9 +118,17 @@ func (p Program) quasi() Program { r[i.a].min = val r[i.a].max = val + if prnt { + fmt.Printf("- %v \t %v\n", i, r) + } np = append(np, Instruction{MUL, i.a, 0}) + if prnt { + fmt.Printf("+ %v\n", np[len(np)-1]) + } np = append(np, Instruction{ADD, i.a, 1}) - fmt.Println("\tReplace EQL with mul 0, add 1") + if prnt { + fmt.Printf("+ %v\n", np[len(np)-1]) + } continue } @@ -93,8 +140,13 @@ func (p Program) quasi() Program { r[i.a].min = 0 r[i.a].max = 0 + if prnt { + fmt.Printf("- %v \t %v\n", i, r) + } np = append(np, Instruction{MUL, i.a, 0}) - fmt.Println("\tReplace EQLR with mul 0") + if prnt { + fmt.Printf("+ %v\n", np[len(np)-1]) + } continue } @@ -107,9 +159,17 @@ func (p Program) quasi() Program { r[i.a].min = val r[i.a].max = val + if prnt { + fmt.Printf("- %v \t %v\n", i, r) + } np = append(np, Instruction{MUL, i.a, 0}) + if prnt { + fmt.Printf("+ %v\n", np[len(np)-1]) + } np = append(np, Instruction{ADD, i.a, 1}) - fmt.Println("\tReplace EQLR with mul 0, add 1") + if prnt { + fmt.Printf("+ %v\n", np[len(np)-1]) + } continue } @@ -117,8 +177,17 @@ func (p Program) quasi() Program { r[i.a].max = 1 case MOD: - r[i.a].min = 0 - r[i.a].max = i.b + if r[i.a].max <= 0 || r[i.a].max >= i.b { + r[i.a].max = i.b - 1 + } + + if r[i.a].min <= 0 || r[i.a].min >= i.b { + r[i.a].min = 0 + + } + + // r[i.a].min = 0 + // r[i.a].max = i.b-1 if r[i.a].min > r[i.a].max { r[i.a].min, r[i.a].max = r[i.a].max, r[i.a].min @@ -126,15 +195,22 @@ func (p Program) quasi() Program { default: - fmt.Println("\tBROKE") + if prnt { + fmt.Printf("\tBROKE: %v\n", i.op) + } broken = true } } + if prnt { + fmt.Printf("%v \t %v\n", i, r) + } + np = append(np, i) } + sp = append(sp, SubProgram{p[counter1:], r[3].min, r[3].max}) - return np + return np, sp[1:] } diff --git a/2021/24/scratch b/2021/24/scratch index a0ac571..f875ca1 100644 --- a/2021/24/scratch +++ b/2021/24/scratch @@ -1,293 +1,265 @@ -PART1 -inp w -add y w -add y 1 -add z y -add x 1 +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 1 +ADD [x], 14 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 1 +MUL [y], [x] +ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 1 +ADD [x], 15 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 7 +MUL [y], [x] +ADD [z], [y] -PART2 -INP [w] -ADD [y], [w] -ADD [y], 1 -ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 1 +ADD [x], 15 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 13 +MUL [y], [x] +ADD [z], [y] -w = ? x = 1 y = ? z = ? -INP [w] -MUL [x], 0 -ADD [x], [z] -MOD [x], 26 -ADD [x], 15 -MUL [x], 0 -MUL [x], 0 -ADD [x], 1 -MUL [y], 0 -ADD [y], 25 -MUL [y], [x] -ADD [y], 1 -MUL [z], [y] -MUL [y], 0 -ADD [y], [w] -ADD [y], 7 -MUL [y], [x] -ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 26 +ADD [x], -6 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 10 +MUL [y], [x] +ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 1 +ADD [x], 14 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 0 +MUL [y], [x] +ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 26 +ADD [x], -4 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 13 +MUL [y], [x] +ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 1 +ADD [x], 15 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 11 +MUL [y], [x] +ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 1 +ADD [x], 15 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 6 +MUL [y], [x] +ADD [z], [y] -ORIGINAL -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 14 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 1 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 7 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 13 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -6 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 10 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 14 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 0 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -4 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 13 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 11 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 15 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 6 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 1 -add x 11 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 1 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x 0 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 7 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x 0 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 11 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -3 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 14 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -9 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 4 -mul y x -add z y -inp w -mul x 0 -add x z -mod x 26 -div z 26 -add x -9 -eql x w -eql x 0 -mul y 0 -add y 25 -mul y x -add y 1 -mul z y -mul y 0 -add y w -add y 10 -mul y x -add z y +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 1 +ADD [x], 11 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 1 +MUL [y], [x] +ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 26 +ADD [x], 0 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 7 +MUL [y], [x] +ADD [z], [y] +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 26 +ADD [x], 0 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 11 +MUL [y], [x] +ADD [z], [y] + +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 26 +ADD [x], -3 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 14 +MUL [y], [x] +ADD [z], [y] + +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 26 +ADD [x], -9 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 4 +MUL [y], [x] +ADD [z], [y] + +INP [w] +MUL [x], 0 +ADD [x], [z] +MOD [x], 26 +DIV [z], 26 +ADD [x], -9 +EQL [x], [w] +EQL [x], 0 +MUL [y], 0 +ADD [y], 25 +MUL [y], [x] +ADD [y], 1 +MUL [z], [y] +MUL [y], 0 +ADD [y], [w] +ADD [y], 10 +MUL [y], [x] +ADD [z], [y]