This commit is contained in:
2025-02-14 15:14:03 +00:00
parent a529516bab
commit 759b9c9544
23 changed files with 11146 additions and 6 deletions

297
2024/go/day24/day24.go Normal file
View File

@@ -0,0 +1,297 @@
package day24
import (
"adventofcode2024/utils"
"fmt"
"regexp"
"sort"
"strings"
)
type Network struct {
gates []*Gate
wires []*Wire
}
type State int
const (
NA State = iota - 1
ZERO
ONE
)
type Wire struct {
name string
state State
}
type Operation int
const (
AND Operation = iota
OR
XOR
)
type Gate struct {
in [2]*Wire
out *Wire
op Operation
}
func Part1(input string) int {
network := &Network{}
network.wires = make([]*Wire, 0)
data := strings.Split(input, "\n\n")
network.AddWires(data[0])
network.AddGates(data[1])
for {
if network.OutputKnown() {
break
}
for _, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
if gate.out.state == NA && gate.in[0].state != NA && gate.in[1].state != NA {
switch gate.op {
case AND:
gate.out.state = And(gate.in[0].state, gate.in[1].state)
case OR:
gate.out.state = Or(gate.in[0].state, gate.in[1].state)
case XOR:
gate.out.state = Xor(gate.in[0].state, gate.in[1].state)
}
}
}
}
return int(network.Output())
}
func Part2(input string) int64 {
data := strings.Split(input, "\n\n")
inputs := strings.Split(data[0], "\n")
num_inputs := len(inputs) / 2
fmt.Println(num_inputs)
var x_value int64
var y_value int64
var z_value int64
y_value = 0
for i := 0; i < num_inputs; i++ {
// y_value = 1 << i
x_value = 1 << i
network := &Network{}
network.wires = make([]*Wire, 0)
network.AddWires2("x", num_inputs, x_value)
network.AddWires2("y", num_inputs, y_value)
network.AddGates(data[1])
// for i, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
// }
network.SwapOutputs("z07", "rts")
network.SwapOutputs("z12", "jpj")
network.SwapOutputs("z26", "kgj")
network.SwapOutputs("vvw", "chv")
// for i, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
// }
for {
if network.OutputKnown() {
break
}
for _, gate := range network.gates {
// fmt.Printf("%d: %v\n", i, gate)
if gate.out.state == NA && gate.in[0].state != NA && gate.in[1].state != NA {
switch gate.op {
case AND:
gate.out.state = And(gate.in[0].state, gate.in[1].state)
case OR:
gate.out.state = Or(gate.in[0].state, gate.in[1].state)
case XOR:
gate.out.state = Xor(gate.in[0].state, gate.in[1].state)
}
}
}
}
z_value = network.Output()
if x_value + y_value != z_value {
fmt.Printf("(%d):\t x:%4d\t: y:%4d z:%4d\n", i, x_value, y_value, z_value)
}
}
ans := []string{"z07", "rts", "z12", "jpj", "z26", "kgj", "vvw", "chv"}
sort.Strings(ans)
fmt.Println(strings.Join(ans, ","))
return z_value
}
func (n *Network) AddWires(data string) {
for _, line := range strings.Split(data, "\n") {
v := strings.Split(line, ": ")
n.AddWire(&Wire{name: v[0], state: to_state(v[1])})
}
}
func (n *Network) AddWire(wire *Wire) {
n.wires = append(n.wires, wire)
}
func (n *Network) AddWires2(w string, count int, value int64) {
for x := 0; x < count; x++ {
name := fmt.Sprintf("%s%02d", w, x)
v := fmt.Sprintf("%d", (value>>x)&1)
n.AddWire(&Wire{name: name, state: to_state(v)})
}
}
func (n *Network) AddGates(data string) {
// ntg XOR fgs -> mjb
pattern := `^([a-z0-9]{3}) (AND|OR|XOR) ([a-z0-9]{3}) -> ([a-z[0-9]{3})$`
re := regexp.MustCompile(pattern)
for _, line := range strings.Split(data, "\n") {
matches := re.FindAllStringSubmatch(line, -1)
for _, match := range matches {
n.AddGate(match[1], match[2], match[3], match[4], &n.wires)
}
}
}
func (n *Network) SwapOutputs(a, b string) {
_, wire1 := to_wire(a, n.wires)
_, wire2 := to_wire(b, n.wires)
for _, gate := range n.gates {
if gate.out.name == a {
gate.out = wire2
} else if gate.out.name == b {
gate.out = wire1
}
}
}
func (n *Network) AddGate(in0, op, in1, out string, wires *[]*Wire) {
var in [2]*Wire
var outw *Wire
*wires, in[0] = to_wire(in0, *wires)
*wires, in[1] = to_wire(in1, *wires)
*wires, outw = to_wire(out, *wires)
n.gates = append(n.gates, &Gate{in: in,
op: to_operation(op),
out: outw})
}
func (n *Network) OutputKnown() bool {
for _, gate := range n.gates {
if gate.out.name[0] != 'z' {
continue
}
if gate.out.state == NA {
return false
}
}
return true
}
func (n *Network) Output() int64 {
var ret int64
ret = 0
for _, gate := range n.gates {
if gate.out.name[0] != 'z' {
continue
}
addr := utils.MustAtoi(gate.out.name[1:])
if gate.out.state == ONE {
ret += 1 << addr
}
}
return ret
}
func (n Gate) String() string {
return n.in[0].name + "(" + n.in[0].state.String() + ")\t" + n.op.String() + " " + n.in[1].name + "(" + n.in[1].state.String() + ")\t ->\t" + n.out.name + " (" + n.out.state.String() + ")"
}
func to_state(in string) State {
switch in {
case "1":
return ONE
case "0":
return ZERO
}
return NA
}
func to_operation(in string) Operation {
var val Operation
switch in {
case "AND":
val = AND
case "OR":
val = OR
case "XOR":
val = XOR
}
return val
}
func to_wire(in string, wires []*Wire) ([]*Wire, *Wire) {
for _, v := range wires {
if in == v.name {
return wires, v
}
}
wire := Wire{name: in, state: NA}
wires = append(wires, &wire)
return wires, &wire
}
func And(a, b State) State {
if a == ONE && b == ONE {
return ONE
}
return ZERO
}
func Or(a, b State) State {
if a == ONE || b == ONE {
return ONE
}
return ZERO
}
func Xor(a, b State) State {
if (a == ONE && b == ZERO) || (a == ZERO && b == ONE) {
return ONE
}
return ZERO
}
func (state State) String() string {
switch state {
case NA:
return "NA"
case ZERO:
return "0"
case ONE:
return "1"
default:
return "Invalid"
}
}
func (op Operation) String() string {
switch op {
case OR:
return "OR"
case AND:
return "AND"
case XOR:
return "XOR"
default:
return "Invalid"
}
}

View File

@@ -0,0 +1,17 @@
package day24
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestPart1(t *testing.T) {
r := Part1("")
require.Equal(t, 0, r)
}
func TestPart2(t *testing.T) {
r := Part2("")
require.Equal(t, 0, r)
}

313
2024/go/day24/input.txt Normal file
View File

@@ -0,0 +1,313 @@
x00: 1
x01: 0
x02: 1
x03: 1
x04: 0
x05: 0
x06: 1
x07: 1
x08: 0
x09: 1
x10: 1
x11: 1
x12: 1
x13: 0
x14: 1
x15: 1
x16: 1
x17: 1
x18: 1
x19: 1
x20: 0
x21: 1
x22: 0
x23: 1
x24: 0
x25: 1
x26: 1
x27: 1
x28: 1
x29: 0
x30: 0
x31: 1
x32: 0
x33: 1
x34: 1
x35: 0
x36: 0
x37: 1
x38: 0
x39: 1
x40: 1
x41: 1
x42: 1
x43: 0
x44: 1
y00: 1
y01: 0
y02: 0
y03: 1
y04: 1
y05: 0
y06: 0
y07: 0
y08: 0
y09: 0
y10: 0
y11: 1
y12: 0
y13: 1
y14: 0
y15: 1
y16: 1
y17: 1
y18: 1
y19: 0
y20: 0
y21: 1
y22: 1
y23: 1
y24: 1
y25: 0
y26: 0
y27: 1
y28: 1
y29: 1
y30: 1
y31: 0
y32: 0
y33: 0
y34: 1
y35: 1
y36: 1
y37: 0
y38: 1
y39: 1
y40: 1
y41: 1
y42: 0
y43: 1
y44: 1
x03 AND y03 -> htr
gwb AND kvf -> pkd
x04 AND y04 -> jjm
qcm XOR twv -> z21
rrq XOR bmp -> z44
x43 AND y43 -> pnn
x06 XOR y06 -> qmt
x26 AND y26 -> z26
y00 AND x00 -> whb
jfq XOR fbb -> z36
y33 AND x33 -> mmb
x38 AND y38 -> vqt
bbh OR qtd -> jfq
cbs AND ttb -> qtd
wqs OR cmf -> tpf
x10 AND y10 -> bfm
djp OR pfb -> qvr
x20 XOR y20 -> vhb
kkd XOR cjg -> z32
qpp XOR stg -> z41
kkd AND cjg -> mdv
tpp OR pfj -> twv
www AND qdf -> vjf
y15 XOR x15 -> hmr
mtg XOR sqm -> z09
x33 XOR y33 -> chc
x41 AND y41 -> pkj
x31 AND y31 -> cvn
x09 AND y09 -> nvw
mtg AND sqm -> chg
pkr AND kcv -> thc
x07 XOR y07 -> cds
x15 AND y15 -> fpr
mwv AND jsg -> wdw
mwv XOR jsg -> z38
y16 XOR x16 -> svs
y14 XOR x14 -> fnq
wth OR vjf -> btv
bvp AND gdb -> stc
cjb XOR rjc -> z04
x13 AND y13 -> pfb
x30 AND y30 -> qgf
htq AND rtk -> dsm
x18 XOR y18 -> kvf
y12 AND x12 -> mqn
bcj XOR bkh -> z03
x07 AND y07 -> sdj
bdf OR wbw -> qkf
y30 XOR x30 -> kbn
tpf AND vhb -> tpp
hqd OR fpr -> hgh
vfm XOR hbw -> z23
x01 AND y01 -> bdf
nvw OR chg -> vgp
x21 XOR y21 -> qcm
bwg AND mfn -> djp
dnf OR pkj -> ksp
y44 AND x44 -> gqr
y11 AND x11 -> smr
smr OR dsm -> ksn
jkm OR pkd -> rjf
thc OR sqt -> rbd
qvr XOR fnq -> z14
cjb AND rjc -> fsb
svg XOR fmt -> z31
x06 AND y06 -> ssv
dtj OR vvq -> jvp
chv XOR fqf -> z34
cvr AND hck -> pjd
dqp AND nbm -> hvv
x29 AND y29 -> vvq
y13 XOR x13 -> mfn
ksn AND nft -> z12
jjd XOR whb -> z01
chc AND rnq -> vjh
y36 AND x36 -> kfn
cwh OR vvw -> ttb
qkf AND wsv -> pqc
rdj OR kfv -> gdb
x08 AND y08 -> jrr
x02 AND y02 -> vdf
x12 XOR y12 -> nft
ptf OR jrr -> sqm
tdv OR wjp -> cjw
qvr AND fnq -> mch
x28 XOR y28 -> cfj
gtn XOR qmt -> z06
mqn OR jpj -> bwg
x36 XOR y36 -> fbb
qht OR bfm -> htq
y42 AND x42 -> mkg
ksn XOR nft -> jpj
x20 AND y20 -> pfj
cmt AND nbq -> gmc
rbd XOR knm -> z25
pvj XOR ksp -> z42
kgj OR stc -> www
tpf XOR vhb -> z20
pjd OR dsg -> mwv
cbs XOR ttb -> z35
bfk OR jvm -> gwb
ffj XOR rpg -> z17
vjr OR kwg -> pkr
pvj AND ksp -> dkc
y37 XOR x37 -> cvr
btv XOR cfj -> z28
gtq OR qgf -> fmt
nbq XOR cmt -> z39
wgq AND dqj -> tws
x24 AND y24 -> sqt
whj OR pnn -> bmp
x02 XOR y02 -> wsv
stg AND qpp -> dnf
kbn XOR jvp -> z30
y39 AND x39 -> gwq
cds AND rkv -> nph
kvf XOR gwb -> z18
mkg OR dkc -> sch
bqh XOR rjf -> z19
hck XOR cvr -> z37
jmk OR ssv -> rkv
x21 AND y21 -> cgd
pqc OR vdf -> bkh
rff OR mts -> rpg
bkh AND bcj -> rhq
bnv OR bst -> stg
bwg XOR mfn -> z13
sgt AND scc -> bnv
btv AND cfj -> tdv
svs AND hgh -> rff
hbw AND vfm -> kwg
x40 XOR y40 -> scc
y17 AND x17 -> jvm
y34 AND x34 -> chv
y35 AND x35 -> bbh
mdv OR rft -> rnq
fqf AND chv -> cwh
y28 AND x28 -> wjp
sch AND srj -> whj
htr OR rhq -> rjc
x05 XOR y05 -> dqp
cvn OR qnk -> cjg
y14 AND x14 -> tfr
y11 XOR x11 -> rtk
jfq AND fbb -> trr
ppb AND hmr -> hqd
gtb OR hvv -> gtn
y44 XOR x44 -> rrq
rtk XOR htq -> z11
x01 XOR y01 -> jjd
hmv XOR rts -> z08
y10 XOR x10 -> vpc
jvp AND kbn -> gtq
cjw AND ntj -> dtj
x22 AND y22 -> prp
ppb XOR hmr -> z15
y18 AND x18 -> jkm
x39 XOR y39 -> nbq
jjd AND whb -> wbw
x34 XOR y34 -> vvw
x19 AND y19 -> wqs
gwq OR gmc -> sgt
rbd AND knm -> rdj
srj XOR sch -> z43
y05 AND x05 -> gtb
x08 XOR y08 -> hmv
y25 AND x25 -> kfv
cgd OR jth -> dqj
vpc XOR vgp -> z10
tws OR prp -> hbw
jjm OR fsb -> nbm
wdw OR vqt -> cmt
rrq AND bmp -> cbv
rts AND hmv -> ptf
svs XOR hgh -> z16
y41 XOR x41 -> qpp
ntj XOR cjw -> z29
ffj AND rpg -> bfk
gqr OR cbv -> z45
x25 XOR y25 -> knm
chc XOR rnq -> z33
y43 XOR x43 -> srj
vgp AND vpc -> qht
x00 XOR y00 -> z00
cds XOR rkv -> rts
x24 XOR y24 -> kcv
x32 AND y32 -> rft
nbm XOR dqp -> z05
x35 XOR y35 -> cbs
mch OR tfr -> ppb
x16 AND y16 -> mts
www XOR qdf -> z27
x23 AND y23 -> vjr
x26 XOR y26 -> bvp
gtn AND qmt -> jmk
x29 XOR y29 -> ntj
y19 XOR x19 -> bqh
rjf AND bqh -> cmf
y38 XOR x38 -> jsg
x32 XOR y32 -> kkd
y03 XOR x03 -> bcj
y31 XOR x31 -> svg
y22 XOR x22 -> wgq
qkf XOR wsv -> z02
bvp XOR gdb -> kgj
x04 XOR y04 -> cjb
x17 XOR y17 -> ffj
y37 AND x37 -> dsg
y27 AND x27 -> wth
y23 XOR x23 -> vfm
sgt XOR scc -> z40
mmb OR vjh -> fqf
qcm AND twv -> jth
y09 XOR x09 -> mtg
sdj OR nph -> z07
wgq XOR dqj -> z22
trr OR kfn -> hck
y27 XOR x27 -> qdf
kcv XOR pkr -> z24
x42 XOR y42 -> pvj
x40 AND y40 -> bst
svg AND fmt -> qnk