Skip to content

Commit

Permalink
day24 part1
Browse files Browse the repository at this point in the history
  • Loading branch information
Akuli committed Jan 4, 2025
1 parent ea9892e commit 58ea13a
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 0 deletions.
140 changes: 140 additions & 0 deletions examples/aoc2024/day24/part1.jou
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import "stdlib/str.jou"
import "stdlib/ascii.jou"
import "stdlib/io.jou"


enum LogicOp:
And
Or
Xor


class LogicGate:
inputs: int*[2] # -1 = undefined, otherwise 0 or 1
output: int*
op: LogicOp

def run(self) -> None:
if *self->inputs[0] == -1 or *self->inputs[1] == -1:
return

i1 = (*self->inputs[0] == 1)
i2 = (*self->inputs[1] == 1)

if self->op == LogicOp::And:
*self->output = (i1 and i2) as int
elif self->op == LogicOp::Or:
*self->output = (i1 or i2) as int
elif self->op == LogicOp::Xor:
*self->output = (i1 != i2) as int
else:
assert False


class VariableManager:
variables: int[500]
nvariables: int
varnames: byte[4][500]

def get_var(self, name: byte*) -> int*:
for i = 0; i < self->nvariables; i++:
if strcmp(name, self->varnames[i]) == 0:
return &self->variables[i]
return NULL

def get_or_create_var(self, name: byte*) -> int*:
exist = self->get_var(name)
if exist != NULL:
return exist

assert self->nvariables < 500
i = self->nvariables++

assert strlen(name) == 3
strcpy(self->varnames[i], name)
self->variables[i] = -1 # uninitialized

return &self->variables[i]

def get_result(self) -> long:
# Variables starting with z are named z00, z01, z02, ...
# Loop backwards to get bit order right.
zcount = 0
for i = 0; i < self->nvariables; i++:
if self->varnames[i][0] == 'z':
zcount++

result = 0L
for i = zcount-1; i >= 0; i--:
name: byte[100]
sprintf(name, "z%02d", i)

v = self->get_var(name)
assert v != NULL
if *v == -1:
return -1

result *= 2
result += *v

return result


def main() -> int:
varmgr = VariableManager{}

gates: LogicGate[500]
ngates = 0

f = fopen("input", "r")
assert f != NULL

line: byte[100]
while fgets(line, sizeof(line) as int, f) != NULL:
trim_ascii_whitespace(line)
if line[0] == '\0':
# end of initial values, start of logic gates
break

# initial value of variable, e.g. "x01: 1"
assert strlen(line) == 6
assert line[3] == ':'
line[3] = '\0'
*varmgr.get_or_create_var(line) = atoi(&line[5])

input1, op, input2, output: byte[4]
while fscanf(f, "%3s %3s %3s -> %3s\n", input1, op, input2, output) == 4:
if strcmp(op, "AND") == 0:
op_enum = LogicOp::And
elif strcmp(op, "OR") == 0:
op_enum = LogicOp::Or
elif strcmp(op, "XOR") == 0:
op_enum = LogicOp::Xor
else:
assert False

assert ngates < sizeof(gates)/sizeof(gates[0])
gates[ngates++] = LogicGate{
inputs = [varmgr.get_or_create_var(input1), varmgr.get_or_create_var(input2)],
output = varmgr.get_or_create_var(output),
op = op_enum,
}

# Check that no gate has multiple outputs hooked up to its input
for i = 0; i < ngates; i++:
for k = 0; k < 2; k++:
var = gates[i].inputs[k]
count = 0
for g = &gates[0]; g < &gates[ngates]; g++:
if g->output == var:
count++
assert count <= 1

while varmgr.get_result() == -1:
for g = &gates[0]; g < &gates[ngates]; g++:
g->run()

printf("%lld\n", varmgr.get_result()) # Output: 2024

fclose(f)
return 0
47 changes: 47 additions & 0 deletions examples/aoc2024/day24/sampleinput.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
x00: 1
x01: 0
x02: 1
x03: 1
x04: 0
y00: 1
y01: 1
y02: 1
y03: 1
y04: 1

ntg XOR fgs -> mjb
y02 OR x01 -> tnw
kwq OR kpj -> z05
x00 OR x03 -> fst
tgd XOR rvg -> z01
vdt OR tnw -> bfw
bfw AND frj -> z10
ffh OR nrd -> bqk
y00 AND y03 -> djm
y03 OR y00 -> psh
bqk OR frj -> z08
tnw OR fst -> frj
gnj AND tgd -> z11
bfw XOR mjb -> z00
x03 OR x00 -> vdt
gnj AND wpb -> z02
x04 AND y00 -> kjc
djm OR pbm -> qhw
nrd AND vdt -> hwm
kjc AND fst -> rvg
y04 OR y02 -> fgs
y01 AND x02 -> pbm
ntg OR kjc -> kwq
psh XOR fgs -> tgd
qhw XOR tgd -> z09
pbm OR djm -> kpj
x03 XOR y03 -> ffh
x00 XOR y04 -> ntg
bfw OR bqk -> z06
nrd XOR fgs -> wpb
frj XOR qhw -> z04
bqk OR frj -> z07
y03 OR x01 -> nrd
hwm AND bqk -> z03
tgd XOR rvg -> z12
tnw OR pbm -> gnj

0 comments on commit 58ea13a

Please sign in to comment.