2021 - Day 24
This commit is contained in:
363
2021/24/old/precomp.go
Normal file
363
2021/24/old/precomp.go
Normal file
@@ -0,0 +1,363 @@
|
||||
package main
|
||||
|
||||
// import "fmt"
|
||||
|
||||
type RegisterState struct {
|
||||
value int
|
||||
last int
|
||||
known bool
|
||||
}
|
||||
|
||||
// @TODO Apply DRY
|
||||
// The function will go through all the instruction and precompute as much as possible
|
||||
func (p Program) precomp() Program {
|
||||
var np Program
|
||||
var r [4]RegisterState
|
||||
|
||||
// Initalize the registers
|
||||
for i := range r {
|
||||
r[i].known = true
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
if i.b == 1 {
|
||||
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 MULR:
|
||||
if r[i.a].known && r[i.a].value == 0 {
|
||||
r[i.a].value = 0
|
||||
// fmt.Printf("- \t%v\n", r)
|
||||
continue
|
||||
}
|
||||
|
||||
if r[i.b].known && r[i.b].value == 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
|
||||
}
|
||||
|
||||
if r[i.b].known && r[i.b].value == 1 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 DIVR:
|
||||
if r[i.a].known && r[i.a].value == 0 {
|
||||
r[i.a].value = 0
|
||||
// fmt.Printf("- \t%v\n", r)
|
||||
continue
|
||||
}
|
||||
|
||||
if r[i.b].known && r[i.b].value == 1 {
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if r[i.b].known && r[i.b].value == -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
|
||||
}
|
||||
|
||||
if r[i.b].known && r[i.b].value == 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
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
val := 0
|
||||
if r[i.a].value == i.b {
|
||||
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
|
||||
}
|
||||
|
||||
if r[i.a].known && r[i.b].known {
|
||||
val := 0
|
||||
if r[i.a].value == r[i.b].value {
|
||||
val = 1
|
||||
}
|
||||
r[i.a].value = val
|
||||
// fmt.Printf("- \t%v\n", r)
|
||||
continue
|
||||
}
|
||||
|
||||
if r[i.a].known {
|
||||
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 {
|
||||
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])
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Emit all the non-zero known registers
|
||||
for i := range r {
|
||||
if r[i].known && r[i].value != 0 {
|
||||
np = append(np, Instruction{ADD, i, r[i].value})
|
||||
}
|
||||
}
|
||||
|
||||
return np
|
||||
}
|
||||
Reference in New Issue
Block a user