Compare commits

...

32 Commits

Author SHA1 Message Date
53014651e9 day6, a set kills all 2024-04-14 01:16:42 +02:00
3ec99a8a10 day6, from N^3 to N^2 2024-04-14 00:19:55 +02:00
b360d60a05 day 18, compile with codon for speed 2023-06-12 12:49:11 +02:00
712049e929 add input for benchmark 2023-05-03 10:34:13 +02:00
42a525352a day 10, part 2, no need to buffer, spare 10 loc 2023-01-02 12:35:09 +01:00
4f3a52c210 more stats 2022-12-30 23:05:12 +01:00
6ff32e169a day 22, in Rust, not mine 2022-12-29 12:36:44 +01:00
5d4d2f9f38 day 25, base conversion 2022-12-29 12:09:51 +01:00
f4d71daadf day 24, not mine 2022-12-29 12:08:35 +01:00
72433f9e9d day 23, a bit faster with bool instead of None 2022-12-29 12:02:17 +01:00
1172b9bb2e day 23, fast with codon: <1s 2022-12-24 01:09:55 +01:00
ccb284ef87 day 23, animate elves' spreading 2022-12-23 23:18:15 +01:00
611e99dbf5 day 23, game set and match 2022-12-23 21:04:46 +01:00
9897d22863 day 22, paper, cisors and glue 2022-12-22 23:54:52 +01:00
0a4b8a70a9 day 20, double linked list, pypy to make it fast 2022-12-22 02:13:03 +01:00
ec41730982 day 21, what's make part 1 elegant makes part 2 ugly 2022-12-21 21:54:04 +01:00
861d166533 day 19, beam search, not mine 2022-12-20 00:02:42 +01:00
707bc3745c day 16, part 2 never ends, research space is too big 2022-12-19 15:43:28 +01:00
72112e2311 day 18, was easy thanks to openscad 2022-12-19 15:12:35 +01:00
673ad56fd0 day 15 ; three attempts for part 2, only the last fits in CPU and RAM. big up for Codon for accelerating python 2022-12-15 16:11:21 +01:00
efc1f11758 day 12, add nice color pictures 2022-12-14 14:34:10 +01:00
f05ac7a70f day 14, quick and nice 2022-12-14 11:55:52 +01:00
f3177e66a3 day 12, draw montain 2022-12-14 01:18:14 +01:00
e62a2c70b7 day 13, with help 2022-12-13 13:29:08 +01:00
33fd08d182 day 12, add nice picture of the result 2022-12-13 01:09:53 +01:00
cfb99d24f4 day 12, at last, some graph algorithm 2022-12-13 01:03:06 +01:00
6a9d3da725 day 11, compact 2022-12-11 21:07:16 +01:00
ba932dcc92 day 11, no room for dignity 2022-12-11 14:04:43 +01:00
9f935aedf7 day 9, animation with checked pattern background and colors 2022-12-10 22:51:25 +01:00
c8b2258994 day 10, prettier and a awk solution for part 2 2022-12-10 21:49:42 +01:00
38a377ac84 day 10, awk solution for part 1 2022-12-10 20:00:49 +01:00
c089762042 day 9, add terminal animation 2022-12-10 17:42:29 +01:00
59 changed files with 2481 additions and 49 deletions

View File

@@ -1,17 +1,17 @@
BEGIN { W = 14 }
{
for (i=1; i<=length($1); i++) {
{ # use -vW=4 or 14
for (i=1; ; i++) {
window = substr($1,i,W)
# compare each char of the window to rest of the window
S = 0 # to count match
for (j=1; j<=W; j++) {
for (j=1; j<W; j++) {
for (k=j+1; k<=W; k++) {
N++
S+= (substr(window,j,1) == substr(window,k,1)) ? 1 : 0
}
}
if (S == 0) {
print i + W - 1
print i + W - 1, "(" N " loops)"
next
}
}
}
} # O(N*W^2)

17
d06/exec1.awk Normal file
View File

@@ -0,0 +1,17 @@
{ N=0; # use -vW=4 or 14
for (i=1; ; i++) {
window = substr($0,i,W)
# compare each char of the window to rest of the window
S = 0 # to count match
for (j=1; j<W; j++) {
for (k=j+1; k<=W; k++) {
N++
S+= (substr(window,j,1) == substr(window,k,1)) ? 1 : 0
}
}
if (S == 0) {
print i + W - 1, "(" N " loops)"
next
}
}
} # O(N*W^2)

17
d06/exec2.awk Normal file
View File

@@ -0,0 +1,17 @@
{ N=0; j=0; # use -vW=4 or 14
for (i=1; ; i++) {
c = substr($0,i,1);
# look backward for a "new j" > j
for (k=i-1; k>j; k--) {
N++
if (substr($0,k,1) == c) {
j = k
break
}
}
if ((i-j) == W) {
print i, "(" N " loops)"
next
}
}
} # O(N*W)

13
d06/exec3.awk Normal file
View File

@@ -0,0 +1,13 @@
{ # use -vW=4 or 14
for (i=1; ; i++) {
window = substr($0,i,W)
for (j=1; j<=W; j++) { # populate a Set
A[substr(window,j,1)]=1
}
if (length(A) == W) {
print i + W - 1
next
}
delete A
}
} # O(N*W*log2(W))

66
d09/anim.py Normal file
View File

@@ -0,0 +1,66 @@
import sys, os
import numpy
import time
class display:
def __init__(self):
self.w, self.h = tuple(os.get_terminal_size())
border = "o"
self.delta = numpy.array((self.w//2, self.h//2))
top = border * (self.w)
wodd = self.w%2
lines = [
border + "" * (self.w//2-1) + ""*wodd + border,
border + "" * (self.w//2-1) + " "*wodd + border
]
self.background = [
top + "".join(lines[h%2] for h in range(self.h - 2)) + top,
top + "".join(lines[1-h%2] for h in range(self.h - 2)) + top
]
def __call__(self, knots):
print("\033[0;0H", end='')
x, y = self.delta + knots[0]
J = 19 # must be odd to see scroll
if x <= 0:
self.delta[0] += J
if x >= self.w-1:
self.delta[0] -= J
if y <= 0:
self.delta[1] += J
if y >= self.h-1:
self.delta[1] -= J
txt = [c for c in self.background[sum(self.delta)%2]]
for i,knot in enumerate(reversed(knots)):
x, y = knot + self.delta
txt[int(x + y * self.w)] = "\033[30;43m" + str(9-i) + "\033[0m"
print("".join(txt),end='')
time.sleep(.008)
d = display()
def input():
for l in sys.stdin:
m, q = l.split()
m = dict(U=(0,1), D=(0,-1), L=(-1,0), R=(1, 0))[m]
for _ in range(int(q)):
yield m
def follow(head, tail):
delta = head - tail
if max(abs(delta)) <= 1: # no move
return
if delta[0]:
tail[0] += 1 if delta[0] > 0 else -1
if delta[1]:
tail[1] += 1 if delta[1] > 0 else -1
knots = [numpy.array((0, 0)) for _ in range(10)]
visits = [ {(0,0)} for _ in range(10)]
for direction in input():
knots[0] += direction
for n in range(1, 10):
follow(knots[n-1], knots[n])
d(knots)
visits[n].add(tuple(knots[n]))
print(" ".join(str(len(v)) for v in visits))

11
d10/part1.awk Normal file
View File

@@ -0,0 +1,11 @@
BEGIN { x=1 }
function inc() {
c+=1
S += index("20,60,100,140,180,220,", c ",")>0 ? x*c : 0
}
{ inc() }
$1 == "addx" {
inc()
x+=$2
}
END { print S }

10
d10/part2.awk Normal file
View File

@@ -0,0 +1,10 @@
function inc() {
i = (c++%40)
printf "%s", (i==x||i==x+1||i==x+2) ? "█" : " "
printf "%s", (i==39) ? "\n" : ""
}
{ inc() }
$1 == "addx" {
inc()
x += $2
}

View File

@@ -2,14 +2,14 @@ import sys
X = 1
C = 0
LCD = [["."]*40 for _ in range(6)]
LCD = [[""]*40 for _ in range(6)]
def inc():
global C
(r,c) = divmod(C, 40)
C+=1
if c in [X, X-1, X+1]:
LCD[r][c]="#"
LCD[r][c]=""
for l in sys.stdin.read().splitlines():
m, q = (l+" _").split(" ")[:2]

45
d11/input1.py Normal file
View File

@@ -0,0 +1,45 @@
from collections import deque
M = [
[
deque([ 84, 72, 58, 51])
, lambda old: old * 3
, lambda x: 7 if divmod(x,13)[1] else 1
,0
],[
deque([ 88, 58, 58 ])
, lambda old: old + 8
, lambda x: 5 if divmod(x,2)[1] else 7
,0
],[
deque([ 93, 82, 71, 77, 83, 53, 71, 89])
, lambda old: old * old
, lambda x: 4 if divmod(x,7)[1] else 3
,0
],[
deque([ 81, 68, 65, 81, 73, 77, 96])
, lambda old: old + 2
, lambda x: 6 if divmod(x,17)[1] else 4
,0
],[
deque([ 75, 80, 50, 73, 88])
, lambda old: old + 3
, lambda x: 0 if divmod(x,5)[1] else 6
,0
],[
deque([ 59, 72, 99, 87, 91, 81])
, lambda old: old * 17
, lambda x: 3 if divmod(x,11)[1] else 2
,0
],[
deque([ 86, 69])
, lambda old: old + 6
, lambda x: 0 if divmod(x,3)[1] else 1
,0
],[
deque([ 91])
, lambda old: old + 1
, lambda x: 5 if divmod(x,19)[1] else 2
, 0
]
]

50
d11/input2.py Normal file
View File

@@ -0,0 +1,50 @@
from collections import deque
PRIMES = (13,2,7,17,5,11,3,19)
def mods(x):
return [x%i for i in PRIMES]
M = [
[
deque(mods(x) for x in [ 84, 72, 58, 51])
, lambda old: [((o%i)*(3%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 7 if x[0] else 1
,0
],[
deque(mods(x) for x in [ 88, 58, 58 ])
, lambda old: [((o%i)+(8%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 5 if x[1] else 7
,0
],[
deque(mods(x) for x in [ 93, 82, 71, 77, 83, 53, 71, 89])
, lambda old: [((o%i)*(o%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 4 if x[2] else 3
,0
],[
deque(mods(x) for x in [ 81, 68, 65, 81, 73, 77, 96])
, lambda old: [((o%i)+(2%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 6 if x[3] else 4
,0
],[
deque(mods(x) for x in [ 75, 80, 50, 73, 88])
, lambda old: [((o%i)+(3%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 0 if x[4] else 6
,0
],[
deque(mods(x) for x in [ 59, 72, 99, 87, 91, 81])
, lambda old: [((o%i)*(17%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 3 if x[5] else 2
,0
],[
deque(mods(x) for x in [ 86, 69])
, lambda old: [((o%i)+(6%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 0 if x[6] else 1
,0
],[
deque(mods(x) for x in [ 91])
, lambda old: [((o%i)+(1%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 5 if x[7] else 2
,0
]
]

18
d11/part1.py Normal file
View File

@@ -0,0 +1,18 @@
import sys
mod = __import__(sys.argv[1])
M = mod.M
for r in range(20):
for k,m in enumerate(M):
items = m[0]
m[3] += len(items)
for _ in range(len(items)):
i = items.popleft()
ni = m[1](i) // 3
nm = m[2](ni)
M[nm][0].append(ni)
L=list(m[3] for m in M)
print(L)
LS=list(sorted(L))
print(LS[-1]*LS[-2])

20
d11/part2.py Normal file
View File

@@ -0,0 +1,20 @@
import sys
mod = __import__(sys.argv[1])
M = mod.M
for r in range(10*1000):
print(f"\rround {r+1}",end='')
for m in M:
items = m[0]
m[3] += len(items)
for _ in range(len(items)):
i = items.popleft()
ni = m[1](i) #// 3
nm = m[2](ni)
M[nm][0].append(ni)
print()
L=list(m[3] for m in M)
print(L)
LS=list(sorted(L))
print(LS[-1]*LS[-2])

35
d11/run.py Normal file
View File

@@ -0,0 +1,35 @@
import sys
from math import prod
part = int(sys.argv[1])
T = sys.stdin.read().split('\n\n')
M = [] # monkey: 0:items, 1:func, 2:divider, 3:iftrue, 4:iffalse, 5:count
D = 1
for t in T:
u = t.split('\n')
m = []
m.append([int(i) for i in u[1].split(':')[1].split(',')])
m.append(u[2].split("=")[1])
d = int(u[3].split(" ")[-1])
m.append(d) # devider
D *= d
m.append(int(u[4].split(" ")[-1]))
m.append(int(u[5].split(" ")[-1]))
m.append(0)
M.append(m)
for _ in range(20 if part==1 else 10000):
for k,m in enumerate(M):
for i in m[0]:
m[5] += 1
ni = eval(m[1].replace("old", str(i))) % D
if part == 1:
ni = ni // 3
nm = m[4] if ni % m[2] else m[3]
M[nm][0].append(ni)
m[0] = []
L=list(m[5] for m in M)
print(L)
LS=list(sorted(L))
print(LS[-1]*LS[-2])

24
d11/sample1.py Normal file
View File

@@ -0,0 +1,24 @@
from collections import deque
M = [
[
deque([ 79, 98 ])
, lambda old: old * 19
, lambda x: 3 if divmod(x,23)[1] else 2
,0
],[
deque([ 54, 65, 75, 74 ])
, lambda old: old + 6
, lambda x: 0 if divmod(x,19)[1] else 2
,0
],[
deque([ 79, 60, 97 ])
, lambda old: old * old
, lambda x: 3 if divmod(x,13)[1] else 1
,0
],[
deque([ 74 ])
, lambda old: old + 3
, lambda x: 1 if divmod(x,17)[1] else 0
,0
]
]

30
d11/sample2.py Normal file
View File

@@ -0,0 +1,30 @@
from collections import deque
PRIMES = (23,19,13,17)
def mods(x):
return [x%i for i in PRIMES]
M = [
[
deque(mods(x) for x in [ 79, 98 ])
, lambda old: [((o%i)*(19%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 3 if x[0] else 2
,0
],[
deque(mods(x) for x in [ 54, 65, 75, 74 ])
, lambda old: [((o%i)+(6%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 0 if x[1] else 2
,0
],[
deque(mods(x) for x in [ 79, 60, 97 ])
, lambda old: [((o%i)*(o%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 3 if x[2] else 1
,0
],[
deque(mods(x) for x in [ 74 ])
, lambda old: [((o%i)+(3%i))%i for (o,i) in zip(old,PRIMES)]
, lambda x: 1 if x[3] else 0
,0
]
]

BIN
d12/P.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

BIN
d12/Q.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

BIN
d12/R.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

BIN
d12/S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 KiB

BIN
d12/T.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

6
d12/cmd.txt Normal file
View File

@@ -0,0 +1,6 @@
pandoc -o fail.pdf -t pdf fail.md
awk -f draw.awk < input >| input.pgm
convert input.pgm -scale 1600% input.png
base64 input.png | tr -d '\n'

20
d12/draw.awk Normal file
View File

@@ -0,0 +1,20 @@
BEGIN { print "P2"
print "81 41"
print "25"
}
{
split($0,arr,"")
r = ""
#for (a in arr) {
# print a, arr[a]
#}
#nextfile
for (i=1;i<=81;i++) {
c = arr[i]
if (c == "S") { v = 0 }
else if (c == "E") { v = 25 }
else { v = index("abcdefghijklmnopqrstuvwxyz", c)-1 }
r = r " " v
}
print r
}

58
d12/draw.py Normal file
View File

@@ -0,0 +1,58 @@
import sys
import networkx as netx
M = [ list(l) for l in sys.stdin.read().splitlines() ]
H = len(M)
W = len(M[0])
START = tuple()
END = tuple()
G = netx.DiGraph()
for x in range(H):
for y in range(W):
k = (x,y)
v = M[x][y]
if v == 'S':
START = k
v = 'a'
if v == 'E':
END = k
v = 'z'
v = ord(v)
for dx,dy in [(-1,0),(1,0),(0,-1),(0,1)]:
nx, ny = (x+dx, y+dy)
if nx>=0 and nx<H and ny>=0 and ny<W:
nk = (nx,ny)
nv = M[nx][ny]
if nv == 'S':
nv = 'a'
if nv == 'E':
nv = 'z'
nv = ord(nv)
dv = nv - v
if dv <=1: # can go down !
G.add_edge(k,nk)
# palette by https://gka.github.io/palettes/#/26|s|ffffe5,fe9929,662506|ffffe0,ff005e,93003a|1|1
C = [ '#ffffe5','#fff4d3','#ffeac1','#ffdfb0','#ffd49f','#fcca91','#f8c084','#f3b677','#edac6c','#e7a361','#e19a58','#da914e','#d38846','#cb803e','#c47737','#bc6f30','#b3672a','#ab5f24','#a3571f','#9a501a','#924816','#894112','#803a0e','#77330b','#6f2c09','#662506']
c2i = lambda x: int("0x"+x,16)
C = [ " ".join(map(str,map(c2i,[c[1:3],c[3:5],c[5:]]))) for c in C ]
for x in range(H):
for y in range(W):
v = M[x][y]
if v == 'S':
v = 'a'
if v == 'E':
v = 'z'
M[x][y] = C[ord(v)-ord("a")]
S = netx.shortest_path(G, START, END)
print("P3")
print("81 41")
print("255")
for (x,y) in S:
M[x][y] = "64 196 64"
print("\n".join("\n".join(l) for l in M))

34
d12/fail.md Normal file
View File

@@ -0,0 +1,34 @@
I have only on patch of P
![](P.png)
\newpage
So I have to choose this patch of Q
![](Q.png)
\newpage
Then this patch of R
![](R.png)
\newpage
then this patch of S
![](S.png)
\newpage
But then, this patch of S is not connected to the patch of T
![](T.png)
I feel like i'm stucked :(
But actually, [not](https://www.reddit.com/r/adventofcode/comments/zjqz5y/2022_day_12_is_my_input_invalid_or/)

41
d12/input Normal file
View File

@@ -0,0 +1,41 @@
abcccccaaaccccaacaaccaaaaaaaaaaaaaaaaaaaaccccccccccccccccccccccccccccccccccaaaaaa
abcccccaaaacccaaaaaccaaaaaaaaaaaaaaaaaaaaacccccccccccccccccccccccccccccccccccaaaa
abcccccaaaaccaaaaaccccaaaccaaaaaacccacaaaaccccccccccccccccaaaccccccccccccccccaaaa
abcccccaaacccaaaaaaccccccccaaaaaacccccaaccccccccccccccccccaaaccccccccccccccccaaaa
abcccccccccccccaaaacccccccaaaaaaaaccccccccccccccccccccccccaaacccccccccccccccaaaaa
abccccccaacccccaacccccccccaaaaaaaaccccccccccccccccccccccccaaaaccaaacccccccccccccc
abccccccaacccccccccccccccaaacccaaaacccaacaaccccccccccacaccaaacaajaacccccccccccccc
abcccaaaaaaaaccccacccccccaaaccccaaacccaaaaaccccccccccaaaaaaajjjjkkkccccccaacccccc
abcccaaaaaaaacaaaacccccccccccccccccccaaaaaccccccccciiiijjjjjjjjjkkkkcaaaaaacccccc
abcccccaaaacccaaaaaacccccccccccccccccaaaaaacccccciiiiiijjjjjjjrrrkkkkaaaaaaaacccc
abcccccaaaaacccaaaacccccccccaacccccccccaaaaccccciiiiiiiijjjjrrrrrsskkaaaaaaaacccc
abccccaaaaaaccaaaaacccccccccaaaacccccccaccccccciiiiqqqqrrrrrrrrrssskkkaaaaaaacccc
abaaccaaccaaccaacaacccccccaaaaaaccccccccccccccciiiqqqqqrrrrrrruussskkkaaaaacccccc
abaaaacccccccccccccccccccccaaaaccccccccaaaccccciiqqqqqttrrrruuuuussskkaaaaacccccc
abaaaacccccccccccccccccccccaaaaaccccccccaaaaccchiqqqtttttuuuuuuuussskkcccaacccccc
abaaacccccaaaccacccccccccccaacaaccccccaaaaaaccchhqqqtttttuuuuxxuussslllcccccccccc
abaaaaccccaaaaaacaaccccccaccccccccccccaaaaacccchhqqqttxxxxuuxxyyusssllllccccccccc
abacaaccccaaaaaacaaaaaaaaaaccccccccccccaaaaaccchhqqqttxxxxxxxxyuusssslllccccccccc
abcccccccaaaaaaacaaaaaaaaaccccaacccccccaaccaccchhhqqtttxxxxxxyyvvvsssslllcccccccc
abcccccccaaaaaaaaaaaaaaaaaccccaaaaccccccccccccchhhppqttxxxxxyyyvvvvsqqqlllccccccc
SbcccaaccaaaaaaaaaaaaaaaaaacaaaaaacccccccccccchhhhpptttxxxEzzyyyyvvvqqqqlllcccccc
abcccaaccccaaacaaaaaaaaaaaaacaaaaccccccccccccchhhppptttxxxyyyyyyyyvvvqqqlllcccccc
abaaaaaaaacaaacaaaaaaaaaaaaacaaaaacaaccccccccchhpppsssxxyyyyyyyyvvvvvqqqlllcccccc
abaaaaaaaaccccccccaaacaaaccccaacaaaaaccccccaagggpppsswwwwwwyyyvvvvvvqqqmmmmcccccc
abccaaaaccccaacaacaaacaaacccccccccaaacaaaccaagggppssswwwwwwyyywvvqqqqqqmmmccccccc
abcaaaaaccccaaaaacaaccaaccaaaccaaaaaaaaaaaaaagggppsssswwwswwyywvrqqqqmmmmcccccccc
abcaaaaaaccaaaaacccccccccaaaaccaaaaaaaaaacaaagggpppssssssswwwwwwrrqmmmmmccccccccc
abcaacaaaccaaaaaaccccccccaaaaccccaaaaaacccaaagggppppssssssrwwwwrrrmmmmmdccccccccc
abccccaaaccaaaaaaccccccccaaaaccccaaaaaacccaacggggpooooooosrrwwwrrnmmmddddcacccccc
abccccaaaaaaaacccccccccccccccccccaaaaaaaccccccggggoooooooorrrrrrrnnmdddddaaaacccc
abcccccaaaaaaccccccccccccccccccccaaacaaacccccccggggfffooooorrrrrrnnddddaaaaaacccc
abccaaaaaaaacccccccccccccccccccccaccccccccccccccggffffffooonrrrrnnndddaaaaaaacccc
abccaaaaaaaaaccccaacccccccccccccccccccccccccccccccfffffffoonnnnnnndddcaaaaacccccc
abccaaaaaaaaaacccaaccccccccccccccaccccccccccccccccccccffffnnnnnnnedddaaaaaacccccc
abcccccaaaaaaaaaaaacccccccaccccaaacccccccccccccccccccccfffeennnneeedcccccaacccccc
abcccccaaacccaaaaaaaaccccaaacccaaaccacccccccccccccccccccafeeeeeeeeecccccccccccccc
abcccccaaccccaaaaaaaaacccaaaaaaaaaaaaccccccaaaccccccccccaaeeeeeeeeeccccccccccccca
abaccccccccccaaaaaaaaacccaaaaaaaaaaacccccccaaaaacccccccaaaaceeeeecccccccccccaccca
abaccccccccccaaaaaaaaccaaaaaaaaaaaaaacccccaaaaaccccccccaaaccccaaacccccccccccaaaaa
abaccccccccccaaaaaaacccaaaaaaaaaaaaaacccccaaaaacccccccccccccccccccccccccccccaaaaa
abaccccccccccaccaaaacccaaaaaaaaaaaaaaccccccaaaaaccccccccccccccccccccccccccccaaaaa

50
d12/run.py Normal file
View File

@@ -0,0 +1,50 @@
import sys
import networkx as netx
M = [ list(l) for l in sys.stdin.read().splitlines() ]
H = len(M)
W = len(M[0])
START = tuple()
END = tuple()
G = netx.DiGraph()
for x in range(H):
for y in range(W):
k = (x,y)
v = M[x][y]
if v == 'S':
START = k
v = 'a'
if v == 'E':
END = k
v = 'z'
v = ord(v)
for dx,dy in [(-1,0),(1,0),(0,-1),(0,1)]:
nx, ny = (x+dx, y+dy)
if nx>=0 and nx<H and ny>=0 and ny<W:
nk = (nx,ny)
nv = M[nx][ny]
if nv == 'S':
nv = 'a'
if nv == 'E':
nv = 'z'
nv = ord(nv)
dv = nv - v
if dv <=1: # can go down !
G.add_edge(k,nk)
print(G)
# part 1
S = netx.shortest_path(G, START, END)
print(len(S), "=>", len(S)-1)
for (x,y) in S:
M[x][y] = "\033[30;43m"+M[x][y].upper()+"\033[0m"
print("\n".join("".join(l) for l in M))
# part 2
R = []
for x in range(H):
S = netx.shortest_path(G, (x,0), END)
R.append(len(S)-1)
print(min(R))

5
d12/viewpng.html Normal file
View File

@@ -0,0 +1,5 @@
<img>
<script>
let img = document.querySelector('img');
img.src = "data:image/png;base64,"+ window.location.hash.substring(1);
</script>

33
d13/run.py Normal file
View File

@@ -0,0 +1,33 @@
import sys
P = [ tuple(map(eval, p.split("\n"))) for p in sys.stdin.read().split("\n\n") ]
def C(l,r):
T = (type(l),type(r))
if T == (int,int):
if l<r: return -1
return l>r # 0 or 1
elif T == (int,list):
return C([l],r)
elif T == (list,int):
return C(l,[r])
else: # list,list
for q in zip(l,r):
c = C(*q)
if c: return c
return C(len(l),len(r))
# part 1
S = 0
for i,p in enumerate(P):
if C(*p) <= 0:
S += i+1
print(S)
# part 2
from functools import cmp_to_key
Q = [ q for (l,r) in P for q in [l,r] ]
Q.append([[2]])
Q.append([[6]])
Q.sort(key=cmp_to_key(C))
print((Q.index([[2]])+1)*(Q.index([[6]])+1))

48
d14/part1.py Normal file
View File

@@ -0,0 +1,48 @@
import sys
W = 1000
H = 200
L = [[0 for _ in range(W)] for _ in range(H)]
def pr():
t = ".#o+"
print("\n".join("".join(t[i] for i in l[489:489+92]) for l in L))
def s2li(s,sep=','):
return list(map(int,s.split(sep)))
for l in sys.stdin.read().splitlines():
lp = l.split(" -> ")
for f,t in zip(lp,lp[1:]):
(a,b,c,d)= (*s2li(f),*s2li(t))
x0 = min(a,c)
y0 = min(b,d)
x1 = max(a,c)
y1 = max(b,d)
for x in range(x0,x1+1):
for y in range(y0,y1+1):
L[y][x] = 1
stop = False
N = 0
while not stop:
N += 1
y = 0
x = 500
more = True
while more and not stop:
more = False
while L[y][x]==0 and not stop: # if only air
y+=1
stop = y >= H-3
if L[y][x-1]==0: # can fall left
x -= 1
more = True
elif L[y][x+1]==0: # can fall right
x += 1
more = True
L[y-1][x] = 2 # mark sand
pr()
print(N-1)

69
d14/part2.py Normal file
View File

@@ -0,0 +1,69 @@
import sys
W = 1000
H = 200
L = [[0 for _ in range(W)] for _ in range(H)]
def prPGM():
print("P2")
print("367 184")
print("2")
t = "201"
print("\n".join(" ".join(t[i] for i in l[317:684]) for l in L))
def pr():
if len(sys.argv)>1 and sys.argv[1] == "G":
prPGM()
else:
t = ".#o+"
print("\n".join("".join(t[i] for i in l[450:550]) for l in L))
def s2li(s,sep=','):
return list(map(int,s.split(sep)))
MAX_Y = 0
for l in sys.stdin.read().splitlines():
lp = l.split(" -> ")
for f,t in zip(lp,lp[1:]):
(a,b,c,d)= (*s2li(f),*s2li(t))
x0 = min(a,c)
y0 = min(b,d)
x1 = max(a,c)
y1 = max(b,d)
MAX_Y = max(MAX_Y, y1)
for x in range(x0,x1+1):
for y in range(y0,y1+1):
L[y][x] = 1
for x in range(W):
L[MAX_Y+2][x] = 1
L = L[:MAX_Y+3]
stop = False
N = 0
while not stop:
N += 1
y = 0
x = 500
more = True # can all left or right
while more and not stop:
more = False
while L[y][x]==0 : #and not stop: # if only air
#print(N, x,y)
y+=1
stop = y == MAX_Y+2
#print(N, x,y)
if L[y][x-1]==0: # can fall left
x -= 1
more = True
elif L[y][x+1]==0: # can fall right
x += 1
more = True
else:
stop = y == 1 # can't put more sand
L[y-1][x] = 2 # mark sand
pr()
print(N)

40
d15/draw.py Normal file
View File

@@ -0,0 +1,40 @@
import sys
from collections import defaultdict
S = set()
B = set()
P = dict()
Q = defaultdict(list)
for l in sys.stdin.read().splitlines():
(_,_,X,Y,_,_,_,_,A,J) = l.split(" ")
x = int(X[2:-1])
y = int(Y[2:-1])
a = int(A[2:-1])
b = int(J[2:])
S.add((x,y))
B.add((a,b))
P[(x,y)] = (a,b)
Q[(a,b)].append((x,y))
if False:
print("digraph G {")
print("overlap = false;")
def toid(x):
(x,y) = x
return str(x).replace("-","m")+"_"+str(y).replace("-","m")
for (k,v) in P.items():
print("S_"+toid(k), "->", "B_"+toid(v),";")
print('}')
if True:
print("digraph G {")
print("overlap = false;")
def toid(x):
(x,y) = x
return str(x).replace("-","m")+"_"+str(y).replace("-","m")
for (k,V) in Q.items():
for v in V:
print("B_"+toid(k), "->", "C_"+toid(v),";")
print('}')

52
d15/part1.py Normal file
View File

@@ -0,0 +1,52 @@
import sys
from collections import defaultdict
BX = 1765036
BY = 2000000
def mtn(P,Q):
(x,y) = P
(u,v) = Q
return abs(u-x)+abs(v-y)
S = set()
B = set()
P = dict()
Q = defaultdict(list)
for l in sys.stdin.read().splitlines():
(_,_,X,Y,_,_,_,_,A,J) = l.split(" ")
x = int(X[2:-1])
y = int(Y[2:-1])
a = int(A[2:-1])
b = int(J[2:])
S.add((x,y))
B.add((a,b))
P[(x,y)] = (a,b)
Q[(a,b)].append((x,y))
if len(S) < 20:
BX = 2
BY = 10
Xs = set()
for s in S:
(x,y) = s
sB = P[s] # nearest bc
dB = mtn(s,sB) # max range before first bc
dy = abs(y-BY) # to reach THE bc
r = dB - dy
if len(S) < 20:
print(s, sB, (BX,BY), dB, dy, r)
if r > 0:
for d in range(-r,r+1):
nx = x+d
if abs(nx-BX)>=0:
Xs.add(nx)
print(len(Xs)-1)
if len(S) < 20:
print(Xs)

53
d15/part2a.py Normal file
View File

@@ -0,0 +1,53 @@
import sys
from collections import defaultdict
W = H = 4*1000*1000+1
def mtn(P,Q):
(x,y) = P
(u,v) = Q
return abs(u-x)+abs(v-y)
P = dict()
for l in sys.stdin.read().splitlines():
(_,_,X,Y,_,_,_,_,A,J) = l.split(" ")
x = int(X[2:-1]) #+ 2
y = int(Y[2:-1])
a = int(A[2:-1]) #+ 2
b = int(J[2:])
P[(x,y)] = (a,b)
if len(P) < 20:
print("S -> B", P)
if len(P) < 20:
W = H = 30
M = [ [1 for _ in range(W) ] for _ in range(H) ]
for s,sB in P.items():
(x,y) = s
dB = mtn(s,sB) # max range before first bc
if len(P) < 20:
print(s, sB, dB)
for rx in range(dB+1):
for ry in range(dB-rx+1):
for (nx,ny) in [(x-rx,y-ry),(x-rx,y+ry),(x+rx,y-ry),(x+rx,y+ry)]:
if nx>=0 and nx<W and ny>=0 and ny<H:
M[ny][nx] = 0
for y,r in enumerate(M):
for x,c in enumerate(r):
if c == 0:
if len(P)>20:
print(x,y)
pass
if len(P) < 20:
print("\n".join(" ".join(str(i) for i in l) for l in M))
# take too much memory

37
d15/part2b.py Normal file
View File

@@ -0,0 +1,37 @@
import sys
from collections import defaultdict
def mtn(P,Q):
(x,y) = P
(u,v) = Q
return abs(u-x)+abs(v-y)
S = list()
for l in sys.stdin.read().splitlines():
(_,_,X,Y,_,_,_,_,A,J) = l.split(" ")
x = int(X[2:-1])
y = int(Y[2:-1])
a = int(A[2:-1])
b = int(J[2:])
S.append((x,y,abs(x-a)+abs(y-b)))
print(S)
W = H = 4*1000*1000 #+1
if len(sys.argv)>1:
W = H = 20+1
for i in range(W):
print(".", end ='')
for j in range(H):
# is this point reachable by any sensor
r = False
for (x,y,db) in S:
dp = abs(x-i)+abs(y-j)
if dp <= db:
r = True
break
if not r:
print(i,j)
# taking too long

39
d15/part2c.py Normal file
View File

@@ -0,0 +1,39 @@
import sys
W = H = 4_000_000
if len(sys.argv)>1: # sample
W = H = 20
# store position that are not reachable, row by row
L = [ [(0,0) for _ in range(32)] for _ in range(H+1) ]
for i,l in enumerate(sys.stdin.read().splitlines()):
(_,_,X,Y,_,_,_,_,A,J) = l.split(" ")
x = int(X[2:-1])
y = int(Y[2:-1])
a = int(A[2:-1])
b = int(J[2:])
d = abs(x-a)+abs(y-b)
for ny in range(y-d, y+d+1):
if ny>=0 and ny<=H:
dy = abs(ny-y)
dx = d-dy
L[ny][i] = (x-dx,x+dx)
#L[ny] = intesec(L[ny], (x-dy,x+dy))
if len(sys.argv)>1: # sample
for l in L:
print(l)
d=0
for (y,I) in enumerate(L):
SI = sorted(I)
maxx = 0
for (a,b) in SI:
if a>maxx+1:
d+=1
print(y, maxx+1, (maxx+1)*4_000_000+y)
maxx = max(maxx,b)
print(d) # should be 1

106
d16/draw.ipynb Normal file

File diff suppressed because one or more lines are too long

47
d16/part1.py Normal file
View File

@@ -0,0 +1,47 @@
import sys
import re
pat = re.compile('Valve ([A-Z]{2}) has flow rate=([0-9]+); tunnels? leads? to valves? ([ ,A-Z]+)')
P = dict()
for i,l in enumerate(sys.stdin.read().splitlines()):
g = pat.search(l)
p = int(g[2])
P[g[1]] = (i, p, g[3].split(", "))
STEPS = int(sys.argv[1])
ALLO = 0
for _,(i,p,_) in P.items():
if p == 0:
ALLO = ALLO | (1<<i)
cache = {}
def step(pos="AA", left=STEPS, opens=ALLO):
"""
opens store valves openess 0: closed, 1: open
1 2 3 4 5 6 7 8 9 10
eg: 0b1000011110 -> 0 1 1 1 1 0 0 0 0 1
return : score = max(p*left + open valve if not open and continue, not open valve and continue)
"""
if left <= 0:
return 0
key = (pos, left, opens)
r = cache.get(key, -1)
if r >= 0:
return r
(i, p, nh) = P[pos]
is_open = opens & (1 << i)
#print(minutes, path, i, bool(is_open), p, nh)
a = 0
if not is_open: # also means 0 - worth opening valve ?
#print("open", i)
left -= 1 # cost to open
opens = opens | (1<<i)
a = p*(left+30-STEPS) + max(step(n, left-1, opens) for n in nh)
b = max(step(n, left-1, opens) for n in nh)
r = max(a,b)
cache[key] = r
return r
print(step())

50
d16/part2.py Normal file
View File

@@ -0,0 +1,50 @@
import sys
import re
pat = re.compile('Valve ([A-Z]{2}) has flow rate=([0-9]+); tunnels? leads? to valves? ([ ,A-Z]+)')
P = dict()
for i,l in enumerate(sys.stdin.read().splitlines()):
g = pat.search(l)
p = int(g[2])
P[g[1]] = (i, p, g[3].split(", "))
STEPS = int(sys.argv[1])
ALLO = 0
for _,(i,p,_) in P.items():
if p == 0:
ALLO = ALLO | (1<<i)
cache = {}
def step(pos1="AA", pos2="AA", left=STEPS, opens=ALLO):
"""
opens store valves openess 0: closed, 1: open
1 2 3 4 5 6 7 8 9 10
eg: 0b1000011110 -> 0 1 1 1 1 0 0 0 0 1
return : score = max(p*left + open valve if not open and continue, not open valve and continue)
"""
if left <= 0:
return 0
key = (min(pos1, pos2), max(pos1,pos2), left, opens)
r = cache.get(key, -1)
if r >= 0:
return r
(i1, p1, nh1) = P[pos1]
(i2, p2, nh2) = P[pos2]
isopen1 = opens & (1 << i1)
isopen2 = opens & (1 << i2)
a = b = c = d = 0
if pos1 != pos2 and not isopen1 and not isopen2: # open both if not same, but don't move
a = p1*(left+26-STEPS-1) + p2*(left+26-STEPS-1) + step(pos1, pos2, left-1, opens|(1<<i1)|(1<<i2))
if not isopen1: # p1 opens, p2 moves
b = p1*(left+26-STEPS-1) + max(step(pos1, n2, left-1, opens|(1<<i1)) for n2 in nh2)
if not isopen2: # p1 moves, p2 opens
c = p2*(left+26-STEPS-1) + max(step(n1, pos2, left-1, opens|(1<<i2)) for n1 in nh1)
# both moves, no new open
d = max(step(n1, n2, left-1, opens) for n1 in nh1 for n2 in nh2)
r = max(a,b,c,d)
cache[key] = r
return r
print(step())
print(len(cache))

1
d18/draw.awk Normal file
View File

@@ -0,0 +1 @@
{ print "translate([" $1+0.05 "," $2+0.05 "," $3+0.05 "]) cube([0.9,0.9,0.9]);" }

14
d18/part1.py Normal file
View File

@@ -0,0 +1,14 @@
import sys
S = set()
for l in sys.stdin.read().splitlines():
S.add(tuple(map(int,l.split(','))))
N = 0
for (x,y,z) in S:
n = 6
for (i,j,k) in [(0,0,1),(0,0,-1),(0,1,0),(0,-1,0),(1,0,0),(-1,0,0)]:
if (x+i,y+j,z+k) in S:
n -= 1
N += n
print(N)

34
d18/part2.py Normal file
View File

@@ -0,0 +1,34 @@
import sys
S = set() # cubes
for l in sys.stdin.read().splitlines():
(x,y,z) = list(map(int,l.split(','))) # makes type of tuple explicite for codon
S.add((x,y,z))
A = 23
L = set() # water
for x in range(-2,A+1):
for y in range(-2,A+1):
L.add((x,y,-2))
more = True
while more:
more = False
for x in range(-2,A+1):
for y in range(-2,A+1):
for z in range(-2,A+1):
if (x,y,z) not in S and (x,y,z) not in L: # water can only expand in air
for (i,j,k) in [(0,0,1),(0,0,-1),(0,1,0),(0,-1,0),(1,0,0),(-1,0,0)]:
if (x+i,y+j,z+k) in L: # if neighbour is water
L.add((x,y,z)) # water expand
more = True
break
N = 0
for (x,y,z) in S:
for (i,j,k) in [(0,0,1),(0,0,-1),(0,1,0),(0,-1,0),(1,0,0),(-1,0,0)]:
if (x+i,y+j,z+k) in L:
N += 1
print(N)
# ~/.local/programs/codon/bin/codon build --relocation-model=static --release -o part2 part2.py

33
d19/solve.py Normal file
View File

@@ -0,0 +1,33 @@
import sys, re, numpy
V = lambda *a: numpy.array(a)
k = lambda a: tuple(sum(a))
def parse(line):
i,a,b,c,d,e,f = map(int, re.findall(r'\d+',line))
return (i, (V(0,0,0,a), V(0,0,0,1)), # Cost and production
(V(0,0,0,b), V(0,0,1,0)), # of each robot type,
(V(0,0,d,c), V(0,1,0,0)), # in the order geode,
(V(0,f,0,e), V(1,0,0,0)), # obs, clay, and ore.
(V(0,0,0,0), V(0,0,0,0))) # Construct no robot.
BEST = int(sys.argv[1])
def run(blueprint, t):
todo = [(V(0,0,0,0), V(0,0,0,1))] # resources and robots.
for _ in range(t):
todo_ = list() # Queue for the next minute.
for have, make in todo:
for cost, more in blueprint:
if all(have >= cost): # We can afford this robot.
todo_.append((have+make-cost, make+more))
todo = sorted(todo_, key=k)[-BEST:] # adds resources and robots (k)
# the more of both, the better
# then prune the search queue
return max(todo, key=k)[0][0]
part1, part2 = 0, 1
for i, *blueprint in map(parse, sys.stdin):
part1 += run(blueprint, 24) * i
part2 *= run(blueprint, 32) if i<4 else 1
print(part1, part2)

49
d20/part1.py Normal file
View File

@@ -0,0 +1,49 @@
from __future__ import annotations
import sys
from dataclasses import dataclass
@dataclass
class E:
v: int
p: E
n: E
V0 = None
p = None
L = []
for l in sys.stdin.read().splitlines():
e = E(int(l),p,None)
L.append(e)
if l == "0":
V0 = e
if p is not None:
p.n = e
p = e
L[-1].n = L[0]
L[0].p = L[-1]
def swap(l,m):
k = l.p
n = m.n
k.n = m
n.p = l
l.n = n
m.p = k
l.p = m
m.n = l
for l in L:
if l.v > 0:
for _ in range(l.v):
swap(l,l.n)
elif l.v < 0:
for _ in range(-l.v):
swap(l.p,l)
S = 0
s = V0
for i in range(3000+1):
if i in [1000,2000,3000]:
S += s.v
s = s.n
print(S)

51
d20/part2.py Normal file
View File

@@ -0,0 +1,51 @@
from __future__ import annotations
import sys
from dataclasses import dataclass
@dataclass
class E:
v: int
p: E
n: E
DEK = 811589153
V0 = None
p = None
L = []
for l in sys.stdin.read().splitlines():
e = E(int(l)*DEK,p,None)
L.append(e)
if l == "0":
V0 = e
if p is not None:
p.n = e
p = e
L[-1].n = L[0]
L[0].p = L[-1]
def swap(l,m):
k = l.p
n = m.n
k.n = m
n.p = l
l.n = n
m.p = k
l.p = m
m.n = l
for _ in range(10):
for l in L:
if l.v > 0:
for _ in range(l.v%(len(L)-1)):
swap(l,l.n)
elif l.v < 0:
for _ in range(-l.v%(len(L)-1)):
swap(l.p,l)
S = 0
s = V0
for i in range(3000+1):
if i in [1000,2000,3000]:
S += s.v
s = s.n
print(S)

9
d21/draw.awk Normal file
View File

@@ -0,0 +1,9 @@
BEGIN { print "digraph G {"}
{ k = substr($1,1,length($1)-1) }
NF == 2 { print k, "[label=\"" $0 "\"];" }
NF == 4 {
print k, "[label=\"" k " " $3 "\"];"
print k, "->", $2, ";"
print k, "->", $4, ";"
}
END { print "}" }

28
d21/part1.py Normal file
View File

@@ -0,0 +1,28 @@
import sys
N = dict() # numbers
E = dict() # expressions
for l in sys.stdin.read().splitlines():
k, v = l.split(":")
v = v.strip()
if v.isdigit():
N[k]=int(v)
else:
w = v.split(" ")
E[k]=w
O = {
'*': lambda x,y: x*y,
'+': lambda x,y: x+y,
'-': lambda x,y: x-y,
'/': lambda x,y: x/y,
}
while len(E)>0:
D = dict()
for k,v in E.items():
(a,o,b) = v
if a in N and b in N:
N[k] = O[o](N[a],N[b])
else:
D[k] = v
E = D
print(N["root"])

43
d21/part2.py Normal file
View File

@@ -0,0 +1,43 @@
import sys
N = dict() # numbers
E = list() # expressions
I = {"+":"-","-":"+","*":"/","/":"*"}
for l in sys.stdin.read().splitlines():
k, v = l.split(":")
v = v.strip()
if v.isdigit():
N[k]=int(v)
else:
(a,o,b) = v.split(" ")
E.append((k,a,o,b))
if o in {"+","*"}:
E.append((a,k,I[o],b))
E.append((b,k,I[o],a))
else:
E.append((a,k,I[o],b))
E.append((b,a,o,k))
if len(N)<100:
N["pppw"] = 150
else:
N["qmfl"] = 54426117311903
N["qdpj"] = 54426117311903
del N["humn"]
O = {
'/': lambda x,y: x/y,
'-': lambda x,y: x-y,
'+': lambda x,y: x+y,
'*': lambda x,y: x*y,
}
while len(E)>0:
D = list()
for (k,a,o,b) in E:
if a in N and b in N:
N[k] = O[o](N[a],N[b])
if k == "humn":
print(N[k])
D = {}
break
else:
D.append((k,a,o,b))
E = D

BIN
d22/cube.odg Normal file

Binary file not shown.

200
d22/cube.txt Normal file
View File

@@ -0,0 +1,200 @@
.........#...........#...................................#................#...............#.........
..........#.........................#........#..#...........................#.......................
....#.#.......#..#.................#.................................#..........#.......#...........
#................##..............##...#....#..#...............#........#..#.........................
........................#...............#....#.#......................#.#.....#...#.................
....#....#..........###.#.........##..#.......#..##.##.........#..............#..............#....#.
#.......#..............#...............#.................#..........##..............#......#........
...#.......#...........................#................#.....#..............#.........#...........#
.#...#.#....................#...........#..#......#......#.....#.......#...............#............
............#...............#.#....................#....#......#.........#.......#......#.#......#..
....#.................##...........#....###.......................#........................#........
........................#................#..............#.......#...................................
#............................#.........................#.....#...................#...##.........##..
..........##............#....#.....#.........#.............##........#..#.....#......#...#.......#.#
#....#.......#...##.#.........#..........................................#.#........................
...............................#..............................##.....#.......#..#...#..............#
....#.................#...#.....#.......##..............#...#........#........#...#.......#.........
.........#....###......#......#.......................#..#...........##...#.........#.....#.........
#........#.......................................................#.....#.#.........#....#.#.........
.............#...#.......#.........#......#.#...............#...#....###.................#..........
.....#.#....................#.........................#.................................#.#.........
...................#................#...........#.......#................#............#..#..........
..............##.........##.......#.............#.........#.#....#......#.#...#.....................
..#..............................#..........#.............#...................................#.....
......##.......#...#.........#............#....#.........#..#..............#.....................##.
#...#...............#.........##..#........................#..........#...............#.#.#.......#.
...#........#...............#..........#.......#.................#..#................#...........#..
...#........................#...#...............#..#............#........#..............#....#...#..
.....#..##......#...............#.#............#...#....................#...........#.....#...#....#
#....#.................##........#...#............#............................................#....
...........................#............#.......##..#....#......#.#........#....#...#...............
.......#.............................................#.........#........#....................#......
....#..........#...........#................#.#..............................................#......
#................#...............#........#................#...........................#............
...#..#...............#........#.....#.#...........#........#..........##.........#..#..#...#.......
............#......#.......#........#.............##...#.............................##.............
....#.........#..............................#................#...........#.......#.....#....##.....
..#......#...........................#.......................#............#.#.............#......#..
.............#.##.......#.........................#......#.......#..................................
.#..........#.#.#...................#.....#....#................#.#.....#...#............#.......#..
.......#....#..#...#.......#...#...........##........#.#..............#......#......#...............
.#.#...............................#.....###..................#............#....##........#.......#.
..........#........#...#...........##.............##............#.#............................#....
..#....#.#...........#....#................#.#...#.##......##.#........#.....#..................#...
.........#......#.#..........#.......#.....#...............#............#.#.........#........#......
.......................#.....##...................#.....##..#.........#..............##..#..........
.........#....#...........................#...#..........#.#......#...#..........................#.#
#.#........................###......#..................#..................#.....#.....#.............
..............................#......#.#....#.#..#...#..#.....#........#...................#........
..#.........#......#...#.....#.................................#.......#.#.......#.#..............#.
#........#.................#............#.........
..##.#........#...#..#............................
.#..............#..........................#.....#
.......#..#.......#........#...#..#.......#..#..#.
......#...#....##.........#.#....#.#......#....#..
...#...#....#..........................#..........
...........#..#........#..##.......#....#.........
..#...#......#.......#.##.....#.#.................
.......................#.......##.....#.#.........
.....#................#.............#.#...........
..#.....#.............................#.#........#
..#......##......#......................#.......#.
.....#.....................#......................
.....#.......#.#....##........#...................
..................#..#.#................#.#.......
#....#...........#.....##.............#.......#...
#....#........#.....#.............................
.#.......#....#.#................#.....#.....#...#
............#.............#.....#..#..............
...................#..........#...#......#........
...#.....................#....#...#..#...........#
.#...........#....#...............................
....#...#.#............#.......................#..
.#.............................##.#.....#.........
#.#.......#.......................#...............
.....#...##............#......#..............#...#
.............#................#........#........#.
............#.#.....................#.........#...
................#..........#....................#.
.........#.........................#....###..#..#.
..................................#...............
.#...##..#..#............#.......#..##......##....
...#...........#...........#............#.........
..##.........#.......#..........#.................
...........#.............................#...#....
.............#.......#.....#......................
.........#.......................#................
..........................#....#.#..............#.
..........#.....#..................#.........#....
....................#.............#...............
...........#.##.....................#.............
........................#....#..#...#.........#...
.......#......#...................................
.#..#..#..................#..........#.#..........
...............#.................##..........#.#.#
##.....#..........#..#..................#......#..
#..........#.....#......#.............##......#...
#......#.........#.................#............#.
..#...............................#..#.......#...#
.........#...........................#........#...
...............................#.......#...#.......#.............................#..#...............
.............#.#.#..#.......#............#........#.................#............#.......#..........
...........#...#..#.........#....#..............#.......#...#......#...............................#
..........#.........#........#.....................#.....................#.#............#.....#..#..
.....#.........#.......................#........##.#.....................................#..........
#...........#....#..##.....................#...........#..............#...#..#.#....................
......#..........................##.......#..............#.......................#..................
#......#.#......#.............#...............#...........##...#..........#........#......#......#..
..............#.....#..#.............#...#.....#................##..................................
.....#..............#................#................#.............................#........#......
.......##...#..........#...............#.............#.........#.#..#..#.....#....#............#....
.............#............###...........#..................#.......#................................
...............#.........#........#............................#..............................#.....
...#......#......#......##.#.............................#...#............................##........
.....#..............#.#............#.......#.##..........##................#......#..#............##
........................#..#......#...........#......#.........#.#...#..####.....#...#..............
......#.......#......#........#..#....#......##.....#...#..#.....#..............##.......#....#.....
...##.#.........#..#.......#.........#........#...........................#..........#......#....#..
.................#......#............#......................#..#.....#............#...#.....#.#.....
.........#............##...........#...........#....###.................#...........................
..#......#........#...........#....##..#..............#...#.....#......................#..........#.
..........#................#........#.......#.......#.......##...##...#..........................#..
.......#.#....#....#..............#.......#....#..#..............##.................................
...........#..#.......#....#.............#...#...........##..#..#............#........##..........#.
#.#....................#....#....#.#.....#..........#....#..........#.........#................#....
....................#.#.##.........................................###.........#...........#........
...............#...#..................#..........#...........#...........#.........#..#..#...#...#.#
........#...........###...#...........#..........................##...........#..................#..
.......#..#.............................#......#............#....................#.............#....
....#...............#.......#...........##.##.....#..................#...#...#......................
.#.....#.......#....................................#..#..#.......................#.........#.......
......................#.#.##............#............#............#......#.......#......#..##.......
........................................##......................#..................#.......#........
...................................#..#....#.......#.#........#.....#......###............#.........
.....#................#..#..............#........#.........##........................#..............
..............#...........#........#..............#........#..............#.........................
##...................#...#................#.....#......#.#...#...##......#........#....#........#...
#..#....#..............................#...........#..#........#..#.....#......#....................
#...............#...#.##..............................#......##...............#..................#..
............#.#..#.#................#...#..#..................#......#.#................#...........
#.....................#..........#.......#.....#...........#.........................##....#........
#....................#..........#..............#...................#.........#.##.....#..##.......#.
........#...........#....#...#.#...........#.......#......................#.....#.......#.#.........
#.....................#.....#..#..............##.....#...........#..................................
......................#.................#.............#.......................................#.#...
....#..#........#....#........#...............#......#....#......#..#....#.........##...............
.............#.#...........#...............#.......................#................................
......................#.#............#.....#..............................#.......#.................
....#...#.............#...................#...........#...................................#.........
.....................#......#...#......#..##...........#...........#.....#...............#..........
....#.#....#.................#....#...............
..........#...#..........#..#.................#...
...........#............#..#.......#...........#..
........#..#....##......#.........#...............
#........................##..#.#...............#..
...#.........##...................................
...#...................#....#........#............
.#.#...............#.#..#.........................
...#.#..........#..............................#..
........#.............#..............#...#..#.....
...#.....................#...............#.#.....#
.#......#.#..................#.....#....#.....#.#.
.............#..##..............#.......#....#....
......#.......#........#...#...........#...#......
...#..#.................#.#....#..................
..#..................#......#...............#.....
...............#.............#..............#.....
..#..........#....................................
.................#.............#.#......#.....#...
............................................#....#
.........#.............#.........#....#...........
##....#................#.............#.#..........
....#....#............#.................#...#.....
...........#.........#................#.#.........
...#..#........................#....#.........#...
.##..................#....#.........###..##..#.#..
...#..........#...................#.....#.#.#.....
##.......#......##................#..........#....
...#....#...#...........#.............#.#........#
.....................#.........#.##..#.##....#....
...........#......................##.#............
.........................#.........#.#....#.......
.......................#......#....#....#..#......
...........................#..............#.......
.................#..............#..........#..#...
.......#...#....#.....#.#.....................#...
.....#....#..#.........#..............#......#....
..........................#.#.......#.#..........#
.........#.........#......#.......................
........#.......#..........##.....................
..#......#.....##.................................
.##..#...#..............#....#....#.#.#...........
.............#............#......#..........#..#..
...........#.#.................#..#......#...##...
#......##....#..........#......#....#.........#...
#............................#...........#..#.#...
..........#............#...........#..............
..............#.........................#.......#.
...#...#.....#..........#...................#.....
#.#.....#.............#...............#.........#.

36
d22/draw.awk Normal file
View File

@@ -0,0 +1,36 @@
BEGIN {
print "P2"
#print "150 200"
print "604 805"
print "2" # max
C = ""
for (i=1;i<=150;i++) { C = C " " }
}
function sep() {
r = ""
for (i=1;i<=604;i++) {
r = r "1 "
}
print r
}
NR == 1 { sep() }
{
split($0 C,A,"")
r = "1 "
for (i=1;i<=150;i++) {
c = A[i]
if (c==" ") p="2"; #"1";
if (c==".") p="2";
if (c=="#") p="0";
r = r p " " p " " p " " p " "
if (i%50 == 0) {
r = r "1 "
}
}
print r
print r
print r
print r
}
NR % 50 == 0 { sep() }

146
d22/part1.rs Normal file
View File

@@ -0,0 +1,146 @@
use std::iter::repeat;
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub struct Instruction {
dist: Option<isize>,
rotation: Option<isize>,
}
pub fn main() {
let s = include_bytes!("./input");
let mut pos = (s.iter().position(|b| *b == b'.').unwrap() as isize, 0);
let mut facing: (isize, isize) = (1, 0);
let w = s
.split(|b| *b == b'\n')
.take_while(|l| !l.is_empty())
.map(|l| l.len())
.max()
.unwrap();
let map = s
.split(|b| *b == b'\n')
.take_while(|l| !l.is_empty())
.map(|l| {
l.iter()
.take(l.len())
.chain(repeat(&b' ').take(w - l.len()))
.copied()
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
let h = map.len();
let mut path: Vec<Instruction> = Vec::new();
let mut acc = 0;
s.split(|b| *b == b'\n')
.rev()
.nth(1)
.unwrap()
.iter()
.for_each(|b| match b {
b'0'..=b'9' => {
acc = acc * 10 + (b - b'0') as isize;
}
b'R' => {
path.push(Instruction {
dist: Some(acc),
rotation: None,
});
path.push(Instruction {
dist: None,
rotation: Some(1),
});
acc = 0;
}
b'L' => {
path.push(Instruction {
dist: Some(acc),
rotation: None,
});
path.push(Instruction {
dist: None,
rotation: Some(-1),
});
acc = 0;
}
_ => unreachable!(),
});
path.push(Instruction {
dist: Some(acc),
rotation: None,
});
#[cfg(debug_assertions)]
println!("{} {}", map.len(), map[0].len());
#[cfg(debug_assertions)]
println!(
"pos: ({}, {}), facing ({} {})",
pos.0, pos.1, facing.0, facing.1
);
for ins in path.iter() {
#[cfg(debug_assertions)]
println!("{:?}", ins);
match (ins.dist, ins.rotation) {
(Some(dist), None) => {
for step in 0..dist {
let mut next_pos = (pos.0 + facing.0, pos.1 + facing.1);
#[cfg(debug_assertions)]
println!("next_pos: {} {}", next_pos.0, next_pos.1);
let next_char = if next_pos.0 >= 0
&& next_pos.0 < w as isize
&& next_pos.1 >= 0
&& next_pos.1 < h as isize
{
Some(map[next_pos.1 as usize][next_pos.0 as usize])
} else {
None
};
if next_char == Some(b'.') {
pos = next_pos;
} else if next_char.is_none() || next_char == Some(b' ') {
next_pos = (pos.0 - facing.0, pos.1 - facing.1);
while next_pos.0 >= 0
&& next_pos.0 < w as isize
&& next_pos.1 >= 0
&& next_pos.1 < h as isize
&& map[next_pos.1 as usize][next_pos.0 as usize] != b' '
{
next_pos = (next_pos.0 - facing.0, next_pos.1 - facing.1);
}
next_pos = (next_pos.0 + facing.0, next_pos.1 + facing.1);
if map[next_pos.1 as usize][next_pos.0 as usize] != b'#' {
pos = next_pos;
} else {
#[cfg(debug_assertions)]
println!("pos: {} {}", pos.0, pos.1);
break;
}
} else {
#[cfg(debug_assertions)]
println!("pos: {} {}", pos.0, pos.1);
break;
}
}
}
(None, Some(rot)) => match rot {
1 => (facing.0, facing.1) = (-facing.1, facing.0),
-1 => (facing.0, facing.1) = (facing.1, -facing.0),
_ => unreachable!(),
},
_ => unreachable!(),
}
#[cfg(debug_assertions)]
println!(
"pos: ({}, {}), facing ({} {})",
pos.0, pos.1, facing.0, facing.1
);
}
let facing_dir = facing.0.abs() * (1 - facing.0) + facing.1.abs() * (1 - facing.1);
#[cfg(debug_assertions)]
println!(
"pos: ({}, {}), facing ({} {}) = {}",
pos.0 + 1,
pos.1 + 1,
facing.0,
facing.1,
facing_dir
);
print!("{} ", 1000 * (pos.1 + 1) + 4 * (pos.0 + 1) + facing_dir);
}

197
d22/part2.rs Normal file
View File

@@ -0,0 +1,197 @@
use std::iter::repeat;
type Pos = (isize, isize);
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
struct Instruction {
dist: Option<isize>,
rotation: Option<isize>,
}
fn rotate(facing: Pos, by: isize) -> Pos {
match by.rem_euclid(4) {
0 => facing,
1 => (-facing.1, facing.0),
2 => (-facing.0, -facing.1),
3 => (facing.1, -facing.0),
_ => unreachable!(),
}
}
fn facing_angle_to_axes(facing: isize) -> Pos {
match facing.rem_euclid(4) {
0 => (1, 0),
1 => (0, 1),
2 => (-1, 0),
3 => (0, -1),
_ => unreachable!(),
}
}
fn next_pos_facing(
pos: Pos,
facing: Pos,
map: &Vec<Vec<u8>>,
edges: &Vec<(Vec<Pos>, Vec<Pos>, isize, isize)>,
) -> (Pos, Pos) {
let mut next_pos = (pos.0 + facing.0, pos.1 + facing.1);
let mut next_facing = facing;
for edge in edges.iter() {
if let Some(i) = edge.0.iter().position(|p| *p == pos) {
if facing_angle_to_axes(edge.2) == facing {
(next_pos, next_facing) = (edge.1[i], rotate(facing, (edge.3 + 2) - edge.2));
#[cfg(debug_assertions)]
println!(
"cross edge: {} {} ({} {}) -> {} {} ({} {})",
pos.0,
pos.1,
facing.0,
facing.1,
next_pos.0,
next_pos.1,
next_facing.0,
next_facing.1
);
}
} else if let Some(i) = edge.1.iter().position(|p| *p == pos) {
if facing_angle_to_axes(edge.3) == facing {
(next_pos, next_facing) = (edge.0[i], rotate(facing, (edge.2 + 2) - edge.3));
#[cfg(debug_assertions)]
println!(
"cross edge: {} {} ({} {}) -> {} {} ({} {})",
pos.0,
pos.1,
facing.0,
facing.1,
next_pos.0,
next_pos.1,
next_facing.0,
next_facing.1
);
}
}
}
(next_pos, next_facing)
}
pub fn main() {
let s = include_bytes!("./input");
let mut pos = (s.iter().position(|b| *b == b'.').unwrap() as isize, 0);
let mut facing: (isize, isize) = (1, 0);
let w = s
.split(|b| *b == b'\n')
.take_while(|l| !l.is_empty())
.map(|l| l.len())
.max()
.unwrap();
let map = s
.split(|b| *b == b'\n')
.take_while(|l| !l.is_empty())
.map(|l| {
l.iter()
.take(l.len())
.chain(repeat(&b' ').take(w - l.len()))
.copied()
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
let l = 50isize;
#[rustfmt::skip]
let edges: Vec<(Vec<Pos>, Vec<Pos>, isize, isize)> = vec![
((0..l).zip(repeat(l*2).take(l as usize)).collect(), repeat(l).take(l as usize).zip(l..l*2).collect(), 3, 2),
(repeat(0).take(l as usize).zip(l*2..l*3).collect(), repeat(l).take(l as usize).zip((0..l).rev()).collect(), 2, 2),
(repeat(0).take(l as usize).zip(l*3..l*4).collect(), (l..l*2).zip(repeat(0).take(l as usize)).collect(), 2, 3),
((0..l).zip(repeat(l*4-1).take(l as usize)).collect(), (l*2..l*3).zip(repeat(0).take(l as usize)).collect(), 1, 3),
(repeat(l-1).take(l as usize).zip(l*3..l*4).collect(), (l..l*2).zip(repeat(l*3-1).take(l as usize)).collect(), 0, 1),
(repeat(l*2-1).take(l as usize).zip(l*2..l*3).collect(), repeat(l*3-1).take(l as usize).zip((0..l).rev()).collect(), 0, 0),
(repeat(l*2-1).take(l as usize).zip(l..l*2).collect(), (l*2..l*3).zip(repeat(l-1).take(l as usize)).collect(), 0, 1),
];
let mut path: Vec<Instruction> = Vec::new();
let mut acc = 0;
s.split(|b| *b == b'\n')
.rev()
.nth(1)
.unwrap()
.iter()
.for_each(|b| match b {
b'0'..=b'9' => {
acc = acc * 10 + (b - b'0') as isize;
}
b'R' => {
path.push(Instruction {
dist: Some(acc),
rotation: None,
});
path.push(Instruction {
dist: None,
rotation: Some(1),
});
acc = 0;
}
b'L' => {
path.push(Instruction {
dist: Some(acc),
rotation: None,
});
path.push(Instruction {
dist: None,
rotation: Some(-1),
});
acc = 0;
}
_ => unreachable!(),
});
path.push(Instruction {
dist: Some(acc),
rotation: None,
});
#[cfg(debug_assertions)]
println!("{} {}", map.len(), map[0].len());
#[cfg(debug_assertions)]
println!(
"pos: ({}, {}), facing ({} {})",
pos.0, pos.1, facing.0, facing.1
);
for ins in path.iter() {
#[cfg(debug_assertions)]
println!("{:?}", ins);
match (ins.dist, ins.rotation) {
(Some(dist), None) => {
for _step in 0..dist {
let (next_pos, next_facing) = next_pos_facing(pos, facing, &map, &edges);
match map[next_pos.1 as usize][next_pos.0 as usize] {
b'#' => {
break;
}
b'.' => {
(pos, facing) = (next_pos, next_facing);
}
_ => {
panic!("unexpected wall as next character");
}
}
}
}
(None, Some(rot)) => {
(facing.0, facing.1) = rotate((facing.0, facing.1), rot);
}
_ => unreachable!(),
}
#[cfg(debug_assertions)]
println!(
"pos: ({}, {}), facing ({} {})",
pos.0, pos.1, facing.0, facing.1
);
}
let facing_dir = facing.0.abs() * (1 - facing.0) + facing.1.abs() * (2 - facing.1);
#[cfg(debug_assertions)]
println!(
"pos: ({}, {}), facing ({} {}) = {}",
pos.0 + 1,
pos.1 + 1,
facing.0,
facing.1,
facing_dir
);
print!("{} ", 1000 * (pos.1 + 1) + 4 * (pos.0 + 1) + facing_dir);
}

75
d23/input Normal file
View File

@@ -0,0 +1,75 @@
...#######...####..#........#.#.##...##.##..#.##.####..####.##.##...###..##
##.###.#...##..#....###..#.##.###.##..##..###..#....##.#..##.####..#.#.#.##
..##.#.###.#......#...#....#...#.#.#...##......####..######.##....#####.##.
##.#####.#.###.####.#....#.....####.#####..##.....#.##...###...#.####..#...
...#.....#.#..#.######.###....#.....#.###..##..#.#.###..##..#.#......#..#..
.###.#.##.##.##.....##.........#....#.#.#..#....###..####..#.#.###..###..#.
.#####.......##.#..#...###.##...#.###...#..##.#.###.......##.#..#..##...##.
.###.#.#.###.#.#..#..###..###..###.########.###..#.##.#.##...##.##.###.#...
.....######.###.###.......####...##.#.##..#.#.##.#....##.###.#.###...###..#
..#..##...#..#...##.#.#..###...#.##.##.##..##.###.#.#..#...#.#..#......####
##..##.##..#.#.##...#.#.#...###.....#....###....#######.#####..#...#.##..##
####....######.#..##...#....#.##....##.#..#.##..##..#.#.....##..####..#....
....####..#.......##...#........#.##..#.#.#.##.##..##.##.....##..#...#.##.#
.####..######.##.#.#.#.##...###..##...######..#.#.#.####.######.#...###....
##..#.#...#.#.#.#.###.#.###.#.#.##.....#..##..##.##...###....#...#.###...#.
#####.##...###..#.#.######..#.###...###..#..###.....#....####..#.####...###
#.#.#....###.##...#.###.#.###.###..###.#.#.....#.##....#.##.##.#####..##..#
...##.#...##....####.#.##.#.####.###...#.##....#..##.###..#......#######.##
....#..#.#.#...##....#.####.##...#..#####...#.##..###..##...#..#.##.#.#.#.#
..#..#####.#..#.#.#..#.###.##...#........#.#.....#.##.....#.##.#..#.#.#.#..
..#.##.###....##.#..#.#####.....#.##.....#.#..###.###..#.#......#..#...#.##
##.#.#...#...#.##..#......###.#.#.####.#...#########.#..#..##...##...##.###
...#.###.#..#######.#.#.##.##..###.##.#.######.#.##.##.##.#########.#...#.#
#..#...##.##.######.#..#.####...####.###.#...##.####..##..#.#...##.#.#.##..
.##.###..#####.###.##..#.#.#.#....#.#....#...#....######.##.#...#...#.#...#
#..#.....##....#.#..##.###..#..####..######...##.#..#######....#.#..##.##..
##...#.##.#...#....#.##.##..#####...##.#.#.#.#...#...#.#....#.##..##..##..#
..##....#..###...#.#.#.##....#...##...###.##.#.....#..#####.#####.....##..#
.#.##..#.#.###..#...###.....##...###..#.#######.#..#.#.##.##..##.#.#..##.##
#.#...#..###..#...####.#.#..##.#..#....#.#.#.###.#.##.##.#.......#.##....##
.#.##.#.#..#.#.#.#.##..#.###..#....#..#...###.#.#.##..#.##..#..#.#..#...###
..#..#.##......#....##.#######..#..##.....#.#.##..#..#..#.#.#..#.#..#.##...
#.#.###.###..######.##....#####.####..#....##.##.##.....##..#..###...##..##
.##..#.#.###..##.....###.#.##.#..#.....#.##..#...#...###...#...##...#####.#
.....#....######..##.#..##..#...##.#.##.#..##...####.##..#.#.####.###......
#..##....#.#.#.#....##..#....##...##.#...###.##..#....#.#...#.#..###...#..#
...###.#.####..##...###.#.##.#..#.####.#.#.#####....####.#.#.#.##...#.##...
.#..##.#...#..##.######.#######.#.#...##...##..#.#.########..#..##.#..###..
..#####.####.#.#.##........###...#..###...##...#...#....####...##.#.#######
#.#####......###.#..###.....##..##...######.#..##.#.#.#######..##.####...#.
#.#.#.#..##..#.##..###....##.#.##.####..#.#####..###......#...#..#..###....
..#...#.##..##.#..#####.######...###...#...##..#.#####..#.###....#..#.#.#..
###..#.#####.##.#.######..##.#####...#...#####.#.#.#.#...#.#.#.#....##....#
#.#...###...#.#...####..........#####..###..#.#...####...#.#.###.#..####.##
..#..##.###.##...####.#....#..##.....####.##.#.#....#..#..##.#..##.#.#..###
..#......##.#.####..###.####..##.####.##...#.#.####.#.#..#..######.##.##.##
....###...#.##.####....#...#.#..#..##.#.####...##...#...#.#.##...##.##..#.#
######....#.#..####.#.#...#####.#.#..##.######.#.###.#.#.#....#...#....##..
....####...#..#.#.#.####.#..#..###..#..#.##.########...#..#.#.........#.#..
##....#.#.##.####.#.#..##.#..##.#.#.#.#.#.#..#######.##..#.##....####...###
##.#.#.##.#...###.#...#...##..#.#.#...#....#...#....#.#..###.##.##...##....
.####....#.##...#.#.#.....#.#.#.#..#.....###.##.#..#...#...###.#..#.#..##.#
##..#.#....##....#.##.##.#.###........#.#..#.#....#.#.###...####..##.####.#
.##.#..###..#.#...###.###.###.###.#.#...##.#.#.###.#.####.###.##...#.#.#...
.#.##.##..#.#.####..##.#####.#..#..####.###..###..####.....###.###.......#.
##.#..#.#..###..#.....#.##.....#.#.#.##..######.#..#.#...#...##..###..##.#.
##..##...#........##..##.######.#.####...#..#..####..#.##.#...#..#.##.#.##.
#..#.##..###.#......####..##.##.#....#.###.##..#.#.#.##.##..#..#.##..##....
.....#....#.#.##..#.##....####.####.....#.###.#.#..#.#.....#..##..##.###...
.#......##....#.##.#...#.#####...##..##.....#.##.##.....#..#..##.#...#####.
##.#...##...#....#.####.#.#....#.#..######..........####.....#.#.#......#..
#.#.#....###..#..####..#.##...##.#####.#...#.#...###...#..##..##.####.#...#
#...###.##.#..#.###..##...##.##..#...##.#....#.#.##.##....#.#....#...#####.
#....##..####.....#.##.#####.#...##..##....#...###...#...#..#.#...#..#...##
#..##.##.....##..#.###..........###...#.#...#..#..##..#...##.####.#....###.
.#....#..#..##.###..########.#......#...#..#..##.##....###.###.....#...##.#
##..###.#....#.#...##.#.###.#.#..#..#..###.#...#.##.#####.#.#..##..#.#..#.#
#.#.#...#....#####.####..#.##.####..#.#.#...#....#..#.###...###.###...#...#
.###..##.#..##..#..#...##.#.#...###..##.#.####.#....#.#...##....#....##..##
..#.##..####.##..##...##..#.###.......#..####.##..#.#......#...##..###.....
##....##.####.####..#.#.#..#####.....###.##..###..####.###.#####..#.....#.#
.####.#..#####.....#..######...##.#....####......######...###..###..#.#.###
.#..#.#.####.#.##........###.#.#.#.##.#..#...#......###.#.##.#..#.#...#...#
.#..#.##....#...#...#.##..#...##.....#..######..##.###...#..#..####..#.#.#.
##.#.#.#..#.##..#.#......#.######..#####...#.##.###.######.#...#.###.##...#

69
d23/paint.py Normal file
View File

@@ -0,0 +1,69 @@
import sys
E = { (y,x) for y,l in enumerate(sys.stdin.read().splitlines())
for x,c in enumerate(l)
if c == '#' }
def can(y,x):
can1 = (y-1,x-1) not in E
can2 = (y-1,x) not in E
can3 = (y-1,x+1) not in E
can4 = (y,x+1) not in E
can5 = (y+1,x+1) not in E
can6 = (y+1,x) not in E
can7 = (y+1,x-1) not in E
can8 = (y,x-1) not in E
return [can1,can2,can3,can4,can5,can6,can7,can8]
def canN(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can1 and can2 and can3:
return (y-1,x)
def canS(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can5 and can6 and can7:
return (y+1,x)
def canW(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can7 and can8 and can1:
return (y,x-1)
def canE(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can3 and can4 and can5:
return (y,x+1)
def draw(r):
with open(f"./pics/{r:05d}.pbm","wt") as f:
(minx,maxx,miny,maxy) = (-13,129,-13,129)
w = 4*(maxx -minx +1)
print("P1",file=f)
print(f"{w} {w}", file=f)
for y in range(miny,maxy+1):
a="".join(["0000","1111"][(y,x) in E] for x in range(minx,maxx+1))
print(a,file=f)
print(a,file=f)
print(a,file=f)
print(a,file=f)
from collections import deque
dirs = deque([canN,canS,canW,canE])
for r in range(int(sys.argv[1])): # rounds
P = dict() # { new_pos: old_pos }
for e in E: # for each elve
(y,x) = e
cans = can(y,x) # compute once instead of four
moves = [ d(y,x,*cans) for d in dirs ]
if all(m is not None for m in moves): # far away
continue
if all(m is None for m in moves): # all packed
continue
p = next(filter(lambda m: m is not None ,moves))
if p not in P: # can move
P[p] = (y,x)
else: # occupied, invalidate move for all
P[p] = None
moved = { v for k,v in P.items() if v is not None }
newpos = { k for k,v in P.items() if v is not None }
if len(newpos) == 0:
break
if r % 11 == 0:
draw(r)
E = (E - moved) | newpos
dirs.rotate(-1)
# then, $TIME convert -delay 25 -loop 0 pics/* a.gif

52
d23/run.co.py Normal file
View File

@@ -0,0 +1,52 @@
import sys
from typing import Tuple
E = { (y,x) for y,l in enumerate(sys.stdin.read().splitlines())
for x,c in enumerate(l)
if c == '#' }
def dim():
minx = min(x for (_,x) in E)
maxx = max(x for (_,x) in E)
miny = min(y for (y,_) in E)
maxy = max(y for (y,_) in E)
return (maxx-minx+1,maxy-miny+1) # W,H
MARK = (-9999,-9999)
for r in range(int(sys.argv[1])): # rounds
P = dict() # { new_pos: old_pos }
for (y,x) in E: # for each elve
can1 = (y-1,x-1) not in E
can2 = (y-1,x) not in E
can3 = (y-1,x+1) not in E
can4 = (y,x+1) not in E
can5 = (y+1,x+1) not in E
can6 = (y+1,x) not in E
can7 = (y+1,x-1) not in E
can8 = (y,x-1) not in E
canN = can1 and can2 and can3
canS = can5 and can6 and can7
canW = can7 and can8 and can1
canE = can3 and can4 and can5
if all((canN, canS, canW, canE)): # far away
continue
if not any((canN, canS, canW, canE)): # all packed
continue
moves = (((y-1,x),canN), ((y+1,x),canS), ((y,x-1),canW), ((y,x+1),canE))
moves = (moves[(r+0)%4], moves[(r+1)%4], moves[(r+2)%4], moves[(r+3)%4])
p:Tuple[int,int] = next(filter(lambda m: m[1], moves))[0]
#p:Tuple[int,int] = next(filter(lambda m: m[1], (moves[(r+i)%4] for i in (0,1,2,3)) ))[0] # using generator is slower than a tuple in codon ^^
if p not in P: # can move
P[p] = (y,x)
else: # occupied, invalidate move for all
P[p] = MARK
moved = { v for k,v in P.items() if v != MARK }
newpos = { k for k,v in P.items() if v != MARK }
if r+1 == 10:
(W,H) = dim()
print(W, H, W * H - len(E))
if len(newpos) == 0:
(W,H) = dim()
print(f"no move after {r+1}, {W}, {H}")
break
E = (E - moved) | newpos

65
d23/run.py Normal file
View File

@@ -0,0 +1,65 @@
import sys
E = { (y,x) for y,l in enumerate(sys.stdin.read().splitlines())
for x,c in enumerate(l)
if c == '#' }
def can(y,x):
can1 = (y-1,x-1) not in E
can2 = (y-1,x) not in E
can3 = (y-1,x+1) not in E
can4 = (y,x+1) not in E
can5 = (y+1,x+1) not in E
can6 = (y+1,x) not in E
can7 = (y+1,x-1) not in E
can8 = (y,x-1) not in E
return [can1,can2,can3,can4,can5,can6,can7,can8]
def canN(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can1 and can2 and can3:
return (y-1,x)
def canS(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can5 and can6 and can7:
return (y+1,x)
def canW(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can7 and can8 and can1:
return (y,x-1)
def canE(y,x,can1,can2,can3,can4,can5,can6,can7,can8):
if can3 and can4 and can5:
return (y,x+1)
def dim():
minx = min(x for (_,x) in E)
maxx = max(x for (_,x) in E)
miny = min(y for (y,_) in E)
maxy = max(y for (y,_) in E)
return (maxx-minx+1,maxy-miny+1) # W,H
from collections import deque
dirs = deque([canN,canS,canW,canE])
for r in range(int(sys.argv[1])): # rounds
P = dict() # { new_pos: old_pos }
for e in E: # for each elve
(y,x) = e
cans = can(y,x) # compute once instead of four
moves = [ d(y,x,*cans) for d in dirs ]
if all(m is not None for m in moves): # far away
continue
if all(m is None for m in moves): # all packed
continue
p = next(filter(lambda m: m is not None ,moves))
if p not in P: # can move
P[p] = (y,x)
else: # occupied, invalidate move for all
P[p] = None
moved = { v for k,v in P.items() if v is not None }
newpos = { k for k,v in P.items() if v is not None }
if r+1 == 10:
(W,H) = dim()
print(W, H, W * H - len(E))
if len(newpos) == 0:
(W,H) = dim()
print(f"no move after {r+1}, {W}, {H}")
break
E = (E - moved) | newpos
dirs.rotate(-1)

54
d24/run.py Normal file
View File

@@ -0,0 +1,54 @@
import sys
from collections import deque, namedtuple
MOVES = [(0, 1), (0, -1), (1, 0), (-1, 0), (0, 0)]
Blizzards = namedtuple('Blizzards', ['rows', 'cols', 'left', 'right', 'up', 'down'])
def is_free(blizz, r, c, t):
return not any((
(r, (c-t) % blizz.cols) in blizz.right,
(r, (c+t) % blizz.cols) in blizz.left,
((r-t) % blizz.rows, c) in blizz.down,
((r+t) % blizz.rows, c) in blizz.up
))
def parse(data):
lines = [l[1:-1] for l in data.splitlines()[1:-1]] # Cut off walls
rows, cols = len(lines), len(lines[0])
left = frozenset((r, c) for r in range(rows) for c in range(cols) if lines[r][c] == '<')
right = frozenset((r, c) for r in range(rows) for c in range(cols) if lines[r][c] == '>')
up = frozenset((r, c) for r in range(rows) for c in range(cols) if lines[r][c] == '^')
down = frozenset((r, c) for r in range(rows) for c in range(cols) if lines[r][c] == 'v')
return Blizzards(rows, cols, left, right, up, down)
def shortest_path(blizz, start, end, start_time):
visited = set()
q = deque()
while True:
# When do we enter the board? We can enter at any time after the start_time
while not q:
start_time += 1 # Increment first, because it takes one timestep to enter the board
if is_free(blizz, start[0], start[1], start_time):
q.append((start[0], start[1], start_time))
r, c, t = q.popleft()
if (r, c, t) in visited:
continue
visited.add((r, c, t))
if (r, c) == end:
return t + 1
for dr, dc in MOVES:
nr, nc = r + dr, c + dc
if 0 <= nr < blizz.rows and 0 <= nc < blizz.cols and is_free(blizz, nr, nc, t+1):
q.append((nr, nc, t+1))
if __name__ == '__main__':
b = parse(sys.stdin.read())
start = (0, 0)
end = (b.rows-1, b.cols-1)
t1 = shortest_path(b, start, end, 0)
t2 = shortest_path(b, end, start, t1)
t3 = shortest_path(b, start, end, t2)
print(t1)
print(t3)

21
d25/part1.py Normal file
View File

@@ -0,0 +1,21 @@
import sys
def snafu2dec(s:str)->int:
D = {'0': 0, '1':1, '2':2, '-':-1, '=':-2 }
n = 0
for (i,c) in enumerate(reversed(s)):
n += 5**i * D[c]
return n
def dec2snafu(n:int) -> str:
d = "=-012"
l = []
while n>0:
r=(n+2)%5-2
l.append(d[r+2])
n = (n-r) // 5
return "".join(reversed(l))
if __name__ == "__main__":
print(dec2snafu(sum(snafu2dec(l) for l in sys.stdin.read().splitlines())))

193
stats.slk
View File

@@ -2,117 +2,228 @@ ID;PCALCOOO32
C;X1;Y1;K217872
C;X2;Y1;K28530
C;X3;Y1;K246402;EA1+B1
C;X5;Y1;K204702
C;X6;Y1;K8364
C;X7;Y1;K213066;EE1+F1
C;X4;Y1;K0.11578639783768;EB1/C1
C;X6;Y1;K242990
C;X7;Y1;K10457
C;X8;Y1;K253447;EF1+G1
C;X9;Y1;K0.0412591192635936;EG1/H1
C;X10;Y1;K"stock calories"
C;X1;Y2;K194482
C;X2;Y2;K8024
C;X3;Y2;K202506;EA2+B2
C;X5;Y2;K169839
C;X6;Y2;K7521
C;X7;Y2;K177360;EE2+F2
C;X4;Y2;K0.0396235173278816;EB2/C2
C;X6;Y2;K204642
C;X7;Y2;K9507
C;X8;Y2;K214149;EF2+G2
C;X9;Y2;K0.044394323578443;EG2/H2
C;X10;Y2;K"pierre feuille ciseaux"
C;X1;Y3;K137678
C;X2;Y3;K38713
C;X3;Y3;K176391;EA3+B3
C;X5;Y3;K143978
C;X6;Y3;K7051
C;X7;Y3;K151029;EE3+F3
C;X4;Y3;K0.21947264883129;EB3/C3
C;X6;Y3;K177465
C;X7;Y3;K8919
C;X8;Y3;K186384;EF3+G3
C;X9;Y3;K0.047852819984548;EG3/H3
C;X10;Y3;K"elves packages"
C;X1;Y4;K106585
C;X2;Y4;K6568
C;X3;Y4;K113153;EA4+B4
C;X5;Y4;K131242
C;X6;Y4;K2170
C;X7;Y4;K133412;EE4+F4
C;X4;Y4;K0.0580453014944367;EB4/C4
C;X6;Y4;K164350
C;X7;Y4;K2919
C;X8;Y4;K167269;EF4+G4
C;X9;Y4;K0.0174509323305574;EG4/H4
C;X10;Y4;K"pair overlap"
C;X1;Y5;K93739
C;X2;Y5;K4820
C;X3;Y5;K98559;EA5+B5
C;X5;Y5;K109082
C;X6;Y5;K2026
C;X7;Y5;K111108;EE5+F5
C;X4;Y5;K0.0489047169715602;EB5/C5
C;X6;Y5;K141388
C;X7;Y5;K2457
C;X8;Y5;K143845;EF5+G5
C;X9;Y5;K0.0170808856755535;EG5/H5
C;X10;Y5;K"cargo cranes"
C;X1;Y6;K92062
C;X2;Y6;K7157
C;X3;Y6;K99219;EA6+B6
C;X5;Y6;K105272
C;X6;Y6;K966
C;X7;Y6;K106238;EE6+F6
C;X4;Y6;K0.0721333615537347;EB6/C6
C;X6;Y6;K140026
C;X7;Y6;K1287
C;X8;Y6;K141313;EF6+G6
C;X9;Y6;K0.00910744234429953;EG6/H6
C;X10;Y6;K"start-of-packet marker 4,14"
C;X1;Y7;K90753
C;X2;Y7;K2480
C;X3;Y7;K93233;EA7+B7
C;X5;Y7;K65714
C;X6;Y7;K1988
C;X7;Y7;K67702;EE7+F7
C;X4;Y7;K0.0266000235967951;EB7/C7
C;X6;Y7;K101987
C;X7;Y7;K2151
C;X8;Y7;K104138;EF7+G7
C;X9;Y7;K0.0206552843342488;EG7/H7
C;X10;Y7;K"unix dirs"
C;X1;Y8;K70599
C;X2;Y8;K12569
C;X3;Y8;K83168;EA8+B8
C;X5;Y8;K24458
C;X6;Y8;K6391
C;X7;Y8;K30849;EE8+F8
C;X4;Y8;K0.151127837629858;EB8/C8
C;X6;Y8;K96958
C;X7;Y8;K6555
C;X8;Y8;K103513;EF8+G8
C;X9;Y8;K0.0633253794209423;EG8/H8
C;X10;Y8;K"plantation"
C;X1;Y9;K65999
C;X2;Y9;K10759
C;X3;Y9;K76758;EA9+B9
C;X7;Y9;K0;EE9+F9
C;X4;Y9;K0.140167800099012;EB9/C9
C;X6;Y9;K74595
C;X7;Y9;K10205
C;X8;Y9;K84800;EF9+G9
C;X9;Y9;K0.120341981132075;EG9/H9
C;X10;Y9;K"cordes"
C;X1;Y10;K67262
C;X2;Y10;K1897
C;X3;Y10;K69159;EA10+B10
C;X7;Y10;K0;EE10+F10
C;X4;Y10;K0.0274295464075536;EB10/C10
C;X6;Y10;K76812
C;X7;Y10;K4735
C;X8;Y10;K81547;EF10+G10
C;X9;Y10;K0.0580646743595718;EG10/H10
C;X10;Y10;K"écran"
C;X1;Y11;K60349
C;X2;Y11;K338
C;X3;Y11;K60687;EA11+B11
C;X7;Y11;K0;EE11+F11
C;X4;Y11;K0.00556956185014913;EB11/C11
C;X6;Y11;K62101
C;X7;Y11;K8303
C;X8;Y11;K70404;EF11+G11
C;X9;Y11;K0.117933640134083;EG11/H11
C;X10;Y11;K"monkey backpack"
C;X1;Y12;K50948
C;X2;Y12;K2102
C;X3;Y12;K53050;EA12+B12
C;X7;Y12;K0;EE12+F12
C;X4;Y12;K0.0396229971724788;EB12/C12
C;X6;Y12;K52925
C;X7;Y12;K903
C;X8;Y12;K53828;EF12+G12
C;X9;Y12;K0.0167756557925243;EG12/H12
C;X10;Y12;K"montain"
C;X1;Y13;K53038
C;X2;Y13;K929
C;X3;Y13;K53967;EA13+B13
C;X7;Y13;K0;EE13+F13
C;X4;Y13;K0.017214223506958;EB13/C13
C;X6;Y13;K46027
C;X7;Y13;K1048
C;X8;Y13;K47075;EF13+G13
C;X9;Y13;K0.0222623473181094;EG13/H13
C;X10;Y13;K"packet ordering"
C;X1;Y14;K47059
C;X2;Y14;K7170
C;X3;Y14;K54229;EA14+B14
C;X7;Y14;K0;EE14+F14
C;X4;Y14;K0.132217079422449;EB14/C14
C;X6;Y14;K43760
C;X7;Y14;K866
C;X8;Y14;K44626;EF14+G14
C;X9;Y14;K0.0194057276027428;EG14/H14
C;X10;Y14;K"sable"
C;X1;Y15;K39432
C;X2;Y15;K3564
C;X3;Y15;K42996;EA15+B15
C;X7;Y15;K0;EE15+F15
C;X4;Y15;K0.0828914317610941;EB15/C15
C;X6;Y15;K35093
C;X7;Y15;K5328
C;X8;Y15;K40421;EF15+G15
C;X9;Y15;K0.131812671631083;EG15/H15
C;X10;Y15;K"losanges"
C;X1;Y16;K33597
C;X2;Y16;K1709
C;X3;Y16;K35306;EA16+B16
C;X7;Y16;K0;EE16+F16
C;X4;Y16;K0.0484053701920354;EB16/C16
C;X6;Y16;K19647
C;X7;Y16;K5217
C;X8;Y16;K24864;EF16+G16
C;X9;Y16;K0.209821428571429;EG16/H16
C;X10;Y16;K"vanne volcan"
C;X1;Y17;K33586
C;X2;Y17;K1511
C;X3;Y17;K35097;EA17+B17
C;X7;Y17;K0;EE17+F17
C;X4;Y17;K0.0430521127161866;EB17/C17
C;X6;Y17;K18320
C;X7;Y17;K5789
C;X8;Y17;K24109;EF17+G17
C;X9;Y17;K0.240117798332573;EG17/H17
C;X10;Y17;K"tetris"
C;X1;Y18;K25687
C;X2;Y18;K183
C;X3;Y18;K25870;EA18+B18
C;X7;Y18;K0;EE18+F18
C;X4;Y18;K0.00707383069192114;EB18/C18
C;X6;Y18;K22011
C;X7;Y18;K4558
C;X8;Y18;K26569;EF18+G18
C;X9;Y18;K0.171553314012571;EG18/H18
C;X10;Y18;K"lava obsidian"
C;X1;Y19;K17189
C;X2;Y19;K258
C;X3;Y19;K17447;EA19+B19
C;X7;Y19;K0;EE19+F19
C;X4;Y19;K0.0147876425746547;EB19/C19
C;X6;Y19;K14198
C;X7;Y19;K902
C;X8;Y19;K15100;EF19+G19
C;X9;Y19;K0.0597350993377483;EG19/H19
C;X10;Y19;K"geode factory"
C;X1;Y20;K23207
C;X2;Y20;K377
C;X3;Y20;K23584;EA20+B20
C;X7;Y20;K0;EE20+F20
C;X4;Y20;K0.0159854138398915;EB20/C20
C;X6;Y20;K18813
C;X7;Y20;K925
C;X8;Y20;K19738;EF20+G20
C;X9;Y20;K0.0468639173168508;EG20/H20
C;X10;Y20;K"grove positioning system"
C;X1;Y21;K20211
C;X2;Y21;K6492
C;X3;Y21;K26703;EA21+B21
C;X7;Y21;K0;EE21+F21
C;X4;Y21;K0.243118750702168;EB21/C21
C;X6;Y21;K19701
C;X7;Y21;K2823
C;X8;Y21;K22524;EF21+G21
C;X9;Y21;K0.125332978156633;EG21/H21
C;X10;Y21;K"math expr"
C;X1;Y22;K16039
C;X2;Y22;K6058
C;X3;Y22;K22097;EA22+B22
C;X7;Y22;K0;EE22+F22
C;X4;Y22;K0.274154862651039;EB22/C22
C;X6;Y22;K12355
C;X7;Y22;K4803
C;X8;Y22;K17158;EF22+G22
C;X9;Y22;K0.279927730504721;EG22/H22
C;X10;Y22;K"cube"
C;X1;Y23;K13576
C;X2;Y23;K2189
C;X3;Y23;K15765;EA23+B23
C;X7;Y23;K0;EE23+F23
C;X4;Y23;K0.138851887091659;EB23/C23
C;X6;Y23;K15250
C;X7;Y23;K231
C;X8;Y23;K15481;EF23+G23
C;X9;Y23;K0.0149215166978877;EG23/H23
C;X10;Y23;K"éparpillement delfs"
C;X1;Y24;K13103
C;X2;Y24;K132
C;X3;Y24;K13235;EA24+B24
C;X7;Y24;K0;EE24+F24
C;X4;Y24;K0.00997355496788818;EB24/C24
C;X6;Y24;K12944
C;X7;Y24;K190
C;X8;Y24;K13134;EF24+G24
C;X9;Y24;K0.0144662707476778;EG24/H24
C;X10;Y24;K"blizzard"
C;X1;Y25;K11320
C;X2;Y25;K5992
C;X3;Y25;K17312;EA25+B25
C;X7;Y25;K0;EE25+F25
C;X4;Y25;K0.346118299445471;EB25/C25
C;X6;Y25;K9855
C;X7;Y25;K6023
C;X8;Y25;K15878;EF25+G25
C;X9;Y25;K0.37932989041441;EG25/H25
C;X10;Y25;K"base 5 -2"
C;X1;Y27;K2021
C;X6;Y27;K2022
E