Added 2017/16
This commit is contained in:
parent
6aaae91ea6
commit
72a2175d09
@ -33,8 +33,6 @@ dance?
|
|||||||
|
|
||||||
Your puzzle answer was `ehdpincaogkblmfj`.
|
Your puzzle answer was `ehdpincaogkblmfj`.
|
||||||
|
|
||||||
The first half of this puzzle is complete! It provides one gold star: \*
|
|
||||||
|
|
||||||
## \-\-- Part Two \-\-- {#part2}
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
Now that you\'re starting to get a feel for the dance moves, you turn
|
Now that you\'re starting to get a feel for the dance moves, you turn
|
||||||
@ -53,7 +51,13 @@ In the example above, their second dance would *begin* with the order
|
|||||||
|
|
||||||
*In what order are the programs standing* after their billion dances?
|
*In what order are the programs standing* after their billion dances?
|
||||||
|
|
||||||
Answer:
|
Your puzzle answer was `bpcekomfgjdlinha`.
|
||||||
|
|
||||||
Although it hasn\'t changed, you can still [get your puzzle
|
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](16/input).
|
input](16/input).
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
import sys,re,collections
|
import sys,re,collections
|
||||||
|
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
sys.path.insert(0, '../../')
|
sys.path.insert(0, '../../')
|
||||||
from fred import list2int
|
from fred import list2int
|
||||||
|
|
||||||
@ -91,6 +92,7 @@ if part == 1:
|
|||||||
#########################################
|
#########################################
|
||||||
if part == 2:
|
if part == 2:
|
||||||
|
|
||||||
|
start_value = list('abcdefghijklmnop')
|
||||||
|
|
||||||
with open(input_f) as file:
|
with open(input_f) as file:
|
||||||
for line in file:
|
for line in file:
|
||||||
@ -100,9 +102,14 @@ if part == 2:
|
|||||||
|
|
||||||
#print(programs)
|
#print(programs)
|
||||||
#print(instructions)
|
#print(instructions)
|
||||||
print(len(instructions))
|
#print(len(instructions))
|
||||||
|
|
||||||
for r in range(0,1000000000):
|
duplicates = []
|
||||||
|
done = False
|
||||||
|
indx = 0
|
||||||
|
while not done:
|
||||||
|
#print(r,list(programs))
|
||||||
|
#input()
|
||||||
for idx,i in enumerate(instructions):
|
for idx,i in enumerate(instructions):
|
||||||
inst = parse_input(i)
|
inst = parse_input(i)
|
||||||
#print(idx,end=' ')
|
#print(idx,end=' ')
|
||||||
@ -122,11 +129,15 @@ if part == 2:
|
|||||||
else:
|
else:
|
||||||
print(inst)
|
print(inst)
|
||||||
input()
|
input()
|
||||||
if r % 10000 == 0:
|
|
||||||
print(r)
|
|
||||||
|
|
||||||
|
|
||||||
|
if start_value == list(programs):
|
||||||
|
#print(start_value)
|
||||||
|
#print(list(programs))
|
||||||
|
done = True
|
||||||
|
duplicates.append(list(programs))
|
||||||
|
|
||||||
for i in programs:
|
indx += 1
|
||||||
print(i,end='')
|
|
||||||
print()
|
|
||||||
|
print(''.join(duplicates[(1000000000%indx)-1]))
|
||||||
|
92
2017/17/17.md
Normal file
92
2017/17/17.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
## \-\-- Day 17: Spinlock \-\--
|
||||||
|
|
||||||
|
Suddenly, whirling in the distance, you notice what looks like a
|
||||||
|
massive, [pixelated
|
||||||
|
hurricane]{title="You know, as opposed to all those non-pixelated hurricanes you see on TV."}:
|
||||||
|
a deadly [spinlock](https://en.wikipedia.org/wiki/Spinlock). This
|
||||||
|
spinlock isn\'t just consuming computing power, but memory, too; vast,
|
||||||
|
digital mountains are being ripped from the ground and consumed by the
|
||||||
|
vortex.
|
||||||
|
|
||||||
|
If you don\'t move quickly, fixing that printer will be the least of
|
||||||
|
your problems.
|
||||||
|
|
||||||
|
This spinlock\'s algorithm is simple but efficient, quickly consuming
|
||||||
|
everything in its path. It starts with a circular buffer containing only
|
||||||
|
the value `0`, which it marks as the *current position*. It then steps
|
||||||
|
forward through the circular buffer some number of steps (your puzzle
|
||||||
|
input) before inserting the first new value, `1`, after the value it
|
||||||
|
stopped on. The inserted value becomes the *current position*. Then, it
|
||||||
|
steps forward from there the same number of steps, and wherever it
|
||||||
|
stops, inserts after it the second new value, `2`, and uses that as the
|
||||||
|
new *current position* again.
|
||||||
|
|
||||||
|
It repeats this process of *stepping forward*, *inserting a new value*,
|
||||||
|
and *using the location of the inserted value as the new current
|
||||||
|
position* a total of `2017` times, inserting `2017` as its final
|
||||||
|
operation, and ending with a total of `2018` values (including `0`) in
|
||||||
|
the circular buffer.
|
||||||
|
|
||||||
|
For example, if the spinlock were to step `3` times per insert, the
|
||||||
|
circular buffer would begin to evolve like this (using parentheses to
|
||||||
|
mark the current position after each iteration of the algorithm):
|
||||||
|
|
||||||
|
- `(0)`, the initial state before any insertions.
|
||||||
|
- `0 (1)`: the spinlock steps forward three times (`0`, `0`, `0`), and
|
||||||
|
then inserts the first value, `1`, after it. `1` becomes the current
|
||||||
|
position.
|
||||||
|
- `0 (2) 1`: the spinlock steps forward three times (`0`, `1`, `0`),
|
||||||
|
and then inserts the second value, `2`, after it. `2` becomes the
|
||||||
|
current position.
|
||||||
|
- `0 2 (3) 1`: the spinlock steps forward three times (`1`, `0`,
|
||||||
|
`2`), and then inserts the third value, `3`, after it. `3` becomes
|
||||||
|
the current position.
|
||||||
|
|
||||||
|
And so on:
|
||||||
|
|
||||||
|
- `0 2 (4) 3 1`
|
||||||
|
- `0 (5) 2 4 3 1`
|
||||||
|
- `0 5 2 4 3 (6) 1`
|
||||||
|
- `0 5 (7) 2 4 3 6 1`
|
||||||
|
- `0 5 7 2 4 3 (8) 6 1`
|
||||||
|
- `0 (9) 5 7 2 4 3 8 6 1`
|
||||||
|
|
||||||
|
Eventually, after 2017 insertions, the section of the circular buffer
|
||||||
|
near the last insertion looks like this:
|
||||||
|
|
||||||
|
1512 1134 151 (2017) 638 1513 851
|
||||||
|
|
||||||
|
Perhaps, if you can identify the value that will ultimately be *after*
|
||||||
|
the last value written (`2017`), you can short-circuit the spinlock. In
|
||||||
|
this example, that would be `638`.
|
||||||
|
|
||||||
|
*What is the value after `2017`* in your completed circular buffer?
|
||||||
|
|
||||||
|
Your puzzle answer was `725`.
|
||||||
|
|
||||||
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
The spinlock does not short-circuit. Instead, it gets *more* angry. At
|
||||||
|
least, you assume that\'s what happened; it\'s spinning significantly
|
||||||
|
faster than it was a moment ago.
|
||||||
|
|
||||||
|
You have good news and bad news.
|
||||||
|
|
||||||
|
The good news is that you have improved calculations for how to stop the
|
||||||
|
spinlock. They indicate that you actually need to identify *the value
|
||||||
|
after `0`* in the current state of the circular buffer.
|
||||||
|
|
||||||
|
The bad news is that while you were determining this, the spinlock has
|
||||||
|
just finished inserting its fifty millionth value (`50000000`).
|
||||||
|
|
||||||
|
*What is the value after `0`* the moment `50000000` is inserted?
|
||||||
|
|
||||||
|
Your puzzle answer was `27361412`.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Your puzzle input was `329`{.puzzle-input}.
|
77
2017/17/solution.py
Normal file
77
2017/17/solution.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int
|
||||||
|
|
||||||
|
input_f = 'input'
|
||||||
|
|
||||||
|
part = 2
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
jump = 0
|
||||||
|
arr = [0]
|
||||||
|
pos = 0
|
||||||
|
with open(input_f) as file:
|
||||||
|
jump = int(file.read().rstrip())
|
||||||
|
|
||||||
|
for i in range(1,2017+1):
|
||||||
|
#print(arr)
|
||||||
|
#print(len(arr),i)
|
||||||
|
pos = (pos+jump)%len(arr)
|
||||||
|
loc = (pos)+1
|
||||||
|
#print(loc)
|
||||||
|
pos += 1
|
||||||
|
arr.insert(loc,i)
|
||||||
|
#input()
|
||||||
|
|
||||||
|
f_pos = arr.index(2017)
|
||||||
|
|
||||||
|
|
||||||
|
print(arr[f_pos-1],arr[f_pos],arr[f_pos+1])
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
jump = 0
|
||||||
|
arr = [0]
|
||||||
|
pos = 0
|
||||||
|
loc = 0
|
||||||
|
with open(input_f) as file:
|
||||||
|
jump = int(file.read().rstrip())
|
||||||
|
|
||||||
|
prev = 0
|
||||||
|
|
||||||
|
for i in range(1,50000000+1):
|
||||||
|
#print(arr)
|
||||||
|
#print(len(arr),i)
|
||||||
|
pos = (pos+jump)%i
|
||||||
|
loc = (pos)+1
|
||||||
|
#print(loc)
|
||||||
|
pos += 1
|
||||||
|
|
||||||
|
#arr.insert(loc,i)
|
||||||
|
#input()
|
||||||
|
if i%1000000 == 0:
|
||||||
|
print(i)
|
||||||
|
|
||||||
|
if pos == 1:
|
||||||
|
#print('INSERT')
|
||||||
|
prev = i
|
||||||
|
#print(i-1)
|
||||||
|
#print(pos,loc)
|
||||||
|
print(prev)
|
||||||
|
|
||||||
|
#f_pos = arr.index(0)
|
||||||
|
|
||||||
|
|
||||||
|
#print(arr[f_pos-1],arr[f_pos],arr[f_pos+1])
|
79
2017/18/18.md
Normal file
79
2017/18/18.md
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
## \-\-- Day 18: Duet \-\--
|
||||||
|
|
||||||
|
You discover a tablet containing some strange assembly code labeled
|
||||||
|
simply \"[Duet](https://en.wikipedia.org/wiki/Duet)\". Rather than
|
||||||
|
bother the sound card with it, you decide to run the code yourself.
|
||||||
|
Unfortunately, you don\'t see any documentation, so you\'re left to
|
||||||
|
figure out what the instructions mean on your own.
|
||||||
|
|
||||||
|
It seems like the assembly is meant to operate on a set of *registers*
|
||||||
|
that are each named with a single letter and that can each hold a single
|
||||||
|
[integer](https://en.wikipedia.org/wiki/Integer). You suppose each
|
||||||
|
register should start with a value of `0`.
|
||||||
|
|
||||||
|
There aren\'t that many instructions, so it shouldn\'t be hard to figure
|
||||||
|
out what they do. Here\'s what you determine:
|
||||||
|
|
||||||
|
- `snd X` *[plays a
|
||||||
|
sound]{title="I don't recommend actually trying this."}* with a
|
||||||
|
frequency equal to the value of `X`.
|
||||||
|
- `set X Y` *sets* register `X` to the value of `Y`.
|
||||||
|
- `add X Y` *increases* register `X` by the value of `Y`.
|
||||||
|
- `mul X Y` sets register `X` to the result of *multiplying* the value
|
||||||
|
contained in register `X` by the value of `Y`.
|
||||||
|
- `mod X Y` sets register `X` to the *remainder* of dividing the value
|
||||||
|
contained in register `X` by the value of `Y` (that is, it sets `X`
|
||||||
|
to the result of `X`
|
||||||
|
[modulo](https://en.wikipedia.org/wiki/Modulo_operation) `Y`).
|
||||||
|
- `rcv X` *recovers* the frequency of the last sound played, but only
|
||||||
|
when the value of `X` is not zero. (If it is zero, the command does
|
||||||
|
nothing.)
|
||||||
|
- `jgz X Y` *jumps* with an offset of the value of `Y`, but only if
|
||||||
|
the value of `X` is *greater than zero*. (An offset of `2` skips the
|
||||||
|
next instruction, an offset of `-1` jumps to the previous
|
||||||
|
instruction, and so on.)
|
||||||
|
|
||||||
|
Many of the instructions can take either a register (a single letter) or
|
||||||
|
a number. The value of a register is the integer it contains; the value
|
||||||
|
of a number is that number.
|
||||||
|
|
||||||
|
After each *jump* instruction, the program continues with the
|
||||||
|
instruction to which the *jump* jumped. After any other instruction, the
|
||||||
|
program continues with the next instruction. Continuing (or jumping) off
|
||||||
|
either end of the program terminates it.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
set a 1
|
||||||
|
add a 2
|
||||||
|
mul a a
|
||||||
|
mod a 5
|
||||||
|
snd a
|
||||||
|
set a 0
|
||||||
|
rcv a
|
||||||
|
jgz a -1
|
||||||
|
set a 1
|
||||||
|
jgz a -2
|
||||||
|
|
||||||
|
- The first four instructions set `a` to `1`, add `2` to it, square
|
||||||
|
it, and then set it to itself modulo `5`, resulting in a value of
|
||||||
|
`4`.
|
||||||
|
- Then, a sound with frequency `4` (the value of `a`) is played.
|
||||||
|
- After that, `a` is set to `0`, causing the subsequent `rcv` and
|
||||||
|
`jgz` instructions to both be skipped (`rcv` because `a` is `0`, and
|
||||||
|
`jgz` because `a` is not greater than `0`).
|
||||||
|
- Finally, `a` is set to `1`, causing the next `jgz` instruction to
|
||||||
|
activate, jumping back two instructions to another jump, which jumps
|
||||||
|
again to the `rcv`, which ultimately triggers the *recover*
|
||||||
|
operation.
|
||||||
|
|
||||||
|
At the time the *recover* operation is executed, the frequency of the
|
||||||
|
last sound played is `4`.
|
||||||
|
|
||||||
|
*What is the value of the recovered frequency* (the value of the most
|
||||||
|
recently played sound) the *first* time a `rcv` instruction is executed
|
||||||
|
with a non-zero value?
|
||||||
|
|
||||||
|
To begin, [get your puzzle input](18/input).
|
||||||
|
|
||||||
|
Answer:
|
42
2017/18/solution.py
Normal file
42
2017/18/solution.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int
|
||||||
|
|
||||||
|
input_f = 'test'
|
||||||
|
|
||||||
|
part = 1
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
def parse_input(input_str):
|
||||||
|
pattern = r"^(s(\d+)|x(\d+)/(\d+)|p([a-zA-Z])/([a-zA-Z]))$"
|
||||||
|
|
||||||
|
match = re.match(pattern, input_str)
|
||||||
|
if match:
|
||||||
|
if match.group(2):
|
||||||
|
return ('s', int(match.group(2)))
|
||||||
|
elif match.group(3) and match.group(4):
|
||||||
|
return ('x', int(match.group(3)), int(match.group(4)))
|
||||||
|
elif match.group(5) and match.group(6):
|
||||||
|
return ('p', match.group(5), match.group(6))
|
||||||
|
return None
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
with open(input_f) as file:
|
||||||
|
for line in file:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
exit()
|
Loading…
Reference in New Issue
Block a user