porting over AOC from previous years to a monorepo.
This commit is contained in:
commit
84c4cf9991
194 changed files with 30104 additions and 0 deletions
140
2020/.gitignore
vendored
Normal file
140
2020/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
# ---> Python
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
1
2020/.python-version
Normal file
1
2020/.python-version
Normal file
|
|
@ -0,0 +1 @@
|
|||
3.13
|
||||
3
2020/README.md
Normal file
3
2020/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# advent_of_code_2020
|
||||
|
||||
Python [advent of code](https://adventofcode.com/2020) 2020
|
||||
54
2020/days/01/day1.py
Executable file
54
2020/days/01/day1.py
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
def parse(puzzle_input):
|
||||
"""Parse input"""
|
||||
return [int(string) for string in puzzle_input.splitlines()]
|
||||
|
||||
def part1(data:list[int]):
|
||||
"""Solve part 1"""
|
||||
data.sort()
|
||||
while True:
|
||||
if len(data)<2:
|
||||
raise ValueError('no match found')
|
||||
s = data[0]+data[-1]
|
||||
if s>2020:
|
||||
data.pop(-1)
|
||||
elif s<2020:
|
||||
data.pop(0)
|
||||
else:
|
||||
return data[0]*data[-1]
|
||||
|
||||
def part2(data):
|
||||
"""Solve part 2"""
|
||||
data.sort()
|
||||
while True:
|
||||
if len(data)<3:
|
||||
raise ValueError('no match found')
|
||||
if data[0]+data[1]+data[-1]>2020:
|
||||
data.pop(-1)
|
||||
elif data[0]+data[-1]+data[-2]<2020:
|
||||
data.pop(0)
|
||||
elif data[0]+data[1]+data[-1]==2020:
|
||||
return data[0]*data[1]*data[-1]
|
||||
else:
|
||||
return data[0]*data[-1]*data[-2]
|
||||
|
||||
def solve(puzzle_input):
|
||||
"""Solve the puzzle for the given input"""
|
||||
data = parse(puzzle_input)
|
||||
solution1 = part1(data.copy())
|
||||
solution2 = part2(data.copy())
|
||||
|
||||
return solution1, solution2
|
||||
|
||||
if __name__ == "__main__":
|
||||
for path in sys.argv[1:]:
|
||||
print(f"{path}:")
|
||||
puzzle_input = pathlib.Path(path).read_text().strip()
|
||||
solutions = solve(puzzle_input)
|
||||
print("\n".join(str(solution) for solution in solutions))
|
||||
6
2020/days/01/example1
Normal file
6
2020/days/01/example1
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
1721
|
||||
979
|
||||
366
|
||||
299
|
||||
675
|
||||
1456
|
||||
200
2020/days/01/input
Normal file
200
2020/days/01/input
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
1772
|
||||
1065
|
||||
1827
|
||||
1671
|
||||
1181
|
||||
1915
|
||||
1657
|
||||
1632
|
||||
1053
|
||||
1546
|
||||
1039
|
||||
1388
|
||||
1698
|
||||
1174
|
||||
1275
|
||||
1250
|
||||
1988
|
||||
1078
|
||||
1075
|
||||
1958
|
||||
1617
|
||||
1387
|
||||
1543
|
||||
1965
|
||||
1867
|
||||
1771
|
||||
1755
|
||||
1331
|
||||
1677
|
||||
1935
|
||||
1488
|
||||
911
|
||||
1001
|
||||
1516
|
||||
1949
|
||||
1626
|
||||
1083
|
||||
1402
|
||||
1223
|
||||
1179
|
||||
2001
|
||||
1790
|
||||
1551
|
||||
1117
|
||||
1990
|
||||
1968
|
||||
1532
|
||||
1999
|
||||
1175
|
||||
1126
|
||||
1869
|
||||
1666
|
||||
1753
|
||||
513
|
||||
1349
|
||||
1139
|
||||
1941
|
||||
1823
|
||||
1647
|
||||
1835
|
||||
1943
|
||||
1459
|
||||
1833
|
||||
1398
|
||||
1877
|
||||
1625
|
||||
1749
|
||||
1631
|
||||
1864
|
||||
1826
|
||||
1499
|
||||
1336
|
||||
1264
|
||||
1091
|
||||
1558
|
||||
1321
|
||||
1754
|
||||
1729
|
||||
1585
|
||||
1740
|
||||
1767
|
||||
1774
|
||||
1164
|
||||
1318
|
||||
1930
|
||||
1236
|
||||
1995
|
||||
1611
|
||||
1319
|
||||
1361
|
||||
1119
|
||||
1563
|
||||
1578
|
||||
1047
|
||||
1797
|
||||
1787
|
||||
1038
|
||||
1921
|
||||
1656
|
||||
1898
|
||||
1828
|
||||
1727
|
||||
1825
|
||||
2010
|
||||
536
|
||||
1395
|
||||
1865
|
||||
1882
|
||||
1638
|
||||
1954
|
||||
1565
|
||||
1296
|
||||
1723
|
||||
1187
|
||||
60
|
||||
1130
|
||||
1102
|
||||
1963
|
||||
1048
|
||||
1493
|
||||
1795
|
||||
472
|
||||
1496
|
||||
1278
|
||||
1444
|
||||
1889
|
||||
860
|
||||
1975
|
||||
1961
|
||||
1070
|
||||
1570
|
||||
1495
|
||||
1644
|
||||
1881
|
||||
1293
|
||||
1090
|
||||
1906
|
||||
1385
|
||||
1549
|
||||
1143
|
||||
1195
|
||||
2004
|
||||
1397
|
||||
1032
|
||||
1681
|
||||
2000
|
||||
1574
|
||||
1400
|
||||
1911
|
||||
1868
|
||||
1917
|
||||
1872
|
||||
1696
|
||||
1086
|
||||
1291
|
||||
1761
|
||||
1703
|
||||
1202
|
||||
1486
|
||||
1705
|
||||
1924
|
||||
1186
|
||||
1676
|
||||
1615
|
||||
1951
|
||||
1556
|
||||
1604
|
||||
1534
|
||||
2002
|
||||
1334
|
||||
1109
|
||||
1108
|
||||
1713
|
||||
1422
|
||||
1909
|
||||
1418
|
||||
1592
|
||||
1887
|
||||
1037
|
||||
1568
|
||||
1914
|
||||
1780
|
||||
1929
|
||||
1973
|
||||
1684
|
||||
1581
|
||||
1148
|
||||
1931
|
||||
1619
|
||||
1082
|
||||
1166
|
||||
1913
|
||||
1312
|
||||
1330
|
||||
1540
|
||||
1841
|
||||
1977
|
||||
1769
|
||||
1691
|
||||
1821
|
||||
33
2020/days/01/test_day1.py
Normal file
33
2020/days/01/test_day1.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import pytest
|
||||
import day1 as aoc
|
||||
|
||||
PUZZLE_DIR = pathlib.Path(__file__).parent
|
||||
|
||||
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
|
||||
@pytest.fixture
|
||||
def example1():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.fixture
|
||||
def example2():
|
||||
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_parse_example1(example1):
|
||||
"""Test that input is parsed properly"""
|
||||
assert example1 == [1721, 979, 366, 299, 675, 1456]
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part1_example1(example1):
|
||||
"""Test part 1 on example input"""
|
||||
assert aoc.part1(example1) == 514579
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part2_example2(example1):
|
||||
"""Test part 2 on example input"""
|
||||
assert aoc.part2(example1) == 241861950
|
||||
51
2020/days/02/day2.py
Executable file
51
2020/days/02/day2.py
Executable file
|
|
@ -0,0 +1,51 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class PasswordSpec:
|
||||
first:int
|
||||
second:int
|
||||
letter:str
|
||||
password:str
|
||||
|
||||
def parse(puzzle_input: str):
|
||||
"""Parse input"""
|
||||
regex = re.compile(r'^(\d+)-(\d+) (\w): (\w+)$')
|
||||
toInt = lambda x: PasswordSpec(int(x[0]), int(x[1]), x[2], x[3])
|
||||
return [toInt(regex.match(i).groups()) for i in puzzle_input.splitlines()]
|
||||
|
||||
def part1(data):
|
||||
"""Solve part 1"""
|
||||
test = lambda x: x.first<=x.password.count(x.letter)<=x.second
|
||||
# these two lines are equivilant.
|
||||
# return sum(1 for p in data if test(p))
|
||||
return len([1 for p in data if test(p)])
|
||||
|
||||
def test_password(passwordSpec: PasswordSpec):
|
||||
if passwordSpec.password[passwordSpec.first-1]==passwordSpec.letter:
|
||||
return passwordSpec.password[passwordSpec.second-1]!=passwordSpec.letter
|
||||
else:
|
||||
return passwordSpec.password[passwordSpec.second-1]==passwordSpec.letter
|
||||
|
||||
def part2(data):
|
||||
"""Solve part 2"""
|
||||
return sum(1 for p in data if test_password(p))
|
||||
|
||||
def solve(puzzle_input):
|
||||
"""Solve the puzzle for the given input"""
|
||||
data = parse(puzzle_input)
|
||||
solution1 = part1(data)
|
||||
solution2 = part2(data)
|
||||
|
||||
return solution1, solution2
|
||||
|
||||
if __name__ == "__main__":
|
||||
for path in sys.argv[1:]:
|
||||
print(f"{path}:")
|
||||
puzzle_input = pathlib.Path(path).read_text().strip()
|
||||
solutions = solve(puzzle_input)
|
||||
print("\n".join(str(solution) for solution in solutions))
|
||||
3
2020/days/02/example1
Normal file
3
2020/days/02/example1
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
1-3 a: abcde
|
||||
1-3 b: cdefg
|
||||
2-9 c: ccccccccc
|
||||
1000
2020/days/02/input
Normal file
1000
2020/days/02/input
Normal file
File diff suppressed because it is too large
Load diff
37
2020/days/02/test_day2.py
Normal file
37
2020/days/02/test_day2.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import pytest
|
||||
import day2 as aoc
|
||||
|
||||
PUZZLE_DIR = pathlib.Path(__file__).parent
|
||||
|
||||
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
|
||||
@pytest.fixture
|
||||
def example1():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.fixture
|
||||
def example2():
|
||||
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_parse_example1(example1):
|
||||
"""Test that input is parsed properly"""
|
||||
assert example1 == [
|
||||
aoc.PasswordSpec(first=1, second=3, letter='a', password='abcde'),
|
||||
aoc.PasswordSpec(first=1, second=3, letter='b', password='cdefg'),
|
||||
aoc.PasswordSpec(first=2, second=9, letter='c', password='ccccccccc')
|
||||
]
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part1_example1(example1):
|
||||
"""Test part 1 on example input"""
|
||||
assert aoc.part1(example1) == 2
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part2_example2(example1):
|
||||
"""Test part 2 on example input"""
|
||||
assert aoc.part2(example1) == 1
|
||||
38
2020/days/03/day3.py
Executable file
38
2020/days/03/day3.py
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from pprint import pprint
|
||||
|
||||
def parse(puzzle_input: str):
|
||||
"""Parse input"""
|
||||
# returns a 2 dimentional array where true means there is a tree there.
|
||||
return [[i=='#' for i in j] for j in puzzle_input.splitlines()]
|
||||
|
||||
def part1(data):
|
||||
"""Solve part 1"""
|
||||
return solveForSlope(data, 3, 1)
|
||||
|
||||
def solveForSlope(data, right: int, down: int):
|
||||
return sum(1 for index, row in enumerate(data[::down]) if row[(right*index)%len(row)])
|
||||
|
||||
def part2(data):
|
||||
"""Solve part 2"""
|
||||
return solveForSlope(data,1,1)*solveForSlope(data,3,1)*solveForSlope(data,5,1)*solveForSlope(data,7,1)*solveForSlope(data,1,2)
|
||||
|
||||
def solve(puzzle_input):
|
||||
"""Solve the puzzle for the given input"""
|
||||
data = parse(puzzle_input)
|
||||
solution1 = part1(data)
|
||||
solution2 = part2(data)
|
||||
|
||||
return solution1, solution2
|
||||
|
||||
if __name__ == "__main__":
|
||||
for path in sys.argv[1:]:
|
||||
print(f"{path}:")
|
||||
puzzle_input = pathlib.Path(path).read_text().strip()
|
||||
solutions = solve(puzzle_input)
|
||||
print("\n".join(str(solution) for solution in solutions))
|
||||
11
2020/days/03/example1
Normal file
11
2020/days/03/example1
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
..##.......
|
||||
#...#...#..
|
||||
.#....#..#.
|
||||
..#.#...#.#
|
||||
.#...##..#.
|
||||
..#.##.....
|
||||
.#.#.#....#
|
||||
.#........#
|
||||
#.##...#...
|
||||
#...##....#
|
||||
.#..#...#.#
|
||||
323
2020/days/03/input
Normal file
323
2020/days/03/input
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
........#.............#........
|
||||
...#....#...#....#.............
|
||||
.#..#...#............#.....#..#
|
||||
..#......#..##............###..
|
||||
..........#......#..#..#.......
|
||||
.#..#.......#.........#.#......
|
||||
.........#..#....##..#.##....#.
|
||||
..#....##...#..................
|
||||
##..........#.##...#....##..#..
|
||||
...#....#...#..............#...
|
||||
...........................#..#
|
||||
..##.##.#..................#...
|
||||
...#.##..#............#........
|
||||
........#.......#...#.....##.#.
|
||||
.##..........#......#.......#..
|
||||
...#..........#...#..#.......#.
|
||||
......#...#...#.##.......#.#...
|
||||
........#...#...#...##.........
|
||||
#..............#.#....#.......#
|
||||
..#..#..#.#....#...............
|
||||
.....#........#...#..........#.
|
||||
##......#...#..#.##.......#....
|
||||
..#.#.....#.#.............#.#.#
|
||||
#..#..##......##...#...........
|
||||
..#......#........#.....#......
|
||||
.....#.......#....#.#...#......
|
||||
...#........#...........#...#..
|
||||
.......#.#...........###....#..
|
||||
...#...........##....##........
|
||||
#....#..####....#.....#..#....#
|
||||
..........#...........#........
|
||||
...#.......#....#.#.........#..
|
||||
....#...#.......#..###.........
|
||||
......#......#..#......#..#....
|
||||
...#.....#............#..#.....
|
||||
...#.#.#.#..#.......#.....#....
|
||||
#....##...#.........#...##.....
|
||||
#..#.......#..#..#..#...##.....
|
||||
#.......#............#.....#...
|
||||
.#........##....##...#........#
|
||||
.....#...#.....................
|
||||
.......#........#..............
|
||||
.....#............#.#.#...#.#..
|
||||
.....##..#.............#.......
|
||||
..#.##..#........#..#...#......
|
||||
.........#.#....#...........#..
|
||||
.#.....#..#....#.....#...#.....
|
||||
....#.#................#.......
|
||||
...............##......#...#...
|
||||
.##...#...#.......##.#....#....
|
||||
............#........#.......#.
|
||||
......##.#.#...................
|
||||
.#.#..............#.......#....
|
||||
#.....#...#.......#..#...#.....
|
||||
.............#....#..#......#..
|
||||
........#...##................#
|
||||
.......#...#..#..##............
|
||||
..#..#...##...#..#.#.....#...#.
|
||||
.#.#...#.........#.#...........
|
||||
...###....#.......#...#........
|
||||
........#......##.#...#..##..#.
|
||||
.....................#.#.......
|
||||
.............#...........#...#.
|
||||
#..#..#.....#.#...#............
|
||||
...#....#.....#...........#....
|
||||
..##.....##...#......#..##.....
|
||||
#.....#.....###.#.....#....##..
|
||||
.#...........###...............
|
||||
..................#..##.#...#..
|
||||
................#....##.#......
|
||||
.#.#.#...#....#.........#..#.#.
|
||||
#.......#........##............
|
||||
.......##.#....#.#............#
|
||||
..........#..##.#....#.........
|
||||
........##..#....#.............
|
||||
.........#....#...........##...
|
||||
#.........#.#..#..#..........#.
|
||||
.....#........#......#.........
|
||||
....#.#.#...............#......
|
||||
.#..#..##...#.##..........#....
|
||||
..#....................#.#.....
|
||||
.........#....#...........#.#.#
|
||||
........#....##.##.............
|
||||
..#.....#.......#..#......#....
|
||||
#..........#.#.....#.#....#....
|
||||
........##.#.....#..#.....#.#..
|
||||
...................#...#....#.#
|
||||
............#..#....#...#...#..
|
||||
..............#.#.........#....
|
||||
...#..#..#.#..##..##...........
|
||||
.#...........................#.
|
||||
.#.......#...........#....#.#.#
|
||||
......#..#...#........#...##...
|
||||
.........#......#.#.......#...#
|
||||
...#..##................#......
|
||||
.............#.#..##....#.#....
|
||||
...............#..#......#.....
|
||||
.#......#.#.#....#........#....
|
||||
........#..#.##..#..#.........#
|
||||
...#....#.#...#..#.......#..#..
|
||||
..#...##.........#..#...#......
|
||||
...#...........#.............#.
|
||||
....#.....................#....
|
||||
.....#..#...............#.#...#
|
||||
....#..........#........#......
|
||||
..#....#........##..##.........
|
||||
...#....#..#.#.......#...#.....
|
||||
..#........#....#...##....#.#..
|
||||
.#...#........##.....#....###..
|
||||
#....#....##......#........#...
|
||||
.........#..#.#..........#....#
|
||||
....#...#.....#.......##.......
|
||||
..............#..........#.##..
|
||||
#...#..#..............#......#.
|
||||
.................#......##....#
|
||||
..#..##..#.......#..#.#......#.
|
||||
.............#........#.....#.#
|
||||
.#.##............#..#..........
|
||||
..#...#...........#..##........
|
||||
.#....#...#....#.......#.......
|
||||
...#.#..#..#..#....#.....#..#..
|
||||
....#..##..............#...#...
|
||||
#..........###......###........
|
||||
.##.##......#..#............#..
|
||||
.#...........#.#.....#...#.....
|
||||
#.#..#...#............#........
|
||||
.........#...#...#..........##.
|
||||
.......###..#..........#.......
|
||||
...........###.....#........#..
|
||||
.#.............#.....#......#..
|
||||
...#.....#....#.#.........##...
|
||||
....##..##...#.......##........
|
||||
......#....##.........#......#.
|
||||
..........#.....##..#.....#..#.
|
||||
..........####...#..#.........#
|
||||
.##....#..#.#...#.......#......
|
||||
...#.#.##.#.#...#....#.#.#.....
|
||||
.........#...##........##.....#
|
||||
..#........#..........##...##.#
|
||||
##...##..........#.#...........
|
||||
..............#......#.........
|
||||
........#.....#.#.......#......
|
||||
.#...#.....#....#.#..#.........
|
||||
.....#....................##...
|
||||
....#..................#.#...##
|
||||
.....#............#..##........
|
||||
#..........#....#.#.......##.#.
|
||||
....#..#.....................#.
|
||||
#..#....##.....#...............
|
||||
..#...#..#..##....#.#..........
|
||||
.......#......#.#.......#.....#
|
||||
...#.#.......#...#.##..........
|
||||
....#..........#....#.#.#......
|
||||
.......#..#..........#..##.....
|
||||
#......#......#...#......#...#.
|
||||
###..#....##......##........#..
|
||||
.#..........#.....#.......#.#..
|
||||
.......#.....#.....#.#.........
|
||||
..#...#....#...................
|
||||
..............#.##.............
|
||||
.#...#.......#.##...#.#.......#
|
||||
.......#......................#
|
||||
....#.#...#.#........#.........
|
||||
.#......#....#...#.............
|
||||
#.......#...###.....#.#.#..#...
|
||||
#....##.#...............##.....
|
||||
..#.......#..................#.
|
||||
.....####...............#......
|
||||
.##......#......#.#.......##.#.
|
||||
#......##..###....#....#......#
|
||||
.##.......##.##...#.##.........
|
||||
......##............#.......#..
|
||||
......#..#.....##.#............
|
||||
.#..........#.....##...........
|
||||
#.........#......#......##.#...
|
||||
.........#.......#..#......#.#.
|
||||
.........#.......#...........#.
|
||||
.#..##.#..................##...
|
||||
.............#.............#...
|
||||
.....##........#......##...##..
|
||||
..#..#.#.....#..#....#.........
|
||||
.....#....#.....#.....#........
|
||||
#......##.....#....#....#......
|
||||
#.................#..#.#......#
|
||||
.......#..#......#....#.#...#.#
|
||||
....#.........#..#..........#.#
|
||||
##......#............#...#...#.
|
||||
....##......#...#.....#....##..
|
||||
.#...##.........#..............
|
||||
......#.....................#..
|
||||
..#..........###....#..........
|
||||
#....#...#..#.............#....
|
||||
#........#.#......#....#.......
|
||||
.#...#.......#..#...#.#...#..#.
|
||||
................##.#.....#.....
|
||||
###.......#...#................
|
||||
...#.......#...#.#.....#.......
|
||||
..#.........#.....#.#.......#..
|
||||
......#.......................#
|
||||
#.....#.#..#....#.......#......
|
||||
...#....#..#....####...........
|
||||
.............#.....#...##......
|
||||
.......#.........#...#..#......
|
||||
.##..#.........#....#.#........
|
||||
....##...#.#...........#....#..
|
||||
.........................##....
|
||||
..###.......##....#.#.........#
|
||||
.#....#.#.#...........##....#..
|
||||
......#...#..#..#..#..#.......#
|
||||
..#....#.#.......#..#..#..#...#
|
||||
.....##...#.##....#.#...#......
|
||||
.........#..#....#..#..........
|
||||
.##..##.........#.#.....#......
|
||||
..........#...##...#.#...#.....
|
||||
#.##..#..#.............#.......
|
||||
...#...........#.......#......#
|
||||
.......#....#....#...##.......#
|
||||
..#.##........###..#......#....
|
||||
...#...........###......#..#..#
|
||||
.#.........#.#.........#.#.....
|
||||
##.......##.##.##......##......
|
||||
............#...#..........#...
|
||||
....................#..........
|
||||
...#..#...........#...#...#....
|
||||
.................#...#......###
|
||||
...#................#.#.##.....
|
||||
...............#........#......
|
||||
#.............##......#.#..#...
|
||||
..#.#.....#..#.##.....##...#...
|
||||
......#.........#......#.......
|
||||
#.......#......#....#........#.
|
||||
.#..##.....#.........#.........
|
||||
....##.##.#...#.........##.#...
|
||||
...............#..#..#..##.....
|
||||
.#..#...............###........
|
||||
.##............##..............
|
||||
...............#...##...#...#.#
|
||||
..#.#......#.#..#.............#
|
||||
#.#..#..##.........#.#.#...#...
|
||||
....##.#....................##.
|
||||
.........#..#.....#.....#..#..#
|
||||
....#......#......#.##....#....
|
||||
........###..#.............#..#
|
||||
##................#.........#..
|
||||
#.....#.......#....#...........
|
||||
..#.......#..#........#....#...
|
||||
..#.#.##..#.#...##........#.##.
|
||||
..#..........#............#....
|
||||
..........#...............##...
|
||||
..........###........#.#.......
|
||||
.....###..#.............#......
|
||||
##.............#...#.....#.....
|
||||
.....#......#....#........#.#..
|
||||
............#..#..............#
|
||||
.................#...........##
|
||||
#........#.........###.....#...
|
||||
..#.#..............##......#.#.
|
||||
.#...........#.........#..##..#
|
||||
...............................
|
||||
.#.....#..#....#....#......#...
|
||||
.#...#......#.#..#....#.......#
|
||||
......#.##.......#......#......
|
||||
......#..###..#................
|
||||
#..#.....#........##...#.......
|
||||
......##.........##....#...##..
|
||||
.#..........#.................#
|
||||
#..#.......#...............#...
|
||||
.........#..###....#.#.##.#....
|
||||
..#...#.##..##...............##
|
||||
.........#.....................
|
||||
.#....##...#......#....#.......
|
||||
............#..........#..#....
|
||||
...#......##....#....#........#
|
||||
.#...................#.........
|
||||
#.#........###....#..........#.
|
||||
.........#....#....#........##.
|
||||
.#....#..#.........#..#........
|
||||
...............#..#...#..#...##
|
||||
.........#....##....#......#...
|
||||
.#.............................
|
||||
...#........#...#.#...#.#..#...
|
||||
.....#..##...#.#...............
|
||||
#.....#....#.........#.........
|
||||
#...#...........##.........#...
|
||||
..##........#.#...#...#......#.
|
||||
...........#.....#...#.#.......
|
||||
......###....#.....#...........
|
||||
......##...#..........#....#.#.
|
||||
.......##..##..........#.......
|
||||
....#............#..#....##....
|
||||
..##...................#.#.....
|
||||
...#.#..#.#....................
|
||||
.#..##..#............##.###..#.
|
||||
#.#...#....#.#..........#.#....
|
||||
........#....#.....#...........
|
||||
..##....#...#.......#..........
|
||||
...........##.##....#..........
|
||||
.....#............#............
|
||||
.......#.............#....#....
|
||||
.................#......#......
|
||||
......##.......#....#..##...#..
|
||||
.#..#....#.....................
|
||||
...#.#.#...#......##...........
|
||||
##........##.#....#....#.......
|
||||
.......#.....#..#..#...#.##....
|
||||
#..........#....#.#..#..#..#...
|
||||
...##..............#...........
|
||||
.........#.....#.#....#.......#
|
||||
.........#....##..#..##..#.....
|
||||
.....#......................#..
|
||||
...###...#..#......#...........
|
||||
....#.....................#....
|
||||
...............................
|
||||
..#.....###.......#..#....#....
|
||||
#..........#.................#.
|
||||
......#.......###.......#..##..
|
||||
.............#.##..............
|
||||
......#..#.#..#...........#....
|
||||
...#....##.#...#..#.#...#....#.
|
||||
..................#...#....#.##
|
||||
......#.#....#.................
|
||||
......#.#.....#.....#..##......
|
||||
#..##...........#..#.....#.##..
|
||||
43
2020/days/03/test_day3.py
Normal file
43
2020/days/03/test_day3.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import pytest
|
||||
import day3 as aoc
|
||||
|
||||
PUZZLE_DIR = pathlib.Path(__file__).parent
|
||||
|
||||
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
|
||||
@pytest.fixture
|
||||
def example1():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.fixture
|
||||
def example2():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_parse_example1(example1):
|
||||
"""Test that input is parsed properly"""
|
||||
assert example1 == [[False, False, True, True, False, False, False, False, False, False, False],
|
||||
[True, False, False, False, True, False, False, False, True, False, False],
|
||||
[False, True, False, False, False, False, True, False, False, True, False],
|
||||
[False, False, True, False, True, False, False, False, True, False, True],
|
||||
[False, True, False, False, False, True, True, False, False, True, False],
|
||||
[False, False, True, False, True, True, False, False, False, False, False],
|
||||
[False, True, False, True, False, True, False, False, False, False, True],
|
||||
[False, True, False, False, False, False, False, False, False, False, True],
|
||||
[True, False, True, True, False, False, False, True, False, False, False],
|
||||
[True, False, False, False, True, True, False, False, False, False, True],
|
||||
[False, True, False, False, True, False, False, False, True, False, True]]
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part1_example1(example1):
|
||||
"""Test part 1 on example input"""
|
||||
assert aoc.part1(example1) == 7
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part2_example2(example2):
|
||||
"""Test part 2 on example input"""
|
||||
assert aoc.part2(example2) == 336
|
||||
132
2020/days/04/day4.py
Executable file
132
2020/days/04/day4.py
Executable file
|
|
@ -0,0 +1,132 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from pprint import pprint
|
||||
|
||||
@dataclass
|
||||
class Passport:
|
||||
birthYear: int | None
|
||||
issueYear: int | None
|
||||
expirationYear: int | None
|
||||
height: str | None
|
||||
hairColor: str | None
|
||||
eyeColor: str | None
|
||||
passportId: str | None
|
||||
countryId: str | None
|
||||
|
||||
def regexUnwrap(match, group:int)->str | None:
|
||||
return match[group] if match is not None else None
|
||||
|
||||
def parse(puzzle_input: str)->list[Passport]:
|
||||
"""Parse input"""
|
||||
rawRecords = [i.replace('\n', ' ') for i in puzzle_input.split('\n\n')]
|
||||
records = []
|
||||
for rawRecord in rawRecords:
|
||||
birthYear=re.search(r'byr:(\S+)', rawRecord)
|
||||
issueYear=re.search(r'iyr:(\S+)', rawRecord)
|
||||
expirationYear=re.search(r'eyr:(\S+)', rawRecord)
|
||||
height=re.search(r'hgt:(\S+)', rawRecord)
|
||||
hairColor=re.search(r'hcl:(\S+)', rawRecord)
|
||||
eyeColor=re.search(r'ecl:(\S+)', rawRecord)
|
||||
passportId=re.search(r'pid:(\S+)', rawRecord)
|
||||
countryId=re.search(r'cid:(\S+)', rawRecord)
|
||||
records.append(Passport(
|
||||
int(birthYear[1]) if birthYear is not None else None,
|
||||
int(issueYear[1]) if issueYear is not None else None,
|
||||
int(expirationYear[1]) if expirationYear is not None else None,
|
||||
regexUnwrap(height,1),
|
||||
regexUnwrap(hairColor,1),
|
||||
regexUnwrap(eyeColor,1),
|
||||
regexUnwrap(passportId,1),
|
||||
regexUnwrap(countryId,1),
|
||||
))
|
||||
return records
|
||||
|
||||
def lazyCheckPassport(passport: Passport)->bool:
|
||||
return (
|
||||
passport.birthYear is not None
|
||||
and passport.issueYear is not None
|
||||
and passport.expirationYear is not None
|
||||
and passport.height is not None
|
||||
and passport.hairColor is not None
|
||||
and passport.eyeColor is not None
|
||||
and passport.passportId is not None
|
||||
)
|
||||
|
||||
def part1(data):
|
||||
"""Solve part 1"""
|
||||
return sum(1 for record in data if lazyCheckPassport(record))
|
||||
|
||||
def checkBirthYear(passport: Passport)->bool:
|
||||
if passport.birthYear is None: return False
|
||||
return (1920<=passport.birthYear<=2002)
|
||||
|
||||
def checkIssueYear(passport: Passport)->bool:
|
||||
if passport.issueYear is None: return False
|
||||
return (2010<=passport.issueYear<=2020)
|
||||
|
||||
def checkExpirationYear(passport: Passport)->bool:
|
||||
if passport.expirationYear is None: return False
|
||||
return (2020<=passport.expirationYear<=2030)
|
||||
|
||||
def checkHeight(passport: Passport)->bool:
|
||||
if passport.height is None: return False
|
||||
rematch = re.match(r'(\d+)((?:in)|(?:cm))', passport.height)
|
||||
if rematch is None: return False
|
||||
number = int(rematch.group(1))
|
||||
unit = rematch.group(2)
|
||||
if unit == 'in':
|
||||
return (59<=number<=76)
|
||||
else:
|
||||
return (150<=number<=193)
|
||||
|
||||
def checkHairColour(passport: Passport)->bool:
|
||||
if passport.hairColor is None: return False
|
||||
return (re.match(r'#[0123456789abcdef]{6}$', passport.hairColor) is not None)
|
||||
|
||||
def checkEyeColour(passport: Passport)->bool:
|
||||
if passport.eyeColor is None: return False
|
||||
return (passport.eyeColor == 'amb'
|
||||
or passport.eyeColor == 'blu'
|
||||
or passport.eyeColor == 'brn'
|
||||
or passport.eyeColor == 'gry'
|
||||
or passport.eyeColor == 'grn'
|
||||
or passport.eyeColor == 'hzl'
|
||||
or passport.eyeColor == 'oth'
|
||||
)
|
||||
|
||||
def checkPassportId(passport: Passport)->bool:
|
||||
if passport.passportId is None: return False
|
||||
return (re.match(r'[0-9]{9}$', passport.passportId) is not None)
|
||||
|
||||
def checkPassport(passport: Passport)->bool:
|
||||
return (checkBirthYear(passport)
|
||||
and checkIssueYear(passport)
|
||||
and checkExpirationYear(passport)
|
||||
and checkHeight(passport)
|
||||
and checkHairColour(passport)
|
||||
and checkEyeColour(passport)
|
||||
and checkPassportId(passport)
|
||||
)
|
||||
|
||||
def part2(data):
|
||||
"""Solve part 2"""
|
||||
return sum(1 for record in data if checkPassport(record))
|
||||
|
||||
def solve(puzzle_input):
|
||||
"""Solve the puzzle for the given input"""
|
||||
data = parse(puzzle_input)
|
||||
solution1 = part1(data)
|
||||
solution2 = part2(data)
|
||||
|
||||
return solution1, solution2
|
||||
|
||||
if __name__ == "__main__":
|
||||
for path in sys.argv[1:]:
|
||||
print(f"{path}:")
|
||||
puzzle_input = pathlib.Path(path).read_text().strip()
|
||||
solutions = solve(puzzle_input)
|
||||
print("\n".join(str(solution) for solution in solutions))
|
||||
13
2020/days/04/example1
Normal file
13
2020/days/04/example1
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
|
||||
byr:1937 iyr:2017 cid:147 hgt:183cm
|
||||
|
||||
iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
|
||||
hcl:#cfa07d byr:1929
|
||||
|
||||
hcl:#ae17e1 iyr:2013
|
||||
eyr:2024
|
||||
ecl:brn pid:760753108 byr:1931
|
||||
hgt:179cm
|
||||
|
||||
hcl:#cfa07d eyr:2025 pid:166559648
|
||||
iyr:2011 ecl:brn hgt:59in
|
||||
1146
2020/days/04/input
Normal file
1146
2020/days/04/input
Normal file
File diff suppressed because it is too large
Load diff
65
2020/days/04/test_day4.py
Normal file
65
2020/days/04/test_day4.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import pytest
|
||||
import day4 as aoc
|
||||
from day4 import Passport
|
||||
|
||||
PUZZLE_DIR = pathlib.Path(__file__).parent
|
||||
|
||||
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
|
||||
@pytest.fixture
|
||||
def example1():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.fixture
|
||||
def example2():
|
||||
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_parse_example1(example1):
|
||||
"""Test that input is parsed properly"""
|
||||
assert example1 == [Passport(birthYear=1937,
|
||||
issueYear=2017,
|
||||
expirationYear=2020,
|
||||
height='183cm',
|
||||
hairColor='#fffffd',
|
||||
eyeColor='gry',
|
||||
passportId='860033327',
|
||||
countryId='147'),
|
||||
Passport(birthYear=1929,
|
||||
issueYear=2013,
|
||||
expirationYear=2023,
|
||||
height=None,
|
||||
hairColor='#cfa07d',
|
||||
eyeColor='amb',
|
||||
passportId='028048884',
|
||||
countryId='350'),
|
||||
Passport(birthYear=1931,
|
||||
issueYear=2013,
|
||||
expirationYear=2024,
|
||||
height='179cm',
|
||||
hairColor='#ae17e1',
|
||||
eyeColor='brn',
|
||||
passportId='760753108',
|
||||
countryId=None),
|
||||
Passport(birthYear=None,
|
||||
issueYear=2011,
|
||||
expirationYear=2025,
|
||||
height='59in',
|
||||
hairColor='#cfa07d',
|
||||
eyeColor='brn',
|
||||
passportId='166559648',
|
||||
countryId=None)]
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part1_example1(example1):
|
||||
"""Test part 1 on example input"""
|
||||
assert aoc.part1(example1) == 2
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part2_example2(example1):
|
||||
"""Test part 2 on example input"""
|
||||
assert aoc.part2(example1) == 2
|
||||
46
2020/days/05/day5.py
Executable file
46
2020/days/05/day5.py
Executable file
|
|
@ -0,0 +1,46 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from pprint import pprint
|
||||
|
||||
def row_to_int(string: str)->int:
|
||||
return int(string.replace('F','0').replace('B','1'),2)
|
||||
|
||||
def col_to_int(string: str)->int:
|
||||
return int(string.replace('L','0').replace('R','1'),2)
|
||||
|
||||
def parse(puzzle_input: str):
|
||||
"""Parse input"""
|
||||
rows_and_cols = [(row_to_int(x[:7]),col_to_int(x[7:])) for x in puzzle_input.splitlines()]
|
||||
return set([x[0]*8+x[1] for x in rows_and_cols])
|
||||
|
||||
def part1(data):
|
||||
"""Solve part 1"""
|
||||
return max(data)
|
||||
|
||||
def part2(data):
|
||||
"""Solve part 2"""
|
||||
for row in range(128):
|
||||
for col in range(8):
|
||||
potentialID=row*8+col
|
||||
if potentialID not in data:
|
||||
if (potentialID+1 in data) and (potentialID-1 in data):
|
||||
return potentialID
|
||||
|
||||
def solve(puzzle_input):
|
||||
"""Solve the puzzle for the given input"""
|
||||
data = parse(puzzle_input)
|
||||
solution1 = part1(data)
|
||||
solution2 = part2(data)
|
||||
|
||||
return solution1, solution2
|
||||
|
||||
if __name__ == "__main__":
|
||||
for path in sys.argv[1:]:
|
||||
print(f"{path}:")
|
||||
puzzle_input = pathlib.Path(path).read_text().strip()
|
||||
solutions = solve(puzzle_input)
|
||||
print("\n".join(str(solution) for solution in solutions))
|
||||
4
2020/days/05/example1
Normal file
4
2020/days/05/example1
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
FBFBBFFRLR
|
||||
BFFFBBFRRR
|
||||
FFFBBBFRRR
|
||||
BBFFBBFRLL
|
||||
859
2020/days/05/input
Normal file
859
2020/days/05/input
Normal file
|
|
@ -0,0 +1,859 @@
|
|||
BBFFBFFRRR
|
||||
FBBFFBBLRR
|
||||
FFBFBFBRRR
|
||||
FFFBFBFRRR
|
||||
BBFFBBFLRR
|
||||
BFFBFBFLRL
|
||||
FBBBBBFRRR
|
||||
FFFFBFFLLR
|
||||
BFBFFBFLLR
|
||||
FFBBFFFLRR
|
||||
BFFFFFFLLL
|
||||
FBFFBFFRLL
|
||||
FFBFFBFRLR
|
||||
FBBBFBFRRR
|
||||
FBFFBBBRRL
|
||||
FBFFBFFLRL
|
||||
BFBBFFFLLL
|
||||
FBBFBFBRRL
|
||||
BFFBFFFLRR
|
||||
FFFFBFFRLR
|
||||
FFFBBBFRLR
|
||||
FBFFFBFLLL
|
||||
BFBFBBBLRR
|
||||
FBBBFFBRLR
|
||||
BBFFFFFLLL
|
||||
BFFFFBFRRL
|
||||
FBBBFBFRRL
|
||||
FFBBBFBRLR
|
||||
FFFFBBFLLL
|
||||
FBFBFBBRLL
|
||||
BFFFBFBRLL
|
||||
FFBFBFBRLR
|
||||
FBFFFBBRLR
|
||||
BBFFFBBLRR
|
||||
BFFBBFFRRL
|
||||
BFBBBFFRRR
|
||||
FFBFBFFRRL
|
||||
FBFBBFBLLR
|
||||
BFFBFBBRRR
|
||||
BFFFFBFLLR
|
||||
FFFBFFFRRR
|
||||
FBFFFBFRLR
|
||||
BFBFFBFRLR
|
||||
FBBBFFFLLR
|
||||
FBBFFBFLLL
|
||||
BFBBFBFLLR
|
||||
FFBFBBFLLL
|
||||
BFFFBFBLRL
|
||||
FBBFBBBLLL
|
||||
FFFBFFBLLR
|
||||
BFFFFFFRRR
|
||||
BFBBBBFRRL
|
||||
FFBFBBFRLL
|
||||
FBBBFBBLRL
|
||||
BFFBFBFLRR
|
||||
BBFFFBFRRL
|
||||
BFFBBFFLRR
|
||||
BFBFFFFLLR
|
||||
FBFBFFFLRR
|
||||
BFBBFBBLRL
|
||||
FBFBFFFRLR
|
||||
FFBBBFFRLR
|
||||
BBFBBFFRLR
|
||||
BFFFFBBRLL
|
||||
FFFBFBBLRR
|
||||
FFFFBFBRRL
|
||||
BFFBFBFRRL
|
||||
FBFFBBBRRR
|
||||
BFBBFFBLRL
|
||||
FFBBFFFLLL
|
||||
FBFBBFBRRR
|
||||
FBBBFFFLRL
|
||||
FBBFFBFLRR
|
||||
FBBBBBFRRL
|
||||
BFFFBBBLRL
|
||||
FFFBBFBRLL
|
||||
FFFFFBBLLR
|
||||
FFBFBBBRLL
|
||||
FFBBFBFLLR
|
||||
FBFBBFFLLL
|
||||
FFFBFFBRLL
|
||||
BFBBFBFRLR
|
||||
BFBFBBFRRL
|
||||
FFFBFFFLRL
|
||||
FBBFBBFRLR
|
||||
BFFBFFBRRL
|
||||
BBFFFBBRLR
|
||||
FBBBBBFRLL
|
||||
FFBBFFFRLL
|
||||
BBFBFBBRLR
|
||||
FFBBBFFLLR
|
||||
BFBBBBBLLL
|
||||
FFFBFBBLLL
|
||||
FBFFBFFRRL
|
||||
FBFBFFBLLL
|
||||
BFFBBBFRRL
|
||||
FBBBBBFLLL
|
||||
FBFBBFBLRR
|
||||
FFBBBBFLLR
|
||||
BBFFBFFRRL
|
||||
FBBBBBFLRR
|
||||
FBFFFFFRLR
|
||||
FBFFBBFLLR
|
||||
FFBBBFBLRR
|
||||
BFFFBBBRRL
|
||||
FBFBFBFRRL
|
||||
FFFBFBBRLL
|
||||
FFBFBFBLRL
|
||||
FBBBFBBLLL
|
||||
FBBBFBFLRL
|
||||
FBBBBFFLRL
|
||||
FBFBBBBRLR
|
||||
FBBFFBFLLR
|
||||
FBFFBBFLRR
|
||||
FBFFFBBLLL
|
||||
BBFFBBFRRR
|
||||
FBBFBBBRLL
|
||||
BFFBBBFLLR
|
||||
FBFFFFFLRR
|
||||
FBFFBBFRRL
|
||||
BFFBBFBLLL
|
||||
FBBBFBBLLR
|
||||
FBBBBFBLRL
|
||||
FBBBFFFRRR
|
||||
FFFFBBFRRR
|
||||
BFBFFFFRRR
|
||||
BFBFFBBLRL
|
||||
BFFFFFBLLR
|
||||
BFBBFFFRRR
|
||||
FBFFFBFRRL
|
||||
BFFBBFFLRL
|
||||
FFFBFFBRRL
|
||||
FFBFBFBLLL
|
||||
FFBFBFFLLL
|
||||
BBFFFBBRRR
|
||||
FFFFFBFLRL
|
||||
BFBFFFBLRL
|
||||
BFBFBFFLRR
|
||||
BFFBBBBRLL
|
||||
BFFFBFFRRR
|
||||
BBFBFFBRLL
|
||||
FBFFFBBRRL
|
||||
FFBBFBBRRL
|
||||
FFBFFFFLLR
|
||||
FFFBFFFLLL
|
||||
FBBFFBBLRL
|
||||
BFBFBBFLLR
|
||||
FBFBFFFRRL
|
||||
BBFFFFFLRR
|
||||
BBFFFBFLRL
|
||||
BBFFBBBLLL
|
||||
BFBBFBFLLL
|
||||
BFBFFBFRRL
|
||||
FBFFFFBRRL
|
||||
FBFFBBBRLR
|
||||
BFBBFBBRLL
|
||||
BFFBBFFLLR
|
||||
FBBBFFBLRL
|
||||
BFFFBFFRLR
|
||||
FFFBFFBRLR
|
||||
BFFBBBFLLL
|
||||
FBBBBFFRLL
|
||||
FFFFBBBRLR
|
||||
FBFFBFFLRR
|
||||
FBFBFBBRRL
|
||||
FFFFFFBRRR
|
||||
FFFBBBFLRL
|
||||
FBFFBFBLLR
|
||||
FFFBBBBLRL
|
||||
BBFBFFBLLL
|
||||
FBFFFFBLLR
|
||||
BBFBFBBRRR
|
||||
BFBFFFBRRR
|
||||
FBBFBFFRLL
|
||||
FBBBBFFRLR
|
||||
FFBBFBBLRL
|
||||
BBFBFFBLLR
|
||||
FBBBBBBLRL
|
||||
BFFFBBFLLL
|
||||
BBFBBFFLLR
|
||||
FBFFBFBLRL
|
||||
BFFFBBBLRR
|
||||
BBFFFFFRRR
|
||||
BFBFBBBRLR
|
||||
BBFFFBFLRR
|
||||
FBBFBBFLLR
|
||||
BBFBFFBLRR
|
||||
BFBBBFFLRR
|
||||
FBBFBFFRRL
|
||||
FBFBFBBLRR
|
||||
BFBBFFBRLL
|
||||
FFFBBFBRLR
|
||||
BFFBBBFRRR
|
||||
FBFFBFFRLR
|
||||
FFFBBBBRLL
|
||||
FFFFFBBRLR
|
||||
FBBFBFBLLR
|
||||
FBBFBBFLRR
|
||||
BBFFBBFLLR
|
||||
FFFBFBBLLR
|
||||
FFBFBFFLRR
|
||||
BFBBFBFRLL
|
||||
BFFFFBFRRR
|
||||
BBFBFFFLRL
|
||||
BFFFFBFLLL
|
||||
FBFBFBFLRL
|
||||
BFBBFBBLLR
|
||||
BFFBFFFRLL
|
||||
BBFBFFFRLR
|
||||
BBFFBFFRLL
|
||||
FFFBFBBRLR
|
||||
FBFBBBFLRL
|
||||
FFBFFBBRLR
|
||||
BBFFFBBLRL
|
||||
BFBBBBFLRR
|
||||
FFBFFFBLRL
|
||||
FFBBBFBRLL
|
||||
BBFFBFFLRR
|
||||
BBFFBFFRLR
|
||||
FFFFFBFRRR
|
||||
BBFBFBBLRL
|
||||
BFFBBBBLLL
|
||||
FBBBBFBRRR
|
||||
FFBBBBBLRL
|
||||
FBBFBBFRRR
|
||||
FFBBFFBRLL
|
||||
BFBFBFBLRR
|
||||
BBFBFFFRRR
|
||||
BFFFBBFRRR
|
||||
FBFBFFFLLL
|
||||
FBBFBFBRRR
|
||||
BBFFBFBLLR
|
||||
BBFBFBFLRR
|
||||
BFFFFBBLRL
|
||||
BFBBBFFLRL
|
||||
BBFBFFBLRL
|
||||
BFFBBFFRLL
|
||||
FBFFBFFLLR
|
||||
FBFBFBBLLL
|
||||
BBFBFBFLRL
|
||||
BBFFBBBLRL
|
||||
FFFFFBBRLL
|
||||
FFFBBBBRRR
|
||||
FFBBFFFRLR
|
||||
FFBFFFBRRR
|
||||
FBFBFFBLRR
|
||||
FFBFFBBLLL
|
||||
FBBFBBFLRL
|
||||
FBFFBBBLRL
|
||||
FBBBBFFRRR
|
||||
BFBBBBBLLR
|
||||
FFBFBBBLRR
|
||||
FFFFBFBLRR
|
||||
BFFFFFFRLL
|
||||
FBBFFFBLRR
|
||||
BFBBBBBRLL
|
||||
FFBBFFBLRL
|
||||
BFBBBFFRLR
|
||||
FFBFFBFLLL
|
||||
FFBBFBFRLR
|
||||
BFBFFBBLRR
|
||||
FFFFBFFLRR
|
||||
FFBFFBFLRL
|
||||
BBFFBBFRRL
|
||||
FFBFFFFLLL
|
||||
BBFBFFBRLR
|
||||
FBFBFBBRLR
|
||||
BBFFBBBRRR
|
||||
FBFFBBBRLL
|
||||
BFBFFBBRRR
|
||||
BBFFFBFRLL
|
||||
FBBFBBBLRL
|
||||
FBBFFFFLRR
|
||||
BBFFFBBLLL
|
||||
FFBFFFFLRL
|
||||
FBBFFBFLRL
|
||||
FBBBBFFLLR
|
||||
BFBBFBFRRR
|
||||
FBBFFFBLLL
|
||||
FFBFBFFRLL
|
||||
FFFBBBFLRR
|
||||
FFFBFFFLRR
|
||||
FBFFBFFRRR
|
||||
BFFFBFFLLR
|
||||
BFFFFFFRLR
|
||||
BFFFBFFLLL
|
||||
FBBBFBBRRL
|
||||
BFBFFFBLLL
|
||||
FBFBBBBRRR
|
||||
BFBBBFBRLR
|
||||
BBFFFFBRLR
|
||||
FBFFFFFRLL
|
||||
FBBFFBBRLR
|
||||
BBFBBFFLRR
|
||||
BBFFBFFLLR
|
||||
BBFFBBFRLL
|
||||
FBFFFFFRRL
|
||||
FFBFBBFRRR
|
||||
FFBFFFFRLL
|
||||
BFFFFBBLRR
|
||||
BFBFBFBLRL
|
||||
FBBFFFFRRR
|
||||
FFBBFBBRRR
|
||||
BFBBBBBRLR
|
||||
FBFFFBBLLR
|
||||
BBFFFBFRLR
|
||||
FBFFFBBRRR
|
||||
FBBFFBFRLR
|
||||
BFFFBFBRRR
|
||||
FFBBBBBLLL
|
||||
FFFFFBFLLR
|
||||
FBBFBFBRLL
|
||||
BFBFBFBRRL
|
||||
BBFFFFBRRL
|
||||
FFBFBBFLLR
|
||||
FFBBBFFRRL
|
||||
FBFFBFBRLR
|
||||
FBBFFFFRLL
|
||||
BFFBFFFLLR
|
||||
FBFFFBBLRR
|
||||
BFFBFFFLLL
|
||||
BFBFBBBRRR
|
||||
BFFFFBFLRL
|
||||
FFFFBFBLLL
|
||||
FFFBFFBLLL
|
||||
BFFFBBFRRL
|
||||
BFBFBBFRLL
|
||||
FFFBBBBLLL
|
||||
BFFBFBBRLR
|
||||
BFBBBBBLRR
|
||||
BFBBBFBRRL
|
||||
FFBFFFBRLR
|
||||
BFFBFFFLRL
|
||||
FFBFBBBLLL
|
||||
BFBFBBFRRR
|
||||
BFBFFBFRRR
|
||||
FFBFFFBRLL
|
||||
FBFFFFFLRL
|
||||
BBFFBBFLLL
|
||||
BFBFBBBRLL
|
||||
FFFBFFFRRL
|
||||
FBBBBBBLLR
|
||||
FFFBFBBLRL
|
||||
FBBFBBFRLL
|
||||
FFBFFFFRRR
|
||||
FFFBBBFLLR
|
||||
BFFBBFFRLR
|
||||
FFFFFBFLRR
|
||||
FFFBBBBLLR
|
||||
FBFFBFBRRL
|
||||
FBBFFFFLLL
|
||||
FFFFFBFRRL
|
||||
BFFBBBFRLL
|
||||
FFFBBFFRLL
|
||||
FFFBBFFLRR
|
||||
FFFFBBFRLL
|
||||
BFBBBBBRRR
|
||||
BFFBFBFLLL
|
||||
BBFBFBFLLR
|
||||
FFBBBBFRLR
|
||||
FFFBBBFRLL
|
||||
BFBBBBFRRR
|
||||
FBFBFFBRLR
|
||||
FFBFBBFRRL
|
||||
BBFFBBBRRL
|
||||
FFBFBBFRLR
|
||||
FFFFBFFRLL
|
||||
FBFFFBBRLL
|
||||
BBFFBFBRRL
|
||||
BFBFBFBLLR
|
||||
FBFBFBBLRL
|
||||
FBBFFFFRRL
|
||||
FFFBBFFRRR
|
||||
FFBBBBBLRR
|
||||
BBFBFBBLRR
|
||||
FFFFBBBLRR
|
||||
FFBBBBBRLL
|
||||
FFBFFFBRRL
|
||||
BFBBFFFRLL
|
||||
FBBBFBFRLL
|
||||
BBFFBFFLRL
|
||||
BBFFBFBRLR
|
||||
BFFBBBBRRR
|
||||
FBBBBBBRRL
|
||||
BBFBFFFRLL
|
||||
BFFBBFFRRR
|
||||
BFBBFFFRRL
|
||||
FFBFFBFLRR
|
||||
FBFBBFFRLL
|
||||
FBBFBBFRRL
|
||||
BBFBBFFRRR
|
||||
FFBBFBFRRL
|
||||
FFBBFBFLLL
|
||||
FBBFFFFLLR
|
||||
BFBFFBBRLR
|
||||
BFBBFFFLLR
|
||||
FBBBFFFLLL
|
||||
FFFBFFBLRR
|
||||
FFFBFBFRLR
|
||||
BFFBBBBRLR
|
||||
FBFFBBBLLR
|
||||
FFFFBBBRRR
|
||||
FFBBBBFLLL
|
||||
FBBBBFBLLR
|
||||
BFBFBFFRRL
|
||||
BBFFBBBLRR
|
||||
FBBFFBFRRL
|
||||
FFFBBBFLLL
|
||||
BFFFFBBLLL
|
||||
BBFBFBFRRR
|
||||
BFBBBFBLRR
|
||||
FBBFBBBLLR
|
||||
FFBBBBFLRL
|
||||
FFFBFFBLRL
|
||||
FBBBFFBRRL
|
||||
BFFBBFBRLL
|
||||
BFBFBFBRRR
|
||||
BBFBFBBRLL
|
||||
FBFFFBFRLL
|
||||
BFFFBFBLRR
|
||||
BFBFFFFLRL
|
||||
BBFFFFBLRR
|
||||
BFBBFFBRRL
|
||||
BBFBFBBLLR
|
||||
FFFBBBFRRL
|
||||
BFBBBFFRRL
|
||||
FFBFFBFLLR
|
||||
FFBBBFBLLL
|
||||
FBFBBBFLLL
|
||||
FFBBBBBRLR
|
||||
BBFFBBBRLL
|
||||
BFBFBBBRRL
|
||||
FFBBFBBRLL
|
||||
FBFBBFBLRL
|
||||
BBFFBFBLLL
|
||||
FBFBFFFLRL
|
||||
FFBFFBBLRL
|
||||
FFBFBBFLRL
|
||||
BBFBFBBLLL
|
||||
FFBBFBFRLL
|
||||
BBFBBFFLLL
|
||||
FBFFFFBLRL
|
||||
FBFBBBFRLR
|
||||
FFBFFBFRLL
|
||||
FBBFFFBRRR
|
||||
FBFBFFBLRL
|
||||
BFFFFBBLLR
|
||||
FBFBFBBRRR
|
||||
BBFFBBFLRL
|
||||
BFBBFFFRLR
|
||||
FBFFFFFLLR
|
||||
FBBFFBBLLL
|
||||
FFFFFBBRRL
|
||||
FFFBBFBRRL
|
||||
BFFBBBBRRL
|
||||
FBFFFBFLRL
|
||||
FFBBFFFLLR
|
||||
FBBBBBBLRR
|
||||
BFFFBBFRLL
|
||||
FFBFFFBLLR
|
||||
FBBBFFFRLL
|
||||
FFFFBBBLRL
|
||||
BBFFBFBLRR
|
||||
FFFFBBFLRR
|
||||
BFFBFBFRLR
|
||||
FFBFBBBLRL
|
||||
FBFBFBFLLR
|
||||
FFBBFBBRLR
|
||||
BFBFBFFRRR
|
||||
BBFFFFBRLL
|
||||
FFBFBFFRRR
|
||||
FFBFBBFLRR
|
||||
BFBBFBFLRR
|
||||
FFFFBBBLLR
|
||||
FFBBBBBRRL
|
||||
FBBFFBBRRR
|
||||
FFFBBBBRLR
|
||||
BFFBBBFLRL
|
||||
BFBBFFBRRR
|
||||
BBFFBBFRLR
|
||||
FBBBBBFLRL
|
||||
FFFBBFFLLL
|
||||
BFBBBFFRLL
|
||||
FBFFFFFLLL
|
||||
FBFBBFBLLL
|
||||
FFFBFFBRRR
|
||||
BFBFBFFLLL
|
||||
BFBFBFBLLL
|
||||
BFBBBFFLLL
|
||||
FFFFBBFRLR
|
||||
BFFBBFBRRL
|
||||
BFBBFBBLLL
|
||||
FBBFBFBRLR
|
||||
BFFFBFFLRL
|
||||
FBFBBFFLRL
|
||||
FFFFFBFLLL
|
||||
FBBFFBFRRR
|
||||
FBFBBBBLLL
|
||||
FBBBBBFRLR
|
||||
FBFFBBFRLL
|
||||
FFBFFBFRRR
|
||||
FFBFFFFRRL
|
||||
BFFBFBBLLR
|
||||
BFBBFBBRRR
|
||||
FFBBFBBLRR
|
||||
FBFFFFBRLR
|
||||
FFBBBBFRLL
|
||||
BBFFFBFRRR
|
||||
FFFBFBBRRR
|
||||
BFFFBFFRLL
|
||||
BFFBBBBLRR
|
||||
FBBBBFBLLL
|
||||
BFFFFFFLLR
|
||||
BFBFFFFLRR
|
||||
BFFBBBBLLR
|
||||
FFBBBFBRRR
|
||||
FBBFBFFRRR
|
||||
FBBFFFBRLR
|
||||
BFBFBBFRLR
|
||||
BFFBFFBRLL
|
||||
FBFBBFBRLR
|
||||
BFFFFFBLRR
|
||||
BFFBFFBRRR
|
||||
BFBFFBFLRL
|
||||
BBFFFBFLLL
|
||||
BBFBFBFLLL
|
||||
BFBFBFFLRL
|
||||
FBBFBFFLLL
|
||||
FBFFBFBLLL
|
||||
BFFFBFBRLR
|
||||
FFFBFFFRLL
|
||||
BBFBFFFLLL
|
||||
BFFFBBBRLR
|
||||
FBFBFBFLRR
|
||||
FFBBBBFRRR
|
||||
FBFBFBFRLR
|
||||
BBFFBFFLLL
|
||||
FBBBBFBLRR
|
||||
FBBBBBFLLR
|
||||
BFBFFFFRLL
|
||||
FBFFFBFLRR
|
||||
FFBFFFBLLL
|
||||
BFBFFBBLLR
|
||||
FFBBBFBLLR
|
||||
FBFFFBBLRL
|
||||
FFBBBFFRRR
|
||||
FBBBFBFLLR
|
||||
FBBBBFFLRR
|
||||
FBFFBBBLLL
|
||||
FFBFBFFLLR
|
||||
FFFFFBBLLL
|
||||
BFFFFFBLRL
|
||||
BBFFFFBRRR
|
||||
BFBFFFBRRL
|
||||
BBFFFFFRRL
|
||||
BFBBBBBLRL
|
||||
FBBBBFBRLL
|
||||
FFBFFFFLRR
|
||||
BFBBBFFLLR
|
||||
BFFFFBBRLR
|
||||
FFBBFFBRRL
|
||||
BFBFBFFRLR
|
||||
FFBBBBFLRR
|
||||
BFBFFBFLLL
|
||||
FBBFFBBRRL
|
||||
FFFBBFFLLR
|
||||
FFFFBFFRRR
|
||||
BFFBBBFRLR
|
||||
BFFFFFBRRR
|
||||
FFBFBFBLLR
|
||||
FFFBBBFRRR
|
||||
BBFBFBFRLR
|
||||
FFBBFFBLLR
|
||||
FBFBBBBLRL
|
||||
FFFBFBFLRL
|
||||
FFFFBBBRLL
|
||||
FBFFFFBRRR
|
||||
FFBBBFFRLL
|
||||
FBFBFFBRRL
|
||||
BFFBFFBLLL
|
||||
FFFFFBFRLL
|
||||
BBFFFBBRLL
|
||||
FBBFBFBLRL
|
||||
BFBFBFFLLR
|
||||
BFBBFBBRLR
|
||||
FFBFFFBLRR
|
||||
BBFBFFFLRR
|
||||
FBBFBBBLRR
|
||||
FBBBFFBLLR
|
||||
BFBBBBBRRL
|
||||
BFBBFFBLLR
|
||||
FBBBFBFLRR
|
||||
BFFBFBBLLL
|
||||
BFFBFFBLRL
|
||||
BFBFBFBRLR
|
||||
FBFFBBBLRR
|
||||
FBFBBBBRRL
|
||||
BFBFBBFLLL
|
||||
FBFBBBBLRR
|
||||
BFFBBFBRLR
|
||||
FFFBFBFRRL
|
||||
BFFFFBBRRR
|
||||
FBFFBBFRLR
|
||||
BFBBFBFLRL
|
||||
BFFFBBBLLL
|
||||
BFFFFFBRLR
|
||||
BBFFFFBLRL
|
||||
BFFBFFFRRR
|
||||
BFBBBBFRLL
|
||||
FBFBBFBRLL
|
||||
FBBFFFBLLR
|
||||
FFFBBFBRRR
|
||||
FBFBBBBLLR
|
||||
FFFFBFFLLL
|
||||
FFFFFBFRLR
|
||||
BFFFFBFRLR
|
||||
FBBFFFBLRL
|
||||
BFBFFBFLRR
|
||||
FFFFFFBRLL
|
||||
FFBBFFFLRL
|
||||
BBFFFFBLLL
|
||||
FFFBBFFRRL
|
||||
FBBFBBFLLL
|
||||
FBFFBFBLRR
|
||||
FFBBFBBLLL
|
||||
BFFFBBBRRR
|
||||
BFFFBBBLLR
|
||||
BBFBFBFRLL
|
||||
BFFFBBFRLR
|
||||
FFBFBBBRRL
|
||||
FBFBFFFRRR
|
||||
FBBBBBBRRR
|
||||
FFBBBFFLRL
|
||||
BFFBFBBRRL
|
||||
BFBFBFFRLL
|
||||
BFFFBFFRRL
|
||||
BBFFBBBRLR
|
||||
BBFFFFFRLL
|
||||
FFBBFFBRRR
|
||||
FBBFBFFLLR
|
||||
FBBBFBBRLR
|
||||
FFBFFBBRRL
|
||||
FBBBFFBLLL
|
||||
FBBFFFBRRL
|
||||
BFFBFFFRRL
|
||||
FBBFBFFRLR
|
||||
BFFBBBBLRL
|
||||
FFBFFBBRRR
|
||||
FBFBBBFLRR
|
||||
BFBBBBFRLR
|
||||
FFFBFBFLLL
|
||||
FBBBBBBRLL
|
||||
FFBFFBBLRR
|
||||
BBFFFFFLLR
|
||||
FFFFBBFRRL
|
||||
BBFFFFFRLR
|
||||
FBFBFFBRLL
|
||||
BBFFBFBRRR
|
||||
FBFFFBFLLR
|
||||
FFBBFBBLLR
|
||||
FBFBFFFRLL
|
||||
BFBBBFBRLL
|
||||
FFFFFFBRLR
|
||||
FFBBFFFRRL
|
||||
BBFBBFFRLL
|
||||
FBBFFFFRLR
|
||||
BBFBBFFLRL
|
||||
FBBFFBBLLR
|
||||
BFFFBBFLLR
|
||||
BBFBFBBRRL
|
||||
BFFBFFBLLR
|
||||
FFBBFBFRRR
|
||||
FBBBBFBRLR
|
||||
FFFBFBFLLR
|
||||
FFBBBFBRRL
|
||||
FFBBBFFLLL
|
||||
FFBFBBBRLR
|
||||
FBFBBFFLRR
|
||||
FFFBFBBRRL
|
||||
FFFFBFBRRR
|
||||
FFFFBBBLLL
|
||||
FFFBFBFLRR
|
||||
BFBBBFBLLR
|
||||
BFBFFFFRRL
|
||||
BFBBFFBLRR
|
||||
FFBFFBFRRL
|
||||
BFBBFBFRRL
|
||||
BFFFFFBRRL
|
||||
FBBBBFFLLL
|
||||
FFBFBBBLLR
|
||||
FBBBFBFRLR
|
||||
FFFBBFFRLR
|
||||
BBFFBFBRLL
|
||||
BBFBFBFRRL
|
||||
FFBBBBFRRL
|
||||
FBBBFBBLRR
|
||||
BFFBFFBRLR
|
||||
FFBBFFBRLR
|
||||
FFBFBFBLRR
|
||||
BFBFFFBLLR
|
||||
BFFFBBFLRL
|
||||
FBBBFBBRLL
|
||||
BBFFFBFLLR
|
||||
BBFFFBBRRL
|
||||
BFBFFFBRLL
|
||||
BFBFFFBLRR
|
||||
FFBFBFFRLR
|
||||
BFFFFFFRRL
|
||||
BFFFBFFLRR
|
||||
BFBBBBFLRL
|
||||
FFFBFFFLLR
|
||||
BFFFFFFLRR
|
||||
BBFBBFFRRL
|
||||
BFFFFFFLRL
|
||||
FFFFBFBRLL
|
||||
BFFBBFBLRR
|
||||
FFFFBFFLRL
|
||||
BBFFFFFLRL
|
||||
FBBFBFBLRR
|
||||
FBFBBFFRLR
|
||||
FFFFFBBRRR
|
||||
BFFFBFBRRL
|
||||
FBFFBFBRRR
|
||||
BBFFFBBLLR
|
||||
BFFBFBBLRR
|
||||
FFFBFBFRLL
|
||||
FBFBBFFRRR
|
||||
FFBFBBBRRR
|
||||
BFBFFFBRLR
|
||||
FBBFFFBRLL
|
||||
FFBFBFBRRL
|
||||
FFBBBFBLRL
|
||||
FBBFBBBRRL
|
||||
FBFFBFBRLL
|
||||
BFBFBBFLRL
|
||||
FFFBBBBLRR
|
||||
BFFBFBBRLL
|
||||
FFFBFFFRLR
|
||||
FBFBFFBLLR
|
||||
FBFFBBFLLL
|
||||
FBBBFBBRRR
|
||||
FBBFBBBRRR
|
||||
FBFBBBFRRL
|
||||
BFBBFBBRRL
|
||||
BFBFBBBLRL
|
||||
FBBFBBBRLR
|
||||
FFBBFFBLRR
|
||||
FBBFBFFLRL
|
||||
FBFBFFBRRR
|
||||
FFBBBBBLLR
|
||||
BFBBFFFLRR
|
||||
FFBBFBFLRR
|
||||
BFBBBBFLLR
|
||||
BFBFFBBRRL
|
||||
FBFBBFFRRL
|
||||
BFFFFFBLLL
|
||||
FBBBBFBRRL
|
||||
FBBBFFBRLL
|
||||
BBFBFFFLLR
|
||||
FFFBBFBLLL
|
||||
BFFFBBBRLL
|
||||
BFBFFBBLLL
|
||||
BFBFBBBLLR
|
||||
FBFFBBFLRL
|
||||
FFFFBBFLRL
|
||||
FBBFFFFLRL
|
||||
FBBBBFFRRL
|
||||
BFBBFBBLRR
|
||||
BFBFBFBRLL
|
||||
FBBBFBFLLL
|
||||
FBFBBBBRLL
|
||||
FBBBFFBLRR
|
||||
FFBBFBFLRL
|
||||
FFFFBFBLRL
|
||||
FFBBBFFLRR
|
||||
FFBBFFFRRR
|
||||
FFBFFBBRLL
|
||||
FFFFBFFRRL
|
||||
FBBFFBFRLL
|
||||
BFFFBBFLRR
|
||||
BFBFFBBRLL
|
||||
BFFBBFFLLL
|
||||
FBBBBBBLLL
|
||||
BFFBFBFRRR
|
||||
BFBFFFFRLR
|
||||
BFFBFBBLRL
|
||||
BFBBBFBLRL
|
||||
FBFBFBFRLL
|
||||
FBBFBFFLRR
|
||||
BFBBBFBLLL
|
||||
BFFBBBFLRR
|
||||
BFBBBBFLLL
|
||||
BFBBFFBRLR
|
||||
FFFBBFBLRR
|
||||
FFFFBBFLLR
|
||||
FFBFFBBLLR
|
||||
FBFBBBFLLR
|
||||
BFBBBFBRRR
|
||||
BFFFFFBRLL
|
||||
BBFBFFBRRL
|
||||
BFBBFFBLLL
|
||||
FFFBBBBRRL
|
||||
FBFBBBFRRR
|
||||
BFFBBFBLRL
|
||||
BFFBFFFRLR
|
||||
FFFFFBBLRR
|
||||
FBFBFFFLLR
|
||||
FFBFFFFRLR
|
||||
FBFFFBFRRR
|
||||
FBFBFBFRRR
|
||||
FFBFBFBRLL
|
||||
FFFFFFBRRL
|
||||
FFBBBBBRRR
|
||||
FFFBBFFLRL
|
||||
BFFFBFBLLL
|
||||
FBFFFFBLRR
|
||||
FBBBBBBRLR
|
||||
FBFBBFBRRL
|
||||
FFBBFFBLLL
|
||||
FBFFBBFRRR
|
||||
FBFFFFBLLL
|
||||
BBFBFFFRRL
|
||||
FFFFBFBLLR
|
||||
BFFBFBFLLR
|
||||
BBFBFFBRRR
|
||||
FBFFFFFRRR
|
||||
FFBFBFFLRL
|
||||
BFFBBFBLLR
|
||||
FBBBFFFRRL
|
||||
BFFBBFBRRR
|
||||
BFBFBBFLRR
|
||||
FBBBFFFRLR
|
||||
FBBFBFBLLL
|
||||
FBFBFBFLLL
|
||||
BFBBFFFLRL
|
||||
BBFFBBBLLR
|
||||
BFFFFBBRRL
|
||||
FFFBBFBLLR
|
||||
BFFFFBFRLL
|
||||
FFFFFBBLRL
|
||||
FBFBBBFRLL
|
||||
BFBFFBFRLL
|
||||
FBFFBFFLLL
|
||||
FBFBFBBLLR
|
||||
FFFFBFBRLR
|
||||
BFFFBFBLLR
|
||||
BFFBFFBLRR
|
||||
BFFFFBFLRR
|
||||
FBBFFBBRLL
|
||||
FFFFBBBRRL
|
||||
FBBBFFBRRR
|
||||
BFFBFBFRLL
|
||||
BBFFBFBLRL
|
||||
FFFBBFBLRL
|
||||
BBFFFFBLLR
|
||||
FBFFFFBRLL
|
||||
BFBFBBBLLL
|
||||
FBFBBFFLLR
|
||||
FBBBFFFLRR
|
||||
33
2020/days/05/test_day5.py
Normal file
33
2020/days/05/test_day5.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import pytest
|
||||
import day5 as aoc
|
||||
|
||||
PUZZLE_DIR = pathlib.Path(__file__).parent
|
||||
|
||||
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
|
||||
@pytest.fixture
|
||||
def example1():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.fixture
|
||||
def example2():
|
||||
puzzle_input = (PUZZLE_DIR / "input").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_parse_example1(example1):
|
||||
"""Test that input is parsed properly"""
|
||||
assert example1 == {119, 357, 567, 820}
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part1_example1(example1):
|
||||
"""Test part 1 on example input"""
|
||||
assert aoc.part1(example1) == 820
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part2_example2(example2):
|
||||
"""Test part 2 on example input"""
|
||||
assert aoc.part2(example2) == 640
|
||||
47
2020/days/06/day6.py
Executable file
47
2020/days/06/day6.py
Executable file
|
|
@ -0,0 +1,47 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from pprint import pprint
|
||||
|
||||
def parse(puzzle_input: str):
|
||||
"""Parse input"""
|
||||
records = [[list(y) for y in x.splitlines()] for x in puzzle_input.split('\n\n')]
|
||||
return records
|
||||
|
||||
def part1(data):
|
||||
"""Solve part 1"""
|
||||
results = []
|
||||
for group in data:
|
||||
result = set()
|
||||
for person in group:
|
||||
result |= set(person)
|
||||
results.append(len(result))
|
||||
return sum(results)
|
||||
|
||||
def part2(data):
|
||||
"""Solve part 2"""
|
||||
results = []
|
||||
for group in data:
|
||||
result = set(group[0])
|
||||
for person in group:
|
||||
result &= set(person)
|
||||
results.append(len(result))
|
||||
return sum(results)
|
||||
|
||||
def solve(puzzle_input):
|
||||
"""Solve the puzzle for the given input"""
|
||||
data = parse(puzzle_input)
|
||||
solution1 = part1(data)
|
||||
solution2 = part2(data)
|
||||
|
||||
return solution1, solution2
|
||||
|
||||
if __name__ == "__main__":
|
||||
for path in sys.argv[1:]:
|
||||
print(f"{path}:")
|
||||
puzzle_input = pathlib.Path(path).read_text().strip()
|
||||
solutions = solve(puzzle_input)
|
||||
print("\n".join(str(solution) for solution in solutions))
|
||||
15
2020/days/06/example1
Normal file
15
2020/days/06/example1
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
abc
|
||||
|
||||
a
|
||||
b
|
||||
c
|
||||
|
||||
ab
|
||||
ac
|
||||
|
||||
a
|
||||
a
|
||||
a
|
||||
a
|
||||
|
||||
b
|
||||
2199
2020/days/06/input
Normal file
2199
2020/days/06/input
Normal file
File diff suppressed because it is too large
Load diff
55
2020/days/06/test_day6.py
Normal file
55
2020/days/06/test_day6.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import pytest
|
||||
import day6 as aoc
|
||||
|
||||
PUZZLE_DIR = pathlib.Path(__file__).parent
|
||||
|
||||
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
|
||||
@pytest.fixture
|
||||
def example1():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.fixture
|
||||
def example2():
|
||||
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_parse_example1(example1):
|
||||
"""Test that input is parsed properly"""
|
||||
assert example1 == [
|
||||
[
|
||||
['a', 'b', 'c']
|
||||
],
|
||||
[
|
||||
['a'],
|
||||
['b'],
|
||||
['c']
|
||||
],
|
||||
[
|
||||
['a', 'b'],
|
||||
['a', 'c']
|
||||
],
|
||||
[
|
||||
['a'],
|
||||
['a'],
|
||||
['a'],
|
||||
['a']
|
||||
],
|
||||
[
|
||||
['b']
|
||||
]
|
||||
]
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part1_example1(example1):
|
||||
"""Test part 1 on example input"""
|
||||
assert aoc.part1(example1) == 11
|
||||
|
||||
# @pytest.mark.skip(reason="Not implemented")
|
||||
def test_part2_example2(example1):
|
||||
"""Test part 2 on example input"""
|
||||
assert aoc.part2(example1) == 6
|
||||
6
2020/main.py
Normal file
6
2020/main.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
def main():
|
||||
print("Hello from 2020!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
9
2020/pyproject.toml
Normal file
9
2020/pyproject.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[project]
|
||||
name = "AOC-2020"
|
||||
version = "0.1.0"
|
||||
description = "Advent of code 2020 in python."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"pytest>=9.0.3",
|
||||
]
|
||||
31
2020/template/template.py
Executable file
31
2020/template/template.py
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import sys
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
from pprint import pprint
|
||||
|
||||
def parse(puzzle_input: str):
|
||||
"""Parse input"""
|
||||
|
||||
def part1(data):
|
||||
"""Solve part 1"""
|
||||
|
||||
def part2(data):
|
||||
"""Solve part 2"""
|
||||
|
||||
def solve(puzzle_input):
|
||||
"""Solve the puzzle for the given input"""
|
||||
data = parse(puzzle_input)
|
||||
solution1 = part1(data)
|
||||
solution2 = part2(data)
|
||||
|
||||
return solution1, solution2
|
||||
|
||||
if __name__ == "__main__":
|
||||
for path in sys.argv[1:]:
|
||||
print(f"{path}:")
|
||||
puzzle_input = pathlib.Path(path).read_text().strip()
|
||||
solutions = solve(puzzle_input)
|
||||
print("\n".join(str(solution) for solution in solutions))
|
||||
33
2020/template/test_template.py
Normal file
33
2020/template/test_template.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#! /usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import pytest
|
||||
import template as aoc
|
||||
|
||||
PUZZLE_DIR = pathlib.Path(__file__).parent
|
||||
|
||||
#these test fixtures setup the test, mainly by reading the filename into a string in this simple case.
|
||||
@pytest.fixture
|
||||
def example1():
|
||||
puzzle_input = (PUZZLE_DIR / "example1").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.fixture
|
||||
def example2():
|
||||
puzzle_input = (PUZZLE_DIR / "example2").read_text().strip()
|
||||
return aoc.parse(puzzle_input)
|
||||
|
||||
@pytest.mark.skip(reason="Not implemented")
|
||||
def test_parse_example1(example1):
|
||||
"""Test that input is parsed properly"""
|
||||
assert example1 == ...
|
||||
|
||||
@pytest.mark.skip(reason="Not implemented")
|
||||
def test_part1_example1(example1):
|
||||
"""Test part 1 on example input"""
|
||||
assert aoc.part1(example1) == ...
|
||||
|
||||
@pytest.mark.skip(reason="Not implemented")
|
||||
def test_part2_example2(example2):
|
||||
"""Test part 2 on example input"""
|
||||
assert aoc.part2(example2) == ...
|
||||
75
2020/uv.lock
generated
Normal file
75
2020/uv.lock
generated
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.13"
|
||||
|
||||
[[package]]
|
||||
name = "aoc-2020"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "pytest" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "pytest", specifier = ">=9.0.3" }]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "26.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/df/de/0d2b39fb4af88a0258f3bac87dfcbb48e73fbdea4a2ed0e2213f9a4c2f9a/packaging-26.1.tar.gz", hash = "sha256:f042152b681c4bfac5cae2742a55e103d27ab2ec0f3d88037136b6bfe7c9c5de", size = 215519, upload-time = "2026-04-14T21:12:49.362Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl", hash = "sha256:5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f", size = 95831, upload-time = "2026-04-14T21:12:47.56Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.20.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "9.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "iniconfig" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pluggy" },
|
||||
{ name = "pygments" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" },
|
||||
]
|
||||
1
2022/.gitignore
vendored
Normal file
1
2022/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
197
2022/Cargo.lock
generated
Normal file
197
2022/Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aoc_libs"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day01"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day02"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day03"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day04"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day05"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day06"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day07"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day08"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "day09"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc_libs",
|
||||
"once_cell",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day10"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc_libs",
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "template"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc_libs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
21
2022/Cargo.toml
Normal file
21
2022/Cargo.toml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"template",
|
||||
"aoc_libs",
|
||||
"days/*",
|
||||
]
|
||||
default-members = [ "days/*", "aoc_libs" ]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
authors = ["Gabriel Venberg"]
|
||||
edition = "2021"
|
||||
description = "advent of code 2022 in rust"
|
||||
|
||||
[workspace.dependencies]
|
||||
aoc_libs = {path = "./aoc_libs"}
|
||||
regex = "1"
|
||||
once_cell = "1.16"
|
||||
thiserror = "1.0"
|
||||
nom = "7.1"
|
||||
6
2022/aoc_libs/Cargo.toml
Normal file
6
2022/aoc_libs/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "aoc_libs"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
description.workspace = true
|
||||
1
2022/aoc_libs/src/lib.rs
Normal file
1
2022/aoc_libs/src/lib.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod points;
|
||||
211
2022/aoc_libs/src/points.rs
Normal file
211
2022/aoc_libs/src/points.rs
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Hash)]
|
||||
pub struct Point {
|
||||
pub x: isize,
|
||||
pub y: isize,
|
||||
}
|
||||
|
||||
impl Point {
|
||||
/// converts a point (representing a point on a 4 quadrant grid with positive xy in the
|
||||
/// top-right) into a upoint (representing a point on a 1 quadrant grid with the origin in the
|
||||
/// top-left corner). Returns none if the resulting point would have either number negative.
|
||||
pub fn to_upoint(self, zero_coord: &UPoint) -> Option<UPoint> {
|
||||
Some(UPoint {
|
||||
x: zero_coord.x.checked_add_signed(self.x)?,
|
||||
y: zero_coord.y.checked_add_signed(-self.y)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign for Point {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x - rhs.x,
|
||||
y: self.y - rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::SubAssign for Point {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = *self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Neg for Point {
|
||||
type Output = Point;
|
||||
|
||||
fn neg(self) -> Self::Output {
|
||||
Point {
|
||||
x: -self.x,
|
||||
y: -self.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// an unsigned point in 2d space
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct UPoint {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
}
|
||||
|
||||
impl UPoint {
|
||||
/// converts a upoint (representing a point on a 1 quadrant grid with the origin in the
|
||||
/// top-left corner) into a point( representing a point on a 4 quadrant grid with positive xy
|
||||
/// in the top-right)
|
||||
pub fn to_point(self, zero_coord: &UPoint) -> Point {
|
||||
Point {
|
||||
x: -(zero_coord.x as isize - self.x as isize),
|
||||
y: zero_coord.y as isize - self.y as isize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Add for UPoint {
|
||||
type Output = UPoint;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::AddAssign for UPoint {
|
||||
fn add_assign(&mut self, rhs: Self) {
|
||||
*self = *self + rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for UPoint {
|
||||
type Output = UPoint;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x - rhs.x,
|
||||
y: self.y - rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::SubAssign for UPoint {
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = *self - rhs
|
||||
}
|
||||
}
|
||||
|
||||
/// A matrix that allows negative co-oordinates. Will panic if referencing out of bounds, just like
|
||||
/// a normal 2d array.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct FourQuadrantMatrix<const X: usize, const Y: usize, T> {
|
||||
matrix: [[T; X]; Y],
|
||||
max_point: Point,
|
||||
min_point: Point,
|
||||
zero_coord: UPoint,
|
||||
}
|
||||
|
||||
impl<const X: usize, const Y: usize, T> FourQuadrantMatrix<{ X }, { Y }, T>
|
||||
where
|
||||
T: Copy,
|
||||
T: Default,
|
||||
{
|
||||
/// generates a new FourQuadrantMatrix with a given zero point (the point in the underlying 2d
|
||||
/// array considered to be (0,0))
|
||||
pub fn new(zero_coord: UPoint) -> FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||
FourQuadrantMatrix {
|
||||
matrix: [[T::default(); X]; Y],
|
||||
max_point: UPoint { x: X - 1, y: 0 }.to_point(&zero_coord),
|
||||
min_point: UPoint { x: 0, y: Y - 1 }.to_point(&zero_coord),
|
||||
zero_coord,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn zero_coord(&self) -> UPoint {
|
||||
self.zero_coord
|
||||
}
|
||||
|
||||
pub fn min_point(&self) -> Point {
|
||||
self.min_point
|
||||
}
|
||||
|
||||
pub fn max_point(&self) -> Point {
|
||||
self.max_point
|
||||
}
|
||||
|
||||
/// makes sure a point is in bounds and if not, brings it in bounds.
|
||||
pub fn bound_point(&self, point: &mut Point) {
|
||||
if point.x > self.max_point.x {
|
||||
point.x = self.max_point.x
|
||||
}
|
||||
|
||||
if point.y > self.max_point.y {
|
||||
point.y = self.max_point.y
|
||||
}
|
||||
|
||||
if point.x < self.min_point.x {
|
||||
point.x = self.min_point.x
|
||||
}
|
||||
|
||||
if point.y < self.min_point.y {
|
||||
point.y = self.min_point.y
|
||||
}
|
||||
}
|
||||
|
||||
/// checks if the point is in bounds.
|
||||
pub fn is_in_bounds(&self, point: &Point) -> bool {
|
||||
point.x <= self.max_point.x
|
||||
&& point.y <= self.max_point.y
|
||||
&& point.x >= self.min_point.x
|
||||
&& point.y >= self.min_point.y
|
||||
}
|
||||
/// fills the matrix with the Ts default value.
|
||||
pub fn reset_matrix(&mut self) {
|
||||
self.matrix = [[T::default(); X]; Y];
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const X: usize, const Y: usize> std::ops::IndexMut<Point> for FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||
fn index_mut(&mut self, index: Point) -> &mut Self::Output {
|
||||
let upoint = index
|
||||
.to_upoint(&self.zero_coord)
|
||||
.expect("would result in negative unsigned coordinate!");
|
||||
&mut self.matrix[upoint.y][upoint.x]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const X: usize, const Y: usize> std::ops::Index<Point> for FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||
type Output = T;
|
||||
|
||||
fn index(&self, index: Point) -> &Self::Output {
|
||||
let upoint = index
|
||||
.to_upoint(&self.zero_coord)
|
||||
.expect("would result in negative unsigned coordinate!");
|
||||
&self.matrix[upoint.y][upoint.x]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, const X: usize, const Y: usize> From<FourQuadrantMatrix<{ X }, { Y }, T>> for [[T; X]; Y] {
|
||||
fn from(value: FourQuadrantMatrix<{ X }, { Y }, T>) -> Self {
|
||||
value.matrix
|
||||
}
|
||||
}
|
||||
6
2022/days/01/Cargo.toml
Normal file
6
2022/days/01/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day01"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
2255
2022/days/01/src/input.txt
Normal file
2255
2022/days/01/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
14
2022/days/01/src/main.rs
Normal file
14
2022/days/01/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod parse;
|
||||
mod part1;
|
||||
mod part2;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = parse::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&_structured_input));
|
||||
}
|
||||
48
2022/days/01/src/parse.rs
Normal file
48
2022/days/01/src/parse.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Elf(pub Vec<usize>);
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Elf> {
|
||||
input
|
||||
.trim()
|
||||
.split("\n\n")
|
||||
.map(|group| {
|
||||
Elf(group
|
||||
.split('\n')
|
||||
.map(|line| line.parse().unwrap())
|
||||
.collect())
|
||||
})
|
||||
.collect::<Vec<Elf>>()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "1000
|
||||
2000
|
||||
3000
|
||||
|
||||
4000
|
||||
|
||||
5000
|
||||
6000
|
||||
|
||||
7000
|
||||
8000
|
||||
9000
|
||||
|
||||
10000";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Elf(vec![1000, 2000, 3000]),
|
||||
Elf(vec![4000]),
|
||||
Elf(vec![5000, 6000]),
|
||||
Elf(vec![7000, 8000, 9000]),
|
||||
Elf(vec![10000])
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
27
2022/days/01/src/part1.rs
Normal file
27
2022/days/01/src/part1.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::parse;
|
||||
|
||||
pub fn part1(input: &[parse::Elf]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.map(|elf| elf.0.iter().sum::<usize>())
|
||||
.max()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
parse::Elf(vec![1000, 2000, 3000]),
|
||||
parse::Elf(vec![4000]),
|
||||
parse::Elf(vec![5000, 6000]),
|
||||
parse::Elf(vec![7000, 8000, 9000]),
|
||||
parse::Elf(vec![10000]),
|
||||
];
|
||||
|
||||
assert_eq!(part1(&input), 24000);
|
||||
}
|
||||
}
|
||||
27
2022/days/01/src/part2.rs
Normal file
27
2022/days/01/src/part2.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::parse;
|
||||
|
||||
pub fn part2(input: &[parse::Elf]) -> usize {
|
||||
let mut input = input
|
||||
.iter()
|
||||
.map(|elf| elf.0.iter().sum::<usize>())
|
||||
.collect::<Vec<usize>>();
|
||||
input.sort_unstable();
|
||||
input[input.len() - 3..].iter().sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
parse::Elf(vec![1000, 2000, 3000]),
|
||||
parse::Elf(vec![4000]),
|
||||
parse::Elf(vec![5000, 6000]),
|
||||
parse::Elf(vec![7000, 8000, 9000]),
|
||||
parse::Elf(vec![10000]),
|
||||
];
|
||||
assert_eq!(part2(&input), 45000);
|
||||
}
|
||||
}
|
||||
6
2022/days/02/Cargo.toml
Normal file
6
2022/days/02/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day02"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
2500
2022/days/02/src/input.txt
Normal file
2500
2022/days/02/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
13
2022/days/02/src/main.rs
Normal file
13
2022/days/02/src/main.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(_input));
|
||||
}
|
||||
62
2022/days/02/src/part1.rs
Normal file
62
2022/days/02/src/part1.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
use crate::utilities::*;
|
||||
pub fn part1(input: &str) -> usize {
|
||||
parse(input).iter().map(calc_score).sum()
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Strategy> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let elf = match line.as_bytes()[0] {
|
||||
b'A' => Play::Rock,
|
||||
b'B' => Play::Paper,
|
||||
b'C' => Play::Scissors,
|
||||
_ => panic!("your opponent not playing defined strategy!"),
|
||||
};
|
||||
let you = match line.as_bytes()[2] {
|
||||
b'X' => Play::Rock,
|
||||
b'Y' => Play::Paper,
|
||||
b'Z' => Play::Scissors,
|
||||
_ => panic!("you are not playing defined strategy!"),
|
||||
};
|
||||
Strategy { elf, you }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = "A Y
|
||||
B X
|
||||
C Z";
|
||||
assert_eq!(part1(input), 15);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "A Y
|
||||
B X
|
||||
C Z";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Strategy {
|
||||
elf: Play::Rock,
|
||||
you: Play::Paper
|
||||
},
|
||||
Strategy {
|
||||
elf: Play::Paper,
|
||||
you: Play::Rock
|
||||
},
|
||||
Strategy {
|
||||
elf: Play::Scissors,
|
||||
you: Play::Scissors
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
87
2022/days/02/src/part2.rs
Normal file
87
2022/days/02/src/part2.rs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub enum GameResult {
|
||||
Win,
|
||||
Loss,
|
||||
Draw,
|
||||
}
|
||||
|
||||
pub struct ResultStrategy {
|
||||
pub elf: Play,
|
||||
pub you: GameResult,
|
||||
}
|
||||
|
||||
pub fn part2(input: &str) -> usize {
|
||||
parse(input)
|
||||
.iter()
|
||||
.map(gen_strategy)
|
||||
.map(|strat| calc_score(&strat))
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn gen_strategy(input: &ResultStrategy) -> Strategy {
|
||||
match input.you {
|
||||
GameResult::Win => Strategy {
|
||||
elf: input.elf,
|
||||
you: gen_win(input.elf),
|
||||
},
|
||||
GameResult::Draw => Strategy {
|
||||
elf: input.elf,
|
||||
you: input.elf,
|
||||
},
|
||||
GameResult::Loss => Strategy {
|
||||
elf: input.elf,
|
||||
you: gen_loss(input.elf),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_win(opponent: Play) -> Play {
|
||||
match opponent {
|
||||
Play::Rock => Play::Paper,
|
||||
Play::Paper => Play::Scissors,
|
||||
Play::Scissors => Play::Rock,
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_loss(opponent: Play) -> Play {
|
||||
match opponent {
|
||||
Play::Rock => Play::Scissors,
|
||||
Play::Paper => Play::Rock,
|
||||
Play::Scissors => Play::Paper,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Vec<ResultStrategy> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let elf = match line.as_bytes()[0] {
|
||||
b'A' => Play::Rock,
|
||||
b'B' => Play::Paper,
|
||||
b'C' => Play::Scissors,
|
||||
_ => panic!("your opponent not playing defined strategy!"),
|
||||
};
|
||||
let you = match line.as_bytes()[2] {
|
||||
b'X' => GameResult::Loss,
|
||||
b'Y' => GameResult::Draw,
|
||||
b'Z' => GameResult::Win,
|
||||
_ => panic!("you are not playing defined strategy!"),
|
||||
};
|
||||
ResultStrategy { elf, you }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = "A Y
|
||||
B X
|
||||
C Z";
|
||||
assert_eq!(part2(input), 12);
|
||||
}
|
||||
}
|
||||
36
2022/days/02/src/utilities.rs
Normal file
36
2022/days/02/src/utilities.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Play {
|
||||
Rock = 1,
|
||||
Paper = 2,
|
||||
Scissors = 3,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Strategy {
|
||||
pub elf: Play,
|
||||
pub you: Play,
|
||||
}
|
||||
|
||||
pub fn calc_score(input: &Strategy) -> usize {
|
||||
//an enum wins if (you-elf)%3 = 1, looses if it = 2
|
||||
(match (input.you as i8 - input.elf as i8).rem_euclid(3) {
|
||||
1 => 6,
|
||||
2 => 0,
|
||||
0 => 3,
|
||||
_ => unreachable!("you were {}, elf was {}", input.you as i8, input.elf as i8),
|
||||
}) + input.you as usize //play enum has value corresponding to its score.
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_calc_score() {
|
||||
let input = Strategy {
|
||||
elf: Play::Scissors,
|
||||
you: Play::Scissors,
|
||||
};
|
||||
assert_eq!(calc_score(&input), 6);
|
||||
}
|
||||
}
|
||||
6
2022/days/03/Cargo.toml
Normal file
6
2022/days/03/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day03"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
300
2022/days/03/src/input.txt
Normal file
300
2022/days/03/src/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
|
||||
14
2022/days/03/src/main.rs
Normal file
14
2022/days/03/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&_structured_input));
|
||||
}
|
||||
54
2022/days/03/src/part1.rs
Normal file
54
2022/days/03/src/part1.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &[Rucksack]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.map(|rucksack| rucksack.0.intersection(&rucksack.1).next().unwrap())
|
||||
.map(find_char_score)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Rucksack(
|
||||
HashSet::from(['v', 'J', 'r', 'w', 'p', 'W', 't', 'w', 'J', 'g', 'W', 'r']),
|
||||
HashSet::from(['h', 'c', 's', 'F', 'M', 'M', 'f', 'F', 'F', 'h', 'F', 'p']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'j', 'q', 'H', 'R', 'N', 'q', 'R', 'j', 'q', 'z', 'j', 'G', 'D', 'L', 'G', 'L',
|
||||
]),
|
||||
HashSet::from([
|
||||
'r', 's', 'F', 'M', 'f', 'F', 'Z', 'S', 'r', 'L', 'r', 'F', 'Z', 's', 'S', 'L',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['P', 'm', 'm', 'd', 'z', 'q', 'P', 'r', 'V']),
|
||||
HashSet::from(['v', 'P', 'w', 'w', 'T', 'W', 'B', 'w', 'g']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'w', 'M', 'q', 'v', 'L', 'M', 'Z', 'H', 'h', 'H', 'M', 'v', 'w', 'L', 'H',
|
||||
]),
|
||||
HashSet::from([
|
||||
'j', 'b', 'v', 'c', 'j', 'n', 'n', 'S', 'B', 'n', 'v', 'T', 'Q', 'F', 'n',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['t', 't', 'g', 'J', 't', 'R', 'G', 'J']),
|
||||
HashSet::from(['Q', 'c', 't', 'T', 'Z', 't', 'Z', 'T']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['C', 'r', 'Z', 's', 'J', 's', 'P', 'P', 'Z', 's', 'G', 'z']),
|
||||
HashSet::from(['w', 'w', 's', 'L', 'w', 'L', 'm', 'p', 'w', 'M', 'D', 'w']),
|
||||
),
|
||||
];
|
||||
assert_eq!(part1(&input), 157);
|
||||
}
|
||||
}
|
||||
78
2022/days/03/src/part2.rs
Normal file
78
2022/days/03/src/part2.rs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
use crate::utilities::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
struct Group(HashSet<char>, HashSet<char>, HashSet<char>);
|
||||
|
||||
pub fn part2(input: &[Rucksack]) -> usize {
|
||||
seperate_groups(input)
|
||||
.iter()
|
||||
.map(|group| {
|
||||
//manual implementation of intersection because doing chained intersections is annoying...
|
||||
group
|
||||
.0
|
||||
.iter()
|
||||
.filter(|c| group.1.contains(c))
|
||||
.filter(|c| group.2.contains(c))
|
||||
.next()
|
||||
.unwrap()
|
||||
})
|
||||
.map(find_char_score)
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn seperate_groups(input: &[Rucksack]) -> Vec<Group> {
|
||||
let mut output: Vec<Group> = Vec::new();
|
||||
for group in input.chunks_exact(3) {
|
||||
output.push(Group(
|
||||
group[0].0.union(&group[0].1).copied().collect(),
|
||||
group[1].0.union(&group[1].1).copied().collect(),
|
||||
group[2].0.union(&group[2].1).copied().collect(),
|
||||
));
|
||||
}
|
||||
output
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
Rucksack(
|
||||
HashSet::from(['v', 'J', 'r', 'w', 'p', 'W', 't', 'w', 'J', 'g', 'W', 'r']),
|
||||
HashSet::from(['h', 'c', 's', 'F', 'M', 'M', 'f', 'F', 'F', 'h', 'F', 'p']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'j', 'q', 'H', 'R', 'N', 'q', 'R', 'j', 'q', 'z', 'j', 'G', 'D', 'L', 'G', 'L',
|
||||
]),
|
||||
HashSet::from([
|
||||
'r', 's', 'F', 'M', 'f', 'F', 'Z', 'S', 'r', 'L', 'r', 'F', 'Z', 's', 'S', 'L',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['P', 'm', 'm', 'd', 'z', 'q', 'P', 'r', 'V']),
|
||||
HashSet::from(['v', 'P', 'w', 'w', 'T', 'W', 'B', 'w', 'g']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'w', 'M', 'q', 'v', 'L', 'M', 'Z', 'H', 'h', 'H', 'M', 'v', 'w', 'L', 'H',
|
||||
]),
|
||||
HashSet::from([
|
||||
'j', 'b', 'v', 'c', 'j', 'n', 'n', 'S', 'B', 'n', 'v', 'T', 'Q', 'F', 'n',
|
||||
]),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['t', 't', 'g', 'J', 't', 'R', 'G', 'J']),
|
||||
HashSet::from(['Q', 'c', 't', 'T', 'Z', 't', 'Z', 'T']),
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['C', 'r', 'Z', 's', 'J', 's', 'P', 'P', 'Z', 's', 'G', 'z']),
|
||||
HashSet::from(['w', 'w', 's', 'L', 'w', 'L', 'm', 'p', 'w', 'M', 'D', 'w']),
|
||||
),
|
||||
];
|
||||
assert_eq!(part2(&input), 70);
|
||||
}
|
||||
}
|
||||
93
2022/days/03/src/utilities.rs
Normal file
93
2022/days/03/src/utilities.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use std::collections::HashSet;
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Rucksack(pub HashSet<char>, pub HashSet<char>);
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Rucksack> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let (first, second) = line.split_at(line.len() / 2);
|
||||
Rucksack(first.chars().collect(), second.chars().collect())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn find_char_score(input: &char) -> usize {
|
||||
if input.is_uppercase() {
|
||||
*input as usize - 38
|
||||
} else {
|
||||
*input as usize - 96
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_find_char_score() {
|
||||
static CHARS: [char; 52] = [
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
|
||||
'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
|
||||
'Z',
|
||||
];
|
||||
|
||||
for character in CHARS {
|
||||
println!("{}", character);
|
||||
assert_eq!(
|
||||
find_char_score(&character),
|
||||
CHARS.iter().position(|c| *c == character).unwrap() + 1
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "vJrwpWtwJgWrhcsFMMfFFhFp
|
||||
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
|
||||
PmmdzqPrVvPwwTWBwg
|
||||
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
|
||||
ttgJtRGJQctTZtZT
|
||||
CrZsJsPPZsGzwwsLwLmpwMDw";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Rucksack(
|
||||
HashSet::from(['v', 'J', 'r', 'w', 'p', 'W', 't', 'w', 'J', 'g', 'W', 'r']),
|
||||
HashSet::from(['h', 'c', 's', 'F', 'M', 'M', 'f', 'F', 'F', 'h', 'F', 'p'])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'j', 'q', 'H', 'R', 'N', 'q', 'R', 'j', 'q', 'z', 'j', 'G', 'D', 'L', 'G',
|
||||
'L'
|
||||
]),
|
||||
HashSet::from([
|
||||
'r', 's', 'F', 'M', 'f', 'F', 'Z', 'S', 'r', 'L', 'r', 'F', 'Z', 's', 'S',
|
||||
'L'
|
||||
])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['P', 'm', 'm', 'd', 'z', 'q', 'P', 'r', 'V']),
|
||||
HashSet::from(['v', 'P', 'w', 'w', 'T', 'W', 'B', 'w', 'g'])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from([
|
||||
'w', 'M', 'q', 'v', 'L', 'M', 'Z', 'H', 'h', 'H', 'M', 'v', 'w', 'L', 'H',
|
||||
]),
|
||||
HashSet::from([
|
||||
'j', 'b', 'v', 'c', 'j', 'n', 'n', 'S', 'B', 'n', 'v', 'T', 'Q', 'F', 'n',
|
||||
])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['t', 't', 'g', 'J', 't', 'R', 'G', 'J',]),
|
||||
HashSet::from(['Q', 'c', 't', 'T', 'Z', 't', 'Z', 'T',])
|
||||
),
|
||||
Rucksack(
|
||||
HashSet::from(['C', 'r', 'Z', 's', 'J', 's', 'P', 'P', 'Z', 's', 'G', 'z',]),
|
||||
HashSet::from(['w', 'w', 's', 'L', 'w', 'L', 'm', 'p', 'w', 'M', 'D', 'w',])
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
10
2022/days/04/Cargo.toml
Normal file
10
2022/days/04/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day04"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
1000
2022/days/04/src/input.txt
Normal file
1000
2022/days/04/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
14
2022/days/04/src/main.rs
Normal file
14
2022/days/04/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&_structured_input));
|
||||
}
|
||||
27
2022/days/04/src/part1.rs
Normal file
27
2022/days/04/src/part1.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &[(Range, Range)]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.filter(|tuple| tuple.0.complete_overlap(&tuple.1))
|
||||
.count()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
(Range::new(2, 4), Range::new(6, 8)),
|
||||
(Range::new(2, 3), Range::new(4, 5)),
|
||||
(Range::new(5, 7), Range::new(7, 9)),
|
||||
(Range::new(2, 8), Range::new(3, 7)),
|
||||
(Range::new(6, 6), Range::new(4, 6)),
|
||||
(Range::new(2, 6), Range::new(4, 8)),
|
||||
(Range::new(19, 30), Range::new(5, 18)),
|
||||
];
|
||||
assert_eq!(part1(&input), 2);
|
||||
}
|
||||
}
|
||||
27
2022/days/04/src/part2.rs
Normal file
27
2022/days/04/src/part2.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part2(input: &[(Range, Range)]) -> usize {
|
||||
input
|
||||
.iter()
|
||||
.filter(|tuple| tuple.0.any_overlap(&tuple.1))
|
||||
.count()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
(Range::new(2, 4), Range::new(6, 8)),
|
||||
(Range::new(2, 3), Range::new(4, 5)),
|
||||
(Range::new(5, 7), Range::new(7, 9)),
|
||||
(Range::new(2, 8), Range::new(3, 7)),
|
||||
(Range::new(6, 6), Range::new(4, 6)),
|
||||
(Range::new(2, 6), Range::new(4, 8)),
|
||||
(Range::new(19, 30), Range::new(5, 18)),
|
||||
];
|
||||
assert_eq!(part2(&input), 4);
|
||||
}
|
||||
}
|
||||
79
2022/days/04/src/utilities.rs
Normal file
79
2022/days/04/src/utilities.rs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Range {
|
||||
start: u16,
|
||||
end: u16,
|
||||
}
|
||||
|
||||
impl Range {
|
||||
pub fn new(start: u16, end: u16) -> Self {
|
||||
Self {
|
||||
start: start.min(end),
|
||||
end: end.max(start),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_overlap(&self, other: &Self) -> bool {
|
||||
self.start <= other.end && self.end >= other.start
|
||||
}
|
||||
|
||||
pub fn calc_overlap(&self, other: &Self) -> Range {
|
||||
let overlap_start = self.start.min(other.start);
|
||||
let overlap_end = self.end.max(other.end);
|
||||
Range::new(overlap_start, overlap_end)
|
||||
}
|
||||
|
||||
pub fn complete_overlap(&self, other: &Self) -> bool {
|
||||
self.calc_overlap(other) == *self || self.calc_overlap(other) == *other
|
||||
}
|
||||
}
|
||||
|
||||
static PARSE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^(\d+)-(\d+),(\d+)-(\d+)").unwrap());
|
||||
|
||||
pub fn parse(input: &str) -> Vec<(Range, Range)> {
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let cap = PARSE_REGEX.captures(line).unwrap();
|
||||
(
|
||||
Range::new(
|
||||
cap.get(1).unwrap().as_str().parse().unwrap(),
|
||||
cap.get(2).unwrap().as_str().parse().unwrap(),
|
||||
),
|
||||
Range::new(
|
||||
cap.get(3).unwrap().as_str().parse().unwrap(),
|
||||
cap.get(4).unwrap().as_str().parse().unwrap(),
|
||||
),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "2-4,6-8
|
||||
2-3,4-5
|
||||
5-7,7-9
|
||||
2-8,3-7
|
||||
6-6,4-6
|
||||
2-6,4-8
|
||||
19-30,5-18";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
(Range::new(2, 4), Range::new(6, 8)),
|
||||
(Range::new(2, 3), Range::new(4, 5)),
|
||||
(Range::new(5, 7), Range::new(7, 9)),
|
||||
(Range::new(2, 8), Range::new(3, 7)),
|
||||
(Range::new(6, 6), Range::new(4, 6)),
|
||||
(Range::new(2, 6), Range::new(4, 8)),
|
||||
(Range::new(19, 30), Range::new(5, 18)),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
10
2022/days/05/Cargo.toml
Normal file
10
2022/days/05/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day05"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
514
2022/days/05/src/input.txt
Normal file
514
2022/days/05/src/input.txt
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
[S] [C] [Z]
|
||||
[F] [J] [P] [T] [N]
|
||||
[G] [H] [G] [Q] [G] [D]
|
||||
[V] [V] [D] [G] [F] [D] [V]
|
||||
[R] [B] [F] [N] [N] [Q] [L] [S]
|
||||
[J] [M] [M] [P] [H] [V] [B] [B] [D]
|
||||
[L] [P] [H] [D] [L] [F] [D] [J] [L]
|
||||
[D] [T] [V] [M] [J] [N] [F] [M] [G]
|
||||
1 2 3 4 5 6 7 8 9
|
||||
|
||||
move 3 from 4 to 6
|
||||
move 1 from 5 to 8
|
||||
move 3 from 7 to 3
|
||||
move 4 from 5 to 7
|
||||
move 1 from 7 to 8
|
||||
move 3 from 9 to 4
|
||||
move 2 from 8 to 2
|
||||
move 4 from 4 to 5
|
||||
move 2 from 5 to 1
|
||||
move 2 from 5 to 6
|
||||
move 7 from 8 to 1
|
||||
move 9 from 3 to 9
|
||||
move 11 from 6 to 5
|
||||
move 2 from 6 to 7
|
||||
move 12 from 1 to 4
|
||||
move 10 from 2 to 9
|
||||
move 2 from 3 to 9
|
||||
move 1 from 7 to 5
|
||||
move 4 from 7 to 6
|
||||
move 2 from 6 to 1
|
||||
move 5 from 1 to 6
|
||||
move 10 from 9 to 1
|
||||
move 9 from 9 to 8
|
||||
move 13 from 4 to 3
|
||||
move 7 from 6 to 2
|
||||
move 2 from 8 to 5
|
||||
move 9 from 3 to 9
|
||||
move 8 from 9 to 8
|
||||
move 4 from 8 to 4
|
||||
move 1 from 7 to 5
|
||||
move 3 from 9 to 1
|
||||
move 7 from 2 to 1
|
||||
move 1 from 3 to 1
|
||||
move 1 from 3 to 6
|
||||
move 1 from 6 to 1
|
||||
move 2 from 3 to 6
|
||||
move 5 from 4 to 1
|
||||
move 1 from 6 to 1
|
||||
move 3 from 8 to 7
|
||||
move 8 from 8 to 4
|
||||
move 3 from 5 to 4
|
||||
move 1 from 6 to 7
|
||||
move 1 from 5 to 8
|
||||
move 4 from 5 to 2
|
||||
move 7 from 5 to 8
|
||||
move 3 from 2 to 7
|
||||
move 7 from 4 to 8
|
||||
move 11 from 8 to 4
|
||||
move 15 from 4 to 1
|
||||
move 25 from 1 to 6
|
||||
move 4 from 8 to 7
|
||||
move 1 from 2 to 4
|
||||
move 11 from 6 to 4
|
||||
move 12 from 6 to 3
|
||||
move 1 from 1 to 9
|
||||
move 1 from 9 to 8
|
||||
move 16 from 1 to 3
|
||||
move 1 from 8 to 7
|
||||
move 12 from 4 to 6
|
||||
move 9 from 6 to 5
|
||||
move 3 from 6 to 5
|
||||
move 6 from 7 to 5
|
||||
move 3 from 3 to 5
|
||||
move 2 from 6 to 3
|
||||
move 11 from 5 to 8
|
||||
move 2 from 8 to 3
|
||||
move 2 from 1 to 4
|
||||
move 7 from 3 to 1
|
||||
move 2 from 4 to 6
|
||||
move 2 from 6 to 2
|
||||
move 5 from 7 to 3
|
||||
move 1 from 1 to 6
|
||||
move 1 from 1 to 8
|
||||
move 2 from 2 to 5
|
||||
move 1 from 7 to 4
|
||||
move 1 from 1 to 2
|
||||
move 10 from 3 to 5
|
||||
move 11 from 3 to 6
|
||||
move 1 from 4 to 9
|
||||
move 1 from 9 to 4
|
||||
move 1 from 4 to 2
|
||||
move 2 from 5 to 9
|
||||
move 2 from 2 to 8
|
||||
move 2 from 1 to 6
|
||||
move 2 from 1 to 2
|
||||
move 2 from 3 to 6
|
||||
move 3 from 8 to 1
|
||||
move 3 from 1 to 4
|
||||
move 7 from 8 to 3
|
||||
move 2 from 9 to 5
|
||||
move 2 from 4 to 9
|
||||
move 7 from 5 to 6
|
||||
move 2 from 8 to 6
|
||||
move 1 from 4 to 8
|
||||
move 2 from 2 to 4
|
||||
move 21 from 6 to 3
|
||||
move 10 from 5 to 7
|
||||
move 7 from 7 to 6
|
||||
move 1 from 9 to 3
|
||||
move 1 from 4 to 9
|
||||
move 1 from 9 to 4
|
||||
move 1 from 8 to 4
|
||||
move 8 from 6 to 4
|
||||
move 1 from 4 to 5
|
||||
move 1 from 5 to 8
|
||||
move 4 from 3 to 6
|
||||
move 1 from 8 to 2
|
||||
move 1 from 4 to 2
|
||||
move 2 from 7 to 3
|
||||
move 2 from 2 to 7
|
||||
move 22 from 3 to 5
|
||||
move 4 from 6 to 2
|
||||
move 2 from 6 to 9
|
||||
move 7 from 3 to 9
|
||||
move 6 from 9 to 1
|
||||
move 18 from 5 to 3
|
||||
move 2 from 5 to 4
|
||||
move 20 from 3 to 5
|
||||
move 3 from 7 to 3
|
||||
move 5 from 1 to 2
|
||||
move 11 from 5 to 7
|
||||
move 1 from 1 to 7
|
||||
move 3 from 9 to 3
|
||||
move 16 from 5 to 8
|
||||
move 7 from 8 to 7
|
||||
move 1 from 9 to 2
|
||||
move 8 from 2 to 3
|
||||
move 2 from 2 to 4
|
||||
move 3 from 3 to 1
|
||||
move 9 from 3 to 8
|
||||
move 1 from 6 to 3
|
||||
move 9 from 7 to 3
|
||||
move 3 from 1 to 8
|
||||
move 1 from 7 to 9
|
||||
move 1 from 9 to 4
|
||||
move 1 from 7 to 5
|
||||
move 10 from 4 to 5
|
||||
move 2 from 4 to 2
|
||||
move 19 from 8 to 5
|
||||
move 1 from 8 to 3
|
||||
move 4 from 3 to 5
|
||||
move 2 from 4 to 8
|
||||
move 4 from 7 to 8
|
||||
move 4 from 3 to 9
|
||||
move 4 from 7 to 6
|
||||
move 2 from 2 to 5
|
||||
move 2 from 3 to 2
|
||||
move 6 from 8 to 7
|
||||
move 1 from 8 to 4
|
||||
move 2 from 6 to 4
|
||||
move 3 from 4 to 8
|
||||
move 3 from 9 to 2
|
||||
move 4 from 7 to 8
|
||||
move 28 from 5 to 8
|
||||
move 16 from 8 to 4
|
||||
move 11 from 8 to 4
|
||||
move 3 from 3 to 4
|
||||
move 7 from 5 to 8
|
||||
move 13 from 8 to 7
|
||||
move 1 from 5 to 6
|
||||
move 1 from 6 to 7
|
||||
move 1 from 9 to 2
|
||||
move 2 from 6 to 2
|
||||
move 12 from 4 to 9
|
||||
move 4 from 4 to 1
|
||||
move 2 from 9 to 8
|
||||
move 4 from 8 to 3
|
||||
move 3 from 4 to 5
|
||||
move 4 from 4 to 1
|
||||
move 4 from 4 to 7
|
||||
move 3 from 7 to 9
|
||||
move 5 from 9 to 7
|
||||
move 7 from 2 to 3
|
||||
move 1 from 5 to 7
|
||||
move 8 from 1 to 5
|
||||
move 1 from 2 to 4
|
||||
move 11 from 3 to 1
|
||||
move 10 from 5 to 3
|
||||
move 3 from 9 to 1
|
||||
move 3 from 9 to 6
|
||||
move 5 from 1 to 6
|
||||
move 7 from 6 to 9
|
||||
move 8 from 9 to 7
|
||||
move 9 from 3 to 4
|
||||
move 1 from 6 to 9
|
||||
move 8 from 7 to 1
|
||||
move 9 from 4 to 2
|
||||
move 2 from 1 to 6
|
||||
move 3 from 2 to 6
|
||||
move 4 from 4 to 6
|
||||
move 2 from 9 to 8
|
||||
move 2 from 1 to 2
|
||||
move 1 from 3 to 8
|
||||
move 2 from 8 to 4
|
||||
move 1 from 6 to 8
|
||||
move 11 from 1 to 6
|
||||
move 1 from 1 to 5
|
||||
move 3 from 2 to 9
|
||||
move 2 from 9 to 3
|
||||
move 1 from 1 to 7
|
||||
move 2 from 4 to 9
|
||||
move 4 from 2 to 9
|
||||
move 2 from 8 to 5
|
||||
move 10 from 6 to 1
|
||||
move 2 from 5 to 6
|
||||
move 5 from 9 to 8
|
||||
move 5 from 8 to 7
|
||||
move 1 from 2 to 1
|
||||
move 7 from 1 to 2
|
||||
move 2 from 9 to 4
|
||||
move 1 from 3 to 5
|
||||
move 15 from 7 to 2
|
||||
move 8 from 6 to 3
|
||||
move 2 from 4 to 3
|
||||
move 2 from 6 to 4
|
||||
move 4 from 7 to 1
|
||||
move 4 from 7 to 5
|
||||
move 1 from 6 to 4
|
||||
move 3 from 1 to 7
|
||||
move 5 from 7 to 6
|
||||
move 4 from 7 to 5
|
||||
move 18 from 2 to 4
|
||||
move 5 from 6 to 4
|
||||
move 4 from 1 to 2
|
||||
move 8 from 3 to 8
|
||||
move 2 from 8 to 4
|
||||
move 2 from 3 to 7
|
||||
move 1 from 5 to 7
|
||||
move 3 from 8 to 4
|
||||
move 2 from 7 to 2
|
||||
move 1 from 3 to 8
|
||||
move 9 from 2 to 6
|
||||
move 2 from 8 to 6
|
||||
move 1 from 7 to 3
|
||||
move 1 from 3 to 5
|
||||
move 3 from 6 to 8
|
||||
move 1 from 8 to 5
|
||||
move 1 from 5 to 9
|
||||
move 1 from 1 to 2
|
||||
move 5 from 4 to 6
|
||||
move 10 from 6 to 2
|
||||
move 5 from 2 to 6
|
||||
move 5 from 6 to 4
|
||||
move 1 from 6 to 3
|
||||
move 6 from 4 to 6
|
||||
move 3 from 2 to 6
|
||||
move 2 from 2 to 3
|
||||
move 11 from 4 to 6
|
||||
move 1 from 9 to 5
|
||||
move 4 from 6 to 7
|
||||
move 1 from 4 to 3
|
||||
move 12 from 4 to 3
|
||||
move 1 from 8 to 6
|
||||
move 9 from 5 to 7
|
||||
move 1 from 5 to 2
|
||||
move 1 from 8 to 5
|
||||
move 1 from 4 to 9
|
||||
move 9 from 7 to 9
|
||||
move 1 from 3 to 4
|
||||
move 2 from 3 to 6
|
||||
move 2 from 5 to 6
|
||||
move 2 from 8 to 5
|
||||
move 11 from 3 to 4
|
||||
move 2 from 3 to 1
|
||||
move 1 from 2 to 3
|
||||
move 1 from 3 to 8
|
||||
move 3 from 7 to 9
|
||||
move 5 from 4 to 2
|
||||
move 2 from 5 to 8
|
||||
move 6 from 4 to 2
|
||||
move 1 from 1 to 3
|
||||
move 12 from 9 to 1
|
||||
move 6 from 1 to 6
|
||||
move 1 from 8 to 4
|
||||
move 1 from 8 to 3
|
||||
move 5 from 2 to 7
|
||||
move 2 from 3 to 9
|
||||
move 5 from 7 to 1
|
||||
move 1 from 7 to 5
|
||||
move 2 from 9 to 1
|
||||
move 14 from 1 to 7
|
||||
move 2 from 4 to 7
|
||||
move 7 from 2 to 4
|
||||
move 1 from 2 to 1
|
||||
move 1 from 1 to 3
|
||||
move 1 from 5 to 4
|
||||
move 1 from 9 to 6
|
||||
move 16 from 6 to 5
|
||||
move 2 from 5 to 4
|
||||
move 12 from 6 to 8
|
||||
move 10 from 4 to 8
|
||||
move 9 from 7 to 3
|
||||
move 4 from 7 to 6
|
||||
move 11 from 5 to 8
|
||||
move 2 from 5 to 2
|
||||
move 14 from 8 to 9
|
||||
move 1 from 5 to 1
|
||||
move 3 from 9 to 4
|
||||
move 2 from 2 to 1
|
||||
move 7 from 8 to 3
|
||||
move 6 from 3 to 5
|
||||
move 8 from 9 to 8
|
||||
move 1 from 6 to 1
|
||||
move 1 from 4 to 2
|
||||
move 4 from 3 to 8
|
||||
move 1 from 7 to 2
|
||||
move 3 from 1 to 5
|
||||
move 2 from 5 to 7
|
||||
move 3 from 9 to 2
|
||||
move 1 from 1 to 8
|
||||
move 5 from 5 to 4
|
||||
move 2 from 7 to 8
|
||||
move 4 from 2 to 5
|
||||
move 1 from 2 to 4
|
||||
move 2 from 7 to 8
|
||||
move 4 from 6 to 2
|
||||
move 6 from 5 to 3
|
||||
move 1 from 6 to 5
|
||||
move 1 from 5 to 3
|
||||
move 1 from 3 to 8
|
||||
move 8 from 8 to 3
|
||||
move 9 from 8 to 5
|
||||
move 9 from 8 to 2
|
||||
move 2 from 8 to 9
|
||||
move 2 from 3 to 8
|
||||
move 5 from 5 to 8
|
||||
move 1 from 3 to 7
|
||||
move 2 from 9 to 5
|
||||
move 7 from 2 to 4
|
||||
move 14 from 4 to 6
|
||||
move 2 from 2 to 7
|
||||
move 1 from 7 to 3
|
||||
move 1 from 7 to 9
|
||||
move 3 from 5 to 2
|
||||
move 1 from 7 to 1
|
||||
move 3 from 2 to 4
|
||||
move 7 from 8 to 2
|
||||
move 3 from 6 to 1
|
||||
move 17 from 3 to 1
|
||||
move 2 from 8 to 3
|
||||
move 6 from 2 to 7
|
||||
move 2 from 7 to 9
|
||||
move 3 from 6 to 8
|
||||
move 2 from 8 to 6
|
||||
move 4 from 2 to 1
|
||||
move 3 from 4 to 7
|
||||
move 1 from 8 to 7
|
||||
move 1 from 8 to 9
|
||||
move 1 from 4 to 2
|
||||
move 3 from 5 to 7
|
||||
move 2 from 3 to 1
|
||||
move 2 from 3 to 5
|
||||
move 5 from 7 to 4
|
||||
move 5 from 7 to 3
|
||||
move 1 from 4 to 8
|
||||
move 3 from 3 to 1
|
||||
move 6 from 1 to 3
|
||||
move 1 from 7 to 5
|
||||
move 2 from 9 to 2
|
||||
move 3 from 5 to 8
|
||||
move 1 from 8 to 1
|
||||
move 8 from 3 to 5
|
||||
move 1 from 4 to 9
|
||||
move 3 from 6 to 5
|
||||
move 3 from 6 to 3
|
||||
move 2 from 3 to 7
|
||||
move 1 from 4 to 7
|
||||
move 3 from 6 to 4
|
||||
move 2 from 7 to 2
|
||||
move 1 from 7 to 8
|
||||
move 2 from 5 to 4
|
||||
move 1 from 6 to 1
|
||||
move 7 from 4 to 7
|
||||
move 7 from 5 to 2
|
||||
move 10 from 2 to 3
|
||||
move 3 from 2 to 6
|
||||
move 3 from 8 to 1
|
||||
move 1 from 8 to 7
|
||||
move 2 from 6 to 3
|
||||
move 1 from 6 to 9
|
||||
move 4 from 7 to 5
|
||||
move 16 from 1 to 5
|
||||
move 1 from 9 to 7
|
||||
move 3 from 7 to 6
|
||||
move 11 from 5 to 6
|
||||
move 2 from 7 to 9
|
||||
move 12 from 6 to 4
|
||||
move 2 from 6 to 9
|
||||
move 6 from 3 to 2
|
||||
move 1 from 5 to 7
|
||||
move 5 from 9 to 5
|
||||
move 1 from 9 to 6
|
||||
move 4 from 3 to 7
|
||||
move 1 from 4 to 2
|
||||
move 7 from 2 to 5
|
||||
move 3 from 5 to 2
|
||||
move 6 from 5 to 6
|
||||
move 3 from 2 to 6
|
||||
move 9 from 6 to 8
|
||||
move 5 from 5 to 9
|
||||
move 5 from 7 to 1
|
||||
move 4 from 1 to 9
|
||||
move 2 from 9 to 4
|
||||
move 1 from 6 to 7
|
||||
move 9 from 4 to 1
|
||||
move 7 from 5 to 9
|
||||
move 18 from 1 to 3
|
||||
move 9 from 9 to 5
|
||||
move 8 from 8 to 2
|
||||
move 1 from 2 to 5
|
||||
move 4 from 2 to 3
|
||||
move 4 from 9 to 6
|
||||
move 1 from 4 to 8
|
||||
move 2 from 5 to 7
|
||||
move 2 from 9 to 2
|
||||
move 10 from 3 to 9
|
||||
move 5 from 5 to 9
|
||||
move 1 from 7 to 2
|
||||
move 2 from 8 to 7
|
||||
move 2 from 3 to 5
|
||||
move 2 from 9 to 1
|
||||
move 2 from 7 to 3
|
||||
move 1 from 2 to 1
|
||||
move 5 from 5 to 8
|
||||
move 1 from 2 to 1
|
||||
move 15 from 3 to 6
|
||||
move 1 from 7 to 6
|
||||
move 10 from 6 to 5
|
||||
move 1 from 7 to 8
|
||||
move 4 from 1 to 6
|
||||
move 1 from 8 to 3
|
||||
move 2 from 1 to 5
|
||||
move 3 from 8 to 1
|
||||
move 1 from 4 to 6
|
||||
move 1 from 4 to 2
|
||||
move 4 from 9 to 7
|
||||
move 6 from 5 to 7
|
||||
move 3 from 1 to 9
|
||||
move 10 from 6 to 8
|
||||
move 2 from 1 to 3
|
||||
move 8 from 7 to 9
|
||||
move 1 from 9 to 6
|
||||
move 2 from 7 to 9
|
||||
move 3 from 3 to 5
|
||||
move 1 from 2 to 6
|
||||
move 2 from 6 to 5
|
||||
move 5 from 9 to 4
|
||||
move 4 from 8 to 2
|
||||
move 1 from 1 to 3
|
||||
move 4 from 5 to 9
|
||||
move 3 from 6 to 1
|
||||
move 2 from 1 to 5
|
||||
move 3 from 5 to 2
|
||||
move 8 from 8 to 3
|
||||
move 11 from 9 to 4
|
||||
move 13 from 4 to 8
|
||||
move 2 from 9 to 2
|
||||
move 2 from 3 to 1
|
||||
move 1 from 4 to 1
|
||||
move 1 from 3 to 8
|
||||
move 2 from 6 to 9
|
||||
move 7 from 8 to 1
|
||||
move 3 from 2 to 5
|
||||
move 7 from 2 to 5
|
||||
move 3 from 4 to 6
|
||||
move 4 from 9 to 2
|
||||
move 2 from 3 to 5
|
||||
move 9 from 5 to 6
|
||||
move 5 from 2 to 7
|
||||
move 2 from 9 to 2
|
||||
move 2 from 9 to 7
|
||||
move 12 from 6 to 8
|
||||
move 5 from 5 to 7
|
||||
move 1 from 9 to 8
|
||||
move 3 from 1 to 6
|
||||
move 5 from 5 to 8
|
||||
move 6 from 1 to 9
|
||||
move 2 from 1 to 5
|
||||
move 1 from 6 to 9
|
||||
move 5 from 9 to 7
|
||||
move 2 from 5 to 8
|
||||
move 11 from 7 to 6
|
||||
move 20 from 8 to 1
|
||||
move 2 from 9 to 8
|
||||
move 4 from 7 to 6
|
||||
move 6 from 8 to 3
|
||||
move 13 from 6 to 9
|
||||
move 4 from 3 to 2
|
||||
move 4 from 6 to 3
|
||||
move 2 from 3 to 6
|
||||
move 5 from 9 to 8
|
||||
move 2 from 7 to 1
|
||||
move 2 from 6 to 9
|
||||
move 6 from 8 to 3
|
||||
move 6 from 3 to 6
|
||||
move 5 from 2 to 9
|
||||
move 22 from 1 to 3
|
||||
move 3 from 2 to 1
|
||||
move 5 from 9 to 3
|
||||
move 1 from 1 to 6
|
||||
move 3 from 6 to 2
|
||||
move 1 from 2 to 4
|
||||
move 33 from 3 to 5
|
||||
move 1 from 8 to 7
|
||||
14
2022/days/05/src/main.rs
Normal file
14
2022/days/05/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {:?}", part1::part1(&_structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {:?}", part2::part2(&_structured_input));
|
||||
}
|
||||
48
2022/days/05/src/part1.rs
Normal file
48
2022/days/05/src/part1.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &(WorkArea, Vec<Move>)) -> Vec<char> {
|
||||
let (mut work_area, moves) = input.to_owned();
|
||||
for r#move in moves {
|
||||
work_area.apply_move_cratemover9000(&r#move)
|
||||
}
|
||||
work_area
|
||||
.get_stacks()
|
||||
.iter()
|
||||
.map(|stack| stack.last().unwrap().to_owned())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = (
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P']]),
|
||||
vec![
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 1,
|
||||
},
|
||||
Move {
|
||||
to: 3,
|
||||
from: 1,
|
||||
number: 3,
|
||||
},
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 2,
|
||||
},
|
||||
Move {
|
||||
to: 2,
|
||||
from: 1,
|
||||
number: 1,
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part1(&input), vec!['C', 'M', 'Z']);
|
||||
}
|
||||
}
|
||||
48
2022/days/05/src/part2.rs
Normal file
48
2022/days/05/src/part2.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part2(input: &(WorkArea, Vec<Move>)) -> Vec<char> {
|
||||
let (mut work_area, moves) = input.to_owned();
|
||||
for r#move in moves {
|
||||
work_area.apply_move_cratemover9001(&r#move)
|
||||
}
|
||||
work_area
|
||||
.get_stacks()
|
||||
.iter()
|
||||
.map(|stack| stack.last().unwrap().to_owned())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = (
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P']]),
|
||||
vec![
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 1,
|
||||
},
|
||||
Move {
|
||||
to: 3,
|
||||
from: 1,
|
||||
number: 3,
|
||||
},
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 2,
|
||||
},
|
||||
Move {
|
||||
to: 2,
|
||||
from: 1,
|
||||
number: 1,
|
||||
},
|
||||
],
|
||||
);
|
||||
assert_eq!(part2(&input), vec!['M', 'C', 'D']);
|
||||
}
|
||||
}
|
||||
144
2022/days/05/src/utilities.rs
Normal file
144
2022/days/05/src/utilities.rs
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Move {
|
||||
pub to: usize,
|
||||
pub from: usize,
|
||||
pub number: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct WorkArea {
|
||||
stacks: Vec<Vec<char>>,
|
||||
}
|
||||
|
||||
impl WorkArea {
|
||||
pub fn new(stacks: Vec<Vec<char>>) -> Self {
|
||||
Self { stacks }
|
||||
}
|
||||
pub fn apply_move_cratemover9000(&mut self, action: &Move) {
|
||||
for _ in 0..action.number {
|
||||
let cargo = self.stacks.get_mut(action.from - 1).unwrap().pop().unwrap();
|
||||
self.stacks.get_mut(action.to - 1).unwrap().push(cargo);
|
||||
}
|
||||
}
|
||||
pub fn apply_move_cratemover9001(&mut self, action: &Move) {
|
||||
let mut crane_holder: Vec<char> = Vec::new();
|
||||
for _ in 0..action.number {
|
||||
let cargo = self.stacks.get_mut(action.from - 1).unwrap().pop().unwrap();
|
||||
crane_holder.push(cargo);
|
||||
}
|
||||
for cargo in crane_holder.iter().rev() {
|
||||
self.stacks.get_mut(action.to - 1).unwrap().push(*cargo);
|
||||
}
|
||||
}
|
||||
pub fn get_stacks(&self) -> &Vec<Vec<char>> {
|
||||
&self.stacks
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> (WorkArea, Vec<Move>) {
|
||||
let mut input = input.split("\n\n");
|
||||
let work_area = parse_work_area(input.next().unwrap());
|
||||
let moves = parse_moves(input.next().unwrap());
|
||||
(work_area, moves)
|
||||
}
|
||||
|
||||
pub fn parse_work_area(input: &str) -> WorkArea {
|
||||
//decode those bottom index numbers
|
||||
let index_row = input.lines().rev().next().unwrap();
|
||||
//some ascii math and array math to get the second to last char and convert it into a number.
|
||||
let index_max: usize = (index_row.as_bytes()[index_row.len() - 2] - b'0') as usize;
|
||||
//initalize the work area:
|
||||
let mut work_area: Vec<Vec<char>> = Vec::new();
|
||||
for _ in 0..index_max {
|
||||
work_area.push(Vec::new())
|
||||
}
|
||||
|
||||
//now parse the rest
|
||||
for line in input.lines().rev() {
|
||||
for (y, cargo_crate) in line.as_bytes().chunks(4).enumerate() {
|
||||
let cargo = cargo_crate[1] as char;
|
||||
//easiest way to filter out that last line is just to filter out digits.
|
||||
if cargo != ' ' && !cargo.is_ascii_digit() {
|
||||
work_area.get_mut(y).unwrap().push(cargo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WorkArea::new(work_area)
|
||||
}
|
||||
|
||||
pub fn parse_moves(input: &str) -> Vec<Move> {
|
||||
static PARSE_MOVES_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^move (\d+) from (\d+) to (\d+)$").unwrap());
|
||||
input
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let cap = PARSE_MOVES_REGEX.captures(line).unwrap();
|
||||
Move {
|
||||
to: cap.get(3).unwrap().as_str().parse().unwrap(),
|
||||
from: cap.get(2).unwrap().as_str().parse().unwrap(),
|
||||
number: cap.get(1).unwrap().as_str().parse().unwrap(),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_work_area() {
|
||||
let input = " [D]
|
||||
[N] [C]
|
||||
[Z] [M] [P]
|
||||
1 2 3 ";
|
||||
assert_eq!(
|
||||
parse_work_area(input),
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P'],],)
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = " [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";
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
(
|
||||
WorkArea::new(vec![vec!['Z', 'N'], vec!['M', 'C', 'D'], vec!['P'],],),
|
||||
vec![
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 1
|
||||
},
|
||||
Move {
|
||||
to: 3,
|
||||
from: 1,
|
||||
number: 3
|
||||
},
|
||||
Move {
|
||||
to: 1,
|
||||
from: 2,
|
||||
number: 2
|
||||
},
|
||||
Move {
|
||||
to: 2,
|
||||
from: 1,
|
||||
number: 1
|
||||
},
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
6
2022/days/06/Cargo.toml
Normal file
6
2022/days/06/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day06"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
1
2022/days/06/src/input.txt
Normal file
1
2022/days/06/src/input.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
bhzhtzzsczszsjjjzddfzdfzfjfzfbbnntnzznwzzvfvrrqmrmmdzzfqfhqhsqqpwpgwpppbtbnnstthmhrrsmmvsmmhjmjfmfsfjfnfnjjvcjjszjszjsszbznzbnzndzzmlldsdgdcddmqmfqqlcllbvllztzctzczdzttlmtlthtmhtmhmmszsllvzvdzzzsqzqbqccvfvcffzsfslfsllcglclwlvwvzzdsslggtzzgzdzmzddjljvvztttsgscsstztjztjztzvzwwthtftppnmpmmcpmmjlmjjjsfjsjppgcgwcggzffzwzbbmbrbprpqqpccfncfnffvcffsqqtzqzqwzwvzwwwbjbfbcbfblltnlnhhcthtvvzzfcfgfddlggbbshsggplglqqbrbggsvvzdvvlfvlvpvhhmggbrrnppjfjhffttfpffbdfbfvfqvvtcvvbvnnhbhhglgjgzzghhwrrtntrtwwfdfdmmcmtctftpptllzqllzflfrrgqgvgdvdfdbddprrrgccqvqnnmtmvmffpzzqggfbfnfwwqdqldqqlnqnttnbttrffnmmzwzjjtrjtrtmmqsmqmffqmfqfhhbthbhdhvdhvdvmvdmdhdshsqslldzztvvmzzdcccmbbhfhshrrrpsrrqqmdmmgdmmwdmdjdqqmcmttpgtgwgpwpprbrprhrsrllhsllprlplhppfzpffbhbccwdwbbrpbpvpqqmsspjssmbbmfmrmnrnwwgbwwbpwpjwwhqqgcqcvqccgffzpfftcffqlqjjznnlflhhlcczhzvhzhmzhmhfhnnqznntstwtggqjgjhggsvslltjlttfjjgffjzjwzzqzrrhlhzhbhphmhlmlzmzsmzmccvllgrrpbrbfbjfjttqjttdrdhhggqgddppqgpqgpgtptjptpllwccmwcmcpmcppdrrtstqqczqzvvlsltlddnvdvggcqqblqqsjqjttzhtzzszllqsqfqddqdbqddwqddfzzlczcscfsfpfdpdrpddsggcqchcfcpcssstwstwtggghvhqhzzqssjddwjwbjjsnjnfnwwglwwfnfhnnscsggzgjzzhzmmqfqsqwqrwqqqdtdcttzvvnbngbbcdbdggddnmddgzghhzgghwwbjbttlwlcctlccwwdhhrqrvrjjlglssgttpllwclwwtptwptwtvthtbhbzhbzhhrsrwwwnrwrfwfnwnhhnqqdjqjpqqwdwttzhttcdttvztzltzlzmzddrsdsfdsfftdfffmwffrjrffqrfqfsfqqqgqjggwzzrnnqfnqffdbfbtbbrpbrpbptpwttjmjjzrrhhqppdzdtdjttqwwtddjdzzmgzzhwwwdsdgssprsrgsgbbphhdpdwppnfppdqqwzzpbzzqwqpqsqhqdhqqtwwjnnmvmwvmmwwgjgzjjvcjcvcjcnjcncmmphmmvmwmwpwbbtbffhnhshgssgvgvrrbwbtbddqmqfqvvfqvqdvvdbvdbdcdfdlflmffrwwgmmttrztrrfrqrpqrrzjrjpjdpjprrnhhbhcbbcwwqlwwcssbddfrfjrfjfrjfjvvdmdtdzzlvzlzhzmhmhphchnnfqnffvccfpfbfpfqpprrmttzrzzjzmjmzjmmfvmmrzrqqdllgjlglcchssgllsbllrbrlrjlrrhhfwwsqwsstpssznzcznzqzssvtvtrrqwqvvtssgfsfhssljjnwjnjddjdggclcrrfsfhsstgtdtctfttvvsbvvbtbttcgcssjlslhlpljpppwzwnwdnngmgjjbzznwwdllrrfppshhvdhhldhdbbdbjbdjjrnjjzhzfhhsqqbqgmsbvnjsptlrsszlqfmgprvscphmqztbgtlrqvcgdzcptcqjncrdtfqnghnbmwwmcjgtjlbvqqzslgbbntrdfnvfjvfgcgngndjcspgwmpnsrqzzvzljbzlzzrwflrqqqmhsvqwbmdftnhwwzgqrlhddbbtwvbphljmstcjzvpjqwcnhlvpqvqdgvntgqzqwrlwbwvngwtqgrhznlzcvbwqmwncccjctrdzrmzjsvrmcfpjjcczhbvdfwhqvczggfmrspvprvvthvtqnsphpcsdmbrtbdqljvssdrhwjsrrlzprstpgqcbpmnpdgzgjttwcfrgjnsghmszlclgvmlsjrqfvflbnhwwphtvrnrbhdvdglcvgpzfsjpwwhtlvvdzthsrldfzhnlrblzsjjnwclqsqzgdbflhvpwcrtfbfbjcjttbjpvfgvfcswnqqwshbmqlscdzzwshfqwsvwnwzltbnrmzzhzvtwpzqcgwshpvzgtcmwrtrwctnpzbznnwqphnrgwljtrcwlqmvlndwrdrctztnmswslqmbjcmtlrmcpjvzccqszrnflqnqzttbhqlrhbmqdpscqvfgtdbnwjdcljwcbgbgjfzgrgpwqzqgbnrtpntfthhdbqmswvhnmwmszpghgjjzrbnbbfjblpstdfslmmmqfdcrhblqjqfphnldrvvfpnfrcvprjnqbzbspfpjtgqhnjbhnrwzcjvdbshhqpgrmzqpmjfmqwqvvdbddbsldwzzsrhnhsjjnvljrbwcnjrnjpmrrvfthftgptgtlpbgqffthflgftwcrqcqwqwrmrcmfrcqgmrnqjbscdcgrqlhjzthvzdgjbvpswflqcgsnlmgmvcsttsgmnqdtvwdvrndvfdcvrcwmqlmlhtrvthsndsrmnsfmdmfnpfmfhzjqmtcjzcrnsjdztztvgdtlrmbdmmstbfgpmmzthcslpvgrpgfljfgqlqhldfwvvvdvbzjtdtppbtrnqwsqztjrsjhtfrgmvsdngvsdzjgpwrldqpzdpvhljzpjvttwltdwcrhcbrgrvdrmpwvdwjchqsjfprbgtjtzggvgrgmlvvwqrjfprbbgjjqrtdfnrdffwbswbvqtqtfsrhsgrjhftqldhmcnmsnfflmdrzqdjmbqqgqsttdmtrrvfsjnccnhcpcvqtrzdjzrpwswmjvvgsgwvnmdgqwlctrlhqnsmczbwsjhmtgvdcgsndzlstcwchcztqqbtdwfvlljdvdlzljslgnzpmqvzfcvqhdzvgchffqgfwrnmwqzwgbzblpmvddlvnhglrhdnwzqwztzgjczjpwcjwmpnrnrhncfjfggrbphrjztwtfqmfjlwfhnqfftfghbnvtwgtmdzzrdrtmfrwhrrbhzmcllsgqzwzzqtgdggvzptvtdcpzmtmsfcfbjtzlbdrwhdbtdhhrgggmddnzsvjwgcdcqfppqwphfvlhmgqsznlhmgpnjvcvrwwppnphchgsrhjwjcpjggsrcwrvnllfgrmjltfzwhmbqwpwwzmrtlqcprrqztcgnghcbvzrbfptjmhtdcfhhffdbrswqpnpppnpqwtflrrmqgjzctmmvvvwzllbsfdvpqjtmvpjcpmjztscsgbdznfgcmtjzdqzwqrsvstnnvddcstzqjtnbsnlptpmbmfqmhppgnjrffqrtchgptbmwlwbwbcqqfngpbwtwdmlmdstmqwcwjtbwbbbhghgptmvhfmvqfvpwqzwnbjdhpwlgjgvprdjbnlzhnllssbpvzfzspwsscfpqtpdvtzvqncfrfrgddsdglqvpblmpcczlqfdmwzmgvrljhqtcglcvfhbdwhbttqqrjbqwhsrhrbjwmtqwqddvdggdwfsmnpbpvvgsqnvvrqntwmbzdnqpmmqtbnlsbmslpfmqjtgvbddhwvlvjtlrhqdpfnjwtbhwjwdrpgctbbrdqvbbnvgqwngrhqfvwzmlqtmhfqphnmczlbdpnbmpvwrsjbcnjnvcfgnsvlhpzdgdzgvfbgwdcrswznrggnghzssdwqvvlwftqhbnwdvghhvjlqqmcnqmvbwhrrnsswlwmwbsmpcpdzzgmcmqnzpvjpzqbwcsgdhqtqhcpbtqftvscmntsbdcbrndvlfhprpblzbjcpqhfljtvnvtgvrcgqbsgl
|
||||
14
2022/days/06/src/main.rs
Normal file
14
2022/days/06/src/main.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
fn main() {
|
||||
let _input = include_str!("./input.txt");
|
||||
// let _structured_input = utilities::parse(_input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(_input));
|
||||
}
|
||||
23
2022/days/06/src/part1.rs
Normal file
23
2022/days/06/src/part1.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part1(input: &str) -> usize {
|
||||
input
|
||||
.as_bytes()
|
||||
.windows(4)
|
||||
.position(|x| !find_dupes_stupid(x))
|
||||
.unwrap()+4
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
assert_eq!(part1("mjqjpqmgbljsphdztnvjfqwrcgsmlb"), 7);
|
||||
assert_eq!(part1("bvwbjplbgvbhsrlpgdmjqwftvncz"), 5);
|
||||
assert_eq!(part1("nppdvjthqldpwncqszvftbrmjlhg"), 6);
|
||||
assert_eq!(part1("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg"), 10);
|
||||
assert_eq!(part1("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw"), 11);
|
||||
}
|
||||
}
|
||||
23
2022/days/06/src/part2.rs
Normal file
23
2022/days/06/src/part2.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
use crate::utilities::*;
|
||||
|
||||
pub fn part2(input: &str) -> usize {
|
||||
input
|
||||
.as_bytes()
|
||||
.windows(14)
|
||||
.position(|x| !find_dupes_stupid(x))
|
||||
.unwrap()+14
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
assert_eq!(part2("mjqjpqmgbljsphdztnvjfqwrcgsmlb"), 19);
|
||||
assert_eq!(part2("bvwbjplbgvbhsrlpgdmjqwftvncz"), 23);
|
||||
assert_eq!(part2("nppdvjthqldpwncqszvftbrmjlhg"), 23);
|
||||
assert_eq!(part2("nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg"), 29);
|
||||
assert_eq!(part2("zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw"), 26);
|
||||
}
|
||||
}
|
||||
19
2022/days/06/src/utilities.rs
Normal file
19
2022/days/06/src/utilities.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
pub fn find_dupes_stupid<T: PartialEq>(slice: &[T]) -> bool {
|
||||
for i in 1..slice.len() {
|
||||
if slice[i..].contains(&slice[i - 1]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/* #[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = "test";
|
||||
assert_eq!(parse(input), 0);
|
||||
}
|
||||
} */
|
||||
11
2022/days/07/Cargo.toml
Normal file
11
2022/days/07/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day07"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
once_cell.workspace = true
|
||||
regex.workspace = true
|
||||
thiserror.workspace = true
|
||||
305
2022/days/07/src/file_tree.rs
Normal file
305
2022/days/07/src/file_tree.rs
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
use std::{
|
||||
cell::RefCell,
|
||||
fmt::Display,
|
||||
ops::Deref,
|
||||
rc::{Rc, Weak},
|
||||
};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum FileTreeError {
|
||||
#[error("Directory operation on file")]
|
||||
IsFile,
|
||||
#[error("File operation on directory")]
|
||||
IsDir,
|
||||
#[error("File not found")]
|
||||
FileNotFound,
|
||||
#[error("File already exists")]
|
||||
FileAlreadyExists,
|
||||
}
|
||||
|
||||
type WeakNodeRef = Weak<RefCell<Node>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NodeRef(pub Rc<RefCell<Node>>);
|
||||
|
||||
impl Deref for NodeRef {
|
||||
type Target = Rc<RefCell<Node>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rc<RefCell<Node>>> for NodeRef {
|
||||
fn from(value: Rc<RefCell<Node>>) -> Self {
|
||||
NodeRef(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NodeRef> for Rc<RefCell<Node>> {
|
||||
fn from(value: NodeRef) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeRef {
|
||||
pub fn add_node(&mut self, mut node: Node) -> Result<NodeRef, FileTreeError> {
|
||||
node.set_parent(self);
|
||||
self.borrow_mut().add_children(node)
|
||||
}
|
||||
pub fn new_dir(name: String) -> NodeRef {
|
||||
NodeRef(Rc::new(RefCell::new(Node::new_dir(name))))
|
||||
}
|
||||
pub fn add_file(&mut self, name: String, size: usize) -> Result<NodeRef, FileTreeError> {
|
||||
self.add_node(Node::new_file(name, size))
|
||||
}
|
||||
pub fn add_dir(&mut self, name: String) -> Result<NodeRef, FileTreeError> {
|
||||
self.add_node(Node::new_dir(name))
|
||||
}
|
||||
pub fn get_all_dirs(&self) -> Vec<NodeRef> {
|
||||
let mut ret = Vec::new();
|
||||
match &self.borrow().contents {
|
||||
Contents::Size(_) => {}
|
||||
Contents::Children(c) => {
|
||||
ret.push(NodeRef(Rc::clone(self)));
|
||||
for node in c {
|
||||
ret.append(&mut node.get_all_dirs())
|
||||
}
|
||||
}
|
||||
};
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Node {
|
||||
pub name: String,
|
||||
parent: Option<WeakNodeRef>,
|
||||
contents: Contents,
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn new_dir(name: String) -> Node {
|
||||
Node {
|
||||
name,
|
||||
parent: None,
|
||||
contents: Contents::Children(Vec::new()),
|
||||
}
|
||||
}
|
||||
pub fn new_file(name: String, size: usize) -> Node {
|
||||
Node {
|
||||
name,
|
||||
parent: None,
|
||||
contents: Contents::Size(size),
|
||||
}
|
||||
}
|
||||
pub fn get_total_size(&self) -> usize {
|
||||
match &self.contents {
|
||||
Contents::Size(s) => *s,
|
||||
Contents::Children(c) => c.iter().map(|f| f.borrow().get_total_size()).sum(),
|
||||
}
|
||||
}
|
||||
fn set_parent(&mut self, newparent: &NodeRef) {
|
||||
self.parent = Some(Rc::downgrade(newparent));
|
||||
}
|
||||
// does not set the parent, needs to be done on the NodeRef. (this is why this func isnt pub).
|
||||
// takes onwership of the node to make sure its not owned by another tree.
|
||||
fn add_children(&mut self, node: Node) -> Result<NodeRef, FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(ref mut c) => {
|
||||
for file in c.iter() {
|
||||
if file.borrow().name == node.name {
|
||||
return Err(FileTreeError::FileAlreadyExists);
|
||||
}
|
||||
}
|
||||
let rc = Rc::new(RefCell::new(node));
|
||||
c.push(NodeRef(Rc::clone(&rc)));
|
||||
Ok(NodeRef(Rc::clone(&rc)))
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn remove_child_by_name(&mut self, name: &str) -> Result<(), FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(ref mut c) => {
|
||||
for (i, file) in c.iter().enumerate() {
|
||||
if file.borrow().name == name {
|
||||
c.remove(i);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Err(FileTreeError::FileNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn get_parent(&self) -> Option<NodeRef> {
|
||||
match &self.parent {
|
||||
Some(w) => Some(NodeRef(w.clone().upgrade()?)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
pub fn get_size(&self) -> Result<usize, FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(s) => Ok(s),
|
||||
Contents::Children(_) => Err(FileTreeError::IsDir),
|
||||
}
|
||||
}
|
||||
pub fn set_size(&mut self, size: usize) -> Result<(), FileTreeError> {
|
||||
match self.contents {
|
||||
Contents::Size(ref mut s) => {
|
||||
*s = size;
|
||||
Ok(())
|
||||
}
|
||||
Contents::Children(_) => Err(FileTreeError::IsDir),
|
||||
}
|
||||
}
|
||||
pub fn get_children(&self) -> Result<impl Iterator<Item = NodeRef> + '_, FileTreeError> {
|
||||
match &self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(c) => Ok(c.iter().map(|n| NodeRef(Rc::clone(n)))),
|
||||
}
|
||||
}
|
||||
pub fn get_child_by_name(&self, name: &str) -> Result<NodeRef, FileTreeError> {
|
||||
match &self.contents {
|
||||
Contents::Size(_) => Err(FileTreeError::IsFile),
|
||||
Contents::Children(c) => {
|
||||
for file in c.iter() {
|
||||
if file.borrow().name == name {
|
||||
return Ok(NodeRef(Rc::clone(file)));
|
||||
}
|
||||
}
|
||||
Err(FileTreeError::FileNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum Contents {
|
||||
Size(usize),
|
||||
Children(Vec<NodeRef>),
|
||||
}
|
||||
|
||||
impl Display for NodeRef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.borrow())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Node {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "- {} {}", self.name, self.contents)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Contents {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Contents::Size(s) => write!(f, "(file, size = {})", s),
|
||||
Contents::Children(c) => {
|
||||
writeln!(f, "(dir)").expect("I have no clue how this could fail");
|
||||
for node in c {
|
||||
//padding
|
||||
for line in format!("{}", node).lines() {
|
||||
writeln!(f, " {line}")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_dir_construction() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
println!("{}", root);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_size_calcs() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut dirs: Vec<NodeRef> = Vec::new();
|
||||
let mut cursor = root.add_dir("a".to_string()).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
assert_eq!(Rc::clone(dirs[0].deref()).borrow().get_total_size(), 94853);
|
||||
assert_eq!(Rc::clone(dirs[1].deref()).borrow().get_total_size(), 584);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[2].deref()).borrow().get_total_size(),
|
||||
24933642
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_get_all_dirs() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_dir("a".to_string()).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
let dirs = root.get_all_dirs();
|
||||
let sizes: Vec<usize> = dirs.iter().map(|d| d.borrow().get_total_size()).collect();
|
||||
println!("{:?}", sizes);
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[0].deref()).borrow().get_total_size(),
|
||||
48381165
|
||||
);
|
||||
assert_eq!(Rc::clone(dirs[1].deref()).borrow().get_total_size(), 94853);
|
||||
assert_eq!(Rc::clone(dirs[2].deref()).borrow().get_total_size(), 584);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[3].deref()).borrow().get_total_size(),
|
||||
24933642
|
||||
);
|
||||
}
|
||||
}
|
||||
1030
2022/days/07/src/input.txt
Normal file
1030
2022/days/07/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
19
2022/days/07/src/main.rs
Normal file
19
2022/days/07/src/main.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use crate::file_tree::NodeRef;
|
||||
|
||||
mod part1;
|
||||
mod part2;
|
||||
mod parser;
|
||||
mod file_tree;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parser::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(NodeRef(Rc::clone(&structured_input))));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(NodeRef(Rc::clone(&structured_input))));
|
||||
}
|
||||
262
2022/days/07/src/parser.rs
Normal file
262
2022/days/07/src/parser.rs
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::file_tree::*;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
static IS_COMMAND_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$").unwrap());
|
||||
static PARSE_CD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$ cd (\S*)$").unwrap());
|
||||
static PARSE_LS_ENTRY_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^([[:alnum:]]*) (\S*)$").unwrap());
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Command {
|
||||
CdRoot,
|
||||
CdUp,
|
||||
Cd(String),
|
||||
Ls(Vec<LsEntry>),
|
||||
}
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum LsEntry {
|
||||
Dir(String),
|
||||
File(ParseFile),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct ParseFile {
|
||||
size: usize,
|
||||
name: String,
|
||||
}
|
||||
|
||||
//parses a single line
|
||||
pub fn parse_to_commands(input: &str) -> Vec<Command> {
|
||||
let mut ret = Vec::new();
|
||||
let mut lines = input.lines().peekable();
|
||||
while lines.peek().is_some() {
|
||||
let line = lines.next().unwrap();
|
||||
if line == "$ ls" {
|
||||
ret.push(Command::Ls(parse_ls(&mut lines)));
|
||||
} else {
|
||||
let captures = PARSE_CD_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
|
||||
ret.push(match &captures[1] {
|
||||
".." => Command::CdUp,
|
||||
"/" => Command::CdRoot,
|
||||
s => Command::Cd(s.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn parse_ls(lines: &mut std::iter::Peekable<std::str::Lines<'_>>) -> Vec<LsEntry> {
|
||||
let mut ret: Vec<LsEntry> = Vec::new();
|
||||
while lines.peek().is_some() {
|
||||
// if the next line is a command, then we are at the end of the ls listing.
|
||||
let line = lines.peek().expect("no next line");
|
||||
if IS_COMMAND_REGEX.is_match(line) {
|
||||
break;
|
||||
}
|
||||
let captures = PARSE_LS_ENTRY_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
ret.push(match &captures[1] {
|
||||
"dir" => LsEntry::Dir(captures[2].to_string()),
|
||||
_ => LsEntry::File(ParseFile {
|
||||
size: str::parse(&captures[1]).unwrap_or_else(|_| panic!("invalid line {}", line)),
|
||||
name: captures[2].to_string(),
|
||||
}),
|
||||
});
|
||||
lines.next();
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> NodeRef {
|
||||
commands_to_tree(parse_to_commands(input))
|
||||
}
|
||||
|
||||
pub fn commands_to_tree(input: Vec<Command>) -> NodeRef {
|
||||
let root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = NodeRef(Rc::clone(&root));
|
||||
for command in input {
|
||||
match command {
|
||||
Command::CdRoot => cursor = NodeRef(Rc::clone(&root)),
|
||||
Command::CdUp => cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap(),
|
||||
Command::Cd(name) => cursor = cursor.add_dir(name).unwrap(),
|
||||
Command::Ls(ls) => {
|
||||
for entry in ls {
|
||||
match entry {
|
||||
LsEntry::Dir(_) => {
|
||||
//dirs dont exist until you cd into them.
|
||||
}
|
||||
LsEntry::File(f) => {
|
||||
cursor.add_file(f.name, f.size).unwrap();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
root
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse_to_commands() {
|
||||
let input = concat!(
|
||||
"$ cd /\n",
|
||||
"$ ls\n",
|
||||
"dir a\n",
|
||||
"14848514 b.txt\n",
|
||||
"8504156 c.dat\n",
|
||||
"dir d\n",
|
||||
"$ cd a\n",
|
||||
"$ ls\n",
|
||||
"dir e\n",
|
||||
"29116 f\n",
|
||||
"2557 g\n",
|
||||
"62596 h.lst\n",
|
||||
"$ cd e\n",
|
||||
"$ ls\n",
|
||||
"584 i\n",
|
||||
"$ cd ..\n",
|
||||
"$ cd ..\n",
|
||||
"$ cd d\n",
|
||||
"$ ls\n",
|
||||
"4060174 j\n",
|
||||
"8033020 d.log\n",
|
||||
"5626152 d.ext\n",
|
||||
"7214296 k"
|
||||
);
|
||||
assert_eq!(
|
||||
parse_to_commands(input),
|
||||
vec![
|
||||
Command::CdRoot,
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("a")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 14848514,
|
||||
name: String::from("b.txt")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8504156,
|
||||
name: String::from("c.dat")
|
||||
}),
|
||||
LsEntry::Dir(String::from("d"))
|
||||
]),
|
||||
Command::Cd(String::from("a")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("e")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 29116,
|
||||
name: String::from("f")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 2557,
|
||||
name: String::from("g")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 62596,
|
||||
name: String::from("h.lst")
|
||||
}),
|
||||
]),
|
||||
Command::Cd(String::from("e")),
|
||||
Command::Ls(vec![LsEntry::File(ParseFile {
|
||||
size: 584,
|
||||
name: String::from("i")
|
||||
}),]),
|
||||
Command::CdUp,
|
||||
Command::CdUp,
|
||||
Command::Cd(String::from("d")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::File(ParseFile {
|
||||
size: 4060174,
|
||||
name: String::from("j")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8033020,
|
||||
name: String::from("d.log")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 5626152,
|
||||
name: String::from("d.ext")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 7214296,
|
||||
name: String::from("k")
|
||||
}),
|
||||
]),
|
||||
]
|
||||
)
|
||||
}
|
||||
#[test]
|
||||
fn test_commands_to_tree() {
|
||||
let input = vec![
|
||||
Command::CdRoot,
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("a")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 14848514,
|
||||
name: String::from("b.txt"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8504156,
|
||||
name: String::from("c.dat"),
|
||||
}),
|
||||
LsEntry::Dir(String::from("d")),
|
||||
]),
|
||||
Command::Cd(String::from("a")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("e")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 29116,
|
||||
name: String::from("f"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 2557,
|
||||
name: String::from("g"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 62596,
|
||||
name: String::from("h.lst"),
|
||||
}),
|
||||
]),
|
||||
Command::Cd(String::from("e")),
|
||||
Command::Ls(vec![LsEntry::File(ParseFile {
|
||||
size: 584,
|
||||
name: String::from("i"),
|
||||
})]),
|
||||
Command::CdUp,
|
||||
Command::CdUp,
|
||||
Command::Cd(String::from("d")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::File(ParseFile {
|
||||
size: 4060174,
|
||||
name: String::from("j"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8033020,
|
||||
name: String::from("d.log"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 5626152,
|
||||
name: String::from("d.ext"),
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 7214296,
|
||||
name: String::from("k"),
|
||||
}),
|
||||
]),
|
||||
];
|
||||
let tree = commands_to_tree(input);
|
||||
println!("{}", tree);
|
||||
assert_eq!(Rc::clone(tree.deref()).borrow().get_total_size(), 48381165)
|
||||
}
|
||||
}
|
||||
37
2022/days/07/src/part1.rs
Normal file
37
2022/days/07/src/part1.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use crate::file_tree::*;
|
||||
|
||||
pub fn part1(input: NodeRef) -> usize {
|
||||
let dirs = input.get_all_dirs();
|
||||
dirs.iter()
|
||||
.map(|d| d.borrow().get_total_size())
|
||||
.filter(|s| *s <= 100000)
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{ops::Deref, rc::Rc};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(part1(root), 95437);
|
||||
}
|
||||
}
|
||||
44
2022/days/07/src/part2.rs
Normal file
44
2022/days/07/src/part2.rs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
use crate::file_tree::*;
|
||||
|
||||
const TOTAL_SPACE: usize = 70000000;
|
||||
const NEEDED_SPACE: usize = 30000000;
|
||||
|
||||
pub fn part2(input: NodeRef) -> usize {
|
||||
let used_space = input.borrow().get_total_size();
|
||||
let unused_space = TOTAL_SPACE - used_space;
|
||||
let space_to_free = NEEDED_SPACE - unused_space;
|
||||
let dirs = input.get_all_dirs();
|
||||
dirs.iter()
|
||||
.map(|d| d.borrow().get_total_size())
|
||||
.filter(|s| *s >= space_to_free)
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{ops::Deref, rc::Rc};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(part2(root), 24933642);
|
||||
}
|
||||
}
|
||||
6
2022/days/08/Cargo.toml
Normal file
6
2022/days/08/Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[package]
|
||||
name = "day08"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
99
2022/days/08/src/input.txt
Normal file
99
2022/days/08/src/input.txt
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
002100030222341303232115221524311502200403234452204125251345024423544443305142410110142101223120110
|
||||
102030322341143330244233013052025453422005415304655426206452251310214055314024034341233110302320003
|
||||
003012203404011430120134554314552441635001641050211406204621114102021543144514102510421243314102033
|
||||
330313423002034140035001210441156554545625042262651356556544202500446121455112434243313013430141203
|
||||
331203121131230002055113430244610062654034520106363462155201210355601153542301323442223310134324300
|
||||
232201231021003254355411402310326206625011564114125202263504451451212600155351424154310240411213431
|
||||
033033333301011523544023206136145505304224325606020360006206455564513553512054354124523232201230441
|
||||
132201032234334044251334220345360402456541662253556375754662323265201641514121105025300453041111234
|
||||
314322341322104402235020206565044225363527617767574524475421763504341061551154250344125514014234344
|
||||
101323043023430543342440532324326413655657527215661116623455613664321005134300223542510253102211310
|
||||
320404242514122111525043444530625417656773117247512712444315767422412130351505513231104322032421303
|
||||
221204123205133142044056245654205231734371546616753217321556472223654044043612554152141554333102034
|
||||
340310155225452152216635634352712541366312326272262143522347111166646736001360102010220214000133002
|
||||
012404003515002416422500163244271366252711531615333437352461454777311142132000140205630042305222013
|
||||
332434552302203445503543424523327464362526657251687634745536521746523154717531643250132300541053000
|
||||
020130312425316362611130462217125425435545265467725256332777233137141524314631100051153314314343032
|
||||
112115124512002346011342433146124542356845483862756322785545283652723747276776403131622540014001524
|
||||
332354013101003031053022245431274627654677343638672643442563448782737464337546541546630431125021330
|
||||
220315320142064161406534365262377268373743527784575246325564676238816733767331345114363612344051535
|
||||
102041153526000601402325625766534543527882476653366727573448727775677146365732431425225562043130034
|
||||
350054114310533002426654125166575285757827422257872378766383267543484865317252532765440216543555512
|
||||
222440404353016144747347457368562668586285847553578732435887584463446862116134751240360645225435344
|
||||
554234546163262630313431762248876668663352436888374587856263343842526635237314231451062036605442520
|
||||
525531324662660356256614344438373575732699988366775989976447384338336827686445577222030363631240512
|
||||
055541261042533424177375756738443482846986979788978997559377679255463858237757327464422026230510130
|
||||
514123221240250442457744728347386637684953574546455344754548333793233865436751231314653541223102202
|
||||
355454250661114645144551785724753237378345375493453967559796675839837444334776625552412552302431302
|
||||
202445234333206767744653874724276586973668878949653473947686567565487325864733735677672241416513452
|
||||
445415223211061633767433865252483574744685974593334963668983745643354885658423263536531213102544202
|
||||
201405464251164654177385783224666473975674643767946648464678958969336335638578275154116223152222102
|
||||
401423140356441654745572266848965593553995667644648964747884544439493545472454437715336645303346422
|
||||
154440323240741427732867467564957336394985859766644495658985963583496399736552632162756445212536404
|
||||
441663663062661372122867364584655388977474857585778686889578799644949733463423826715534215154065204
|
||||
422036122016243651174663588693898583374968974778579585977478599643389537573534354622377452555411315
|
||||
430412403362272513348763673566578945645997454758694486758844958569786758359475575577532661126532300
|
||||
503653020441267422765353469867998339764449596776968996449777464644846938866332635583727771665263026
|
||||
006252631541331635768754753357384754988659585857956567666645975599653466655333342485345762600032403
|
||||
215205542775713732868842389885585646884858449858579777975997584997463698339932263363162431251615251
|
||||
342224450731115175762626546538955447796468885776778879697695699945446388444478355347827635732006646
|
||||
045011110226211633623658548365544498466468766878699597655897586488555435934935526883851537736604133
|
||||
440352212243431376382869634434568447654566895897796875679759667598898849334873844583742271767024403
|
||||
566632367121414762272448784755746799985759966559657989697977677955455754549393784586875275341562621
|
||||
004131167135757426882464486773699786789959957795985595559587775554479945637849747667752242212324244
|
||||
022411031432724262533554794664597446479869568767598899669969588984864457535986725263473577457413134
|
||||
036415005331162527346577487593798458668976888776888766856699598847776567686579476836656723623111342
|
||||
504001302331545267684439554776894957999788577876688969865558955547965687556849786463457244355044511
|
||||
464266074264126575276833864784546697885788878967966988678696686685576789843676844576623242451411411
|
||||
660130573642326366362654785549676574587876888769689696798799988678648554635745724364273772474666502
|
||||
413511521313437652422664948645649566979966676679778669968777776786958464356797545247763267365643645
|
||||
455033174473274564484285387995879595555686569997977698868769855686564847593489668858847744131410225
|
||||
560316675532344635443349663994499869866598568889798868967976679655597494679336978524332246567265361
|
||||
121053163342234352453837754569968465557968697766766888969966667796479457384444468264837376474515455
|
||||
604062313527642634768255846899648545559665886668966887999959659769978495794795825775373713613231451
|
||||
041031112622754332842439776736966994677888699898679988967779696758849589365579766676242256227420364
|
||||
630161363126476778455475799658545955598576568877768698668579988799596866465635488284555252726211044
|
||||
455563641427127283364758796475975894658677688789777769876667978747955677573575525588444241765111511
|
||||
256420063532645225542863884958844496596759999769769687678888788875449888945958948378756476127155054
|
||||
523256165217547362636325547686549767698957967985968987897777685866576744344388256886854362647342110
|
||||
205224606764556763544234874676659474468968576879668558856675855668779847849738247387744421321145610
|
||||
022651355615653552468486676459694744747575877656886776677858584988944678787576556747724125467333305
|
||||
526313424324717126486746644643397589664468865599858886996669788566489473798387676766873216657521426
|
||||
426530404522411762572567697375959747975669667958685679878659587764977658398697353283563215312244014
|
||||
023510245741131775436864579684699874979976567776557765866775469587757498544476554753722641656303654
|
||||
211341433442225414565332887899363678699495567888998675657659688744458493387343842346747477252626250
|
||||
406543152154335614758277748595836896786654948759999978569588555764838686653647362854723163226456101
|
||||
333640633617315535456525364849458558744656899855554897897568844446533866457545654847562377442214226
|
||||
040003053246534354438748723933365934878485997458955574785966996653353969666867276761661111124104550
|
||||
405602516206264365157378627495546935658594587869579958969686766986836687348285865231616336232000100
|
||||
304131030254233641578272475868953446545577766644956989679964489688554398956223433417637732661500540
|
||||
131164662225325441733366324345477954639475997658684766465487974699579665344326248136151472051130445
|
||||
452312154206174654138684277376889449945746954689646875777596486949365968888456226732332263263420000
|
||||
003010154551246223274282454345355673349967689986885795449989359633496728553885221437611730454554455
|
||||
131435126460017635544785754344874379695379366384573934357795398633967475353836864461424146264354142
|
||||
350154544045013352533173566257757787385448697484997454578735937499665628425542376452563635450224022
|
||||
302420224365163651765264446875287359533637498445639443969586466433384346337722662774436566624454214
|
||||
415242456321105173655733744886343826548944666338683876383973497998744488687446541256724244661531431
|
||||
155303206134314124372553618623857237346567857564464797593393675563536467777317174625640132203003240
|
||||
335521544652523624641575451785635352333587957647598535633948867838652636686573137515062356442045153
|
||||
235314500244636615342325346277256685653838226755493858683465683736283367654226655456541546644313125
|
||||
252520511531061305614364671212856473625642477732845278766573642425286572562373137446456005011330433
|
||||
241525455120116046543737642325543677623243884242534423327827446383376441727657314343125403632434002
|
||||
301045223551220356167117621755325772252845222546246588464784874685774676163655131632622146412415515
|
||||
011150133311336614251435416453632383454327534367288242328746537673543714263674263262001132354544412
|
||||
314104033000306256531666256433553535833538337463847277453476563227672715617272601302551120422305504
|
||||
104211442013141664402363645617163435245556228235337864656673626354151416721375243323635625100210424
|
||||
413422313502535362615054171511431775335574748526574728747453724472157632635263350024552502052340024
|
||||
131225301023304456424150404525765416565572272321835377167235317312551645334432406536160545434122120
|
||||
342131052232413325301451041516716541737346252413667115612642227312572433104525003114240240141232002
|
||||
244421101354005430232434420344323273421374225635551363463245561271743411452116466311034334101231020
|
||||
232404402304311415164151401553463731147111147752141732625152553615361046133341313265525232544143442
|
||||
201321033520133414312301326330253041267251614477322566645472656414545035321106361434351501123314104
|
||||
211232034442524242313453325046331353174352335422752364775746537513333534355120322320404054014303124
|
||||
224032233240430510135541652065052415154147565656231651653327511443424113100543020223335130010141400
|
||||
004110101133543440511523265424013341433043655022512172622140322434116104552043413352211021312421433
|
||||
000304433232402410151205333526613043463556021413402141634154404530112303306244402221312522221004042
|
||||
200204441020135232033032541516232550445221141520665016336536052063115335040344025054213324400312303
|
||||
300211022440310123055510053251505226452265556365100101014044645236505213550201425252404100302413231
|
||||
310312413210032422053242024243343060135340422313312403505631104430120233112324204414021331012401232
|
||||
132020341330304022053503522313342026211133610000020554213662244142551253124302245242110111033101203
|
||||
16
2022/days/08/src/main.rs
Normal file
16
2022/days/08/src/main.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod utilities;
|
||||
|
||||
type StructuredInput = Vec<Vec<u8>>;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = utilities::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
85
2022/days/08/src/part1.rs
Normal file
85
2022/days/08/src/part1.rs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
use crate::StructuredInput;
|
||||
|
||||
pub fn part1(input: &StructuredInput) -> usize {
|
||||
let mut acc: usize = 0;
|
||||
for y in 0..input.len(){
|
||||
for x in 0..input[0].len(){
|
||||
if is_visible(x, y, input){
|
||||
acc+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
acc
|
||||
}
|
||||
|
||||
fn is_visible(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
is_visible_north(x, y, input)
|
||||
|| is_visible_east(x, y, input)
|
||||
|| is_visible_south(x, y, input)
|
||||
|| is_visible_west(x, y, input)
|
||||
}
|
||||
fn is_visible_north(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if y == 0 {
|
||||
return true;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
for y in 0..y {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
fn is_visible_east(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if x == input[0].len() {
|
||||
return true;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
for x in (x + 1)..input[0].len() {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
fn is_visible_south(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if y == input.len() {
|
||||
return true;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
for y in (y + 1)..input.len() {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
fn is_visible_west(x: usize, y: usize, input: &StructuredInput) -> bool {
|
||||
if x == input[0].len() {
|
||||
return true;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
for x in 0..x {
|
||||
if input[y][x] >= hight {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0],
|
||||
];
|
||||
assert_eq!(part1(&input), 21);
|
||||
}
|
||||
}
|
||||
109
2022/days/08/src/part2.rs
Normal file
109
2022/days/08/src/part2.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
use crate::StructuredInput;
|
||||
|
||||
pub fn part2(input: &StructuredInput) -> usize {
|
||||
let mut max: usize = 0;
|
||||
for y in 0..input.len() {
|
||||
for x in 0..input[0].len() {
|
||||
let tree_score = tree_score(x, y, input);
|
||||
if max < tree_score{
|
||||
max = tree_score;
|
||||
println!("found new max with score {} at {}, {}", tree_score, x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
max
|
||||
}
|
||||
fn tree_score(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
trees_visible_north(x, y, input)
|
||||
* trees_visible_east(x, y, input)
|
||||
* trees_visible_south(x, y, input)
|
||||
* trees_visible_west(x, y, input)
|
||||
}
|
||||
fn trees_visible_north(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if y == 0 {
|
||||
return 0;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for y in (0..y).rev() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
fn trees_visible_east(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if x == input[0].len() {
|
||||
return 0;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for x in (x + 1)..input[0].len() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
fn trees_visible_south(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if y == input.len() {
|
||||
return 0;
|
||||
};
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for y in (y + 1)..input.len() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
fn trees_visible_west(x: usize, y: usize, input: &StructuredInput) -> usize {
|
||||
if x == input[0].len() {
|
||||
return 0;
|
||||
}
|
||||
let hight = input[y][x];
|
||||
let mut trees: usize = 0;
|
||||
for x in (0..x).rev() {
|
||||
trees += 1;
|
||||
if input[y][x] >= hight {
|
||||
break
|
||||
}
|
||||
}
|
||||
trees
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0],
|
||||
];
|
||||
assert_eq!(part2(&input), 8);
|
||||
}
|
||||
#[test]
|
||||
fn test_trees_visible() {
|
||||
let input = vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0],
|
||||
];
|
||||
assert_eq!(trees_visible_north(2, 3, &input), 2);
|
||||
assert_eq!(trees_visible_east(2, 3, &input), 2);
|
||||
assert_eq!(trees_visible_south(2, 3, &input), 1);
|
||||
assert_eq!(trees_visible_west(2, 3, &input), 2);
|
||||
assert_eq!(tree_score(2, 3, &input), 8);
|
||||
}
|
||||
}
|
||||
26
2022/days/08/src/utilities.rs
Normal file
26
2022/days/08/src/utilities.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
pub fn parse(input: &str) -> Vec<Vec<u8>> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| l.chars().map(|c| c.to_digit(10).unwrap() as u8).collect())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!("30373\n", "25512\n", "65332\n", "33549\n", "35390\n",);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
vec![3, 0, 3, 7, 3],
|
||||
vec![2, 5, 5, 1, 2],
|
||||
vec![6, 5, 3, 3, 2],
|
||||
vec![3, 3, 5, 4, 9],
|
||||
vec![3, 5, 3, 9, 0]
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
11
2022/days/09/Cargo.toml
Normal file
11
2022/days/09/Cargo.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day09"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
regex.workspace = true
|
||||
once_cell.workspace = true
|
||||
2000
2022/days/09/src/input.txt
Normal file
2000
2022/days/09/src/input.txt
Normal file
File diff suppressed because it is too large
Load diff
15
2022/days/09/src/main.rs
Normal file
15
2022/days/09/src/main.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
mod rope;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(&structured_input));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result: {}", part2::part2(&structured_input));
|
||||
}
|
||||
75
2022/days/09/src/parse.rs
Normal file
75
2022/days/09/src/parse.rs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Direction {
|
||||
Up,
|
||||
Right,
|
||||
Down,
|
||||
Left,
|
||||
}
|
||||
|
||||
static PARSE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^([URDL]) (\d+)$").unwrap());
|
||||
|
||||
pub fn parse(input: &str) -> Vec<Direction> {
|
||||
let mut ret = Vec::new();
|
||||
for line in input.lines() {
|
||||
let captures = PARSE_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
let dir = match &captures[1] {
|
||||
"U" => Direction::Up,
|
||||
"R" => Direction::Right,
|
||||
"D" => Direction::Down,
|
||||
"L" => Direction::Left,
|
||||
_ => panic!("invalid direction char"),
|
||||
};
|
||||
for _ in 0..captures[2]
|
||||
.parse()
|
||||
.unwrap_or_else(|_| panic!("invalid line {}", line))
|
||||
{
|
||||
ret.push(dir)
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input =
|
||||
concat!("R 4\n", "U 4\n", "L 3\n", "D 1\n", "R 4\n", "D 1\n", "L 5\n", "R 2\n",);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Down,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Down,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
53
2022/days/09/src/part1.rs
Normal file
53
2022/days/09/src/part1.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use aoc_libs::points::Point;
|
||||
|
||||
use crate::parse::Direction;
|
||||
use crate::rope::Rope;
|
||||
|
||||
pub fn part1(input: &Vec<Direction>) -> usize {
|
||||
let mut visited: HashSet<Point> = HashSet::new();
|
||||
let mut rope: Rope<2> = Rope::new();
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
for direction in input {
|
||||
rope.update_rope(direction);
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
}
|
||||
visited.len()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part1() {
|
||||
let input = vec![
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Down,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Down,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
];
|
||||
assert_eq!(part1(&input), 13);
|
||||
}
|
||||
}
|
||||
31
2022/days/09/src/part2.rs
Normal file
31
2022/days/09/src/part2.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use aoc_libs::points::Point;
|
||||
|
||||
use crate::{parse::Direction, rope::Rope};
|
||||
|
||||
pub fn part2(input: &Vec<Direction>) -> usize {
|
||||
let mut visited: HashSet<Point> = HashSet::new();
|
||||
let mut rope: Rope<10> = Rope::new();
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
for direction in input {
|
||||
rope.update_rope(direction);
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
}
|
||||
visited.len()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::parse::parse;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_part2() {
|
||||
let input = parse(concat!(
|
||||
"R 5\n", "U 8\n", "L 8\n", "D 3\n", "R 17\n", "D 10\n", "L 25\n", "U 20\n",
|
||||
));
|
||||
assert_eq!(part2(&input), 36);
|
||||
}
|
||||
}
|
||||
160
2022/days/09/src/rope.rs
Normal file
160
2022/days/09/src/rope.rs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use crate::parse::Direction;
|
||||
use aoc_libs::points::{Point, UPoint};
|
||||
|
||||
// L is the length of the rope in segments.
|
||||
#[derive(Debug)]
|
||||
pub struct Rope<const L: usize> {
|
||||
segments: [Point; L],
|
||||
}
|
||||
|
||||
impl<const L: usize> Rope<L> {
|
||||
pub fn new() -> Rope<L> {
|
||||
Rope {
|
||||
segments: [Point::default(); L],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_rope(&mut self, direction: &Direction) {
|
||||
self.segments[0] += match direction {
|
||||
Direction::Up => Point { x: 0, y: 1 },
|
||||
Direction::Right => Point { x: 1, y: 0 },
|
||||
Direction::Down => Point { x: 0, y: -1 },
|
||||
Direction::Left => Point { x: -1, y: 0 },
|
||||
};
|
||||
for segment in 1..self.segments.len() {
|
||||
self.segments[segment] += Rope::<L>::update_single_segment_pair(
|
||||
&self.segments[segment - 1],
|
||||
&self.segments[segment],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_tail_pos(&self) -> &Point {
|
||||
&self.segments[self.segments.len() - 1]
|
||||
}
|
||||
|
||||
// the rope segment will not move if the segment ahead of it is only at most one away, and will
|
||||
// move with the following rules if it is 2 away: It moves straight towards the head if the
|
||||
// head is directly up/down/left/right, and diagonally towards it if its not straight
|
||||
// up/down/left/right.
|
||||
fn update_single_segment_pair(head: &Point, tail: &Point) -> Point {
|
||||
let delta = *head - *tail;
|
||||
if delta.x.abs() > 2 || delta.y.abs() > 2 {
|
||||
panic!("invalid delta ({}, {})", delta.y, delta.x)
|
||||
}
|
||||
match (delta.x, delta.y) {
|
||||
(0, 2) => Point { x: 0, y: 1 },
|
||||
(2, 0) => Point { x: 1, y: 0 },
|
||||
(0, -2) => Point { x: 0, y: -1 },
|
||||
(-2, 0) => Point { x: -1, y: 0 },
|
||||
(1, 2) | (2, 2) | (2, 1) => Point { x: 1, y: 1 },
|
||||
(2, -1) | (2, -2) | (1, -2) => Point { x: 1, y: -1 },
|
||||
(-1, -2) | (-2, -2) | (-2, -1) => Point { x: -1, y: -1 },
|
||||
(-2, 1) | (-2, 2) | (-1, 2) => Point { x: -1, y: 1 },
|
||||
_ => Point { x: 0, y: 0 },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<const L: usize> Display for Rope<{ L }> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let grid_size = (self.segments.len() * 2) - 1;
|
||||
let zero_point = UPoint {
|
||||
x: self.segments.len() - 1,
|
||||
y: self.segments.len() - 1,
|
||||
};
|
||||
|
||||
let mut grid: Vec<Vec<char>> = Vec::with_capacity(grid_size);
|
||||
for y in 0..grid_size {
|
||||
grid.push(Vec::with_capacity(grid_size));
|
||||
for _ in 0..grid_size {
|
||||
grid[y].push('.')
|
||||
}
|
||||
}
|
||||
|
||||
for segment in self.segments.iter().skip(1) {
|
||||
let delta = *segment - self.segments[0];
|
||||
let upoint = delta.to_upoint(&zero_point).unwrap();
|
||||
grid[upoint.y][upoint.x] = 'T'
|
||||
}
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
"head is at {}, {}",
|
||||
self.segments[0].x, self.segments[0].y
|
||||
)?;
|
||||
let upoint = Point { x: 0, y: 0 }.to_upoint(&zero_point).unwrap();
|
||||
grid[upoint.y][upoint.x] = 'H';
|
||||
|
||||
for line in grid {
|
||||
let mut writeline = "".to_string();
|
||||
for char in line {
|
||||
writeline.push(char)
|
||||
}
|
||||
writeln!(f, "{}", writeline)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashSet;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_single_segment() {
|
||||
let input = [
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Up,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Down,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
Direction::Down,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Left,
|
||||
Direction::Right,
|
||||
Direction::Right,
|
||||
];
|
||||
let mut visited: HashSet<Point> = HashSet::new();
|
||||
let mut rope: Rope<2> = Rope::new();
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
println!("{}", rope);
|
||||
for direction in input {
|
||||
rope.update_rope(&direction);
|
||||
visited.insert(*rope.get_tail_pos());
|
||||
println!("{}", rope);
|
||||
}
|
||||
// let mut graph = [
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['.', '.', '.', '.', '.', '.'],
|
||||
// ['s', '.', '.', '.', '.', '.'],
|
||||
// ];
|
||||
// for point in &visited {
|
||||
// graph[4 - point.y as usize][point.x as usize] = '#';
|
||||
// }
|
||||
// for line in graph {
|
||||
// println!("{:?}", line)
|
||||
// }
|
||||
assert_eq!(visited.len(), 13)
|
||||
}
|
||||
}
|
||||
10
2022/days/10/Cargo.toml
Normal file
10
2022/days/10/Cargo.toml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "day10"
|
||||
authors.workspace = true
|
||||
description.workspace = true
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
aoc_libs.workspace = true
|
||||
nom.workspace = true
|
||||
118
2022/days/10/src/crt.rs
Normal file
118
2022/days/10/src/crt.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
use std::fmt::Display;
|
||||
|
||||
use crate::machine::Machine;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct Crt {
|
||||
pub screen: [[bool; 40]; 6],
|
||||
}
|
||||
|
||||
impl Crt {
|
||||
pub fn draw_pixel(&mut self, sprite_pos: i32, cycle: usize) {
|
||||
let x_coord = (cycle - 1) % self.screen[0].len();
|
||||
if sprite_pos.abs_diff(x_coord as i32) <= 1 {
|
||||
self[cycle] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Crt {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
screen: [[false; 40]; 6],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Crt {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for line in self.screen {
|
||||
for char in line {
|
||||
if char {
|
||||
write!(f, "#")?;
|
||||
} else {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
writeln!(f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Index<usize> for Crt {
|
||||
type Output = bool;
|
||||
|
||||
fn index(&self, index: usize) -> &Self::Output {
|
||||
let index = index - 1;
|
||||
let x = index % self.screen[0].len();
|
||||
let y = index / self.screen[0].len();
|
||||
&self.screen[y][x]
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::IndexMut<usize> for Crt {
|
||||
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
|
||||
let index = index - 1;
|
||||
let x = index % self.screen[0].len();
|
||||
let y = index / self.screen[0].len();
|
||||
&mut self.screen[y][x]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_index() {
|
||||
let mut input = Crt::default();
|
||||
input[1] = true;
|
||||
input[40] = true;
|
||||
input[41] = true;
|
||||
println!("{}", input);
|
||||
assert_eq!(
|
||||
input,
|
||||
Crt {
|
||||
screen: [
|
||||
[
|
||||
true, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, true
|
||||
],
|
||||
[
|
||||
true, false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false,
|
||||
false, false, false, false, false, false, false, false, false, false
|
||||
]
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
139
2022/days/10/src/input.txt
Normal file
139
2022/days/10/src/input.txt
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
noop
|
||||
addx 12
|
||||
addx -5
|
||||
addx -1
|
||||
noop
|
||||
addx 4
|
||||
noop
|
||||
addx 1
|
||||
addx 4
|
||||
noop
|
||||
addx 13
|
||||
addx -8
|
||||
noop
|
||||
addx -19
|
||||
addx 24
|
||||
addx 1
|
||||
noop
|
||||
addx 4
|
||||
noop
|
||||
addx 1
|
||||
addx 5
|
||||
addx -1
|
||||
addx -37
|
||||
addx 16
|
||||
addx -13
|
||||
addx 18
|
||||
addx -11
|
||||
addx 2
|
||||
addx 23
|
||||
noop
|
||||
addx -18
|
||||
addx 9
|
||||
addx -8
|
||||
addx 2
|
||||
addx 5
|
||||
addx 2
|
||||
addx -21
|
||||
addx 26
|
||||
noop
|
||||
addx -15
|
||||
addx 20
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx -38
|
||||
addx 3
|
||||
noop
|
||||
addx 26
|
||||
addx -4
|
||||
addx -19
|
||||
addx 3
|
||||
addx 1
|
||||
addx 5
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
addx 3
|
||||
noop
|
||||
addx 2
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 3
|
||||
noop
|
||||
addx -30
|
||||
addx -4
|
||||
addx 1
|
||||
addx 18
|
||||
addx -8
|
||||
addx -4
|
||||
addx 2
|
||||
noop
|
||||
addx 7
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx -2
|
||||
addx -20
|
||||
addx 27
|
||||
addx -20
|
||||
addx 25
|
||||
addx -2
|
||||
addx -35
|
||||
noop
|
||||
noop
|
||||
addx 4
|
||||
addx 3
|
||||
addx -2
|
||||
addx 5
|
||||
addx 2
|
||||
addx -11
|
||||
addx 1
|
||||
addx 13
|
||||
addx 2
|
||||
addx 5
|
||||
addx 6
|
||||
addx -1
|
||||
addx -2
|
||||
noop
|
||||
addx 7
|
||||
addx -2
|
||||
addx 6
|
||||
addx 1
|
||||
addx -21
|
||||
addx 22
|
||||
addx -38
|
||||
addx 5
|
||||
addx 3
|
||||
addx -1
|
||||
noop
|
||||
noop
|
||||
addx 5
|
||||
addx 1
|
||||
addx 4
|
||||
addx 3
|
||||
addx -2
|
||||
addx 2
|
||||
noop
|
||||
addx 7
|
||||
addx -1
|
||||
addx 2
|
||||
addx 4
|
||||
addx -10
|
||||
addx -19
|
||||
addx 35
|
||||
addx -1
|
||||
noop
|
||||
noop
|
||||
noop
|
||||
455
2022/days/10/src/machine.rs
Normal file
455
2022/days/10/src/machine.rs
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
use std::{collections::VecDeque, fmt};
|
||||
|
||||
use crate::crt::Crt;
|
||||
use crate::parse::*;
|
||||
|
||||
pub struct Machine {
|
||||
instructions: VecDeque<Instruction>,
|
||||
current_instruction: Option<(Instruction, usize)>,
|
||||
cycle: usize,
|
||||
x: i32,
|
||||
pub crt: Crt,
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
pub fn load_program(instructions: VecDeque<Instruction>) -> Self {
|
||||
let mut res = Machine {
|
||||
instructions,
|
||||
current_instruction: None,
|
||||
cycle: 0,
|
||||
x: 1,
|
||||
crt: Crt::default(),
|
||||
};
|
||||
res.fetch_next_instruction();
|
||||
res
|
||||
}
|
||||
|
||||
pub fn step(&mut self) -> (bool, i32) {
|
||||
if self.current_instruction.is_none() {
|
||||
return (false, self.x);
|
||||
}
|
||||
|
||||
//we return x as it was at the beginning of the cycle.
|
||||
let x = self.x;
|
||||
let (instruction, cycles_left) = self.current_instruction.as_mut().unwrap();
|
||||
*cycles_left -= 1;
|
||||
if *cycles_left == 0 {
|
||||
if let Instruction::Addx(i) = instruction {
|
||||
self.x += *i
|
||||
}
|
||||
|
||||
self.fetch_next_instruction();
|
||||
};
|
||||
|
||||
self.cycle += 1;
|
||||
self.crt.draw_pixel(x, self.cycle);
|
||||
(true, x)
|
||||
}
|
||||
|
||||
fn fetch_next_instruction(&mut self) {
|
||||
self.current_instruction = self.instructions.pop_front().map(|i| (i, i.cycles()));
|
||||
}
|
||||
|
||||
//returns the signal strength during the middle of the 20th cycle.
|
||||
pub fn step20(&mut self) -> i32 {
|
||||
for _ in 0..19 {
|
||||
if !self.step().0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
self.step().1 * self.cycle as i32
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Machine {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"cycle={} x={} current instruction: {:?} ({} instructions left)",
|
||||
self.cycle,
|
||||
self.x,
|
||||
self.current_instruction,
|
||||
self.instructions.len()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_screen() {
|
||||
let input = vec![
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::Addx(6),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-8),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(4),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-35),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(24),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(16),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(21),
|
||||
Instruction::Addx(-15),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(8),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-36),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(6),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(7),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-33),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(8),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(17),
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(26),
|
||||
Instruction::Addx(-30),
|
||||
Instruction::Addx(12),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(18),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(9),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-37),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-21),
|
||||
Instruction::Addx(22),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-10),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(20),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
];
|
||||
let mut machine = Machine::load_program(input.into());
|
||||
//step till we cant anymore.
|
||||
while machine.step().0 {}
|
||||
println!("{}", machine.crt);
|
||||
assert_eq!(
|
||||
machine.crt,
|
||||
Crt {
|
||||
screen: [
|
||||
[
|
||||
true, true, false, false, true, true, false, false, true, true, false,
|
||||
false, true, true, false, false, true, true, false, false, true, true,
|
||||
false, false, true, true, false, false, true, true, false, false, true,
|
||||
true, false, false, true, true, false, false
|
||||
],
|
||||
[
|
||||
true, true, true, false, false, false, true, true, true, false, false,
|
||||
false, true, true, true, false, false, false, true, true, true, false,
|
||||
false, false, true, true, true, false, false, false, true, true, true,
|
||||
false, false, false, true, true, true, false
|
||||
],
|
||||
[
|
||||
true, true, true, true, false, false, false, false, true, true, true, true,
|
||||
false, false, false, false, true, true, true, true, false, false, false,
|
||||
false, true, true, true, true, false, false, false, false, true, true,
|
||||
true, true, false, false, false, false
|
||||
],
|
||||
[
|
||||
true, true, true, true, true, false, false, false, false, false, true,
|
||||
true, true, true, true, false, false, false, false, false, true, true,
|
||||
true, true, true, false, false, false, false, false, true, true, true,
|
||||
true, true, false, false, false, false, false
|
||||
],
|
||||
[
|
||||
true, true, true, true, true, true, false, false, false, false, false,
|
||||
false, true, true, true, true, true, true, false, false, false, false,
|
||||
false, false, true, true, true, true, true, true, false, false, false,
|
||||
false, false, false, true, true, true, true
|
||||
],
|
||||
[
|
||||
true, true, true, true, true, true, true, false, false, false, false,
|
||||
false, false, false, true, true, true, true, true, true, true, false,
|
||||
false, false, false, false, false, false, true, true, true, true, true,
|
||||
true, true, false, false, false, false, false
|
||||
]
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_machine() {
|
||||
let input = vec![
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::Addx(6),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-8),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(4),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-35),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(24),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(16),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(21),
|
||||
Instruction::Addx(-15),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(8),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-36),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(6),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(7),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-33),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(8),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(17),
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(26),
|
||||
Instruction::Addx(-30),
|
||||
Instruction::Addx(12),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(18),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(9),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-37),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-21),
|
||||
Instruction::Addx(22),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-10),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(20),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
];
|
||||
let mut machine = Machine::load_program(input.into());
|
||||
|
||||
//20th
|
||||
assert_eq!(machine.step20(), 420);
|
||||
|
||||
machine.step20();
|
||||
//60th
|
||||
assert_eq!(machine.step20(), 1140);
|
||||
|
||||
machine.step20();
|
||||
//100th
|
||||
assert_eq!(machine.step20(), 1800);
|
||||
|
||||
machine.step20();
|
||||
//140th
|
||||
assert_eq!(machine.step20(), 2940);
|
||||
|
||||
machine.step20();
|
||||
//180th
|
||||
assert_eq!(machine.step20(), 2880);
|
||||
|
||||
machine.step20();
|
||||
//220th
|
||||
assert_eq!(machine.step20(), 3960);
|
||||
}
|
||||
}
|
||||
16
2022/days/10/src/main.rs
Normal file
16
2022/days/10/src/main.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
mod part1;
|
||||
mod part2;
|
||||
mod parse;
|
||||
mod machine;
|
||||
mod crt;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let structured_input = parse::parse(input);
|
||||
|
||||
println!("Part One");
|
||||
println!("Result: {}", part1::part1(structured_input.clone()));
|
||||
|
||||
println!("Part Two");
|
||||
println!("Result:\n{}", part2::part2(structured_input.clone()));
|
||||
}
|
||||
344
2022/days/10/src/parse.rs
Normal file
344
2022/days/10/src/parse.rs
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use nom::{
|
||||
branch::alt,
|
||||
bytes::complete::tag,
|
||||
combinator::{all_consuming, map, value},
|
||||
sequence::preceded,
|
||||
Finish, IResult,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Instruction {
|
||||
NoOp,
|
||||
Addx(i32),
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
fn parse(i: &str) -> IResult<&str, Self> {
|
||||
let noop = tag("noop");
|
||||
let addx = preceded(tag("addx "), nom::character::complete::i32);
|
||||
alt((value(Self::NoOp, noop), map(addx, Self::Addx)))(i)
|
||||
}
|
||||
pub fn cycles(self) -> usize {
|
||||
match self {
|
||||
Self::NoOp => 1,
|
||||
Self::Addx(_) => 2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> VecDeque<Instruction> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| all_consuming(Instruction::parse)(l).finish().unwrap().1)
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let input = concat!(
|
||||
"addx 15\n",
|
||||
"addx -11\n",
|
||||
"addx 6\n",
|
||||
"addx -3\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx -8\n",
|
||||
"addx 13\n",
|
||||
"addx 4\n",
|
||||
"noop\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx 5\n",
|
||||
"addx -1\n",
|
||||
"addx -35\n",
|
||||
"addx 1\n",
|
||||
"addx 24\n",
|
||||
"addx -19\n",
|
||||
"addx 1\n",
|
||||
"addx 16\n",
|
||||
"addx -11\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 21\n",
|
||||
"addx -15\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -3\n",
|
||||
"addx 9\n",
|
||||
"addx 1\n",
|
||||
"addx -3\n",
|
||||
"addx 8\n",
|
||||
"addx 1\n",
|
||||
"addx 5\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -36\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"addx 7\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 2\n",
|
||||
"addx 6\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 7\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx -13\n",
|
||||
"addx 13\n",
|
||||
"addx 7\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"addx -33\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 2\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 8\n",
|
||||
"noop\n",
|
||||
"addx -1\n",
|
||||
"addx 2\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx 17\n",
|
||||
"addx -9\n",
|
||||
"addx 1\n",
|
||||
"addx 1\n",
|
||||
"addx -3\n",
|
||||
"addx 11\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -13\n",
|
||||
"addx -19\n",
|
||||
"addx 1\n",
|
||||
"addx 3\n",
|
||||
"addx 26\n",
|
||||
"addx -30\n",
|
||||
"addx 12\n",
|
||||
"addx -1\n",
|
||||
"addx 3\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -9\n",
|
||||
"addx 18\n",
|
||||
"addx 1\n",
|
||||
"addx 2\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 9\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx -1\n",
|
||||
"addx 2\n",
|
||||
"addx -37\n",
|
||||
"addx 1\n",
|
||||
"addx 3\n",
|
||||
"noop\n",
|
||||
"addx 15\n",
|
||||
"addx -21\n",
|
||||
"addx 22\n",
|
||||
"addx -6\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx 2\n",
|
||||
"addx 1\n",
|
||||
"noop\n",
|
||||
"addx -10\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"addx 20\n",
|
||||
"addx 1\n",
|
||||
"addx 2\n",
|
||||
"addx 2\n",
|
||||
"addx -6\n",
|
||||
"addx -11\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
"noop\n",
|
||||
);
|
||||
assert_eq!(
|
||||
parse(input),
|
||||
vec![
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::Addx(6),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-8),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(4),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(-35),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(24),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(16),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(21),
|
||||
Instruction::Addx(-15),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(8),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(5),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-36),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(6),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(7),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(13),
|
||||
Instruction::Addx(7),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-33),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(8),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(17),
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(-3),
|
||||
Instruction::Addx(11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-13),
|
||||
Instruction::Addx(-19),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(26),
|
||||
Instruction::Addx(-30),
|
||||
Instruction::Addx(12),
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-9),
|
||||
Instruction::Addx(18),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(9),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-37),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(3),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(15),
|
||||
Instruction::Addx(-21),
|
||||
Instruction::Addx(22),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(1),
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(-10),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::Addx(20),
|
||||
Instruction::Addx(1),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(2),
|
||||
Instruction::Addx(-6),
|
||||
Instruction::Addx(-11),
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp,
|
||||
Instruction::NoOp
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue