Collection of tools for solving Advent of Code puzzles in python
- Installation
- Template file generation
- Usage
- Parsing Input
- String / Number
- List (split at newline)
- List (split at arbitryry character)
- Set (split at newline)
- Set (split at arbitryry character)
- Multi-List Parsing - Columns
- Multi-List Parsing - Columns (split at arbitrary separator)
- Multi-List Parsing - Rows
- Multi-List Parsing - Rows (split at arbitrary separator)
- Grid of single characters
- Grid of separated characters
- Key-Value pairs
- Literal
- Literal List
- Submitting Output
- Use example or custom input
- Parsing Input
- Tools
- Simple vector
git clone https://github.com/brtwrst/aoc-tools.git
### Install in edit mode so the packet can be updated just by git pulling
cd aoc-tools
pip install -e . --config-settings editable_mode=compat
or
pip install -e . --user --config-settings editable_mode=compat
- Can be run anywhere once installed with:
python -m aoctools.create <year>
- This will create 25 template files (1 for each day) in a Subfolder for a given year.
- You will be asked if you want to add optional timing code
from aoctools import *
aocd = AOCD(2021, 1)
puzzle_input = aocd.as_str
# calculate the answers
aocd.p1('<answer to part 1>')
aocd.p2('<answer to part 2>')
aocd = AOCD(2021, 1)
This Class will pull your input and submit your solutions.
This will ask you for your AOC session-cookie on the first run. The cookie can be found in the chrome dev tools while you are logged in to adventofcode.com (Application -> Cookies)
- Example Input
1234
aocd.as_int
parse input as single int-
aocd.as_int -> 1234
-
aocd.as_str
parse input as single str-
aocd.as_str -> '1234'
-
- Example Input
12 34
aocd.ilist
parse input as list of int (split at newline)-
aocd.ilist -> [12, 34]
-
aocd.slist
parse input as list of str (split at newline)-
aocd.slist -> ['12', '34']
-
- Example Input
1;2;3;4
aocd.ilist_split_at(sep)
parse input as list of int (split at sep)-
aocd.ilist_split_at(';') -> [1,2,3,4]
-
aocd.slist_split_at(sep)
parse input as list of str (split at sep)-
aocd.slist_split_at(';') -> ['1','2','3','4']
-
- Example Input
1 2 3 4
aocd.icolumns
parse input columns as multiple lists of int-
aocd.icolumns -> [[1,3],[2,4]]
-
aocd.scolumns
parse input columns as multiple lists of str-
aocd.scolumns -> [['1','3'],['2','4']]
-
- Example Input
1,2 3,4
aocd.icolumns_split_at(sep=',')
parse input columns as multiple lists of int (split at sep)-
aocd.icolumns -> [[1,3],[2,4]]
-
aocd.scolumns_split_at(sep=',')
parse input columns as multiple lists of str (split at sep)-
aocd.scolumns -> [['1','3'],['2','4']]
-
- Example Input
1 2 3 4
aocd.irows
parse input rows as multiple lists of int-
aocd.irows -> [[1,2],[3,4]]
-
aocd.srows
parse input rows as multiple lists of str-
aocd.srows -> [['1','2'],['3','4']]
-
- Example Input
1,2 3,4
aocd.irows_split_at(sep=',')
parse input rows as multiple lists of int (split at sep)-
aocd.irows -> [[1,2],[3,4]]
-
aocd.srows_split_at(sep=',')
parse input rows as multiple lists of str (split at sep)-
aocd.srows -> [['1','2'],['3','4']]
-
- Example Input
12 34
aocd.iset
parse input as set of int-
aocd.iset -> {12, 34}
-
aocd.sset
parse input as set of str-
aocd.sset -> {'12', '34'}
-
- Example Input
1;2;3;4;4
aocd.ilist_split_at(sep)
parse input as list of int (split at sep)-
aocd.iset_split_at(';') -> {1,2,3,4}
-
aocd.slist_split_at(sep)
parse input as list of str (split at sep)-
aocd.sset_split_at(';') -> {'1','2','3','4'}]
-
- Example Input
12 34
aocd.igrid
parse input as a grid of single digit numbers (split input at newline)-
aocd.igrid -> { (0,0) : 1, (1,0) : 2, (0,1) : 3, (1,1) : 4, }
-
aocd.sgrid
parse input as a grid of single characters (split input at newline)-
aocd.sgrid -> { (0,0) : '1', (1,0) : '2', (0,1) : '3', (1,1) : '4', }
-
-
aocd.vigrid
parse input as a grid of single digit numbers (split input at newline)-
aocd.igrid -> { Vec(0,0) : 1, Vec(1,0) : 2, Vec(0,1) : 3, Vec(1,1) : 4, }
-
-
aocd.vsgrid
parse input as a grid of single characters (split input at newline)-
aocd.sgrid -> { Vec(0,0) : '1', Vec(1,0) : '2', Vec(0,1) : '3', Vec(1,1) : '4', }
-
-
aocd.mgrid(mapping, vectors=False)
parse input as a grid of single characters but map them to a new value in the dict-
aocd.mgrid(mapping={'1': 'FOO', '2':'BAR'}) -> { (0,0) : 'FOO', (1,0) : 'BAR', (0,1) : '3', (1,1) : '4', }
-
You can set vectors=True to get the keys() as Vectors
- Example Input
1,2 3,4
aocd.igrid_split_at(sep, vectors=False)
parse input as a grid of integers (split input at newline) (split line at sep)-
aocd.igrid_split_at(',') -> { (0,0) : 1, (1,0) : 2, (0,1) : 3, (1,1) : 4, }
-
aocd.sgrid_split_at(sep, vectors=False)
parse input as a grid of strings (split input at newline) (split line at sep)-
aocd.sgrid_split_at(',') -> { (0,0) : '1', (1,0) : '2', (0,1) : '3', (1,1) : '4', }
-
aocd.mgrid_split_at(mapping, sep, vectors=False)
parse input as a grid of single characters but map them to a new value in the dict-
aocd.mgrid(mapping={'1': 'FOO', '2':'BAR'}, sep=',') -> { (0,0) : 'FOO', (1,0) : 'BAR', (0,1) : '3', (1,1) : '4', }
-
- Example Input
ab-cd de-fg
aocd.key_value_split_at(sep, keytype=str, valuetype=str)
parse input as lines of key-value pairs with specific types (default str)-
aocd.dict_split_at('-') -> { 'ab': 'cd', 'de': 'fg' }
-
- Example Input
{ a:1, b:2 }
aocd.literal
parse input as python object-
aocd.literal -> { a:1, b:2 }
-
- Example Input
[1,2] [3,4]
aocd.literal_list
parse input as lines of python objects-
aocd.literal_list -> [ [1,2], [3,4] ]
-
You can use the tool to submit your answer to adventofcode.com The tool will inform you if the answer was wrong and it will cache all submitted answers so you don't submit the same wrong result twice.
aocd.p1(answer)
submit answer for part 1aocd.p2(answer)
submit answer for part 2
The tool allows you to use arbitrary input for a Puzzle. This can be used to test with example input or to run your code with different input.
While you are in "example mode" and use aocd.p1() or aocd.p2()
, the answer will only be displayed and not submitted to the website. So in order to submit your answer, you have to comment out the set_example()
or get_example()
Use aocd.get_example()
to attempt to download the example for the day from the adventofcode.com automatically.
Give the input verbatim as multiline string to aocd.set_example(<input>)
before parsing. The following example uses the input of https://adventofcode.com/2021/day/3
aocd = AOCD(2021, 3)
aocd.set_example("""00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010""")
Some tool functions/classes that help with programming puzzles.
miller_rabin(n)
only works up to about 10**23miller_rabin2(n)
works for big primes but is probability based- Both will return
True
if the given numbern
is prime andFalse
if it is not
matrix_transpose
will transpose a 2D matrix, the result will be a list of tuples.matrix_transpose_lists
will transpose a 2D matrix, the result will be a list of lists.matrix_transpose_strings
will transpose a 2D matrix, the result will be a list of strings.matrix_transpose_dicts
will transpose a 2D matrix, the result will be a list of dicts.matrix_rotate
will rotate a 2D matrix clockwise 90 degrees, the result will be a list of tuples.matrix_rotate_lists
will rotate a 2D matrix clockwise 90 degrees, the result will be a list of lists.matrix_rotate_strings
will rotate a 2D matrix clockwise 90 degrees, the result will be a list of strings.matrix_rotate_dicts
will rotate a 2D matrix clockwise 90 degrees, the result will be a list of dicts.
# consider the following 2D matrix
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
transposed_matrix = matrix_transpose(matrix)
# result
'''
transposed_matrix = [
(1,4,7),
(2,5,8),
(3,6,9)
]
'''
transposed_matrix_lists = matrix_transpose_lists(matrix)
# result
'''
transposed_matrix_lists = [
[1,4,7],
[2,5,8],
[3,6,9]
]
'''
# consider the following 2D matrix - strings are iterables too
matrix = [
'123',
'456',
'789'
]
transposed_matrix_strings = matrix_transpose_strings(matrix)
# result
'''
transposed_matrix_strings = [
'147',
'258',
'369'
]
'''
# consider the following 2D matrix
matrix = [
{'A': 1, 'B': 2, 'C': 3},
{'D': 4, 'E': 5, 'F': 6},
{'G': 7, 'H': 8, 'I': 9}
]
transposed_matrix_dicts = matrix_transpose_dicts(matrix)
# result
'''
transposed_matrix_dicts = [
{'A': 1, 'D': 4, 'G': 7},
{'B': 2, 'E': 5, 'H': 8},
{'C': 3, 'F': 6, 'I': 9}
]
'''
# consider the following 2D matrix
matrix = [
[1,2,3],
[4,5,6],
[7,8,9]
]
rotated_matrix = matrix_rotate(matrix)
# result
'''
rotated_matrix = [
(7,4,1),
(8,5,2),
(9,6,3)
]
'''
rotated_matrix_lists = matrix_rotate_lists(matrix)
# result
'''
rotated_matrix_lists = [
[7,4,1],
[8,5,2],
[9,6,3]
]
'''
# consider the following 2D matrix - strings are iterables too
matrix = [
'123',
'456',
'789'
]
rotated_matrix_strings = matrix_rotate_strings(matrix)
# result
'''
rotated_matrix_strings = [
'741',
'852',
'963'
]
'''
# consider the following 2D matrix
matrix = [
{'A': 1, 'B': 2, 'C': 3},
{'D': 4, 'E': 5, 'F': 6},
{'G': 7, 'H': 8, 'I': 9}
]
rotated_matrix_dicts = matrix_rotate_dicts(matrix)
# result
'''
rotated_matrix_dicts = [
{'G': 7, 'D': 4, 'A': 1},
{'H': 8, 'E': 5, 'B': 2},
{'I': 9, 'F': 6, 'C': 3}
]
'''
v = Vec(1,2,3)
- This is a simple implementation of a vector.
- Objects of this class are hashable (can be used as dict keys)
- Vectors can be any length/dimension
Vec(1,2)
/Vec(1,2,3,4,5)
although only vectors of the same dimension can be added/multiplied
- Dimension/Length
len(Vec(1,2,3))
- Addition
Vec(1,2,3) + Vec(1,2,3)
- Subtraction
Vec(1,2,3) - Vec(1,2,3)
- Vector Multiplication
Vec(1,2,3) * Vec(2,3,4)
- Scalar Multiplication
Vec(1,2,3) * 2
- Scalar Division/Floor Division
Vec(1,2,3) / 2
Vec(1,2,3) // 2
- Cross Product
Vec(1,2,3) @ Vec(1,1,1)
orVec(1,2,3).cross_product(Vec(1,1,1))
- Modulo each element
Vec(1,2,3) % 2
- Exponentiate each element
Vec(1,2,3) ** 2
- Left-Shift each element
Vec(1,2,3) << 2
- Right-Shift each element
Vec(1,2,3) >> 2
- Bitwise-And each element
Vec(1,2,3) & 2
- Bitwise-XOr each element
Vec(1,2,3) ^ 2
- Bitwise-Or each element
Vec(1,2,3) | 2
- Comparison
< > == != <= >=
- Length/Absolute
abs(Vec(1,2,3))
(will give the vector magnitude) - element access
Vec(1,2,3)[0]
(also assignmentVec(1,2,3)[2] = 2
) - count occurances of specific element
Vec(1,2,3).count(0)
(Number of 0s in the vector) - Rotate vector by a Matrix (Matrix is a list of Vec, each Vec represents one row of the matrix)
Vec(1,2,3).rotate_with_matrix([Vec(0,1,0),Vec(0,0,1),Vec(1,0,0)])