Compare commits

..

7 Commits

10 changed files with 752 additions and 16 deletions

View File

@ -67,6 +67,48 @@ larger.)
Before you\'re ready to help them, you need to make sure your
information is correct. *What is the name of the bottom program?*
To begin, [get your puzzle input](7/input).
Your puzzle answer was `xegshds`.
Answer:
## \-\-- Part Two \-\-- {#part2}
The programs explain the situation: they can\'t get down. Rather, they
*could* get down, if they weren\'t expending all of their energy trying
to keep the tower balanced. Apparently, one program has the *wrong
weight*, and until it\'s fixed, they\'re stuck here.
For any program holding a disc, each program standing on that disc forms
a sub-tower. Each of those sub-towers are supposed to be the same
weight, or the disc itself isn\'t balanced. The weight of a tower is the
sum of the weights of the programs in that tower.
In the example above, this means that for `ugml`\'s disc to be balanced,
`gyxo`, `ebii`, and `jptl` must all have the same weight, and they do:
`61`.
However, for `tknk` to be balanced, each of the programs standing on its
disc *and all programs above it* must each match. This means that the
following sums must all be the same:
- `ugml` + (`gyxo` + `ebii` + `jptl`) = 68 + (61 + 61 + 61) = 251
- `padx` + (`pbga` + `havc` + `qoyq`) = 45 + (66 + 66 + 66) = 243
- `fwft` + (`ktlj` + `cntj` + `xhth`) = 72 + (57 + 57 + 57) = 243
As you can see, `tknk`\'s disc is unbalanced: `ugml`\'s stack is heavier
than the other two. Even though the nodes above `ugml` are balanced,
`ugml` itself is too heavy: it needs to be `8` units lighter for its
stack to weigh `243` and keep the towers balanced. If this change were
made, its weight would be `60`.
Given that exactly one program is the wrong weight, *what would its
weight need to be* to balance the entire tower?
Your puzzle answer was `299`.
Both parts of this puzzle are complete! They provide two gold stars:
\*\*
At this point, you should [return to your Advent calendar](/2017) and
try another puzzle.
If you still want to see it, you can [get your puzzle
input](7/input).

View File

@ -1,8 +1,9 @@
#!/bin/python3
import sys, re
from pprint import pprint
from collections import Counter
input_f = 'test'
input_f = 'input'
part = 2
@ -11,7 +12,8 @@ part = 2
# Part 1 #
# #
#########################################
if part == 1:
def part1():
children = []
mains = []
with open(input_f)as file:
@ -27,7 +29,10 @@ if part == 1:
for x in mains:
if x not in children:
print(x)
return x
if part == 1:
print(part1())
@ -36,17 +41,136 @@ if part == 1:
# Part 2 #
# #
#########################################
def find_children(x,grid):
# x will be a string like 'tknk'
print('Testing ',x)
found = []
for i in grid:
if i.startswith(x):
match = re.search(r"-> (.+)", i)
if match:
found = [item.strip() for item in match.group(1).split(",")]
print(found)
else:
print([i for i in grid if i.startswith(x)])
if found != None:
for j in found:
find_children(j,grid)
def calculate_weights(node, tree, weights, total_weights):
# Compute total weight for the current node
total = weights[node]
for child in tree[node]:
total += calculate_weights(child, tree, weights, total_weights)
total_weights[node] = total
return total
def find_outlier(lst):
count = Counter(lst)
outlier = None
reference = None
for num, freq in count.items():
if freq == 1 or freq < len(lst) - 1:
outlier = num
else:
reference = num
return outlier,reference
def find_unbalanced(node, tree, weights, total_weights):
child_weights = [total_weights[child] for child in tree[node]]
if len(set(child_weights)) == 1:
return None
weight_counts = {w: child_weights.count(w) for w in child_weights}
incorrect_weight = next(w for w, count in weight_counts.items() if count == 1)
correct_weight = next(w for w, count in weight_counts.items() if count > 1)
unbalanced_child = tree[node][child_weights.index(incorrect_weight)]
deeper_issue = find_unbalanced(unbalanced_child, tree, weights, total_weights)
if deeper_issue:
return deeper_issue
else:
return unbalanced_child, weights[unbalanced_child] + (correct_weight - incorrect_weight)
if part == 2:
children = []
mains = []
grid = []
with open(input_f)as file:
for line in file:
l = line.rstrip()
if '->' in l:
x = l.split('->')
for i in x[1].split(','):
children.append(i.strip())
match = re.match(r"^(\S+)",x[0])
if match:
mains.append(match.group(1))
grid.append(l)
tree = {}
weights = {}
for line in grid:
match = re.match(r"(\w+) \((\d+)\)(?: -> (.+))?", line)
if match:
name = match.group(1)
weight = int(match.group(2))
children = match.group(3).split(", ") if match.group(3) else []
tree[name] = children
weights[name] = weight
total_weights = {}
calculate_weights(part1(),tree,weights,total_weights)
result = find_unbalanced(part1(), tree, weights, total_weights)
print(result)
#unbalanced_values = []
#for key,value in tree.items():
# if value:
# t_values = []
# max_v = 0
# change = 0
# for i in value:
# t_values.append(int(total_weights[i]))
# if all(v == t_values[0] for v in t_values):
# continue
# else:
# print('STOP')
# print(t_values)
# input()
# unbalanced_values.append(t_values)
#print(unbalanced_values)
#unbalanced_values = list(reversed(unbalanced_values))
#print(unbalanced_values)
#for t_values in unbalanced_values:
# outlier,reference = find_outlier(t_values)
# change = max(outlier,reference) - min(outlier,reference)
# max_v = max(outlier,reference)
#if t_values[0] == t_values[1]:
# if t_values[0] == t_values[2]:
# if t_values[1] == t_values[2]:
# change = t_values[1] - t_values[2]
# max_v = max(t_values[1],t_values[2])
# else:
# change = t_values[0]-t_values[2]
# max_v = max(t_values[0],t_values[2])
#else:
# change = t_values[0] - t_values[1]
# max_v = max(t_values[0],t_values[1])
# print(change)
# print(max_v)
# new_val = max_v-change
# print(new_val)
# for odx,o in enumerate(t_values):
# if o == max_v:
# total_weights[value[odx]] = new_val
#for kx,x in total_weights.items():
# if x == max_v:
# print(weights[kx])
# print(weights[kx]-change)

57
2017/08/8.md Normal file
View File

@ -0,0 +1,57 @@
## \-\-- Day 8: I Heard You Like Registers \-\--
You receive a signal
directly from the CPU. Because of your recent assistance with [jump
instructions](5), it would like you to compute the result of a series of
unusual register instructions.
Each instruction consists of several parts: the register to modify,
whether to increase or decrease that register\'s value, the amount by
which to increase or decrease it, and a condition. If the condition
fails, skip the instruction without modifying the register. The
registers all start at `0`. The instructions look like this:
b inc 5 if a > 1
a inc 1 if b < 5
c dec -10 if a >= 1
c inc -20 if c == 10
These instructions would be processed as follows:
- Because `a` starts at `0`, it is not greater than `1`, and so `b` is
not modified.
- `a` is increased by `1` (to `1`) because `b` is less than `5` (it is
`0`).
- `c` is decreased by `-10` (to `10`) because `a` is now greater than
or equal to `1` (it is `1`).
- `c` is increased by `-20` (to `-10`) because `c` is equal to `10`.
After this process, the largest value in any register is `1`.
You might also encounter `<=` (less than or equal to) or `!=` (not equal
to). However, the CPU doesn\'t have the bandwidth to tell you what all
the registers are named, and leaves that to you to determine.
*What is the largest value in any register* after completing the
instructions in your puzzle input?
Your puzzle answer was `4066`.
## \-\-- Part Two \-\-- {#part2}
To be safe, the CPU also needs to know *the highest value held in any
register during this process* so that it can decide how much memory to
allocate to these operations. For example, in the above instructions,
the highest value ever held was `10` (in register `c` after the third
instruction was evaluated).
Your puzzle answer was `4829`.
Both parts of this puzzle are complete! They provide two gold stars:
\*\*
At this point, you should [return to your Advent calendar](/2017) and
try another puzzle.
If you still want to see it, you can [get your puzzle
input](8/input).

136
2017/08/solution.py Normal file
View File

@ -0,0 +1,136 @@
#!/bin/python3
import sys,re
from pprint import pprint
input_f = 'input'
part = 2
#########################################
# #
# Part 1 #
# #
#########################################
if part == 1:
grid = []
values = {}
with open(input_f) as file:
for line in file:
grid.append(line.rstrip())
#pprint(grid)
pattern = r"(\w+)\s(inc|dec)\s(-?\d+)\sif\s(\w+)\s([<>=!]+)\s(-?\d+)"
# Process each instruction
for instruction in grid:
match = re.match(pattern, instruction)
if match:
input_var = match.group(1)
change = match.group(2)
value = int(match.group(3))
con1 = match.group(4)
con2 = match.group(5)
con3 = int(match.group(6))
#print(f"input = {input_var}, change = {change}, value = {value}, con1 = {con1}, con2 = {con2}, con3 = {con3}")
else:
print(instruction)
print('NO MATCH')
exit()
#print(f"input = {input_var}, change = {change}, value = {value}, con1 = {con1}, con2 = {con2}, con3 = {con3}")
if input_var not in values:
values[input_var] = 0
if con1 not in values:
values[con1] = 0
condition = f"{values[con1]} {con2} {con3}"
#print('calculation =======',condition)
if eval(condition):
if change == 'inc':
values[input_var] += value
if change == 'dec':
values[input_var] -= value
#pprint(values)
max_v = 0
for key, i in values.items():
if max_v < i:
max_v = i
print(max_v)
#########################################
# #
# Part 2 #
# #
#########################################
def find_max(x):
#print(x)
max_v = 0
for key, i in values.items():
if max_v < i:
max_v = i
return max_v
if part == 2:
grid = []
values = {}
total_max = 0
with open(input_f) as file:
for line in file:
grid.append(line.rstrip())
#pprint(grid)
pattern = r"(\w+)\s(inc|dec)\s(-?\d+)\sif\s(\w+)\s([<>=!]+)\s(-?\d+)"
# Process each instruction
for instruction in grid:
match = re.match(pattern, instruction)
if match:
input_var = match.group(1)
change = match.group(2)
value = int(match.group(3))
con1 = match.group(4)
con2 = match.group(5)
con3 = int(match.group(6))
#print(f"input = {input_var}, change = {change}, value = {value}, con1 = {con1}, con2 = {con2}, con3 = {con3}")
else:
print(instruction)
print('NO MATCH')
exit()
#print(f"input = {input_var}, change = {change}, value = {value}, con1 = {con1}, con2 = {con2}, con3 = {con3}")
if input_var not in values:
values[input_var] = 0
if con1 not in values:
values[con1] = 0
condition = f"{values[con1]} {con2} {con3}"
#print('calculation =======',condition)
if eval(condition):
if change == 'inc':
values[input_var] += value
if change == 'dec':
values[input_var] -= value
temp_max = find_max(values)
if total_max < temp_max:
total_max = temp_max
#print('New Max Found',total_max)
print(total_max)
#pprint(values)

103
2017/09/9.md Normal file
View File

@ -0,0 +1,103 @@
## \-\-- Day 9: Stream Processing \-\--
A large stream blocks your path. According to the locals, it\'s not safe
to [cross the
stream]{title="\"Don't cross the streams!\", they yell, even though there's only one. They seem to think they're hilarious."}
at the moment because it\'s full of *garbage*. You look down at the
stream; rather than water, you discover that it\'s a *stream of
characters*.
You sit for a while and record part of the stream (your puzzle input).
The characters represent *groups* - sequences that begin with `{` and
end with `}`. Within a group, there are zero or more other things,
separated by commas: either another *group* or *garbage*. Since groups
can contain other groups, a `}` only closes the *most-recently-opened
unclosed group* - that is, they are nestable. Your puzzle input
represents a single, large group which itself contains many smaller
ones.
Sometimes, instead of a group, you will find *garbage*. Garbage begins
with `<` and ends with `>`. Between those angle brackets, almost any
character can appear, including `{` and `}`. *Within* garbage, `<` has
no special meaning.
In a futile attempt to clean up the garbage, some program has *canceled*
some of the characters within it using `!`: inside garbage, *any*
character that comes after `!` should be *ignored*, including `<`, `>`,
and even another `!`.
You don\'t see any characters that deviate from these rules. Outside
garbage, you only find well-formed groups, and garbage always terminates
according to the rules above.
Here are some self-contained pieces of garbage:
- `<>`, empty garbage.
- `<random characters>`, garbage containing random characters.
- `<<<<>`, because the extra `<` are ignored.
- `<{!>}>`, because the first `>` is canceled.
- `<!!>`, because the second `!` is canceled, allowing the `>` to
terminate the garbage.
- `<!!!>>`, because the second `!` and the first `>` are canceled.
- `<{o"i!a,<{i<a>`, which ends at the first `>`.
Here are some examples of whole streams and the number of groups they
contain:
- `{}`, `1` group.
- `{{{}}}`, `3` groups.
- `{{},{}}`, also `3` groups.
- `{{{},{},{{}}}}`, `6` groups.
- `{<{},{},{{}}>}`, `1` group (which itself contains garbage).
- `{<a>,<a>,<a>,<a>}`, `1` group.
- `{{<a>},{<a>},{<a>},{<a>}}`, `5` groups.
- `{{<!>},{<!>},{<!>},{<a>}}`, `2` groups (since all but the last `>`
are canceled).
Your goal is to find the total score for all groups in your input. Each
group is assigned a *score* which is one more than the score of the
group that immediately contains it. (The outermost group gets a score of
`1`.)
- `{}`, score of `1`.
- `{{{}}}`, score of `1 + 2 + 3 = 6`.
- `{{},{}}`, score of `1 + 2 + 2 = 5`.
- `{{{},{},{{}}}}`, score of `1 + 2 + 3 + 3 + 3 + 4 = 16`.
- `{<a>,<a>,<a>,<a>}`, score of `1`.
- `{{<ab>},{<ab>},{<ab>},{<ab>}}`, score of `1 + 2 + 2 + 2 + 2 = 9`.
- `{{<!!>},{<!!>},{<!!>},{<!!>}}`, score of `1 + 2 + 2 + 2 + 2 = 9`.
- `{{<a!>},{<a!>},{<a!>},{<ab>}}`, score of `1 + 2 = 3`.
*What is the total score* for all groups in your input?
Your puzzle answer was `11898`.
## \-\-- Part Two \-\-- {#part2}
Now, you\'re ready to remove the garbage.
To prove you\'ve removed it, you need to count all of the characters
within the garbage. The leading and trailing `<` and `>` don\'t count,
nor do any canceled characters or the `!` doing the canceling.
- `<>`, `0` characters.
- `<random characters>`, `17` characters.
- `<<<<>`, `3` characters.
- `<{!>}>`, `2` characters.
- `<!!>`, `0` characters.
- `<!!!>>`, `0` characters.
- `<{o"i!a,<{i<a>`, `10` characters.
*How many non-canceled characters are within the garbage* in your puzzle
input?
Your puzzle answer was `5601`.
Both parts of this puzzle are complete! They provide two gold stars:
\*\*
At this point, you should [return to your Advent calendar](/2017) and
try another puzzle.
If you still want to see it, you can [get your puzzle
input](9/input).

46
2017/09/solution.py Normal file
View File

@ -0,0 +1,46 @@
#!/bin/python3
import sys,re
from pprint import pprint
input_f = 'input'
part = 2
#########################################
# #
# Part 1 #
# #
#########################################
if part == 1:
with open(input_f) as file:
for line in file:
clean_string = re.sub(r"!.", "", line.rstrip())
clean_string = re.sub(r"<.*?>", "", clean_string)
clean_string = re.sub(r",", "", clean_string)
level = 0
numbers = []
for i in clean_string:
if i == '{':
level += 1
if i == '}':
numbers.append(level)
level -= 1
print(sum(numbers))
#########################################
# #
# Part 2 #
# #
#########################################
if part == 2:
with open(input_f) as file:
for line in file:
#print(line.rstrip(), end=' ')
length = 0
clean_string = line.rstrip()
clean_string = re.sub(r"!.",'',clean_string)
clean_string = re.findall(r"<(.*?)>", clean_string)
for i in clean_string:
length += len(i)
print(length)

7
2017/09/test2 Normal file
View File

@ -0,0 +1,7 @@
<>
<random characters>
<<<<>
<{!>}>
<!!>
<!!!>>
<{o"i!a,<{i<a>

169
2017/10/10.md Normal file
View File

@ -0,0 +1,169 @@
## \-\-- Day 10: Knot Hash \-\--
You come across some programs that are trying to implement a software
emulation of a hash based on knot-tying. The hash these programs are
implementing isn\'t very strong, but you decide to help them anyway. You
make a mental note to remind the Elves later not to [invent their own
cryptographic functions]{title="NEW CRYPTOSYSTEM WHO DIS"}.
This hash function simulates tying a knot in a circle of string with 256
marks on it. Based on the input to be hashed, the function repeatedly
selects a span of string, brings the ends together, and gives the span a
half-twist to reverse the order of the marks within it. After doing this
many times, the order of the marks is used to build the resulting hash.
4--5 pinch 4 5 4 1
/ \ 5,0,1 / \/ \ twist / \ / \
3 0 --> 3 0 --> 3 X 0
\ / \ /\ / \ / \ /
2--1 2 1 2 5
To achieve this, begin with a *list* of numbers from `0` to `255`, a
*current position* which begins at `0` (the first element in the list),
a *skip size* (which starts at `0`), and a sequence of *lengths* (your
puzzle input). Then, for each length:
- *Reverse* the order of that *length* of elements in the *list*,
starting with the element at the *current position*.
- *Move* the *current position* forward by that *length* plus the
*skip size*.
- *Increase* the *skip size* by one.
The *list* is circular; if the *current position* and the *length* try
to reverse elements beyond the end of the list, the operation reverses
using as many extra elements as it needs from the front of the list. If
the *current position* moves past the end of the list, it wraps around
to the front. *Lengths* larger than the size of the *list* are invalid.
Here\'s an example using a smaller list:
Suppose we instead only had a circular list containing five elements,
`0, 1, 2, 3, 4`, and were given input lengths of `3, 4, 1, 5`.
- The list begins as `[0] 1 2 3 4` (where square brackets indicate the
*current position*).
- The first length, `3`, selects `([0] 1 2) 3 4` (where parentheses
indicate the sublist to be reversed).
- After reversing that section (`0 1 2` into `2 1 0`), we get
`([2] 1 0) 3 4`.
- Then, the *current position* moves forward by the *length*, `3`,
plus the *skip size*, 0: `2 1 0 [3] 4`. Finally, the *skip size*
increases to `1`.
```{=html}
<!-- -->
```
- The second length, `4`, selects a section which wraps:
`2 1) 0 ([3] 4`.
- The sublist `3 4 2 1` is reversed to form `1 2 4 3`:
`4 3) 0 ([1] 2`.
- The *current position* moves forward by the *length* plus the *skip
size*, a total of `5`, causing it not to move because it wraps
around: `4 3 0 [1] 2`. The *skip size* increases to `2`.
```{=html}
<!-- -->
```
- The third length, `1`, selects a sublist of a single element, and so
reversing it has no effect.
- The *current position* moves forward by the *length* (`1`) plus the
*skip size* (`2`): `4 [3] 0 1 2`. The *skip size* increases to `3`.
```{=html}
<!-- -->
```
- The fourth length, `5`, selects every element starting with the
second: `4) ([3] 0 1 2`. Reversing this sublist (`3 0 1 2 4` into
`4 2 1 0 3`) produces: `3) ([4] 2 1 0`.
- Finally, the *current position* moves forward by `8`: `3 4 2 1 [0]`.
The *skip size* increases to `4`.
In this example, the first two numbers in the list end up being `3` and
`4`; to check the process, you can multiply them together to produce
`12`.
However, you should instead use the standard list size of `256` (with
values `0` to `255`) and the sequence of *lengths* in your puzzle input.
Once this process is complete, *what is the result of multiplying the
first two numbers in the list*?
Your puzzle answer was `19591`.
The first half of this puzzle is complete! It provides one gold star: \*
## \-\-- Part Two \-\-- {#part2}
The logic you\'ve constructed forms a single *round* of the *Knot Hash*
algorithm; running the full thing requires many of these rounds. Some
input and output processing is also required.
First, from now on, your input should be taken not as a list of numbers,
but as a string of bytes instead. Unless otherwise specified, convert
characters to bytes using their [ASCII
codes](https://en.wikipedia.org/wiki/ASCII#Printable_characters). This
will allow you to handle arbitrary ASCII strings, and it also ensures
that your input lengths are never larger than `255`. For example, if you
are given `1,2,3`, you should convert it to the ASCII codes for each
character: `49,44,50,44,51`.
Once you have determined the sequence of lengths to use, add the
following lengths to the end of the sequence: `17, 31, 73, 47, 23`. For
example, if you are given `1,2,3`, your final sequence of lengths should
be `49,44,50,44,51,17,31,73,47,23` (the ASCII codes from the input
string combined with the standard length suffix values).
Second, instead of merely running one *round* like you did above, run a
total of `64` rounds, using the same *length* sequence in each round.
The *current position* and *skip size* should be preserved between
rounds. For example, if the previous example was your first round, you
would start your second round with the same *length* sequence
(`3, 4, 1, 5, 17, 31, 73, 47, 23`, now assuming they came from ASCII
codes and include the suffix), but start with the previous round\'s
*current position* (`4`) and *skip size* (`4`).
Once the rounds are complete, you will be left with the numbers from `0`
to `255` in some order, called the *sparse hash*. Your next task is to
reduce these to a list of only `16` numbers called the *dense hash*. To
do this, use numeric bitwise
[XOR](https://en.wikipedia.org/wiki/Bitwise_operation#XOR) to combine
each consecutive block of `16` numbers in the sparse hash (there are
`16` such blocks in a list of `256` numbers). So, the first element in
the dense hash is the first sixteen elements of the sparse hash XOR\'d
together, the second element in the dense hash is the second sixteen
elements of the sparse hash XOR\'d together, etc.
For example, if the first sixteen elements of your sparse hash are as
shown below, and the XOR operator is `^`, you would calculate the first
output number like this:
65 ^ 27 ^ 9 ^ 1 ^ 4 ^ 3 ^ 40 ^ 50 ^ 91 ^ 7 ^ 6 ^ 0 ^ 2 ^ 5 ^ 68 ^ 22 = 64
Perform this operation on each of the sixteen blocks of sixteen numbers
in your sparse hash to determine the sixteen numbers in your dense hash.
Finally, the standard way to represent a Knot Hash is as a single
[hexadecimal](https://en.wikipedia.org/wiki/Hexadecimal) string; the
final output is the dense hash in hexadecimal notation. Because each
number in your dense hash will be between `0` and `255` (inclusive),
always represent each number as two hexadecimal digits (including a
leading zero as necessary). So, if your first three numbers are
`64, 7, 255`, they correspond to the hexadecimal numbers `40, 07, ff`,
and so the first six characters of the hash would be `4007ff`. Because
every Knot Hash is sixteen such numbers, the hexadecimal representation
is always `32` hexadecimal digits (`0`-`f`) long.
Here are some example hashes:
- The empty string becomes `a2582a3a0e66e6e86e3812dcb672a272`.
- `AoC 2017` becomes `33efeb34ea91902bb2f59c9920caa6cd`.
- `1,2,3` becomes `3efbe78a8d82f29979031a4aa0b16a9d`.
- `1,2,4` becomes `63960835bcdc130f0b66d7ff4f6a5a8e`.
Treating your puzzle input as a string of ASCII characters, *what is the
Knot Hash of your puzzle input?* Ignore any leading or trailing
whitespace you might encounter.
Answer:
Although it hasn\'t changed, you can still [get your puzzle
input](10/input).

49
2017/10/solution.py Normal file
View File

@ -0,0 +1,49 @@
#!/bin/python3
import sys,re
from pprint import pprint
input_f = 'input'
def list2int(x):
return list(map(int, x))
part = 1
#########################################
# #
# Part 1 #
# #
#########################################
if part == 1:
size = 256
lengths = []
skip = 0
numbers = []
pos = 0
for i in range(0,size):
numbers.append(i)
with open(input_f) as file:
for line in file:
lengths = list2int(line.rsplit()[0].split(','))
for ldx, length in enumerate(lengths):
sub = [numbers[(pos + i) % len(numbers)] for i in range(length)]
rev = sub[::-1]
for i in range(length):
numbers[(pos + i) % len(numbers)] = rev[i]
pos += (length+skip)
pos = pos % len(numbers)
skip += 1
print(numbers[0]*numbers[1])
#########################################
# #
# Part 2 #
# #
#########################################
if part == 2:
exit()

View File

@ -1,16 +1,17 @@
#!/bin/python3
import sys
import sys,re
from pprint import pprint
input_f = sys.argv[1]
input_f = 'test'
part = 1
#########################################
# #
# Part 1 #
# #
#########################################
if part == 1
with open(input_f) as file:
for line in file:
@ -22,3 +23,5 @@ with open(input_f) as file:
# Part 2 #
# #
#########################################
if part == 2:
exit()