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