readme
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
*.egg-info
|
||||
*.pyc
|
||||
/env
|
||||
/__pycache__
|
||||
.env
|
||||
2
Makefile
Normal file
2
Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
n:
|
||||
python3 make_new_day.py && cd "$(\ls -1dt ./*/ | head -n 1)"
|
||||
5
README.md
Normal file
5
README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
This was a fork of Anthony Sottile's excellent [2015 AoC repo](https://github.com/anthonywritescode/aoc2015), which I've repurposed for my own workflow.
|
||||
|
||||
Note that between day06 and day07 I ripped out `support.py`, so only on day07 will it work with the included items.
|
||||
|
||||
These are my submissions to Advent of Code 2022, done in Python. This is the first year I'm trying to do it every day.
|
||||
0
day01/__init__.py
Normal file
0
day01/__init__.py
Normal file
2250
day01/input.txt
Normal file
2250
day01/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
62
day01/part1.py
Normal file
62
day01/part1.py
Normal file
@@ -0,0 +1,62 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str) -> int:
|
||||
n = 0
|
||||
largest = 0
|
||||
curr = 0
|
||||
for c in s.split('\n'):
|
||||
if c.strip() == "":
|
||||
if curr > largest:
|
||||
largest = curr
|
||||
curr = 0
|
||||
else:
|
||||
curr += int(c)
|
||||
return largest
|
||||
|
||||
|
||||
INPUT_S = '''\
|
||||
1000
|
||||
|
||||
2000
|
||||
|
||||
5000
|
||||
|
||||
1000
|
||||
4001
|
||||
'''
|
||||
EXPECTED = 5001
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
(INPUT_S, EXPECTED),
|
||||
),
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
61
day01/part2.py
Normal file
61
day01/part2.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str) -> int:
|
||||
elves_totals = []
|
||||
curr = 0
|
||||
for c in s.split('\n'):
|
||||
if c.strip() == "":
|
||||
elves_totals.append(curr)
|
||||
curr = 0
|
||||
else:
|
||||
curr += int(c)
|
||||
sor = sorted(elves_totals)
|
||||
return sor[-3] + sor[-2] + sor[-1]
|
||||
|
||||
|
||||
INPUT_S = '''\
|
||||
1000
|
||||
|
||||
2000
|
||||
|
||||
5000
|
||||
|
||||
1000
|
||||
4001
|
||||
'''
|
||||
EXPECTED = 5001
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
(INPUT_S, EXPECTED),
|
||||
),
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
4
day02/Makefile
Normal file
4
day02/Makefile
Normal file
@@ -0,0 +1,4 @@
|
||||
s1:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part1.py input.txt | aoc-submit --part 1
|
||||
s2:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part2.py input.txt | aoc-submit --part 2
|
||||
0
day02/__init__.py
Normal file
0
day02/__init__.py
Normal file
2500
day02/input.txt
Normal file
2500
day02/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
79
day02/part1.py
Normal file
79
day02/part1.py
Normal file
@@ -0,0 +1,79 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str) -> int:
|
||||
"""
|
||||
A for Rock, B for Paper, and C for Scissors. The second column--" Suddenly, the Elf is called away to help with someone's tent.
|
||||
|
||||
The second column, you reason, must be what you should play in response: X for Rock, Y for Paper, and Z for Scissors.
|
||||
|
||||
The score for a single round is the score for the shape you selected (1 for Rock, 2 for Paper, and 3 for Scissors) plus the score for the outcome of the round (0 if you lost, 3 if the round was a draw, and 6 if you won).
|
||||
"""
|
||||
score = 0
|
||||
me_lu = {"X": 1, "Y": 2, "Z": 3}
|
||||
lu = {"A": 1, "B": 2, "C": 3}
|
||||
# 2 > 1
|
||||
# 3 > 2
|
||||
# 1 > 3
|
||||
for line in s.split('\n'):
|
||||
if line.strip() == "":
|
||||
continue
|
||||
elf, _, me = line
|
||||
score += me_lu[me]
|
||||
if me_lu[me] == lu[elf]:
|
||||
score += 3
|
||||
if me_lu[me] == 1 and lu[elf] == 3:
|
||||
score += 6
|
||||
elif me_lu[me] == 3 and lu[elf] == 1:
|
||||
score += 0
|
||||
elif me_lu[me] > lu[elf]:
|
||||
score += 6
|
||||
|
||||
return score
|
||||
|
||||
|
||||
INPUT_S = '''\
|
||||
1000
|
||||
|
||||
2000
|
||||
|
||||
5000
|
||||
|
||||
1000
|
||||
4001
|
||||
'''
|
||||
EXPECTED = 5001
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
(INPUT_S, EXPECTED),
|
||||
),
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
82
day02/part2.py
Normal file
82
day02/part2.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str) -> int:
|
||||
"""
|
||||
A for Rock, B for Paper, and C for Scissors. The second column--" Suddenly, the Elf is called away to help with someone's tent.
|
||||
|
||||
The second column, you reason, must be what you should play in response: X for Rock, Y for Paper, and Z for Scissors.
|
||||
|
||||
The score for a single round is the score for the shape you selected (1 for Rock, 2 for Paper, and 3 for Scissors) plus the score for the outcome of the round (0 if you lost, 3 if the round was a draw, and 6 if you won).
|
||||
"""
|
||||
score = 0
|
||||
me_lu = {"X": "lose", "Y": "draw", "Z": "win"}
|
||||
lu = {"A": 1, "B": 2, "C": 3}
|
||||
# 2 > 1
|
||||
# 3 > 2
|
||||
# 1 > 3
|
||||
for line in s.split('\n'):
|
||||
if line.strip() == "":
|
||||
continue
|
||||
elf, _, me = line
|
||||
goal = me_lu[me]
|
||||
if goal == "draw":
|
||||
score += lu[elf] + 3
|
||||
elif goal == "lose":
|
||||
if lu[elf] == 1:
|
||||
score += 3
|
||||
else:
|
||||
score += lu[elf] - 1
|
||||
else:
|
||||
if lu[elf] == 3:
|
||||
score += 6 + 1
|
||||
else:
|
||||
score += 6 + lu[elf] + 1
|
||||
return score
|
||||
|
||||
|
||||
INPUT_S = '''\
|
||||
1000
|
||||
|
||||
2000
|
||||
|
||||
5000
|
||||
|
||||
1000
|
||||
4001
|
||||
'''
|
||||
EXPECTED = 5001
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
(INPUT_S, EXPECTED),
|
||||
),
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
6
day03/Makefile
Normal file
6
day03/Makefile
Normal file
@@ -0,0 +1,6 @@
|
||||
s1:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part1.py input.txt | aoc-submit --part 1
|
||||
s2:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part2.py input.txt | aoc-submit --part 2
|
||||
d:
|
||||
aoc-download-input
|
||||
0
day03/__init__.py
Normal file
0
day03/__init__.py
Normal file
300
day03/input.txt
Normal file
300
day03/input.txt
Normal file
@@ -0,0 +1,300 @@
|
||||
PcPlnShmrLmBnmcwBhrmcmbHNGFGpwdFFwGNjNbGqNHH
|
||||
tzQfRJfWZZztWzVtCTfRzFZjpFjNZjGLHbdHLDdjpb
|
||||
CCQTzRLzvQVVfRzJfMPsnBlglgPmBgPmvSrl
|
||||
RMfvbbszHTsssFPzDQPggpQJPQ
|
||||
NSNcqVtLVGgDlpQBClVB
|
||||
hmStGNNLhjNrpWLGSjWrZssbZTMMvTfMnThbRRTs
|
||||
fTrTPGTbfftWBBmLjrJL
|
||||
DqHwVMqVplDslmlZmpHVwNnShWZFdBBdjWBtWtdtWJSSLS
|
||||
MNslpDvVHlwsmpQRgQgCfTTcvcRQ
|
||||
pBBhRgDsMsswprBhvgRglZtFGFFRqZtZmRtNqtZPPN
|
||||
TdmmzzmdZdqdGFtF
|
||||
nmSccCVmSCpDCswMwl
|
||||
NptqDsQtDTQzCvlzCpRlRp
|
||||
jmZcndmjbZcjrmDvFMFFlwCvzFnF
|
||||
jjgLVLrGcdDBNhWQTgHg
|
||||
mLVhhfSMSTmMwClHGdpjDHjGdV
|
||||
zPrZgJCgbsnrPtZzsCsbpRDjBRHnjGDRldRHppcG
|
||||
JJrbsFrZqrgWbbqbrgWzJPNTwhTNCmmvfWCShhhmwwfm
|
||||
ftgfljvgfgBTNvtggFDDGLGRDnMDzcQzncGt
|
||||
VdbpbVdZwdwrsVVLRrMrDLDBGnBGcM
|
||||
wmpWwWsHWBCCCPPvjvmSqlfTTmSNgN
|
||||
jSqmzmmSSDRjLMLDwqjNcMMLTTflffWCCsRsTHnHVrfHWTsr
|
||||
tdbgZpgBPdgGZGGFTHVpCsCVfVsJpnWl
|
||||
FnPQFvbvhFFFbvBwScjhzcqSLLSzSN
|
||||
bWdgrWwwFWbgzFWzrmNbdPqttChMSRnmqSPSnqtMRM
|
||||
lcPJLDDPPfpMBCRJBtQtMh
|
||||
lGDGjTGLLDHPPGjlPTsswsbHNFsNrFNFsrzr
|
||||
VmtHfVhBLHVtlhphjZMdnQQZZqZmQDdzQQ
|
||||
CPFwPWrvWgrfNgFPCMqZzMDDbznFTqqzDQ
|
||||
NNPsfffPCsBLjpVltV
|
||||
ssdBBJqJhlTJLsjTJqFFmnmmnnrcmpprmmmPcRlf
|
||||
gqtqzSgWQWqmnRPPcNmmQM
|
||||
GqbSVtGzvgvgWbZjjBhTdhBsTZBJBZ
|
||||
jhNBsPDzLjsVhLSNzgvcvbcwbBWFcgtWCc
|
||||
ZQQTTHHnGpMtnpdHpQJfMgrvWWFqbcWWGgrgwCCwwF
|
||||
nHpmMnQQMmHpRnHRmMJnnTShPzljzjSNmSDhLsNSPtSh
|
||||
GdqnBGFdlqzFnwdSCQZjZLLDZjZRvZLDVvgQ
|
||||
PsptsTcftMfcTfhTghVDvvjnRNjVZnvV
|
||||
WtPfJTfftJcMTrMnpccFwlCSCGFGCbCwJSbqBl
|
||||
GjFLGhjRwFjNSjSdJCBBdQJddbBc
|
||||
MVvMMHRzVtHlvlcQBQJHqdpQqCBC
|
||||
vDgVztvvmrgrVRrMmsrsmZzZnWhGnNhGWTLfnLwTLhLTjngL
|
||||
VljjQJSsrjjrCglsCjsgjVVfDLdZGMdvvGdQMzmvzcDQMc
|
||||
HqPBtcpRWwtHbbFwBHZfmfpDfvffDfMfmGvM
|
||||
PwHNbcwtqFqnwtNNqPNPPWBTThjhhVTCSJTThssVnSlJJV
|
||||
GCccNCrrnCrpnzrnCDPcDDrvHHTBqTPhswqhPTBTTwBhTj
|
||||
VfNmRtZgWWHdBdswdjZv
|
||||
SmtQfgNmVFgVLVLVmrnMpcDLGCGLGDMpCp
|
||||
CrdZdZmPPjrQdRPRDqDLBqBLBSWgWgLDzF
|
||||
sQhTNphsVbhhhMJfhNVGqltVSzSllBzStlzFFFWB
|
||||
hsMpwQhNMZmPmrwHRj
|
||||
cNVpSVRpLHRLsVWWfnfsCshW
|
||||
jvqjTgqZPlJZmbPPfbpswsPb
|
||||
vlqdTZdtJvqdZjgqZrtRpQFtLFRQczHGzt
|
||||
JJQndVQnQgTfNvGf
|
||||
ljpbWbmNbDlGTvggGvZf
|
||||
mpmRbMmmNDFDmScpzCsdzrnJrsCzrrnM
|
||||
tNFtNFFzzjjzjBtVNZVbjZGlpSvTllpWwvnBlWGGBGCC
|
||||
fPdcrrgPHrHMMMWlppGJSPwGSnGv
|
||||
fmrqrhhfhdRddHrhQqQrfnLZjLtNttZjjRtzjFtRNj
|
||||
sphRcpQRhfmnmfpptg
|
||||
WVPlGLlSjCjSlGSHJJWZdmbmfvPmmnftbbgDdt
|
||||
LJjjqVNjlnCTRcRhhsNcFF
|
||||
vwwqttFjwgClRNCCvGNmZZMmJsPJjJpTdMpsZd
|
||||
fBLVHHHrFnhHhnrVSTmfdPdPccTTPsMfsJ
|
||||
QzVWzznzFbWNGNlt
|
||||
vjMddVVmnWpdMndjvhhWfNLpfBsfLLZLBBSqqTZq
|
||||
RFlrzQJPSRGzzzzgBZNsgBZTBflfgf
|
||||
cQFDRHFDDGCJShCnvwVnnhCn
|
||||
hgjlpRRLlPJJhTLJMDnwBndSPBNvMqnN
|
||||
FGWVfZsmCbmVzrvtwCSMtMdnDMCw
|
||||
VsVmVZfVQDmVFrrmzmGrHHTJgJjhHJcllglLQJRL
|
||||
rrTVcTBgsjTffmfWHZTv
|
||||
JLdnDlpGlGSLlpwJpHZfFvRZnWzWrHWqFH
|
||||
wQDpDrdSlSCblCdwdSLlwQGBthPMsghNsVNVtCNNhNPjhs
|
||||
CtCMvNhDMHfDDdffqtDtCflpJlBpvmWWJWwlpwFFvjwB
|
||||
rGSbVGZrSsFJjlmBFZWp
|
||||
rbbQgzVGrFVSPPGqfhftfqztNtqHtt
|
||||
lMGZCGphllZDNshNNmHHND
|
||||
PLwjVwJVsHmRrZZw
|
||||
ffSdzjfZSjtjSjLtLLFFFGqFzznCpCnCBblQ
|
||||
CqRnlzHCRWTlHPTZVQrcQtFsQFTcrQ
|
||||
DfJcdBDBcftQjsrsBtjZ
|
||||
JDfdGhSvNGhNfffGSfRznPvcRWcqCqmlvlcn
|
||||
JPhBBBQCnCJCMhnhMZRrRZgbDgrWrNbglDgR
|
||||
jLtSTwtsShwRNpRWrh
|
||||
FLLSHsjGLGczvfPfJdfhddnHPC
|
||||
BjHBNrWmTjFgJngbJhWd
|
||||
vsGttMDtwCMQCJnqqqFJsggqdg
|
||||
GFtDSwwMpTrzSSfcfm
|
||||
rnWDQvpwWpDDcPjFPPHZjVDZ
|
||||
CTJCRmCJcZZZHCCQ
|
||||
LdlmdQJNpnLWbrfL
|
||||
VdTdcVTZwCRGVGGMVmttlF
|
||||
gnrsbngfgQSpBfpMBBBpSgMNNJbmGmlqGDqDNlFFJlGNFz
|
||||
gprgQhgpMMMPsrRTCdPZwCwZZCRH
|
||||
cHlCVGbbWHWqRNThhcNcmh
|
||||
MwQDzpwdJwpBpPDQvrhShfLTTRLfLdjfNRqS
|
||||
JwMBBrPsPDwQMDPPBPQJwMrvWHFbHHlgbsGnnWHnFnRGlblF
|
||||
PQPjPDjRRQSFLSlgSmLlfh
|
||||
zpLdBddbNCdqGbWJGWpJWWlsFsmmFpwfflFgfHwFhgmh
|
||||
nJLdLVnzqqbjRctcPDQVTP
|
||||
JdztScztPdSWLJLtgMbCjhvlbPRbjbMvCh
|
||||
VZrqfQcFQwGVVFqfrTFTNqhljRHDMvMMGhRDRRHGbDhG
|
||||
NZQNVQQpQmrZFQQFwQQVVZgBszJJgznstnmtcztdBSgs
|
||||
nFHLNJzFbLJGGLMlTTRZbZRhWRTr
|
||||
wVmgBBmtmwlqlWTwTM
|
||||
sdvmgcPsCPPQQSMz
|
||||
SccCqmQmgBmppLQmpSMjjlJzzsNPMDRbPNPlJM
|
||||
VHZvwtZwhZHtdTwrVbNsljlRDlJPDhzsbN
|
||||
dZwftVRftmcgpBCmBf
|
||||
NTTlVlgNSflqbphFFhNbFp
|
||||
wmmLmjwzwbWGLjRmtZZdhZLFtQQLQBFh
|
||||
RvjbMjjvMzMWbDWwvzPjvmWSfVfsTlVVPVgTgPfVsnnnsJ
|
||||
BsBsZHZNdWwsNdrzgCrMMqsjzzMC
|
||||
flfhVWFmLrhQzCCh
|
||||
fVbmFSpnSSmtnPZvdWbwvdvdHZ
|
||||
NsZWWWWLsBZPhfsLmPhcFCCHCMMrqfqcvHMfHH
|
||||
nThSllnplGlMpvFRcCqrrr
|
||||
DnTwSztgzlDnVGTwztmdZhmLdJdNDshBdsWs
|
||||
RBBGTFZGglMHvrtcgSdnNgjg
|
||||
DmVcbmbJmwJDJzVVwzJfmfstnztvjnNjvNSpdptvzCnpjj
|
||||
DsLcfLmbhVQssQJQscWRPBZZMMRLHFHZBGMG
|
||||
FVvhVnhFnFhmvFhVcMBHLgcPClrqqrtqCppldrRRTppldg
|
||||
QLWfDNwsQLtlrrCtDdpq
|
||||
sJwZwLsGJWGGwzzWZNbWNLjQHSVhvHSnhcMFcbVmnvcchSBS
|
||||
jTMNMrHBJWWDffRqfDBqfD
|
||||
QmSFphtQqQmVmqVnPnPlpwgfnRnDPl
|
||||
VqFmLFbLhmZhGFGmCmGtZLtJWzWHcJrNrHMccjMscMHzMZ
|
||||
hGPGmbfPzbPfgdMdWGqBGQcqpp
|
||||
nvFTvDrTdNZZlrjnMHHHpBBcppqq
|
||||
rNlZZNLvRdRCRFFwZwhgbmSJPSmPfhfwhS
|
||||
vjdbFWTtFRRvtvZZvdWJWbGjLhCcnrrrNqLNCPqchShNqc
|
||||
QHQVlDsMfmmDMHDBdLdCSLnhNLNNfqCd
|
||||
VQHsMDpHlzMBBwlsmMzmmlVwptvTWdvJdbvJtRTWgGFJJGtR
|
||||
nSScBcnbbFSQVdBFBtWpwtvtPbTZthtTvT
|
||||
pRzHpGjCDGzHGCGsThqqwZwPhCtvhTqZ
|
||||
NzlzjDDpNldBFrlfFQ
|
||||
qJlDlPPWppgppqPlplpfdvgnbMfGbdgCghMdCM
|
||||
QWTWZcSsWbvVvTnhfC
|
||||
tRFLwZrcrWzzlJmtBqlm
|
||||
HMNMvvzzNcmfNmfbhs
|
||||
qVcwCgjCLtWRSLsTPbmPfmTh
|
||||
RtWCJgddWRtCJdWWgdBjwWWwpzMFpHGprcBGFFnGHQZHQGpF
|
||||
gZgBDgDVGDGjmDZRtgjvVvtQdnLrcRcrdfdfCcnlscsJsn
|
||||
WTqzqHqNzpHpwzNhMHNwWPbQCQcCLsnCrLLfcrffNflcNn
|
||||
zHTwwpTPzTTwlFTFzwqzPbwZGgGZZBtmGGvGmBGZVFStFZ
|
||||
znlSSzfzTcmmfcCt
|
||||
PHWWGpqgPShPMwGwqJFTVtwtCVTCmTJcFc
|
||||
qHqqSggLrRLBbvDDdndzRQ
|
||||
WBddBQWZWWQqqQFMWfmrWsJnmVJJNDDVJGsLmHmLDN
|
||||
PTgCjvCCPPPzSZGJVLsVZCHHnH
|
||||
pzwtPTvzTjRTPtwSjPSzRgBbWMBfMwwZfbWrMrZFqFFM
|
||||
BqDwVqdqlDlblQMf
|
||||
ZcCWWcWzvJZjcPjZZZfTHfQJQHThqpMbQQJf
|
||||
LPCcZcczZLgCjvPWgvstjsjmRRBdmGrdGdmSFGnFrtGmqr
|
||||
CBvgQssVzfCBQSgvvvfmrlGrCtMGwthJlJtbrh
|
||||
TpLqLRFpqdRpRTfNPtRmrMMtMlMMmlMJlt
|
||||
PZTjqFFTHZZNZpqcVWzVvgzcWnSWfBDD
|
||||
SVSTpgpVpdNbpcVdfjcNfbcJnqsltcJPvRJqRwQqlQsJls
|
||||
zhWzDLmFHhmrWZmmzHJJQlnswqsvttrstQqs
|
||||
zGtZFGGCmZmGGFhLBWBGGFdgVjgppMTSTgMfCNfVVSdj
|
||||
CzjNJGcnzQJltPHttcPHTP
|
||||
bLVsqLbLmSSVrqmdhVSmsVFFprfrFWrwTTWWWZpFPtlP
|
||||
ssDsMqLqhvmvhdmdvzRCnQgRzzBjgnlNCM
|
||||
TzTLzzSGRlRSjWzlWRzHGTpNhPhJPmdnNPPbhlbPbdhfPh
|
||||
mBCDBVrCqVQvQMBcVcqBrBDsbtJfnZNbJndNNhthZNJfPZPs
|
||||
wMCrqVvBzmzHTGLw
|
||||
NbfwfZPPdVNPdBdQBcmQzrQz
|
||||
nnWqHLWGFMDFDLDjsqnHLsrQGzmJczmQrgJmJGZmQrgJ
|
||||
FFWRsHMHCZCWFwRwphpvlfTTpp
|
||||
PclPlVZvLDNvVZSLSMvvDttmtfzFtzHqtqtzzccCFc
|
||||
jrggQGhjQsTDbrbJjJQqzzCsdtzzFCdHqmBBHz
|
||||
WGDgngwrQggZMNvMWPMRRV
|
||||
wNgpMdMMcdSscccNcLLTbtQJtQJQltJwFtlBlzBt
|
||||
HHGhrLrCvHWHCPhrWDtnBllnQbfQftGnfnBF
|
||||
HvLjWCLHPZvHHHZjjrqVTTZVcppMgNNNNSpS
|
||||
QQrwQmvWQjgTfvBjfffrSDcrqSqDDVLctqqcVd
|
||||
GnHFnGhGplGMlHMNhzBzlLPLVcVNCPDqVNdcqLdqtV
|
||||
GnMGpslMhGsRzzHzGsZFZQJTTmWfBbvfgfgJRfbwbW
|
||||
MRCtSwMhvjCGtvMZDVWpVZJlVccNDlpb
|
||||
gdLQFFwwLfHJWnQlcJJbWc
|
||||
rdqdmqHLTLmsswsFHLFtMPRMCSSRtSjTPMPSCR
|
||||
jmCCnLCLZjZjRjQTLZQhGPGhhzHhDRGRDzwzwh
|
||||
stlJlrlJJcSSfSMMzPfhhGhzpwhpNwhD
|
||||
rbrbBcSlWmdZWjDnTm
|
||||
PNBRNnnqQRNfVfRtVVzgFLLttpSwgzzzmFFF
|
||||
fcWlcbvvCFzLbwLw
|
||||
rlrMrhTJhDcTTfhRNqHRQPQRQNQB
|
||||
TrprpprRVVfpRpVqTVpzDdvmvbbCchhcttqcthSMdd
|
||||
JlnZnFlsMBZnJHlsLsCLbSNtbNhdbbShCScm
|
||||
FlZjjsHHsnQFQwTDzMRRpGRR
|
||||
wHWzwCTTqJhzzvJhWHWhqJWrFsFQrrrFCfFfgjjgjprfsp
|
||||
DBRmZRtZLbnRBGSBmtGSLpjBrrsfrgsTQVrVrrPrgr
|
||||
DLnbcbtLtmNNmbRcGbcGmHzlThNNhqJTHdvqvWlHJh
|
||||
GSNqjRcqflNLnCTTWrWn
|
||||
BmwQtmtJwPwmzMwQtHtVssvrnpWTTnsTTgpVCLCs
|
||||
DBBQHJJrzhzQDDfSljRfhccfcdZf
|
||||
wtgtChCwzqgLzjggqtHtjFHHFcnPfdRDfZZVcPfVZZfGnfdm
|
||||
vBTrRTTWGGmcTDVD
|
||||
SJMbbpWslJblSSNzNsztRChzqRCj
|
||||
gBHHCtVCSHMQlfFTQqCfmq
|
||||
WrpdwjbwbwQGlPqSqblP
|
||||
wWDncWrDDNdWNRjScScjpzvHZtBMZtJsvLVgvzssBsvs
|
||||
VppWpVfmZPBlnmrGBzhttMzMpctLLcChSh
|
||||
FwgLJvRdHcwMzSzjzc
|
||||
QvbgdQLQgDvsqvqRHRDdDQDBWmBGBflnVbZmZmmnBBWrmW
|
||||
SqShwLFCQGpDHCtZCWpW
|
||||
bdHPHjTbJdsMnPHPbdjgtnBlVlBnVgtZpDBpWV
|
||||
bdmPcjbjMNMvvHbTcQRNfRwRwLffwwqwNF
|
||||
zdRHTpQTQHQnpnnQRHTsNNlJSJWmzJmJllNmSG
|
||||
FBbRvLbFRwLqbbVgBVqqLFqJtJNcltsSGmgmGtNtgWmstm
|
||||
FLhhfvvVwvjqfLRBqLVqbwqZQrTTpHMHjdrpnnDPDQCdCrpC
|
||||
JgjzvbJCWgbjgGbJWjRhgNPGHHBMtqBStZZsHMSsBqtD
|
||||
cfQdwQFdQQppnVVnlFLLBsBZMhqPlPMMqBSHDtHM
|
||||
wnQhcnVddmdWgjvjmvRjjJ
|
||||
QpcRtndvsLcVJtRSzWSlWjzSbjjWBv
|
||||
qGZPqCTmGPqgGTCqHgCqZCPFWbbBNBMNBbdBMlWWrbjlMbFl
|
||||
qhHDGhCmPhZHgDmDVQthttRchLwLdwcc
|
||||
srpPMwlMmsrGFGswvDRhRWRDJJJchJ
|
||||
fSgBbCBNnBTTgCNLTCRJhRJVWhTcVVVFFJdR
|
||||
SbBnnLNZCLFQCZjnCnZFjPrzqmlMmmsrpzrlsmtt
|
||||
BBsfDfsBDSWRwlLqmWCpWcllrl
|
||||
nQMgMnnnhdntgMBrCdpNNLNlNqLqLl
|
||||
FnQFHzPQJjJGRBGvfR
|
||||
lRnVRFFlgMCRVwLgFZRnZQHWdcftHdmcJHmmMdzzfz
|
||||
DGBqGQbhhBDbSBpGDBzqdNHJdtmcWdqdmtcm
|
||||
bjbsBvjhSlVsPRgLQl
|
||||
dDLbRdTMRJMbFRzZBfzNSjtNBzBD
|
||||
PmgspqqVrppTVrvrsPhhfQwZBwNjNtNffzqqfwwN
|
||||
mCcmsngrPvpVTssCVsvsPLRRJllGFlnRGbMJMWWlJJ
|
||||
fGlGZHRRbwgPbZRRNCdcSWpncnQtQWlWcWpW
|
||||
JrTLJgVvVLQQvtSvQncQ
|
||||
JrrrmMTBVTmjBMrVjrshmJzgCfzRPCRZPGHfbwNPzbZHNH
|
||||
qqqlDDZzVVnNqHDDFFFNlQpzjrTvsvzTbgJQQggjJp
|
||||
cWPWcCmMfCMWdtPMhMbQQQjGGjpdvjTbjgjr
|
||||
WtMSBCtCwchChMfBWtcPnNVNqZZLDRNqTRnnlwHn
|
||||
mvQQnhBvhmvBmncmZBclTZTQccRFNFFdqFFgVqSRrgFrppNR
|
||||
MjzJPzGPfffMCjVVjfPHLCFRNFStqrdRSdqdNGRqNptq
|
||||
HDJHPjDJLfjbzfwPjCzCWWTwlmQhBnsWBvVsvBvZ
|
||||
RVjcshhscQhrVjhvzjVfDNnzGtftmDHFttFGGf
|
||||
qLcBCCMBJJbTdBDnNtdfnmDG
|
||||
WpZgLLclTclRwgjgsrwsvj
|
||||
shhhltNPcDtlNcNMcsctNtppLZvWWFLTFFZpTZDQgFLT
|
||||
dRgJVzRHbqnLpTWQvLLJfp
|
||||
mCVCdzqHndbqHCrVqRrmbwtNBsmPwNmScPgtPhBclw
|
||||
bDDZMDrFPsrsMcsrbJZJdMMGpSzpSbwRSSRGpCHCGzlhCC
|
||||
BWWNQjBLQVHhlGpSCmwj
|
||||
ffwnNwfgtnNgVVwfNWBWnFsMJTJTcPFJcTFDsrJstJ
|
||||
vQbQLQBpBvbvpHplHNTHWGZDngntZCQGgZhGhtjG
|
||||
rqccPPmcrffRmsmCjVgnrGChChDjgW
|
||||
fqRJsJMSlSzSWTbT
|
||||
brsjjJPJwrJJsrRRlllNQGWQpwppCtfGGtWzGGMQ
|
||||
ncBqqLTDnmLgVDZVnBDmdtVVtMzWWdMCQdpQWdVz
|
||||
hDZgTSSnTzNPNFSFPF
|
||||
VZVJJtWTsfTVVWsJhPWrCjzSBJlHSmjJCRlNSSlz
|
||||
CqMpwccgvvgLnvLbMMRRjBNHzjmGmwNHlmlN
|
||||
gLqqvpCDfVDrTfVW
|
||||
CNMDGNPPNJCGbLnTffsTLT
|
||||
tcBBRlrBdQrtmtWFjjbnrTjjFbjr
|
||||
cTQQhcmvcBRcwDMVDZZPPCJh
|
||||
mBCdgPLgZmLfGmfvGhtRQJWjtjQGQhtN
|
||||
pMwrVwbwHMsqcTWQhQWzggTTWp
|
||||
nnSMwrlrsmSZgvvmDd
|
||||
WNSzpCzNzqzNdmqrRHrrLHFrJH
|
||||
MtPfvnGMPnMcbnRtDHTRFFDrmJRQ
|
||||
PcBsfPPHPGGfcSzZjNjpNZZdCs
|
||||
mDCZVLDhWVSDCRvGtsGgGRHl
|
||||
JjPwPNdcPnjPdcwNltHzzGmgGJzQJJRQ
|
||||
dqfjnNmwmbmWrZMbMrThhB
|
||||
qtBpNZFpBGFNfZNPmZPmQmHrmPPPTz
|
||||
LLwJLvDvlWWLHdwDrVcCRcDVzzVVcV
|
||||
sMMwvgjnMvjvnlsvNFBqfGHFqHGjtSpS
|
||||
MmZZsFgwJTdTMdgmZdZRgFhDHhPQPPnRPhCrHhnnrPDD
|
||||
fBcLlNNpQCDLDJJC
|
||||
jSbWWlWpBpclWlWpNWlVBbWVdgwswFJmFJsGtdMggZFGbZwd
|
||||
CMVQVMLLMFGRCMWQttnqqwQwhqsm
|
||||
pJzlczSpPpPgmsqNhmPGDstq
|
||||
gZgTccZGGpzdpjclGRVMVRFRMFvHRLRdLf
|
||||
FMWMSBtStZqZWQtFtScWWSZmHPVJJVHwwlTgmgbzQwbwTJ
|
||||
jhGLhdjNjsLvLsshzHJPVdVmmbzHzdHJ
|
||||
jvDRNjnDNGRCzjLzZZpqnrFBSccWrMcB
|
||||
zggmthDDghHvtrdgrVWfSBRwTHLWHwsBWw
|
||||
PGGjpCjQnJQGJcJnnQpjFWVSsZWVLRZLBcsWSZBRWS
|
||||
FGQlpnJCbqqGGRCjjnlCqGMtdNmmmvdNmmmzvhbrmgMz
|
||||
TstvBTdgBhqTsdTcPlfCSrNMrNnrCNNSNNgp
|
||||
HwLQwQDZzDjnDbmMhNSnmm
|
||||
FZLVzLLQHRRzwWHjdPlJctlJtlsllhRs
|
||||
fBtPsMDDswHvBmmVdBlSBRcGGnhVhg
|
||||
LWJbrpFqpTLTTjqqNWlhnRGGSnhrcSdlRlsh
|
||||
JWNbbpjJzTbNNNJNJMvmvfZHvzDsHDCsZw
|
||||
LPGnPNLtwGhFFnJPfsqpVVszzpsP
|
||||
TcWdvlrcWddggrDBDDdDMmWzRJqfVQZqmsfZsRQzZfZzQJ
|
||||
TldWrMrDdlDCDdMTcwSLVCSShLNSwHjhGF
|
||||
JGsWWWQsJmPwQWbBPmccbcbqFfMMpFDVCDFVFVCDqqfFwD
|
||||
ZtLnlvLnNtvLndnCmfMVSmVCClfpVp
|
||||
zTzZtjnZNLNmZvdtznntHHZJbBRGBRQWcJGbGsbsJRPQWT
|
||||
MLmlMTPtQtMNlhbqbbqhflBB
|
||||
rcrvjpSvScbRbBvbDBPG
|
||||
ZZJzSHpzPrJzHFmMVMFmHCLNtV
|
||||
60
day03/part1.py
Normal file
60
day03/part1.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
from string import ascii_letters
|
||||
|
||||
|
||||
def compute(s: str) -> int:
|
||||
total_priorities = 0
|
||||
for line in s.split('\n'):
|
||||
print(line)
|
||||
c1, c2 = line[:int(len(line) / 2)], line[int(len(line)/2):]
|
||||
common = None
|
||||
for char in c1:
|
||||
if char in c2:
|
||||
common = char
|
||||
break
|
||||
if common is None:
|
||||
continue
|
||||
total_priorities += ascii_letters.find(common) + 1
|
||||
|
||||
return total_priorities
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
('vJrwpWtwJgWrhcsFMMfFFhFp', ascii_letters.find('p') + 1),
|
||||
('jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL', ascii_letters.find('L') + 1),
|
||||
('PmmdzqPrVvPwwTWBwg', ascii_letters.find('P') + 1),
|
||||
('wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn', ascii_letters.find('v') + 1),
|
||||
('ttgJtRGJQctTZtZT', ascii_letters.find('t') + 1),
|
||||
('CrZsJsPPZsGzwwsLwLmpwMDw', ascii_letters.find('s') + 1),
|
||||
)
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
63
day03/part2.py
Normal file
63
day03/part2.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
from string import ascii_letters
|
||||
|
||||
|
||||
def compute(s: str) -> int:
|
||||
total_priorities = 0
|
||||
lines = s.split('\n')
|
||||
common = None
|
||||
for idx in range(len(lines) + 1):
|
||||
if (idx + 1) % 3 == 0:
|
||||
l1, l2, l3 = lines[idx], lines[idx - 1], lines[idx - 2]
|
||||
else:
|
||||
continue
|
||||
for char in l1:
|
||||
if char in l2 and char in l3:
|
||||
common = char
|
||||
break
|
||||
if common is None:
|
||||
continue
|
||||
total_priorities += ascii_letters.find(common) + 1
|
||||
|
||||
return total_priorities
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
('vJrwpWtwJgWrhcsFMMfFFhFp', 'p'),
|
||||
('jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL', 'L'),
|
||||
('PmmdzqPrVvPwwTWBwg', 'P'),
|
||||
('wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn', 'v'),
|
||||
('ttgJtRGJQctTZtZT', 't'),
|
||||
('CrZsJsPPZsGzwwsLwLmpwMDw', 's'),
|
||||
)
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
10
day04/Makefile
Normal file
10
day04/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
s1:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part1.py input.txt | aoc-submit --part 1
|
||||
s2:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part2.py input.txt | aoc-submit --part 2
|
||||
d:
|
||||
aoc-download-input
|
||||
t1:
|
||||
pytest part1.py
|
||||
t2:
|
||||
pytest part2.py
|
||||
9
day04/README.md
Normal file
9
day04/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
I went for a fast solution in part 1, which in retrospect I regret since the `range` and `in` approach of part2.py is easier to reason about and works for both parts.
|
||||
|
||||
Another regret: I used AoC for testing instead of writing actual tests. This cost me a five-minute timeout after I made too many submissions.
|
||||
|
||||
Something to research: There's probably something in Python builtins or stdlib which can make this one a really fast calculation.
|
||||
|
||||
Some optimizations I added to the Makefile today, it ultimately didn't contribute much performance though:
|
||||
|
||||
`make t1` and `make t2` to run tests for part 1 or 2, respectively.
|
||||
31
day04/TODO.md
Normal file
31
day04/TODO.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# How it Should Work
|
||||
|
||||
```console
|
||||
> today
|
||||
created directory `day04`, we're ready to go!
|
||||
downloaded input
|
||||
opening `day04/part1.py`...
|
||||
> done
|
||||
testing part1.py...
|
||||
sorry, the tests failed with output '...'
|
||||
> done
|
||||
there aren't any tests, submitting to AoC...
|
||||
sorry, but 'you gave an answer too recently...'
|
||||
> done
|
||||
testing part1.py...
|
||||
passed!
|
||||
submitting to AoC
|
||||
sorry, but 'your answer is incorrect.'
|
||||
> done
|
||||
testing part1.py
|
||||
passed!
|
||||
submitting to AoC
|
||||
your answer is correct!
|
||||
copying part1.py to part2.py
|
||||
opening `day04/part2.py`
|
||||
```
|
||||
|
||||
# TODO
|
||||
|
||||
- [ ] possibly scrape the problem too:
|
||||
- [tesseract in browser](https://towardsdatascience.com/image-to-text-ocr-with-tesseract-js-3540b420e0e7)
|
||||
0
day04/__init__.py
Normal file
0
day04/__init__.py
Normal file
1000
day04/input.txt
Normal file
1000
day04/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
78
day04/part1.py
Normal file
78
day04/part1.py
Normal file
@@ -0,0 +1,78 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
from string import ascii_letters
|
||||
|
||||
|
||||
def compute(s: str):
|
||||
counter = 0
|
||||
for line in s.split('\n'):
|
||||
try:
|
||||
first, second = line.split(',')
|
||||
except ValueError:
|
||||
continue
|
||||
start, end = first.split('-')
|
||||
enc_start, enc_end = second.split('-')
|
||||
start, end, enc_start, enc_end = int(start), int(end), int(enc_start), int(enc_end)
|
||||
rg = range(start, end + 1)
|
||||
enc_rg = list(range(enc_start, enc_end + 1))
|
||||
for i in rg:
|
||||
if i in enc_rg:
|
||||
counter += 1
|
||||
break
|
||||
return counter
|
||||
|
||||
def _compute(s: str):
|
||||
"""
|
||||
actual submission, I pasted `compute()` from part2.py to see if it
|
||||
works here, and it does.
|
||||
"""
|
||||
counter = 0
|
||||
for line in s.split('\n'):
|
||||
try:
|
||||
first, second = line.split(',')
|
||||
except ValueError:
|
||||
continue
|
||||
start, end = first.split('-')
|
||||
enc_start, enc_end = second.split('-')
|
||||
start, end, enc_start, enc_end = int(start), int(end), int(enc_start), int(enc_end)
|
||||
if (
|
||||
(start >= enc_start and end <= enc_end)
|
||||
or (enc_start >= start and enc_end <= end)
|
||||
):
|
||||
counter += 1
|
||||
return counter
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
('2-8,3-7', 1),
|
||||
)
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
58
day04/part2.py
Normal file
58
day04/part2.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
from string import ascii_letters
|
||||
|
||||
|
||||
def compute(s: str):
|
||||
counter = 0
|
||||
for line in s.split('\n'):
|
||||
try:
|
||||
first, second = line.split(',')
|
||||
except ValueError:
|
||||
continue
|
||||
start, end = first.split('-')
|
||||
enc_start, enc_end = second.split('-')
|
||||
start, end, enc_start, enc_end = int(start), int(end), int(enc_start), int(enc_end)
|
||||
rg = range(start, end + 1)
|
||||
enc_rg = list(range(enc_start, enc_end + 1))
|
||||
for i in rg:
|
||||
if i in enc_rg:
|
||||
counter += 1
|
||||
break
|
||||
return counter
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(
|
||||
('2-8,3-7', 1),
|
||||
('2-6,4-8\n2-8,3-7', 2),
|
||||
)
|
||||
)
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
10
day05/Makefile
Normal file
10
day05/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
s1:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part1.py input.txt | aoc-submit --part 1
|
||||
s2:
|
||||
/Users/zev/Documents/repos/advent/2015/env/bin/python3.10 part2.py input.txt | aoc-submit --part 2
|
||||
d:
|
||||
aoc-download-input
|
||||
t1:
|
||||
pytest part1.py
|
||||
t2:
|
||||
pytest part2.py
|
||||
9
day05/README.md
Normal file
9
day05/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
I went for a fast solution in part 1, which in retrospect I regret since the `range` and `in` approach of part2.py is easier to reason about and works for both parts.
|
||||
|
||||
Another regret: I used AoC for testing instead of writing actual tests. This cost me a five-minute timeout after I made too many submissions.
|
||||
|
||||
Something to research: There's probably something in Python builtins or stdlib which can make this one a really fast calculation.
|
||||
|
||||
Some optimizations I added to the Makefile today, it ultimately didn't contribute much performance though:
|
||||
|
||||
`make t1` and `make t2` to run tests for part 1 or 2, respectively.
|
||||
31
day05/TODO.md
Normal file
31
day05/TODO.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# How it Should Work
|
||||
|
||||
```console
|
||||
> today
|
||||
created directory `day04`, we're ready to go!
|
||||
downloaded input
|
||||
opening `day04/part1.py`...
|
||||
> done
|
||||
testing part1.py...
|
||||
sorry, the tests failed with output '...'
|
||||
> done
|
||||
there aren't any tests, submitting to AoC...
|
||||
sorry, but 'you gave an answer too recently...'
|
||||
> done
|
||||
testing part1.py...
|
||||
passed!
|
||||
submitting to AoC
|
||||
sorry, but 'your answer is incorrect.'
|
||||
> done
|
||||
testing part1.py
|
||||
passed!
|
||||
submitting to AoC
|
||||
your answer is correct!
|
||||
copying part1.py to part2.py
|
||||
opening `day04/part2.py`
|
||||
```
|
||||
|
||||
# TODO
|
||||
|
||||
- [ ] possibly scrape the problem too:
|
||||
- [tesseract in browser](https://towardsdatascience.com/image-to-text-ocr-with-tesseract-js-3540b420e0e7)
|
||||
0
day05/__init__.py
Normal file
0
day05/__init__.py
Normal file
511
day05/input.txt
Normal file
511
day05/input.txt
Normal file
@@ -0,0 +1,511 @@
|
||||
[J] [B] [W]
|
||||
[T] [W] [F] [R] [Z]
|
||||
[Q] [M] [J] [R] [W] [H]
|
||||
[F] [L] [P] [R] [N] [Z] [G]
|
||||
[F] [M] [S] [Q] [M] [P] [S] [C]
|
||||
[L] [V] [R] [V] [W] [P] [C] [P] [J]
|
||||
[M] [Z] [V] [S] [S] [V] [Q] [H] [M]
|
||||
[W] [B] [H] [F] [L] [F] [J] [V] [B]
|
||||
1 2 3 4 5 6 7 8 9
|
||||
|
||||
move 3 from 5 to 7
|
||||
move 2 from 8 to 9
|
||||
move 4 from 3 to 5
|
||||
move 2 from 1 to 7
|
||||
move 1 from 3 to 6
|
||||
move 2 from 1 to 7
|
||||
move 1 from 8 to 7
|
||||
move 4 from 2 to 8
|
||||
move 10 from 9 to 1
|
||||
move 6 from 6 to 2
|
||||
move 1 from 6 to 7
|
||||
move 9 from 8 to 6
|
||||
move 4 from 2 to 4
|
||||
move 2 from 4 to 1
|
||||
move 6 from 1 to 6
|
||||
move 1 from 3 to 2
|
||||
move 2 from 1 to 4
|
||||
move 2 from 4 to 3
|
||||
move 2 from 1 to 3
|
||||
move 4 from 3 to 1
|
||||
move 15 from 7 to 9
|
||||
move 4 from 5 to 9
|
||||
move 13 from 9 to 4
|
||||
move 10 from 4 to 8
|
||||
move 1 from 7 to 4
|
||||
move 6 from 9 to 5
|
||||
move 11 from 6 to 7
|
||||
move 4 from 5 to 7
|
||||
move 3 from 8 to 7
|
||||
move 4 from 2 to 4
|
||||
move 1 from 5 to 1
|
||||
move 5 from 8 to 4
|
||||
move 1 from 5 to 4
|
||||
move 10 from 7 to 1
|
||||
move 8 from 7 to 9
|
||||
move 12 from 1 to 9
|
||||
move 8 from 9 to 1
|
||||
move 2 from 6 to 9
|
||||
move 2 from 8 to 4
|
||||
move 1 from 6 to 9
|
||||
move 13 from 4 to 2
|
||||
move 13 from 4 to 2
|
||||
move 1 from 6 to 1
|
||||
move 1 from 6 to 4
|
||||
move 1 from 4 to 5
|
||||
move 14 from 1 to 8
|
||||
move 1 from 5 to 4
|
||||
move 13 from 9 to 5
|
||||
move 9 from 8 to 2
|
||||
move 8 from 2 to 1
|
||||
move 5 from 8 to 2
|
||||
move 5 from 1 to 6
|
||||
move 3 from 1 to 3
|
||||
move 1 from 4 to 8
|
||||
move 9 from 5 to 9
|
||||
move 18 from 2 to 8
|
||||
move 3 from 3 to 5
|
||||
move 2 from 6 to 4
|
||||
move 14 from 2 to 7
|
||||
move 1 from 4 to 2
|
||||
move 1 from 6 to 9
|
||||
move 1 from 2 to 5
|
||||
move 1 from 6 to 2
|
||||
move 1 from 4 to 6
|
||||
move 6 from 8 to 1
|
||||
move 2 from 6 to 9
|
||||
move 5 from 5 to 3
|
||||
move 1 from 7 to 8
|
||||
move 10 from 9 to 7
|
||||
move 13 from 8 to 5
|
||||
move 5 from 5 to 2
|
||||
move 6 from 5 to 7
|
||||
move 1 from 8 to 5
|
||||
move 5 from 5 to 9
|
||||
move 5 from 9 to 7
|
||||
move 4 from 3 to 8
|
||||
move 6 from 1 to 6
|
||||
move 4 from 2 to 4
|
||||
move 3 from 7 to 5
|
||||
move 2 from 2 to 9
|
||||
move 1 from 3 to 7
|
||||
move 29 from 7 to 9
|
||||
move 4 from 5 to 2
|
||||
move 5 from 6 to 4
|
||||
move 3 from 7 to 9
|
||||
move 3 from 8 to 6
|
||||
move 1 from 2 to 6
|
||||
move 3 from 2 to 5
|
||||
move 1 from 8 to 4
|
||||
move 1 from 5 to 9
|
||||
move 8 from 4 to 9
|
||||
move 15 from 9 to 2
|
||||
move 1 from 5 to 1
|
||||
move 10 from 9 to 4
|
||||
move 5 from 4 to 5
|
||||
move 5 from 5 to 4
|
||||
move 1 from 1 to 9
|
||||
move 1 from 4 to 3
|
||||
move 8 from 2 to 4
|
||||
move 7 from 2 to 7
|
||||
move 1 from 3 to 8
|
||||
move 1 from 5 to 6
|
||||
move 4 from 7 to 3
|
||||
move 1 from 8 to 2
|
||||
move 7 from 4 to 7
|
||||
move 11 from 9 to 7
|
||||
move 5 from 4 to 2
|
||||
move 3 from 9 to 6
|
||||
move 3 from 3 to 8
|
||||
move 4 from 2 to 4
|
||||
move 5 from 9 to 5
|
||||
move 1 from 2 to 1
|
||||
move 3 from 8 to 5
|
||||
move 2 from 9 to 1
|
||||
move 1 from 2 to 5
|
||||
move 2 from 9 to 6
|
||||
move 3 from 7 to 5
|
||||
move 7 from 4 to 1
|
||||
move 4 from 4 to 9
|
||||
move 3 from 7 to 2
|
||||
move 3 from 1 to 9
|
||||
move 1 from 2 to 3
|
||||
move 2 from 7 to 9
|
||||
move 6 from 5 to 4
|
||||
move 6 from 4 to 3
|
||||
move 5 from 5 to 1
|
||||
move 6 from 7 to 8
|
||||
move 1 from 5 to 1
|
||||
move 2 from 9 to 4
|
||||
move 1 from 4 to 3
|
||||
move 10 from 6 to 4
|
||||
move 2 from 2 to 1
|
||||
move 6 from 4 to 1
|
||||
move 5 from 8 to 3
|
||||
move 1 from 8 to 2
|
||||
move 7 from 3 to 9
|
||||
move 1 from 6 to 9
|
||||
move 2 from 7 to 3
|
||||
move 20 from 1 to 6
|
||||
move 7 from 3 to 8
|
||||
move 2 from 9 to 6
|
||||
move 1 from 2 to 3
|
||||
move 2 from 3 to 6
|
||||
move 1 from 1 to 4
|
||||
move 6 from 4 to 7
|
||||
move 5 from 8 to 3
|
||||
move 22 from 6 to 4
|
||||
move 2 from 9 to 7
|
||||
move 3 from 3 to 4
|
||||
move 6 from 4 to 2
|
||||
move 11 from 9 to 3
|
||||
move 9 from 3 to 7
|
||||
move 5 from 4 to 2
|
||||
move 5 from 7 to 2
|
||||
move 5 from 7 to 6
|
||||
move 10 from 2 to 4
|
||||
move 3 from 2 to 1
|
||||
move 1 from 6 to 3
|
||||
move 1 from 1 to 7
|
||||
move 17 from 4 to 1
|
||||
move 1 from 8 to 4
|
||||
move 2 from 7 to 5
|
||||
move 3 from 2 to 5
|
||||
move 3 from 3 to 8
|
||||
move 4 from 5 to 1
|
||||
move 3 from 3 to 7
|
||||
move 1 from 4 to 5
|
||||
move 21 from 1 to 5
|
||||
move 3 from 8 to 3
|
||||
move 4 from 7 to 5
|
||||
move 1 from 1 to 7
|
||||
move 1 from 6 to 3
|
||||
move 4 from 4 to 1
|
||||
move 1 from 8 to 1
|
||||
move 3 from 4 to 9
|
||||
move 5 from 1 to 8
|
||||
move 3 from 9 to 3
|
||||
move 5 from 6 to 1
|
||||
move 5 from 1 to 4
|
||||
move 6 from 3 to 2
|
||||
move 1 from 3 to 2
|
||||
move 3 from 8 to 1
|
||||
move 7 from 2 to 1
|
||||
move 10 from 5 to 2
|
||||
move 12 from 5 to 7
|
||||
move 2 from 8 to 3
|
||||
move 5 from 5 to 8
|
||||
move 8 from 1 to 6
|
||||
move 5 from 4 to 5
|
||||
move 3 from 8 to 6
|
||||
move 1 from 8 to 3
|
||||
move 6 from 6 to 7
|
||||
move 2 from 3 to 8
|
||||
move 3 from 2 to 1
|
||||
move 6 from 2 to 9
|
||||
move 2 from 8 to 4
|
||||
move 1 from 3 to 9
|
||||
move 1 from 8 to 6
|
||||
move 1 from 6 to 9
|
||||
move 7 from 9 to 5
|
||||
move 1 from 9 to 7
|
||||
move 1 from 4 to 6
|
||||
move 2 from 6 to 5
|
||||
move 1 from 4 to 1
|
||||
move 1 from 2 to 7
|
||||
move 5 from 1 to 2
|
||||
move 10 from 7 to 4
|
||||
move 12 from 5 to 7
|
||||
move 6 from 4 to 8
|
||||
move 2 from 5 to 6
|
||||
move 1 from 8 to 9
|
||||
move 1 from 9 to 5
|
||||
move 30 from 7 to 9
|
||||
move 4 from 8 to 4
|
||||
move 1 from 8 to 7
|
||||
move 2 from 1 to 4
|
||||
move 6 from 6 to 3
|
||||
move 1 from 4 to 1
|
||||
move 1 from 1 to 2
|
||||
move 8 from 4 to 8
|
||||
move 1 from 4 to 5
|
||||
move 2 from 5 to 6
|
||||
move 2 from 9 to 8
|
||||
move 3 from 2 to 1
|
||||
move 4 from 3 to 2
|
||||
move 1 from 6 to 4
|
||||
move 1 from 7 to 1
|
||||
move 2 from 8 to 2
|
||||
move 1 from 9 to 2
|
||||
move 2 from 3 to 2
|
||||
move 1 from 4 to 2
|
||||
move 4 from 9 to 6
|
||||
move 3 from 6 to 4
|
||||
move 21 from 9 to 8
|
||||
move 13 from 2 to 7
|
||||
move 9 from 8 to 5
|
||||
move 3 from 1 to 4
|
||||
move 14 from 7 to 2
|
||||
move 5 from 8 to 9
|
||||
move 1 from 1 to 2
|
||||
move 7 from 8 to 6
|
||||
move 2 from 8 to 2
|
||||
move 8 from 6 to 9
|
||||
move 1 from 4 to 5
|
||||
move 5 from 8 to 2
|
||||
move 4 from 5 to 9
|
||||
move 9 from 9 to 6
|
||||
move 2 from 7 to 6
|
||||
move 1 from 8 to 7
|
||||
move 9 from 6 to 4
|
||||
move 1 from 6 to 5
|
||||
move 1 from 7 to 3
|
||||
move 1 from 4 to 7
|
||||
move 1 from 7 to 2
|
||||
move 9 from 2 to 3
|
||||
move 8 from 4 to 1
|
||||
move 8 from 9 to 2
|
||||
move 2 from 6 to 5
|
||||
move 4 from 5 to 2
|
||||
move 2 from 9 to 5
|
||||
move 1 from 4 to 9
|
||||
move 10 from 3 to 7
|
||||
move 1 from 9 to 2
|
||||
move 1 from 5 to 3
|
||||
move 7 from 2 to 8
|
||||
move 7 from 1 to 5
|
||||
move 1 from 1 to 2
|
||||
move 2 from 8 to 2
|
||||
move 1 from 3 to 5
|
||||
move 2 from 8 to 6
|
||||
move 2 from 8 to 9
|
||||
move 2 from 4 to 6
|
||||
move 3 from 2 to 8
|
||||
move 3 from 6 to 7
|
||||
move 7 from 5 to 8
|
||||
move 7 from 2 to 7
|
||||
move 1 from 6 to 8
|
||||
move 5 from 2 to 7
|
||||
move 6 from 8 to 3
|
||||
move 2 from 7 to 1
|
||||
move 7 from 2 to 5
|
||||
move 1 from 3 to 5
|
||||
move 1 from 1 to 5
|
||||
move 2 from 9 to 7
|
||||
move 4 from 3 to 7
|
||||
move 2 from 4 to 6
|
||||
move 1 from 1 to 6
|
||||
move 1 from 2 to 4
|
||||
move 16 from 5 to 6
|
||||
move 1 from 4 to 9
|
||||
move 19 from 6 to 1
|
||||
move 1 from 3 to 5
|
||||
move 1 from 9 to 1
|
||||
move 1 from 8 to 5
|
||||
move 5 from 8 to 3
|
||||
move 5 from 7 to 2
|
||||
move 3 from 2 to 9
|
||||
move 5 from 1 to 7
|
||||
move 2 from 5 to 1
|
||||
move 3 from 9 to 4
|
||||
move 4 from 1 to 9
|
||||
move 2 from 2 to 8
|
||||
move 2 from 8 to 6
|
||||
move 1 from 6 to 9
|
||||
move 4 from 3 to 8
|
||||
move 4 from 8 to 3
|
||||
move 2 from 3 to 8
|
||||
move 1 from 8 to 2
|
||||
move 1 from 9 to 7
|
||||
move 10 from 1 to 7
|
||||
move 26 from 7 to 6
|
||||
move 3 from 9 to 3
|
||||
move 1 from 4 to 6
|
||||
move 2 from 1 to 4
|
||||
move 1 from 1 to 6
|
||||
move 1 from 9 to 3
|
||||
move 1 from 2 to 3
|
||||
move 4 from 4 to 9
|
||||
move 10 from 7 to 8
|
||||
move 3 from 7 to 4
|
||||
move 4 from 9 to 4
|
||||
move 4 from 4 to 7
|
||||
move 4 from 3 to 9
|
||||
move 5 from 7 to 5
|
||||
move 3 from 5 to 1
|
||||
move 3 from 9 to 8
|
||||
move 3 from 1 to 5
|
||||
move 2 from 3 to 5
|
||||
move 7 from 8 to 1
|
||||
move 7 from 8 to 9
|
||||
move 4 from 6 to 3
|
||||
move 3 from 3 to 6
|
||||
move 1 from 3 to 4
|
||||
move 2 from 4 to 1
|
||||
move 1 from 9 to 6
|
||||
move 4 from 1 to 3
|
||||
move 3 from 5 to 1
|
||||
move 1 from 5 to 2
|
||||
move 6 from 1 to 2
|
||||
move 6 from 2 to 7
|
||||
move 2 from 7 to 4
|
||||
move 1 from 2 to 6
|
||||
move 1 from 1 to 4
|
||||
move 3 from 5 to 7
|
||||
move 6 from 7 to 4
|
||||
move 1 from 9 to 3
|
||||
move 1 from 3 to 6
|
||||
move 4 from 4 to 3
|
||||
move 9 from 6 to 1
|
||||
move 10 from 1 to 6
|
||||
move 7 from 4 to 5
|
||||
move 28 from 6 to 4
|
||||
move 3 from 6 to 7
|
||||
move 3 from 3 to 8
|
||||
move 4 from 5 to 7
|
||||
move 1 from 8 to 4
|
||||
move 18 from 4 to 7
|
||||
move 8 from 7 to 6
|
||||
move 6 from 4 to 1
|
||||
move 2 from 5 to 4
|
||||
move 8 from 6 to 1
|
||||
move 2 from 8 to 9
|
||||
move 1 from 5 to 3
|
||||
move 1 from 9 to 1
|
||||
move 5 from 9 to 2
|
||||
move 2 from 9 to 3
|
||||
move 1 from 2 to 5
|
||||
move 2 from 1 to 5
|
||||
move 6 from 7 to 5
|
||||
move 1 from 6 to 4
|
||||
move 6 from 5 to 9
|
||||
move 2 from 4 to 1
|
||||
move 8 from 1 to 8
|
||||
move 4 from 9 to 7
|
||||
move 1 from 5 to 6
|
||||
move 1 from 1 to 6
|
||||
move 2 from 1 to 2
|
||||
move 1 from 9 to 7
|
||||
move 3 from 2 to 4
|
||||
move 2 from 8 to 3
|
||||
move 5 from 8 to 2
|
||||
move 4 from 2 to 5
|
||||
move 1 from 8 to 9
|
||||
move 12 from 3 to 2
|
||||
move 2 from 6 to 2
|
||||
move 12 from 2 to 4
|
||||
move 6 from 2 to 3
|
||||
move 4 from 1 to 9
|
||||
move 8 from 4 to 7
|
||||
move 3 from 3 to 4
|
||||
move 1 from 5 to 4
|
||||
move 5 from 9 to 6
|
||||
move 3 from 5 to 8
|
||||
move 1 from 9 to 1
|
||||
move 2 from 8 to 5
|
||||
move 3 from 5 to 6
|
||||
move 1 from 8 to 4
|
||||
move 4 from 7 to 8
|
||||
move 1 from 1 to 3
|
||||
move 2 from 8 to 3
|
||||
move 7 from 6 to 7
|
||||
move 1 from 3 to 7
|
||||
move 2 from 8 to 6
|
||||
move 22 from 7 to 8
|
||||
move 6 from 4 to 8
|
||||
move 5 from 8 to 6
|
||||
move 5 from 6 to 2
|
||||
move 4 from 2 to 3
|
||||
move 6 from 8 to 5
|
||||
move 4 from 4 to 7
|
||||
move 1 from 3 to 7
|
||||
move 4 from 4 to 5
|
||||
move 1 from 5 to 4
|
||||
move 2 from 6 to 5
|
||||
move 9 from 5 to 6
|
||||
move 10 from 6 to 7
|
||||
move 1 from 2 to 1
|
||||
move 3 from 4 to 8
|
||||
move 16 from 7 to 9
|
||||
move 1 from 7 to 8
|
||||
move 1 from 1 to 8
|
||||
move 1 from 8 to 3
|
||||
move 2 from 7 to 4
|
||||
move 15 from 8 to 1
|
||||
move 1 from 8 to 1
|
||||
move 4 from 8 to 4
|
||||
move 7 from 9 to 7
|
||||
move 3 from 5 to 9
|
||||
move 10 from 9 to 6
|
||||
move 2 from 9 to 2
|
||||
move 7 from 7 to 4
|
||||
move 9 from 3 to 2
|
||||
move 8 from 2 to 7
|
||||
move 1 from 8 to 4
|
||||
move 3 from 2 to 1
|
||||
move 9 from 7 to 1
|
||||
move 9 from 4 to 1
|
||||
move 2 from 7 to 5
|
||||
move 1 from 5 to 4
|
||||
move 1 from 5 to 2
|
||||
move 6 from 1 to 3
|
||||
move 16 from 1 to 2
|
||||
move 9 from 2 to 1
|
||||
move 5 from 6 to 9
|
||||
move 2 from 1 to 9
|
||||
move 1 from 2 to 5
|
||||
move 4 from 4 to 8
|
||||
move 2 from 8 to 2
|
||||
move 2 from 2 to 3
|
||||
move 17 from 1 to 2
|
||||
move 2 from 1 to 9
|
||||
move 13 from 2 to 8
|
||||
move 1 from 2 to 4
|
||||
move 11 from 8 to 3
|
||||
move 3 from 3 to 4
|
||||
move 3 from 9 to 2
|
||||
move 1 from 5 to 2
|
||||
move 1 from 9 to 3
|
||||
move 3 from 4 to 3
|
||||
move 1 from 4 to 9
|
||||
move 3 from 3 to 4
|
||||
move 1 from 8 to 7
|
||||
move 7 from 2 to 9
|
||||
move 3 from 1 to 7
|
||||
move 3 from 2 to 8
|
||||
move 3 from 7 to 9
|
||||
move 10 from 3 to 5
|
||||
move 3 from 6 to 9
|
||||
move 8 from 9 to 4
|
||||
move 1 from 2 to 1
|
||||
move 1 from 7 to 9
|
||||
move 2 from 2 to 3
|
||||
move 4 from 4 to 8
|
||||
move 1 from 6 to 2
|
||||
move 7 from 5 to 3
|
||||
move 1 from 5 to 2
|
||||
move 9 from 8 to 9
|
||||
move 12 from 3 to 8
|
||||
move 1 from 1 to 9
|
||||
move 9 from 8 to 6
|
||||
move 1 from 5 to 7
|
||||
move 1 from 5 to 4
|
||||
move 2 from 2 to 9
|
||||
move 1 from 2 to 6
|
||||
move 2 from 4 to 3
|
||||
move 9 from 4 to 8
|
||||
move 6 from 3 to 6
|
||||
move 12 from 6 to 2
|
||||
move 2 from 6 to 7
|
||||
move 8 from 8 to 3
|
||||
move 5 from 8 to 7
|
||||
move 3 from 6 to 5
|
||||
move 6 from 3 to 7
|
||||
move 6 from 7 to 6
|
||||
move 1 from 4 to 9
|
||||
move 4 from 6 to 5
|
||||
move 20 from 9 to 6
|
||||
move 4 from 9 to 8
|
||||
move 2 from 8 to 7
|
||||
move 4 from 6 to 4
|
||||
move 10 from 6 to 1
|
||||
92
day05/part1.py
Normal file
92
day05/part1.py
Normal file
@@ -0,0 +1,92 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str):
|
||||
_stacks = []
|
||||
for _ in range(9):
|
||||
_stacks.append([])
|
||||
stopped_at_idx = None
|
||||
for i, line in enumerate(s.split('\n')):
|
||||
if not line.strip().startswith("["):
|
||||
stopped_at_idx = i
|
||||
break
|
||||
for idx, char in enumerate(line):
|
||||
if char in "[]":
|
||||
continue
|
||||
elif char != " ":
|
||||
if idx == 1:
|
||||
stack_idx = 0
|
||||
else:
|
||||
stack_idx = ((idx - 1) // 4)
|
||||
_stacks[stack_idx].append(char)
|
||||
stacks = []
|
||||
for st in _stacks:
|
||||
stacks.append(list(reversed(st)))
|
||||
|
||||
if stopped_at_idx is None:
|
||||
raise Exception
|
||||
for line in s.split('\n'):
|
||||
if not line.strip().startswith("move"):
|
||||
print(line)
|
||||
continue
|
||||
match = re.match(r".* ([0-9]+).*([0-9]+).*([0-9]+)", line)
|
||||
quantity, fr, t = match[1], match[2], match[3] # type: ignore
|
||||
print(quantity, fr, t)
|
||||
fr = int(fr) - 1
|
||||
t = int(t) - 1
|
||||
print(stacks[fr], stacks[t])
|
||||
for _ in range(int(quantity)):
|
||||
if not stacks[fr]:
|
||||
break
|
||||
stacks[t].append(stacks[fr].pop())
|
||||
print(stacks[fr], stacks[t])
|
||||
answer = ''
|
||||
for stack in stacks:
|
||||
if stack:
|
||||
answer += stack[-1]
|
||||
else:
|
||||
print('appending a blank')
|
||||
answer += " "
|
||||
return answer
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
((""" [D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2""", "CMZ"),
|
||||
))
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
100
day05/part2.py
Normal file
100
day05/part2.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str):
|
||||
_stacks = []
|
||||
for _ in range(9):
|
||||
_stacks.append([])
|
||||
stopped_at_idx = None
|
||||
for i, line in enumerate(s.split('\n')):
|
||||
if not line.strip().startswith("["):
|
||||
stopped_at_idx = i
|
||||
break
|
||||
for idx, char in enumerate(line):
|
||||
if char in "[]":
|
||||
continue
|
||||
elif char != " ":
|
||||
if idx == 1:
|
||||
stack_idx = 0
|
||||
else:
|
||||
stack_idx = ((idx - 1) // 4)
|
||||
_stacks[stack_idx].append(char)
|
||||
stacks = []
|
||||
for st in _stacks:
|
||||
stacks.append(list(reversed(st)))
|
||||
|
||||
if stopped_at_idx is None:
|
||||
raise Exception
|
||||
for line in s.split('\n'):
|
||||
if not line.strip().startswith("move"):
|
||||
print(line)
|
||||
continue
|
||||
match = re.match(r".* ([0-9]+).*([0-9]+).*([0-9]+)", line)
|
||||
quantity, fr, t = match[1], match[2], match[3] # type: ignore
|
||||
print(quantity, fr, t)
|
||||
fr = int(fr) - 1
|
||||
t = int(t) - 1
|
||||
q = int(quantity)
|
||||
print(stacks[fr], stacks[t])
|
||||
|
||||
if len(stacks[fr]) < q:
|
||||
to_move = stacks[fr]
|
||||
stacks[t] += to_move
|
||||
stacks[fr] = []
|
||||
else:
|
||||
to_move = stacks[fr][-q:]
|
||||
stacks[t] += to_move
|
||||
stacks[fr] = stacks[fr][:-q]
|
||||
|
||||
print(stacks[fr], stacks[t])
|
||||
answer = ''
|
||||
for stack in stacks:
|
||||
if stack:
|
||||
answer += stack[-1]
|
||||
else:
|
||||
print('appending a blank')
|
||||
answer += " "
|
||||
print('answer:', answer)
|
||||
return answer
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
((""" [D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3
|
||||
|
||||
move 1 from 2 to 1
|
||||
move 3 from 1 to 3
|
||||
move 2 from 2 to 1
|
||||
move 1 from 1 to 2""", "CMZ"),
|
||||
))
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
10
day06/Makefile
Normal file
10
day06/Makefile
Normal file
@@ -0,0 +1,10 @@
|
||||
s1:
|
||||
python3 part1.py submit
|
||||
s2:
|
||||
python3 part2.py submit
|
||||
d:
|
||||
python3 part1.py get_input
|
||||
t1:
|
||||
pytest part1.py
|
||||
t2:
|
||||
pytest part2.py
|
||||
1
day06/input.txt
Normal file
1
day06/input.txt
Normal file
@@ -0,0 +1 @@
|
||||
bhzhtzzsczszsjjjzddfzdfzfjfzfbbnntnzznwzzvfvrrqmrmmdzzfqfhqhsqqpwpgwpppbtbnnstthmhrrsmmvsmmhjmjfmfsfjfnfnjjvcjjszjszjsszbznzbnzndzzmlldsdgdcddmqmfqqlcllbvllztzctzczdzttlmtlthtmhtmhmmszsllvzvdzzzsqzqbqccvfvcffzsfslfsllcglclwlvwvzzdsslggtzzgzdzmzddjljvvztttsgscsstztjztjztzvzwwthtftppnmpmmcpmmjlmjjjsfjsjppgcgwcggzffzwzbbmbrbprpqqpccfncfnffvcffsqqtzqzqwzwvzwwwbjbfbcbfblltnlnhhcthtvvzzfcfgfddlggbbshsggplglqqbrbggsvvzdvvlfvlvpvhhmggbrrnppjfjhffttfpffbdfbfvfqvvtcvvbvnnhbhhglgjgzzghhwrrtntrtwwfdfdmmcmtctftpptllzqllzflfrrgqgvgdvdfdbddprrrgccqvqnnmtmvmffpzzqggfbfnfwwqdqldqqlnqnttnbttrffnmmzwzjjtrjtrtmmqsmqmffqmfqfhhbthbhdhvdhvdvmvdmdhdshsqslldzztvvmzzdcccmbbhfhshrrrpsrrqqmdmmgdmmwdmdjdqqmcmttpgtgwgpwpprbrprhrsrllhsllprlplhppfzpffbhbccwdwbbrpbpvpqqmsspjssmbbmfmrmnrnwwgbwwbpwpjwwhqqgcqcvqccgffzpfftcffqlqjjznnlflhhlcczhzvhzhmzhmhfhnnqznntstwtggqjgjhggsvslltjlttfjjgffjzjwzzqzrrhlhzhbhphmhlmlzmzsmzmccvllgrrpbrbfbjfjttqjttdrdhhggqgddppqgpqgpgtptjptpllwccmwcmcpmcppdrrtstqqczqzvvlsltlddnvdvggcqqblqqsjqjttzhtzzszllqsqfqddqdbqddwqddfzzlczcscfsfpfdpdrpddsggcqchcfcpcssstwstwtggghvhqhzzqssjddwjwbjjsnjnfnwwglwwfnfhnnscsggzgjzzhzmmqfqsqwqrwqqqdtdcttzvvnbngbbcdbdggddnmddgzghhzgghwwbjbttlwlcctlccwwdhhrqrvrjjlglssgttpllwclwwtptwptwtvthtbhbzhbzhhrsrwwwnrwrfwfnwnhhnqqdjqjpqqwdwttzhttcdttvztzltzlzmzddrsdsfdsfftdfffmwffrjrffqrfqfsfqqqgqjggwzzrnnqfnqffdbfbtbbrpbrpbptpwttjmjjzrrhhqppdzdtdjttqwwtddjdzzmgzzhwwwdsdgssprsrgsgbbphhdpdwppnfppdqqwzzpbzzqwqpqsqhqdhqqtwwjnnmvmwvmmwwgjgzjjvcjcvcjcnjcncmmphmmvmwmwpwbbtbffhnhshgssgvgvrrbwbtbddqmqfqvvfqvqdvvdbvdbdcdfdlflmffrwwgmmttrztrrfrqrpqrrzjrjpjdpjprrnhhbhcbbcwwqlwwcssbddfrfjrfjfrjfjvvdmdtdzzlvzlzhzmhmhphchnnfqnffvccfpfbfpfqpprrmttzrzzjzmjmzjmmfvmmrzrqqdllgjlglcchssgllsbllrbrlrjlrrhhfwwsqwsstpssznzcznzqzssvtvtrrqwqvvtssgfsfhssljjnwjnjddjdggclcrrfsfhsstgtdtctfttvvsbvvbtbttcgcssjlslhlpljpppwzwnwdnngmgjjbzznwwdllrrfppshhvdhhldhdbbdbjbdjjrnjjzhzfhhsqqbqgmsbvnjsptlrsszlqfmgprvscphmqztbgtlrqvcgdzcptcqjncrdtfqnghnbmwwmcjgtjlbvqqzslgbbntrdfnvfjvfgcgngndjcspgwmpnsrqzzvzljbzlzzrwflrqqqmhsvqwbmdftnhwwzgqrlhddbbtwvbphljmstcjzvpjqwcnhlvpqvqdgvntgqzqwrlwbwvngwtqgrhznlzcvbwqmwncccjctrdzrmzjsvrmcfpjjcczhbvdfwhqvczggfmrspvprvvthvtqnsphpcsdmbrtbdqljvssdrhwjsrrlzprstpgqcbpmnpdgzgjttwcfrgjnsghmszlclgvmlsjrqfvflbnhwwphtvrnrbhdvdglcvgpzfsjpwwhtlvvdzthsrldfzhnlrblzsjjnwclqsqzgdbflhvpwcrtfbfbjcjttbjpvfgvfcswnqqwshbmqlscdzzwshfqwsvwnwzltbnrmzzhzvtwpzqcgwshpvzgtcmwrtrwctnpzbznnwqphnrgwljtrcwlqmvlndwrdrctztnmswslqmbjcmtlrmcpjvzccqszrnflqnqzttbhqlrhbmqdpscqvfgtdbnwjdcljwcbgbgjfzgrgpwqzqgbnrtpntfthhdbqmswvhnmwmszpghgjjzrbnbbfjblpstdfslmmmqfdcrhblqjqfphnldrvvfpnfrcvprjnqbzbspfpjtgqhnjbhnrwzcjvdbshhqpgrmzqpmjfmqwqvvdbddbsldwzzsrhnhsjjnvljrbwcnjrnjpmrrvfthftgptgtlpbgqffthflgftwcrqcqwqwrmrcmfrcqgmrnqjbscdcgrqlhjzthvzdgjbvpswflqcgsnlmgmvcsttsgmnqdtvwdvrndvfdcvrcwmqlmlhtrvthsndsrmnsfmdmfnpfmfhzjqmtcjzcrnsjdztztvgdtlrmbdmmstbfgpmmzthcslpvgrpgfljfgqlqhldfwvvvdvbzjtdtppbtrnqwsqztjrsjhtfrgmvsdngvsdzjgpwrldqpzdpvhljzpjvttwltdwcrhcbrgrvdrmpwvdwjchqsjfprbgtjtzggvgrgmlvvwqrjfprbbgjjqrtdfnrdffwbswbvqtqtfsrhsgrjhftqldhmcnmsnfflmdrzqdjmbqqgqsttdmtrrvfsjnccnhcpcvqtrzdjzrpwswmjvvgsgwvnmdgqwlctrlhqnsmczbwsjhmtgvdcgsndzlstcwchcztqqbtdwfvlljdvdlzljslgnzpmqvzfcvqhdzvgchffqgfwrnmwqzwgbzblpmvddlvnhglrhdnwzqwztzgjczjpwcjwmpnrnrhncfjfggrbphrjztwtfqmfjlwfhnqfftfghbnvtwgtmdzzrdrtmfrwhrrbhzmcllsgqzwzzqtgdggvzptvtdcpzmtmsfcfbjtzlbdrwhdbtdhhrgggmddnzsvjwgcdcqfppqwphfvlhmgqsznlhmgpnjvcvrwwppnphchgsrhjwjcpjggsrcwrvnllfgrmjltfzwhmbqwpwwzmrtlqcprrqztcgnghcbvzrbfptjmhtdcfhhffdbrswqpnpppnpqwtflrrmqgjzctmmvvvwzllbsfdvpqjtmvpjcpmjztscsgbdznfgcmtjzdqzwqrsvstnnvddcstzqjtnbsnlptpmbmfqmhppgnjrffqrtchgptbmwlwbwbcqqfngpbwtwdmlmdstmqwcwjtbwbbbhghgptmvhfmvqfvpwqzwnbjdhpwlgjgvprdjbnlzhnllssbpvzfzspwsscfpqtpdvtzvqncfrfrgddsdglqvpblmpcczlqfdmwzmgvrljhqtcglcvfhbdwhbttqqrjbqwhsrhrbjwmtqwqddvdggdwfsmnpbpvvgsqnvvrqntwmbzdnqpmmqtbnlsbmslpfmqjtgvbddhwvlvjtlrhqdpfnjwtbhwjwdrpgctbbrdqvbbnvgqwngrhqfvwzmlqtmhfqphnmczlbdpnbmpvwrsjbcnjnvcfgnsvlhpzdgdzgvfbgwdcrswznrggnghzssdwqvvlwftqhbnwdvghhvjlqqmcnqmvbwhrrnsswlwmwbsmpcpdzzgmcmqnzpvjpzqbwcsgdhqtqhcpbtqftvscmntsbdcbrndvlfhprpblzbjcpqhfljtvnvtgvrcgqbsgl
|
||||
165
day06/part1.py
Normal file
165
day06/part1.py
Normal file
@@ -0,0 +1,165 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import deque
|
||||
import os.path
|
||||
import pathlib as pl
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import typing as t
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
import pytest
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str):
|
||||
four_window = deque(maxlen=4)
|
||||
for idx, char in enumerate(s):
|
||||
if char in four_window:
|
||||
four_window.clear()
|
||||
elif len(four_window) == 3:
|
||||
return idx
|
||||
four_window.append(char)
|
||||
raise Exception('no answer')
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(("mjqjpqmgbljsphdztnvjfqwrcgsmlb", 7))
|
||||
)
|
||||
|
||||
#### HELPERS
|
||||
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> None:
|
||||
print(compute(pl.Path("input.txt").read_text()))
|
||||
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def _get_cookie_headers() -> dict[str, str]:
|
||||
with open(os.path.join(HERE, '../.env')) as f:
|
||||
contents = f.read().strip()
|
||||
return {'Cookie': contents}
|
||||
|
||||
|
||||
def get_input(year: int, day: int) -> str:
|
||||
url = f'https://adventofcode.com/{year}/day/{day}/input'
|
||||
req = urllib.request.Request(url, headers=_get_cookie_headers())
|
||||
return urllib.request.urlopen(req).read().decode()
|
||||
|
||||
|
||||
def get_year_day() -> tuple[int, int]:
|
||||
cwd = os.getcwd() # type: ignore
|
||||
day_s = os.path.basename(cwd)
|
||||
year_s = os.path.basename(os.path.dirname(cwd))
|
||||
|
||||
if not day_s.startswith('day') or not year_s.startswith('20'):
|
||||
raise AssertionError(f'unexpected working dir: {cwd}')
|
||||
|
||||
return int(year_s), int(day_s[len('day'):])
|
||||
|
||||
|
||||
def download_input() -> int:
|
||||
year, day = get_year_day()
|
||||
|
||||
for _ in range(5):
|
||||
try:
|
||||
s = get_input(year, day)
|
||||
except urllib.error.URLError as e:
|
||||
print(f'zzz: not ready yet: {e}')
|
||||
time.sleep(1)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise SystemExit('timed out after attempting many times')
|
||||
|
||||
with open('input.txt', 'w') as f:
|
||||
f.write(s)
|
||||
inputs = s
|
||||
if '\n' in inputs.strip():
|
||||
print('splitting')
|
||||
inputs = inputs.split('\n')
|
||||
print(inputs[0])
|
||||
if inputs[0].isnumeric():
|
||||
print('ints')
|
||||
inputs = list(map(int, inputs))
|
||||
inputs = str(inputs).replace("'", '"')
|
||||
|
||||
lines = s.splitlines()
|
||||
if len(lines) > 10:
|
||||
for line in lines[:10]:
|
||||
print(line)
|
||||
print('...')
|
||||
else:
|
||||
print(lines[0][:80])
|
||||
print('...')
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
TOO_QUICK = re.compile('You gave an answer too recently.*to wait.')
|
||||
WRONG = re.compile(r"That's not the right answer.*?\.")
|
||||
RIGHT = "That's the right answer!"
|
||||
ALREADY_DONE = re.compile(r"You don't seem to be solving.*\?")
|
||||
|
||||
|
||||
def _post_answer(year: int, day: int, part: int, answer: int) -> str:
|
||||
params = urllib.parse.urlencode({'level': part, 'answer': answer})
|
||||
req = urllib.request.Request(
|
||||
f'https://adventofcode.com/{year}/day/{day}/answer',
|
||||
method='POST',
|
||||
data=params.encode(),
|
||||
headers=_get_cookie_headers(),
|
||||
)
|
||||
resp = urllib.request.urlopen(req)
|
||||
|
||||
return resp.read().decode()
|
||||
|
||||
|
||||
def submit_solution() -> int:
|
||||
year, day = get_year_day()
|
||||
part = get_part()
|
||||
answer = compute(pl.Path("input.txt").read_text())
|
||||
|
||||
print(f'answer: {answer}')
|
||||
|
||||
contents = _post_answer(year=year, day=day, part=part, answer=answer)
|
||||
|
||||
for error_regex in (WRONG, TOO_QUICK, ALREADY_DONE):
|
||||
error_match = error_regex.search(contents)
|
||||
if error_match:
|
||||
print(f'\033[41m{error_match[0]}\033[m')
|
||||
return 1
|
||||
|
||||
if RIGHT in contents:
|
||||
print(RIGHT)
|
||||
return 0
|
||||
else:
|
||||
# unexpected output?
|
||||
print(contents)
|
||||
return 1
|
||||
|
||||
|
||||
def get_part() -> t.Literal[1, 2]:
|
||||
if __file__.endswith("2.py"):
|
||||
return 2
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.argv[1] == "get_input":
|
||||
print('getting input data...')
|
||||
download_input()
|
||||
elif sys.argv[1] == "submit":
|
||||
submit_solution()
|
||||
raise SystemExit(main())
|
||||
47
day06/part2.py
Normal file
47
day06/part2.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os.path
|
||||
from collections import deque
|
||||
|
||||
import pytest
|
||||
|
||||
import support
|
||||
|
||||
INPUT_TXT = os.path.join(os.path.dirname(__file__), 'input.txt')
|
||||
|
||||
|
||||
def compute(s: str):
|
||||
four_window = deque(maxlen=14)
|
||||
for idx, char in enumerate(s):
|
||||
if char in four_window:
|
||||
four_window.clear()
|
||||
elif len(four_window) == 13:
|
||||
return idx
|
||||
four_window.append(char)
|
||||
raise Exception('no answer')
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('input_s', 'expected'),
|
||||
(("mjqjpqmgbljsphdztnvjfqwrcgsmlb", 7))
|
||||
)
|
||||
|
||||
def test(input_s: str, expected: int) -> None:
|
||||
assert compute(input_s) == expected
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('data_file', nargs='?', default=INPUT_TXT)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.data_file) as f, support.timing():
|
||||
print(compute(f.read()))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
raise SystemExit(main())
|
||||
28
make_new_day.py
Normal file
28
make_new_day.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import pathlib as pl
|
||||
import subprocess as sp
|
||||
|
||||
|
||||
def main():
|
||||
most_recent_day = get_most_recent_day()
|
||||
sp.call(shell=True, args=f"cp -r day{most_recent_day:02} day{most_recent_day + 1:02}")
|
||||
sp.call(shell=True, args=f"rm day{most_recent_day + 1:02}/part2.py")
|
||||
sp.call(shell=True, args=f"cd day{most_recent_day + 1:02}/ && make d")
|
||||
|
||||
|
||||
def get_most_recent_day() -> int:
|
||||
most_recent = None
|
||||
for item in pl.Path().iterdir():
|
||||
if item.is_dir() and not item.name.startswith('.') and not item.name.startswith('_'):
|
||||
day_num_str = item.name.split("day")[-1]
|
||||
if day_num_str.startswith('0'):
|
||||
day_num_str = day_num_str[-1]
|
||||
day_num = int(day_num_str)
|
||||
if most_recent is None or day_num > most_recent:
|
||||
most_recent = day_num
|
||||
if most_recent is None:
|
||||
raise Exception
|
||||
return most_recent
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user