# Advent of Code 2021: Python Solutions

I am not good at solving problems fast but I try to do them with best I could. And here in this blog post, I try to show my solutions of all days in one post. For the Jupyter Notebook, please refer to this repository. The code will be updated once solved but I am preparing headers, code blocks and links before day starts. Also I am not trying to get into any rank.

## Before Solving Day 1

Last year I had hard time reading input data and thus, this year I am using some helper functions. First of them is get_data().

def get_data(day=1):
"""
Returns test and real data in list format.
Raw data should be maintained as:
[test data]
Split From Here
[actual data]
"""
file_name = f"data/day{day}.txt"

with open(file_name) as fp:
data = [d.strip().split("\n") for d in data]
return data
get_data()

I created a folder data in working directory and inside there will be a text files with names as day[current_day].txt. The file will contain the test input in first half and real input in second half. The separator will be a string "Split From Here".

Additionally, to make things faster, I created text files for all days with below code:

for i in range(2, 26):
with open(f"data/day{i}.txt","w") as fp:
fp.writelines("Split From Here")

## Day 1

### Get Data

data,data1 = get_data()
data = list(map(int, data))
data1 = list(map(int, data1))

data

### Part 1

pd = None
res = []
for d in data:
if pd is None:
res.append(None)
else:
if pd>d:
res.append("0")
else:
res.append("1")
pd=d
res.count("1")

The result will be printed out and it is 7 for test data. Changing variable data1 from data in above code will give the answer.

### Part 2

w = []
wsum = []
i = 0
ps = None
for j in range(3, len(data1)+1):
wsum.append(sum(data1[i:j]))
i+=1

pd = None
res1 = []
for d in wsum:
if pd is None:
res1.append(None)
else:
if pd>=d:
res1.append("0")
else:
res1.append("1")
pd=d
res1.count("1")

## Day 2

### Part 1

data,data1 = get_data(day=2)

hs = 0
vs = 0

for d in data:
k,v = d.split()

if k =="forward":
hs+=int(v)
elif k == "down":
vs+=int(v)
elif k=="up":
vs-=int(v)

print(hs*vs)

The test output will be 150 and for real output, should change the variable to data1.

### Part 2

hs = 0
vs = 0
aim = 0

for d in data1:
k,v = d.split()
v = int(v)

if k =="forward":
hs+=v
vs+=aim*v
elif k == "down":
aim+=v
#         vs+=v
elif k=="up":
aim-=v
#         vs-=v

print(hs*vs)

## Day 3

### Part 1

from collections import Counter
import numpy as np

data,data1 = get_data(day=3)

def part1(inp):
cs = len(inp)
dt = [int(d) for dt in inp for d in dt]
dt = np.array(dt).reshape(-1, cs)

print(dt)

counts = [sorted(dict(Counter(dt[:, i])).items(), key=lambda item: item) for i in range(len(dt))]
counts = np.array(counts).reshape(-1,2)

minidx = np.arange(0, len(counts), 2)
maxidx = np.arange(1, len(counts), 2)

minv = int("".join(list(map(str, counts[minidx, 0]))), 2)
maxv = int("".join(list(map(str, counts[maxidx, 0]))), 2)
print(minv, maxv)
print(minv*maxv)
part1(data)

The result of test input is:

[0 0 1 0 0]
9 22
198

All hail to the NumPy.
For real input, should change the variable name data to data1 and call part1.

### Part 2

def o2(dt):
ndt = dt.copy()
#print(len(ndt))

curr_c = 0
while curr_c<len(dt):
print(f"Current Col: {curr_c}")
counts = [sorted(dict(Counter(ndt[:, curr_c])).items(), key=lambda item: item)]
counts = np.array(counts).reshape(-1,2)
if len(counts)>1:
if counts[0, 1]==counts[1, 1]:
ndt = ndt[ndt[:,curr_c]==1]
else:
ndt = ndt[ndt[:,curr_c]==counts]
else:
ndt = ndt[ndt[:,curr_c]==counts]
print(f"Current Col: {curr_c} Rows: {len(ndt)}")
#         print(counts)
#         print(ndt[ndt[:,curr_c]==counts])

curr_c+=1
res = int("".join(list(map(str, ndt))), 2)
print(res)
return res

def co2(dt):
ndt = dt.copy()
#print(len(ndt))

curr_c = 0
while curr_c<len(dt):

counts = [sorted(dict(Counter(ndt[:, curr_c])).items(), key=lambda item: item)]
counts = np.array(counts).reshape(-1,2)
if len(counts)>1:
if counts[0, 1]== counts[1, 1]:
ndt = ndt[ndt[:,curr_c]==0]
else:
ndt = ndt[ndt[:,curr_c]==counts]
else:
ndt = ndt[ndt[:,curr_c]==counts]

#         print(ndt)
print(f"Current Col: {curr_c} Rows: {len(ndt)}")
curr_c+=1
return int("".join(list(map(str, ndt))), 2)

def part2(inp):
cs = len(inp)
dt = [int(d) for dt in inp for d in dt]
dt = np.array(dt).reshape(-1, cs)

print("O2")
o2v = o2(dt)
co2v = co2(dt)
print(o2v, co2v)
print(o2v*co2v)
part2(data)


Code seems little bit messy and we could refactor it but I am too busy to do so :(. The test output will be:

O2
Current Col: 0
Current Col: 0 Rows: 7
Current Col: 1
Current Col: 1 Rows: 4
Current Col: 2
Current Col: 2 Rows: 3
Current Col: 3
Current Col: 3 Rows: 2
Current Col: 4
Current Col: 4 Rows: 1
23
Current Col: 0 Rows: 5
Current Col: 1 Rows: 2
Current Col: 2 Rows: 1
Current Col: 3 Rows: 1
Current Col: 4 Rows: 1
23 10
230 

## Day 4

### Part 1

import numpy as np
data,data1 = get_data(day=4)

def get_blocks(dt):
block = []
num = [int(i) for i in dt.split(",")]
row = []
tdata=[]
blocks = 0
for d in dt[2:]:
if d == "":
tdata.append(block)
block=[]
blocks+=1

else:
block.append([int(i) for i in d.strip().split(" ") if i!=""])
tdata.append(block)
block=[]
blocks+=1
tdata = np.array(tdata).reshape(blocks,-1, 5)
return tdata, num

def get_first_matched(tdata, num):
results = np.zeros_like(tdata).astype(np.bool)
matched = False

for n in num:
for i,block in enumerate(tdata):
results[i] += block==n
# search across row
if (results[i]==[ True,  True,  True,  True,  True]).all(axis=1).any():
print(f"Row Matched Block:{i}")
matched=True
break

# search across cols
if (results[i].T==[ True,  True,  True,  True,  True]).all(axis=1).any():
print(f"Col Matched Block: {i}")
matched=True
break
if matched:
print(f"\nResult Block: {tdata[i]}")
s = (tdata[i]*~results[i]).sum()
print(f"Sum: {s}")
print(f"Last number: {n}")
break

d1,n1 = get_blocks(data1)
get_first_matched(tdata=d1, num=n1)

# d1, n1

### Part 2

def get_last_matched(tdata, num):
results = np.zeros_like(tdata).astype(np.bool)
matched = False
mblocks=[]
all_blocks = list(range(0, len(results)))

for n in num:
for i,block in enumerate(tdata):
results[i] += block==n
# search across row
if (results[i]==[ True,  True,  True,  True,  True]).all(axis=1).any():
print(f"Row Matched Block:{i}")
if i not in mblocks:
mblocks.append(i)
if len(mblocks) == len(all_blocks):
matched=True

# search across cols
if (results[i].T==[ True,  True,  True,  True,  True]).all(axis=1).any():
print(f"Col Matched Block: {i}")
if i not in mblocks:
mblocks.append(i)
if len(mblocks) == len(all_blocks):
matched=True

if matched:
i = mblocks[i]

print(f"\nResult Block: {tdata[i]}")
s = (tdata[i]*~results[i]).sum()
print(f"Sum: {s}")
print(f"Last number: {n}")
break
get_last_matched(tdata=d1, num=n1)

Again, NumPy came to the aid.

## Day 5

[Here is the problem link.](https://adventofcode.com/2021/day/5)

### Part 1

import numpy as np
data,data1 = get_data(day=5)

# get(x1, y1, x2, y2)
coordinates = []
for d in data:
x1, y1, x2, y2 = list(map(int, d.replace(" -> ", ",").split(",")))
coordinates.append((x1, y1, x2, y2))

coordinates = np.array(coordinates)
mxx,mxy = coordinates[[0, 2]].max(), coordinates[[1, 3]].max()

board = np.zeros((mxx*2, mxy*2))

# check only horizontal or vertical line
m1 = coordinates[:, 0]==coordinates[:, 2]
m2 = coordinates[:, 1]==coordinates[:, 3]
m = m1 | m2

for x in range(min(co, co), max(co, co)+1):
for y in range(min(co, co), max(co, co)+1):
board[x, y] += 1
print((board.flatten()>1).sum())    

The output will be 5 for above code where test data was used. Should use data1 for real output.

### Part 2


# diagonal line
m1 = coordinates[:, 0]!=coordinates[:, 2]
m2 = coordinates[:, 1]!=coordinates[:, 3]
m=m1*m2

# add or sub to x1?
dx = int(co>co) or -1
dy = int(co>co) or -1

for dp in range(abs(co-co)+1):
x = co+dx*dp
y = co+dy*dp
board[x,y]+=1

print((board.flatten()>1).sum())    

The output of above code will be 12 for test data.

## Day 6

Today's challenge was easy but tricky one. I found 4th day's challenge to be more tough than today's but still I had hard time finding the right way to loop through all days.

### Part 1

data,data1 = get_data(day=6)
data = [int(d) for d in data.split(",")]
data1 = [int(d) for d in data1.split(",")]

days = {}
total_days = 81
curr_data = data1.copy()
for day in range(1, total_days):
temp_data = []
new_fish = []
for d in curr_data:
if d == 0:
new_fish.append(8)
d=6
else:
d-=1
temp_data.append(d)
temp_data.extend(new_fish)
curr_data = temp_data
print(f"Total Fish: {len(curr_data)}\n")

Total Fish: 388419

It took around 2 seconds to run above code while total_days was 81 but when total_day was 257, it seemed like loop will be going on forever. And total fish keeps increasing by time. I even tried to make things faster by using NumPy but it did not work out. Thus, I used dictionaries to store lifespans of fish. Since it could be one of the 0 to 8, why bother keeping lifes?

### Part 2

from collections import Counter

lifes = dict(Counter(data1))

days = 256
for day in range(1, days+1):
lifes = {l: (0 if lifes.get(l+1) is None else lifes.get(l+1)) for l in range(-1, 8)}
# make all 8s -1 because we create new fish with 8 after it reaches 0
lifes = lifes[-1]
# add new lifes to that are exhausted
lifes += lifes[-1]
# reset exhausted lifes
lifes[-1] = 0

print(sum(lifes.values()))

## Day 7

I found today's solution to be easier than previous day's.

### Part 1

data,data1 = get_data(day=7)

data = [int(d) for d in data.split(",")]
data1 = [int(d) for d in data1.split(",")]

l = len(data1)
f = []

for v in range(l):
f.append((sum([abs(d-v) for d in data1])))
print(min(f))        

#### One Liner Solution

min([sum([abs(d-v) for d in data1]) for v in range(len(data1))])

### Part 2

l = len(data1)
f = []

for v in range(l):
diff = [abs(d-v) for d in data1]
diffs = sum([sum(list(range(dif+1))) for dif in diff])
f.append(diffs)
print(min(f))        

#### One Liner Solution

min([sum([sum(list(range(abs(d-v)+1))) for d in data1]) for v in range(len(data1))])

## Day 8

First part was very easy but for the second part, I took little help from here.

### Solution

def permutation(li: list):
all_ps = set()
psl = np.prod(np.linspace(1,len(li), len(li)).astype(int))

while len(all_ps)!=psl:
curr_ps = np.random.choice(range(len(li)), len(li), replace=False)
curr_ps = "".join([li[i] for i in curr_ps])
return all_ps

all_ps = permutation("abcdefg")

d = {
"abcefg": 0,
"cf": 1,
"acdeg": 2,
"acdfg": 3,
"bcdf": 4,
"abdfg": 5,
"abdefg": 6,
"acf": 7,
"abcdefg": 8,
"abcdfg": 9,
}

cnts = {2:1, 4:4, 3:7, 7:8}

sol1 = 0
sol2 = 0

for row in data1:
signals, output = row.split("|")
signals = [s.strip() for s in signals.strip().split(" ")]
output = [s.strip() for s in output.strip().split(" ")]

for o in output:
l = len(o)
if ls.get(l):

sol1+=1

for pr in all_ps:
to = str.maketrans("abcdefg", pr)
ts = ["".join(sorted(sig.translate(to))) for sig in signals]
top = ["".join(sorted(op.translate(to))) for op in output]

if all(code in d for code in ts):
sol2 += int("".join(str(d[code]) for code in top))
break
sol1, sol2  

Later I knew there is actually a python generator permutation inside itertools.

## Day 9

First part was not much harder to crack but it still took plenty of time. But second part was tricky.

### Part 1

import numpy as np
data,data1 = get_data(day=9)

dl = len(data1)
dt = np.array([int(d) for dt in data1 for d in dt])
dt = dt.reshape(-1, dl)

nums = []
pos = []
dc = len(dt)
dr = len(dt)
for r in range(len(dt)):
for c in range(len(dt)):
if r==0:
if c==0:
if dt[r,c]<dt[r+1, c] and dt[r,c]<dt[r, c+1]:
nums.append(dt[r,c])
pos.append((r,c))
elif c==dc-1:
if dt[r,c]<dt[r+1, c] and dt[r,c]<dt[r, c-1]:
nums.append(dt[r,c])
pos.append((r,c))
else:
if dt[r,c]<dt[r+1, c] and dt[r,c]<dt[r, c+1] and dt[r,c]<dt[r, c-1]:
nums.append(dt[r,c])
pos.append((r,c))
elif r==dr-1:
if c==0:
if dt[r,c]<dt[r-1, c] and dt[r,c]<dt[r, c+1]:
nums.append(dt[r,c])
pos.append((r,c))
elif c==dc-1:
if dt[r,c]<dt[r-1, c] and dt[r,c]<dt[r, c-1]:
nums.append(dt[r,c])
pos.append((r,c))
else:
if dt[r,c]<dt[r-1, c] and dt[r,c]<dt[r, c+1] and dt[r,c]<dt[r, c-1]:
nums.append(dt[r,c])
pos.append((r,c))
else:
if c==0:
if dt[r,c]<dt[r-1, c] and dt[r,c]<dt[r, c+1] and dt[r,c]<dt[r+1, c]:
nums.append(dt[r,c])
pos.append((r,c))
elif c==dc-1:
if dt[r,c]<dt[r-1, c] and dt[r,c]<dt[r, c-1] and dt[r,c]<dt[r+1, c]:
nums.append(dt[r,c])
pos.append((r,c))
else:
if dt[r,c]<dt[r-1, c] and dt[r,c]<dt[r, c+1] and dt[r,c]<dt[r, c-1] and dt[r,c]<dt[r+1, c]:
nums.append(dt[r,c])
pos.append((r,c))

nums

### Part 2

I thought I had to use some sort of Searching algorithm like DFS or BFS but I found a solution on StackOverflow using NumPy.

from scipy import ndimage

label, num_label = ndimage.label(dt < 9)
size = np.bincount(label.ravel())

top3 = sorted(size[1:], reverse=True)[:3]
print(np.prod(top3))

## Day 10

I forgot the time of the challenge but still managed to make it done. Stack came to the aid.

### Part 1

data,data1=get_data(day=10)

table = {
")": 3,
"]": 57,
"}": 1197,
">": 25137}

pair = {"(":")","{":"}", "[":"]", "<":">"}

corruptions = []
rem = []
for i,r in enumerate(data):
stack = []
is_corr=False
for c in r:
if c in pair:
stack.append(pair[c])
elif stack.pop() != c:
print(f"Corrupted {c} at row {i}")
corruptions.append(c)
is_corr=True
break
if is_corr==False and len(stack)>0:
rem.append(stack)

corr = dict(Counter(corruptions))
sum([table[k]*v for k,v in corr.items()])

### Part 2

mult = {")": 1,
"]": 2,
"}": 3,
">": 4}
all_total=[]
for row in rem:
s = 0
for i,c in enumerate(row):
s+=5**i*mult[c]
all_total.append(s)
at = sorted(all_total)
at[len(at)//2]

## Day 11

Today's challenge was harder than previous day's.

### Solution

adj = [(i,j) for i in range(-1, 2) for j in range(-1,2) if i!=0 or j!=0]
window = {(i,j):darr[i][j] for i in range(10) for j in range(10)}

flashes = 0
i=0
previous = set()

while len(previous)<len(window):
previous = set()
window = {k:v+1 for k, v in window.items()}
while True:
if sum(v>9 for k,v in window.items() if k not in previous)==0:
break

for k,v in window.items():
if k not in previous and v>9:
for ad in [(k+i,k+j) for i,j in adj if (k+i,k+j) in window]:

flashes+=len(previous)
window.update({k:0 for k in previous})
i+=1
if i==100:
print(f"Part 1: {flashes}")

print(f"Part 2: {i}")

## Day 12

Due to work I was unable to solve it on time and thus I had to take help from here.

### Solution

data,data1 = get_data(day=12)

class Solver:
def __init__(self, data):
self.paths = {}
self.data = data
self.visited = set()

self.prepare_paths()
print(self.solve(part="1"))
print(self.solve(part="2"))

def prepare_paths(self):
for d in self.data:
l,r = d.split("-")
if self.paths.get(l):
self.paths[l].append(r)
else:
self.paths[l] = [r]
if self.paths.get(r):
self.paths[r].append(l)
else:
self.paths[r]=[l]

def solve(self, curr_cave="start", part="1"):
if (curr_cave=="end"):
return 1
if curr_cave.islower():

ways_count = sum([self.solve(cave, part) for cave in self.paths[curr_cave] if cave not in self.visited])
ways_count += 0 if part!="2" else sum([self.solve(cave, cave) for cave in self.paths[curr_cave] if cave in self.visited and cave != "start"])

return ways_count

s = Solver(data1)

Search either BFS or DFS comes into the aid.

## Day 13

Today's challenge was fun to do and it was not that hard as well.

### Solution

import numpy as np
data1, data = get_data(day=13)

dots = [list(map(int, f.split(","))) for f in data[:data.index("")]]
folds = data[data.index("")+1:]
folds = [f.split("along ").split("=") for f in folds]
folds = [(f, int(f)) for f in folds]

dots = np.array(dots)
window = np.zeros(dots.max(axis=0)+3)

for c in dots:
window[c, c] = 1
window = window.T

tw = window.copy()
# print(tw)
for f in folds:
print(f)
axis,value=f
cr,cc = tw.shape
print(tw)
if axis=="y":
#fold y axis
chunk = tw[value+1:-2]
# print(value-crs,chunk.shape, chunk)
crs,ccs = chunk.shape
tw[np.abs(value-crs):value] += chunk[::-1]
tw = tw[:value]
tw = np.append(tw, np.zeros((2, tw.shape)), axis=0)
#break

else:
# fold x axis
chunk = tw[:, value+1:-2]
crs,ccs = chunk.shape
print(value-crs,chunk.shape, chunk)
tw[:, abs(value-ccs):value] += chunk[:,::-1]
tw = tw[:, :value]
tw = np.append(tw, np.zeros((tw.shape, 2)), axis=1)
print(f"Dots: {np.sum(tw>0)}")

print(np.array2string(tw>0, separator='',
formatter = {'bool':lambda x: ' █'[x]}))

[[ ██  █  █ ███  ███  ███   ██  █  █ ████   ]
[█  █ █  █ █  █ █  █ █  █ █  █ █  █    █   ]
[█  █ ████ █  █ █  █ █  █ █  █ █  █   █    ]
[████ █  █ ███  ███  ███  ████ █  █  █     ]
[█  █ █  █ █    █ █  █    █  █ █  █ █      ]
[█  █ █  █ █    █  █ █    █  █  ██  ████   ]
[                                          ]
[                                          ]]

## Day 14

They know we could fall into a trap. And again I fell. I went full looping mode and got the result of part 1 but the part 2 could take days.

### Part 1

from collections import Counter
data,data1 = get_data(day=14)

wdata=data1.copy()
polymer = wdata
rule = {v:v for v in [d.split(" -> ") for d in wdata[2:]]}

curr_polymer = polymer
i=0
while i< 10:
tpoly = curr_polymer
#     print(i, tpoly)
ind = 0
for k, c in enumerate(tpoly):
k+=1
ch = curr_polymer[k-1:k+1]

mc = rule.get(ch)
if mc:
tpoly = [c for c in tpoly]
tpoly = "".join(tpoly)
curr_polymer = tpoly
i+=1

res = dict(Counter(curr_polymer))
res = sorted(res.items(), key=lambda x: x, reverse=True)
res-res[-1]

### Part 2

Taken hint from here.

tmp_poly = Counter(a+b for a,b in zip(polymer, polymer[1:]))
print(tmp_poly)
chars = Counter(polymer)

for _ in range(40):
tmp = Counter()
for (c1,c2),value in tmp_poly.items():
mc = rule[c1+c2]
tmp[c1+mc] += value
tmp[mc+c2] += value
chars[mc] += value
tmp_poly=tmp
max(chars.values()) - min(chars.values())

## Day 15

Once I failed DSA in my bachelor's degree and I never really understood Graphs and Path Finding but each year Advent of Code makes me try it once. Instead I used something easier than Dijkastra from scratch. Skimage have a way to find Minimum Cost Path

### Solution

import numpy as np
from skimage import graph

data,data1 = get_data(15)

data = np.array([int(i) for dt in data for i in dt ]).reshape(-1, len(data))
data
data1 = np.array([int(i) for dt in data1 for i in dt ]).reshape(-1, len(data1))

window = data1.copy()

rs,cs = window.shape

cost = graph.MCP(window, fully_connected=False)
cost.find_costs(starts = [(0,0)])

journey = [window[pos] for pos in  cost.traceback((rs-1,cs-1))[1:]]
print(f"Part1: {sum(journey)}")

# 5times bigger
new_window = window.copy()
nrow = np.hstack([new_window, new_window+1, new_window+2, new_window+3, new_window+4])
new_window = np.vstack([nrow,nrow+1,nrow+2,nrow+3,nrow+4])
rs,cs = new_window.shape

new_window%=9
new_window[new_window==0]=9

cost = graph.MCP(new_window, fully_connected=False)
cost.find_costs(starts = [(0,0)])

journey = [new_window[pos] for pos in  cost.traceback((rs-1,cs-1))[1:]]
print(f"Part2: {sum(journey)}")

## Day 16

I was too busy to solve this challenge (but I tried for around 30min) and I did not even want to skip a day so, I had to look over other people's code.
The following code is taken from here. All credit goes to the author of this repository.

### Part 1

data,data1=get_data(day=16)

data = '''38006F45291200'''.splitlines()
data=data1.splitlines()

s = bin(int(data, 16))[2:]
n = len(s)
if n % 4 != 0:
s = '0' * (4 - n % 4) + s
n = len(s)
res = 0
c = 0

while c < n and '1' in s[c:]:
v = int(s[c: c + 3], 2)
res += v
c += 3
t = int(s[c: c + 3], 2)
c += 3

if t == 4:
num = ''
while s[c] == '1':
num += s[c + 1: c + 5]
c += 5
num += s[c + 1: c + 5]
c += 5
num = int(num, 2)
else:
l = int(s[c], 2)
c += 1
if l == 0:
num = int(s[c: c + 15], 2)
c += 15
else:
num = int(s[c: c + 11], 2)
c += 11

print(res)

### Part 2

from functools import reduce

funcDict = {
0: sum,
1: lambda a: reduce(lambda x, y: x * y, a),
2: min,
3: max,
5: lambda a: int(a > a),
6: lambda a: int(a < a),
7: lambda a: int(a == a)
}

def evaluate(u):
if packets[u] == 4:
return packets[u]

res = []
for v in graph[u]:
res.append(evaluate(v))
return funcDict[packets[u]](res)

s = bin(int(data, 16))[2:]
for i in data:
if i != '0':
break
s = '0' * 4 + s
n = len(s)
if n % 4 != 0:
s = '0' * (4 - n % 4) + s
n = len(s)
c = 0
packets = []

while c < n and '1' in s[c:]:
v = int(s[c: c + 3], 2)
c += 3
t = int(s[c: c + 3], 2)
c += 3

if t == 4:
num = ''
while s[c] == '1':
num += s[c + 1: c + 5]
c += 5
num += s[c + 1: c + 5]
c += 5
num = int(num, 2)

packets.append([v, t, num, c])
else:
l = int(s[c], 2)
c += 1
if l == 0:
num = int(s[c: c + 15], 2)
c += 15
else:
num = int(s[c: c + 11], 2)
c += 11

packets.append([v, t, l, num, c])

stack = []
graph = [[] for _ in range(len(packets))]

for i, u in enumerate(packets):
if len(stack) > 0:
p = stack[-1]
graph[p].append(i)
packets[p] -= 1
if packets[p] == 0:
stack.pop()

while len(stack) > 0:
p = stack[-1]
if packets[p] == 0 and packets[p] <= u[-1] - packets[p][-1]:
stack.pop()
else:
break

if u != 4:
stack.append(i)

print(evaluate(0))

Scroll to top