Initial commit
This commit is contained in:
commit
97a4330bc0
110 changed files with 7006 additions and 0 deletions
47
2024/24/one.py
Normal file
47
2024/24/one.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import typing
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
with open(input_file) as fd:
|
||||
lines = [line.rstrip() for line in fd.readlines()]
|
||||
|
||||
gates: dict[str, tuple[str, typing.Callable, str]] = dict()
|
||||
varis: dict[str, int] = dict()
|
||||
funs = {
|
||||
"AND": int.__and__,
|
||||
"OR": int.__or__,
|
||||
"XOR": int.__xor__,
|
||||
}
|
||||
|
||||
step = False
|
||||
for line in lines:
|
||||
if not line:
|
||||
step = True
|
||||
elif step:
|
||||
a, op, b, _, dest = line.split()
|
||||
fun = funs[op]
|
||||
gates[dest] = (a, fun, b)
|
||||
else:
|
||||
dest, val = line.split(":")
|
||||
varis[dest] = int(val)
|
||||
|
||||
|
||||
@functools.cache
|
||||
def get_var(var: str) -> int:
|
||||
if var in varis:
|
||||
return varis[var]
|
||||
a, fun, b = gates[var]
|
||||
avar = get_var(a)
|
||||
bvar = get_var(b)
|
||||
return fun(avar, bvar)
|
||||
|
||||
|
||||
zees = sorted([key for key in gates.keys() if key.startswith("z")])
|
||||
bits = reversed([str(get_var(key)) for key in zees])
|
||||
res = int("".join(bits), base=2)
|
||||
|
||||
print(res)
|
161
2024/24/two.py
Normal file
161
2024/24/two.py
Normal file
|
@ -0,0 +1,161 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import typing
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import networkx as nx
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
with open(input_file) as fd:
|
||||
lines = [line.rstrip() for line in fd.readlines()]
|
||||
|
||||
gates: dict[str, tuple[str, typing.Callable, str]] = dict()
|
||||
varis: dict[str, int] = dict()
|
||||
funs = {
|
||||
"AND": int.__and__, # orange
|
||||
"OR": int.__or__, # green
|
||||
"XOR": int.__xor__, # purple
|
||||
}
|
||||
G = nx.DiGraph()
|
||||
|
||||
swaps = [
|
||||
("ncd", "nfj"),
|
||||
("z37", "vkg"),
|
||||
("z20", "cqr"),
|
||||
("z15", "qnw"),
|
||||
]
|
||||
swapdict: dict[str, str] = dict()
|
||||
for a, b in swaps:
|
||||
swapdict[a] = b
|
||||
swapdict[b] = a
|
||||
|
||||
step = False
|
||||
for line in lines:
|
||||
if not line:
|
||||
step = True
|
||||
elif step:
|
||||
a, op, b, _, dest = line.split()
|
||||
dest = swapdict.get(dest, dest)
|
||||
fun = funs[op]
|
||||
gates[dest] = (a, fun, b)
|
||||
G.add_node(dest, op=op)
|
||||
G.add_edge(a, dest)
|
||||
G.add_edge(b, dest)
|
||||
else:
|
||||
dest, val = line.split(":")
|
||||
varis[dest] = int(val)
|
||||
|
||||
|
||||
def swap(a: str, b: str) -> None:
|
||||
temp = gates[a]
|
||||
gates[a] = gates[b]
|
||||
gates[b] = temp
|
||||
|
||||
|
||||
@functools.cache
|
||||
def get_var(var: str) -> int:
|
||||
if var in varis:
|
||||
return varis[var]
|
||||
a, fun, b = gates[var]
|
||||
avar = get_var(a)
|
||||
bvar = get_var(b)
|
||||
return fun(avar, bvar)
|
||||
|
||||
|
||||
all_keys = list(gates.keys()) + list(varis.keys())
|
||||
all_keys.sort(reverse=True)
|
||||
|
||||
|
||||
def get_number(prefix: str) -> int:
|
||||
tot = 0
|
||||
keys = [key for key in all_keys if key.startswith(prefix)]
|
||||
for key in keys:
|
||||
tot <<= 1
|
||||
tot |= get_var(key)
|
||||
return tot
|
||||
|
||||
|
||||
X = get_number("x")
|
||||
Y = get_number("y")
|
||||
Z = get_number("z")
|
||||
print(f"{X+Y=} = {X=} + {Y=}")
|
||||
print(f" {Z=} {Z == X + Y=}")
|
||||
|
||||
print(",".join(sorted(swapdict.keys())))
|
||||
|
||||
# Viz
|
||||
|
||||
|
||||
@functools.cache
|
||||
def get_node_pos(node: str) -> tuple[float, float]:
|
||||
x: float
|
||||
y: float
|
||||
if node.startswith("x"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 0
|
||||
elif node.startswith("y"):
|
||||
x = -int(node[1:]) * 2 - 1
|
||||
y = 0
|
||||
elif node.startswith("z"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 100
|
||||
else:
|
||||
a, _, b = gates[node]
|
||||
ax, ay = get_node_pos(a)
|
||||
bx, by = get_node_pos(b)
|
||||
x = (ax + bx) / 2
|
||||
y = max(ay, by) + 1
|
||||
return x, y
|
||||
|
||||
|
||||
colors = {
|
||||
"AND": "orange",
|
||||
"OR": "green",
|
||||
"XOR": "purple",
|
||||
}
|
||||
node_colors = []
|
||||
node_pos: dict[str, tuple[float, float]] = dict()
|
||||
node_fixed: set[str] = set()
|
||||
for node in G.nodes():
|
||||
op = G.nodes[node].get("op")
|
||||
node_colors.append(colors.get(op, "cyan" if node.startswith("x") else "blue"))
|
||||
|
||||
x: float
|
||||
y: float
|
||||
fixed = True
|
||||
if node.startswith("x"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 0
|
||||
elif node.startswith("y"):
|
||||
x = -int(node[1:]) * 2 - 1
|
||||
y = 0
|
||||
elif node.startswith("z"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 50
|
||||
else:
|
||||
fixed = False
|
||||
x = -23
|
||||
y = 25
|
||||
|
||||
node_pos[node] = x, y
|
||||
if fixed:
|
||||
node_fixed.add(node)
|
||||
|
||||
# My own layout
|
||||
for i in range(50):
|
||||
for node in G.nodes():
|
||||
if node in node_fixed:
|
||||
continue
|
||||
neighs = list(G.succ[node]) + list(G.pred[node])
|
||||
x = sum(node_pos[neigh][0] for neigh in neighs) / len(neighs)
|
||||
y = sum(node_pos[neigh][1] for neigh in neighs) / len(neighs)
|
||||
node_pos[node] = x, y
|
||||
node_fixed = set(G.nodes())
|
||||
|
||||
node_layout = nx.layout.spring_layout(G, pos=node_pos, fixed=node_fixed)
|
||||
|
||||
nx.draw(G, pos=node_layout, node_color=node_colors, with_labels=True)
|
||||
plt.show()
|
163
2024/24/two_test.py
Normal file
163
2024/24/two_test.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import functools
|
||||
import sys
|
||||
import typing
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import networkx as nx
|
||||
|
||||
input_file = sys.argv[1]
|
||||
|
||||
with open(input_file) as fd:
|
||||
lines = [line.rstrip() for line in fd.readlines()]
|
||||
|
||||
gates: dict[str, tuple[str, typing.Callable, str]] = dict()
|
||||
varis: dict[str, int] = dict()
|
||||
funs = {
|
||||
"AND": int.__and__, # orange
|
||||
"OR": int.__or__, # green
|
||||
"XOR": int.__xor__, # purple
|
||||
}
|
||||
G = nx.DiGraph()
|
||||
|
||||
swaps = [
|
||||
# ("ncd", "nfj"),
|
||||
# ("z37", "vkg"),
|
||||
# ("z20", "cqr"),
|
||||
# ("z15", "qnw"),
|
||||
]
|
||||
swapdict: dict[str, str] = dict()
|
||||
for a, b in swaps:
|
||||
swapdict[a] = b
|
||||
swapdict[b] = a
|
||||
|
||||
step = False
|
||||
for line in lines:
|
||||
if not line:
|
||||
step = True
|
||||
elif step:
|
||||
a, op, b, _, dest = line.split()
|
||||
dest = swapdict.get(dest, dest)
|
||||
fun = funs[op]
|
||||
gates[dest] = (a, fun, b)
|
||||
G.add_node(dest, op=op)
|
||||
G.add_edge(a, dest)
|
||||
G.add_edge(b, dest)
|
||||
else:
|
||||
dest, val = line.split(":")
|
||||
varis[dest] = int(val)
|
||||
|
||||
|
||||
def swap(a: str, b: str) -> None:
|
||||
temp = gates[a]
|
||||
gates[a] = gates[b]
|
||||
gates[b] = temp
|
||||
|
||||
|
||||
@functools.cache
|
||||
def get_var(var: str) -> int:
|
||||
if var in varis:
|
||||
return varis[var]
|
||||
a, fun, b = gates[var]
|
||||
avar = get_var(a)
|
||||
bvar = get_var(b)
|
||||
return fun(avar, bvar)
|
||||
|
||||
|
||||
all_keys = list(gates.keys()) + list(varis.keys())
|
||||
all_keys.sort(reverse=True)
|
||||
|
||||
|
||||
def get_number(prefix: str) -> int:
|
||||
tot = 0
|
||||
keys = [key for key in all_keys if key.startswith(prefix)]
|
||||
for key in keys:
|
||||
tot <<= 1
|
||||
tot |= get_var(key)
|
||||
return tot
|
||||
|
||||
|
||||
X = get_number("x")
|
||||
Y = get_number("y")
|
||||
Z = get_number("z")
|
||||
print(f"{X+Y=} = {X=} + {Y=}")
|
||||
print(f" {Z=} {Z == X + Y=}")
|
||||
|
||||
print(",".join(sorted(swapdict.keys())))
|
||||
|
||||
# Viz
|
||||
|
||||
|
||||
@functools.cache
|
||||
def get_node_pos(node: str) -> tuple[float, float]:
|
||||
x: float
|
||||
y: float
|
||||
if node.startswith("x"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 0
|
||||
elif node.startswith("y"):
|
||||
x = -int(node[1:]) * 2 - 1
|
||||
y = 0
|
||||
elif node.startswith("z"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 100
|
||||
else:
|
||||
a, _, b = gates[node]
|
||||
ax, ay = get_node_pos(a)
|
||||
bx, by = get_node_pos(b)
|
||||
x = (ax + bx) / 2
|
||||
y = max(ay, by) + 1
|
||||
return x, y
|
||||
|
||||
|
||||
colors = {
|
||||
"AND": "orange",
|
||||
"OR": "green",
|
||||
"XOR": "purple",
|
||||
}
|
||||
node_colors = []
|
||||
node_pos: dict[str, tuple[float, float]] = dict()
|
||||
node_fixed: set[str] = set()
|
||||
for node in G.nodes():
|
||||
op = G.nodes[node].get("op")
|
||||
node_colors.append(colors.get(op, "cyan" if node.startswith("x") else "blue"))
|
||||
|
||||
x: float
|
||||
y: float
|
||||
fixed = True
|
||||
if node.startswith("x"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 0
|
||||
elif node.startswith("y"):
|
||||
x = -int(node[1:]) * 2 - 1
|
||||
y = 0
|
||||
elif node.startswith("z"):
|
||||
x = -int(node[1:]) * 2
|
||||
y = 50
|
||||
else:
|
||||
fixed = False
|
||||
x = -23
|
||||
y = 25
|
||||
|
||||
node_pos[node] = x, y
|
||||
if fixed:
|
||||
node_fixed.add(node)
|
||||
|
||||
# # My own layout
|
||||
# for i in range(50):
|
||||
# for node in G.nodes():
|
||||
# if node in node_fixed:
|
||||
# continue
|
||||
# neighs = list(G.succ[node]) + list(G.pred[node])
|
||||
# x = sum(node_pos[neigh][0] for neigh in neighs) / len(neighs)
|
||||
# y = sum(node_pos[neigh][1] for neigh in neighs) / len(neighs)
|
||||
# node_pos[node] = x, y
|
||||
# node_fixed = set(G.nodes())
|
||||
|
||||
node_layout = nx.layout.spring_layout(
|
||||
G.to_undirected(), k=1, iterations=1000, pos=node_pos, fixed=node_fixed
|
||||
)
|
||||
|
||||
nx.draw(G, pos=node_layout, node_color=node_colors, with_labels=True)
|
||||
plt.show()
|
Loading…
Add table
Add a link
Reference in a new issue