advent-of-code/2023/python/shared.py
2023-12-02 23:12:04 -05:00

169 lines
4.1 KiB
Python

from contextlib import contextmanager
from timeit import default_timer
from pathlib import Path
import cProfile
import functools
import pstats
def profile(func):
@functools.wraps(func)
def inner(*args, **kwargs):
profiler = cProfile.Profile()
profiler.enable()
try:
retval = func(*args, **kwargs)
finally:
profiler.disable()
with open("profile.out", "w") as profile_file:
stats = pstats.Stats(profiler, stream=profile_file)
stats.print_stats()
return retval
return inner
spl = lambda y: [int(w) for w in y]
def minmax(l):
return min(l), max(l)
def load_rows(day, part2=False):
return [row for row in load(day,part2)]
def load(day, part2=False):
if part2:
path = Path(get_fname(day)+".part2")
try:
return path.read_text().rstrip().split("\n")
except FileNotFoundError:
# No part 2 file, use first file
pass
path = Path(get_fname(day))
return path.read_text().rstrip().split("\n")
def get_fname(day: int) -> str:
import sys
if sys.argv[-1] == "--sample":
return f"samples/day{day:02}.txt"
else:
return f"full/day{day:02}.txt"
#############
def load_char_matrix(f):
my_file = []
for line in f:
my_file.append(line.rstrip())
return [list(x) for x in my_file]
def load_file_char_matrix(name):
with open(name, "r") as f:
return load_char_matrix(f)
def load_int_matrix(f):
my_file = []
for line in f:
my_file.append(line.rstrip())
return [list(map(int, x)) for x in my_file]
def load_file_int_matrix(name):
with open(name, "r") as f:
return load_int_matrix(f)
def load_word_matrix(f):
my_file = []
for line in f:
my_file.append(line.rstrip())
return [x.split(" ") for x in my_file]
def load_file_word_matrix(name):
with open(name, "r") as f:
return load_word_matrix(f)
#############
def rotate(WHAT, times=1):
what = WHAT
for x in range(times):
what = list(zip(*what[::-1]))
return what
@contextmanager
def elapsed_timer():
start = default_timer()
elapser = lambda: default_timer() - start
yield lambda: elapser()
end = default_timer()
elapser = lambda: end - start
def render_cubes(maxX,maxY,maxZ, my_cubes):
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
def cuboid_data(o, size=(1,1,1)):
X = [[[0, 1, 0], [0, 0, 0], [1, 0, 0], [1, 1, 0]],
[[0, 0, 0], [0, 0, 1], [1, 0, 1], [1, 0, 0]],
[[1, 0, 1], [1, 0, 0], [1, 1, 0], [1, 1, 1]],
[[0, 0, 1], [0, 0, 0], [0, 1, 0], [0, 1, 1]],
[[0, 1, 0], [0, 1, 1], [1, 1, 1], [1, 1, 0]],
[[0, 1, 1], [0, 0, 1], [1, 0, 1], [1, 1, 1]]]
X = np.array(X).astype(float)
for i in range(3):
X[:,:,i] *= size[i]
X += np.array(o)
return X
def plotCubeAt(positions,sizes=None,colors=None, **kwargs):
if not isinstance(colors,(list,np.ndarray)): colors=["C0"]*len(positions)
if not isinstance(sizes,(list,np.ndarray)): sizes=[(1,1,1)]*len(positions)
g = []
for p,s,c in zip(positions,sizes,colors):
g.append( cuboid_data(p, size=s) )
return Poly3DCollection(np.concatenate(g),
facecolors=np.repeat(colors,6, axis=0), **kwargs)
N1 = maxX
N2 = maxY
N3 = maxZ
ma = np.random.choice([0,1], size=(N1,N2,N3), p=[0.99, 0.01])
x,y,z = np.indices((N1,N2,N3))-.5
#positions = np.c_[x[ma==1],y[ma==1],z[ma==1]]
positions = np.c_[my_cubes]
colors= np.random.rand(len(positions),3)
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
ax.set_aspect('equal')
pc = plotCubeAt(positions, colors=colors,edgecolor="k")
ax.add_collection3d(pc)
ax.set_xlim([0,maxX])
ax.set_ylim([0,maxY])
ax.set_zlim([0,maxZ])
#plotMatrix(ax, ma)
#ax.voxels(ma, edgecolor="k")
plt.show()