Updated
This commit is contained in:
parent
1616379e39
commit
6aaae91ea6
138
2017/15/15.md
Normal file
138
2017/15/15.md
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
## \-\-- Day 15: Dueling Generators \-\--
|
||||||
|
|
||||||
|
Here, you encounter a pair of dueling
|
||||||
|
generators.
|
||||||
|
The generators, called *generator A* and *generator B*, are trying to
|
||||||
|
agree on a sequence of numbers. However, one of them is malfunctioning,
|
||||||
|
and so the sequences don\'t always match.
|
||||||
|
|
||||||
|
As they do this, a *judge* waits for each of them to generate its next
|
||||||
|
value, compares the lowest 16 bits of both values, and keeps track of
|
||||||
|
the number of times those parts of the values match.
|
||||||
|
|
||||||
|
The generators both work on the same principle. To create its next
|
||||||
|
value, a generator will take the previous value it produced, multiply it
|
||||||
|
by a *factor* (generator A uses `16807`; generator B uses `48271`), and
|
||||||
|
then keep the remainder of dividing that resulting product by
|
||||||
|
`2147483647`. That final remainder is the value it produces next.
|
||||||
|
|
||||||
|
To calculate each generator\'s first value, it instead uses a specific
|
||||||
|
starting value as its \"previous value\" (as listed in your puzzle
|
||||||
|
input).
|
||||||
|
|
||||||
|
For example, suppose that for starting values, generator A uses `65`,
|
||||||
|
while generator B uses `8921`. Then, the first five pairs of generated
|
||||||
|
values are:
|
||||||
|
|
||||||
|
--Gen. A-- --Gen. B--
|
||||||
|
1092455 430625591
|
||||||
|
1181022009 1233683848
|
||||||
|
245556042 1431495498
|
||||||
|
1744312007 137874439
|
||||||
|
1352636452 285222916
|
||||||
|
|
||||||
|
In binary, these pairs are (with generator A\'s value first in each
|
||||||
|
pair):
|
||||||
|
|
||||||
|
00000000000100001010101101100111
|
||||||
|
00011001101010101101001100110111
|
||||||
|
|
||||||
|
01000110011001001111011100111001
|
||||||
|
01001001100010001000010110001000
|
||||||
|
|
||||||
|
00001110101000101110001101001010
|
||||||
|
01010101010100101110001101001010
|
||||||
|
|
||||||
|
01100111111110000001011011000111
|
||||||
|
00001000001101111100110000000111
|
||||||
|
|
||||||
|
01010000100111111001100000100100
|
||||||
|
00010001000000000010100000000100
|
||||||
|
|
||||||
|
Here, you can see that the lowest (here, rightmost) 16 bits of the third
|
||||||
|
value match: `1110001101001010`. Because of this one match, after
|
||||||
|
processing these five pairs, the judge would have added only `1` to its
|
||||||
|
total.
|
||||||
|
|
||||||
|
To get a significant sample, the judge would like to consider *40
|
||||||
|
million* pairs. (In the example above, the judge would eventually find a
|
||||||
|
total of `588` pairs that match in their lowest 16 bits.)
|
||||||
|
|
||||||
|
After 40 million pairs, *what is the judge\'s final count*?
|
||||||
|
|
||||||
|
Your puzzle answer was `573`.
|
||||||
|
|
||||||
|
The first half of this puzzle is complete! It provides one gold star: \*
|
||||||
|
|
||||||
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
In the interest of trying to align a little better, the generators get
|
||||||
|
more picky about the numbers they actually give to the judge.
|
||||||
|
|
||||||
|
They still generate values in the same way, but now they only hand a
|
||||||
|
value to the judge when it meets their *criteria*:
|
||||||
|
|
||||||
|
- Generator A looks for values that are multiples of `4`.
|
||||||
|
- Generator B looks for values that are multiples of `8`.
|
||||||
|
|
||||||
|
Each generator functions completely *independently*: they both go
|
||||||
|
through values entirely on their own, only occasionally handing an
|
||||||
|
acceptable value to the judge, and otherwise working through the same
|
||||||
|
sequence of values as before until they find one.
|
||||||
|
|
||||||
|
The judge still waits for each generator to provide it with a value
|
||||||
|
before comparing them (using the same comparison method as before). It
|
||||||
|
keeps track of the order it receives values; the first values from each
|
||||||
|
generator are compared, then the second values from each generator, then
|
||||||
|
the third values, and so on.
|
||||||
|
|
||||||
|
Using the example starting values given above, the generators now
|
||||||
|
produce the following first five values each:
|
||||||
|
|
||||||
|
--Gen. A-- --Gen. B--
|
||||||
|
1352636452 1233683848
|
||||||
|
1992081072 862516352
|
||||||
|
530830436 1159784568
|
||||||
|
1980017072 1616057672
|
||||||
|
740335192 412269392
|
||||||
|
|
||||||
|
These values have the following corresponding binary values:
|
||||||
|
|
||||||
|
01010000100111111001100000100100
|
||||||
|
01001001100010001000010110001000
|
||||||
|
|
||||||
|
01110110101111001011111010110000
|
||||||
|
00110011011010001111010010000000
|
||||||
|
|
||||||
|
00011111101000111101010001100100
|
||||||
|
01000101001000001110100001111000
|
||||||
|
|
||||||
|
01110110000001001010100110110000
|
||||||
|
01100000010100110001010101001000
|
||||||
|
|
||||||
|
00101100001000001001111001011000
|
||||||
|
00011000100100101011101101010000
|
||||||
|
|
||||||
|
Unfortunately, even though this change makes more bits similar on
|
||||||
|
average, none of these values\' lowest 16 bits match. Now, it\'s not
|
||||||
|
until the 1056th pair that the judge finds the first match:
|
||||||
|
|
||||||
|
--Gen. A-- --Gen. B--
|
||||||
|
1023762912 896885216
|
||||||
|
|
||||||
|
00111101000001010110000111100000
|
||||||
|
00110101011101010110000111100000
|
||||||
|
|
||||||
|
This change makes the generators much slower, and the judge is getting
|
||||||
|
impatient; it is now only willing to consider *5 million* pairs. (Using
|
||||||
|
the values from the example above, after five million pairs, the judge
|
||||||
|
would eventually find a total of `309` pairs that match in their lowest
|
||||||
|
16 bits.)
|
||||||
|
|
||||||
|
After 5 million pairs, but using this new generator logic, *what is the
|
||||||
|
judge\'s final count*?
|
||||||
|
|
||||||
|
Answer:
|
||||||
|
|
||||||
|
Although it hasn\'t changed, you can still [get your puzzle
|
||||||
|
input](15/input).
|
112
2017/15/debug-full-aoc-response.html
Normal file
112
2017/15/debug-full-aoc-response.html
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<title>Day 15 - Advent of Code 2017</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/static/style.css?31"/>
|
||||||
|
<link rel="stylesheet alternate" type="text/css" href="/static/highcontrast.css?1" title="High Contrast"/>
|
||||||
|
<link rel="shortcut icon" href="/favicon.png"/>
|
||||||
|
<script>window.addEventListener('click', function(e,s,r){if(e.target.nodeName==='CODE'&&e.detail===3){s=window.getSelection();s.removeAllRanges();r=document.createRange();r.selectNodeContents(e.target);s.addRange(r);}});</script>
|
||||||
|
</head><!--
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Oh, hello! Funny seeing you here.
|
||||||
|
|
||||||
|
I appreciate your enthusiasm, but you aren't going to find much down here.
|
||||||
|
There certainly aren't clues to any of the puzzles. The best surprises don't
|
||||||
|
even appear in the source until you unlock them for real.
|
||||||
|
|
||||||
|
Please be careful with automated requests; I'm not a massive company, and I can
|
||||||
|
only take so much traffic. Please be considerate so that everyone gets to play.
|
||||||
|
|
||||||
|
If you're curious about how Advent of Code works, it's running on some custom
|
||||||
|
Perl code. Other than a few integrations (auth, analytics, social media), I
|
||||||
|
built the whole thing myself, including the design, animations, prose, and all
|
||||||
|
of the puzzles.
|
||||||
|
|
||||||
|
The puzzles are most of the work; preparing a new calendar and a new set of
|
||||||
|
puzzles each year takes all of my free time for 4-5 months. A lot of effort
|
||||||
|
went into building this thing - I hope you're enjoying playing it as much as I
|
||||||
|
enjoyed making it for you!
|
||||||
|
|
||||||
|
If you'd like to hang out, I'm @ericwastl@hachyderm.io on Mastodon and
|
||||||
|
@ericwastl on Twitter.
|
||||||
|
|
||||||
|
- Eric Wastl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-->
|
||||||
|
<body>
|
||||||
|
<header><div><h1 class="title-global"><a href="/">Advent of Code</a></h1><nav><ul><li><a href="/2017/about">[About]</a></li><li><a href="/2017/events">[Events]</a></li><li><a href="https://teespring.com/stores/advent-of-code" target="_blank">[Shop]</a></li><li><a href="/2017/settings">[Settings]</a></li><li><a href="/2017/auth/logout">[Log Out]</a></li></ul></nav><div class="user">Frederik Baerentsen <span class="star-count">30*</span></div></div><div><h1 class="title-event"> <span class="title-event-wrap">//</span><a href="/2017">2017</a><span class="title-event-wrap"></span></h1><nav><ul><li><a href="/2017">[Calendar]</a></li><li><a href="/2017/support">[AoC++]</a></li><li><a href="/2017/sponsors">[Sponsors]</a></li><li><a href="/2017/leaderboard">[Leaderboard]</a></li><li><a href="/2017/stats">[Stats]</a></li></ul></nav></div></header>
|
||||||
|
|
||||||
|
<div id="sidebar">
|
||||||
|
<div id="sponsor"><div class="quiet">Our <a href="/2017/sponsors">sponsors</a> help make Advent of Code possible:</div><div class="sponsor"><a href="https://cheppers.com/" target="_blank" onclick="if(ga)ga('send','event','sponsor','sidebar',this.href);" rel="noopener">Cheppers</a> - xor(Pz0pQUI7Ch cmER8YDAEYAh4L GwEP, ↑↑↓↓←→←→BA)</div></div>
|
||||||
|
</div><!--/sidebar-->
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<article><p>You don't seem to be solving the right level. Did you already complete it? <a href="/2017/day/15">[Return to Day 15]</a></p></article>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- ga -->
|
||||||
|
<script>
|
||||||
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||||
|
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||||
|
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||||
|
ga('create', 'UA-69522494-1', 'auto');
|
||||||
|
ga('set', 'anonymizeIp', true);
|
||||||
|
ga('send', 'pageview');
|
||||||
|
</script>
|
||||||
|
<!-- /ga -->
|
||||||
|
</body>
|
||||||
|
</html>
|
72
2017/15/solution.py
Normal file
72
2017/15/solution.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int
|
||||||
|
|
||||||
|
input_f = 'test'
|
||||||
|
|
||||||
|
part = 2
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
a = 634
|
||||||
|
b = 301
|
||||||
|
a_fak = 16807
|
||||||
|
b_fak = 48271
|
||||||
|
rem = 2147483647
|
||||||
|
count = 0
|
||||||
|
for i in range(0,40000000):
|
||||||
|
a = (a*a_fak)%rem
|
||||||
|
b = (b*b_fak)%rem
|
||||||
|
|
||||||
|
a_bin = bin(a)[2:].zfill(32)
|
||||||
|
b_bin = bin(b)[2:].zfill(32)
|
||||||
|
if a_bin[16:] == b_bin[16:]:
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
print(count)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
a = 634
|
||||||
|
b = 301
|
||||||
|
a_fak = 16807
|
||||||
|
b_fak = 48271
|
||||||
|
rem = 2147483647
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
a_matches = []
|
||||||
|
b_matches = []
|
||||||
|
|
||||||
|
while min(len(a_matches),len(b_matches)) < 5000000:
|
||||||
|
a = (a*a_fak)%rem
|
||||||
|
b = (b*b_fak)%rem
|
||||||
|
|
||||||
|
a_bin = bin(a)[2:].zfill(32)
|
||||||
|
b_bin = bin(b)[2:].zfill(32)
|
||||||
|
if a % 4 == 0:
|
||||||
|
a_matches.append(a_bin[16:])
|
||||||
|
if b % 8 == 0:
|
||||||
|
b_matches.append(b_bin[16:])
|
||||||
|
|
||||||
|
print(len(a_matches))
|
||||||
|
print(len(b_matches))
|
||||||
|
for x in range(0,min(len(a_matches),len(b_matches))):
|
||||||
|
if a_matches[x] == b_matches[x]:
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
print(count)
|
59
2017/16/16.md
Normal file
59
2017/16/16.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
## \-\-- Day 16: Permutation Promenade \-\--
|
||||||
|
|
||||||
|
You come upon a very unusual sight; a group of programs here appear to
|
||||||
|
be [dancing](https://www.youtube.com/watch?v=lyZQPjUT5B4&t=53).
|
||||||
|
|
||||||
|
There are sixteen programs in total, named `a` through `p`. They start
|
||||||
|
by standing in a line: `a` stands
|
||||||
|
in position `0`, `b` stands in position `1`, and so on until `p`, which
|
||||||
|
stands in position `15`.
|
||||||
|
|
||||||
|
The programs\' *dance* consists of a sequence of *dance moves*:
|
||||||
|
|
||||||
|
- *Spin*, written `sX`, makes `X` programs move from the end to the
|
||||||
|
front, but maintain their order otherwise. (For example, `s3` on
|
||||||
|
`abcde` produces `cdeab`).
|
||||||
|
- *Exchange*, written `xA/B`, makes the programs at positions `A` and
|
||||||
|
`B` swap places.
|
||||||
|
- *Partner*, written `pA/B`, makes the programs named `A` and `B` swap
|
||||||
|
places.
|
||||||
|
|
||||||
|
For example, with only five programs standing in a line (`abcde`), they
|
||||||
|
could do the following dance:
|
||||||
|
|
||||||
|
- `s1`, a spin of size `1`: `eabcd`.
|
||||||
|
- `x3/4`, swapping the last two programs: `eabdc`.
|
||||||
|
- `pe/b`, swapping programs `e` and `b`: `baedc`.
|
||||||
|
|
||||||
|
After finishing their dance, the programs end up in order `baedc`.
|
||||||
|
|
||||||
|
You watch the dance for a while and record their dance moves (your
|
||||||
|
puzzle input). *In what order are the programs standing* after their
|
||||||
|
dance?
|
||||||
|
|
||||||
|
Your puzzle answer was `ehdpincaogkblmfj`.
|
||||||
|
|
||||||
|
The first half of this puzzle is complete! It provides one gold star: \*
|
||||||
|
|
||||||
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
Now that you\'re starting to get a feel for the dance moves, you turn
|
||||||
|
your attention to *the dance as a whole*.
|
||||||
|
|
||||||
|
Keeping the positions they ended up in from their previous dance, the
|
||||||
|
programs perform it again and again: including the first dance, a total
|
||||||
|
of *one billion* (`1000000000`) times.
|
||||||
|
|
||||||
|
In the example above, their second dance would *begin* with the order
|
||||||
|
`baedc`, and use the same dance moves:
|
||||||
|
|
||||||
|
- `s1`, a spin of size `1`: `cbaed`.
|
||||||
|
- `x3/4`, swapping the last two programs: `cbade`.
|
||||||
|
- `pe/b`, swapping programs `e` and `b`: `ceadb`.
|
||||||
|
|
||||||
|
*In what order are the programs standing* after their billion dances?
|
||||||
|
|
||||||
|
Answer:
|
||||||
|
|
||||||
|
Although it hasn\'t changed, you can still [get your puzzle
|
||||||
|
input](16/input).
|
132
2017/16/solution.py
Normal file
132
2017/16/solution.py
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re,collections
|
||||||
|
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int
|
||||||
|
|
||||||
|
input_f = 'input'
|
||||||
|
|
||||||
|
part = 2
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
inst = []
|
||||||
|
|
||||||
|
programs = 'abcdefghijklmnop'
|
||||||
|
#programs = 'abcde'
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def swap_pos(d, index1, index2):
|
||||||
|
if not (0 <= index1 < len(d)) or not (0 <= index2 < len(d)):
|
||||||
|
raise IndexError("Index out of range")
|
||||||
|
d[index1], d[index2] = d[index2], d[index1]
|
||||||
|
|
||||||
|
def swap_items(d, item1, item2):
|
||||||
|
try:
|
||||||
|
index1 = d.index(item1)
|
||||||
|
index2 = d.index(item2)
|
||||||
|
|
||||||
|
d[index1], d[index2] = d[index2], d[index1]
|
||||||
|
except ValueError as e:
|
||||||
|
raise ValueError(f"One or both items not found in deque: {e}")
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
with open(input_f) as file:
|
||||||
|
for line in file:
|
||||||
|
instructions = line.rstrip().split(',')
|
||||||
|
|
||||||
|
programs = collections.deque(list(programs))
|
||||||
|
|
||||||
|
#print(programs)
|
||||||
|
#print(instructions)
|
||||||
|
print(len(instructions))
|
||||||
|
|
||||||
|
for idx,i in enumerate(instructions):
|
||||||
|
inst = parse_input(i)
|
||||||
|
print(idx,end=' ')
|
||||||
|
#print(i)
|
||||||
|
#rint(inst)
|
||||||
|
if inst[0] == 's':
|
||||||
|
#print('Spin', i)
|
||||||
|
programs.rotate(inst[1])
|
||||||
|
|
||||||
|
elif inst[0] == 'x':
|
||||||
|
#print('Exchange',i)
|
||||||
|
swap_pos(programs,inst[1],inst[2])
|
||||||
|
|
||||||
|
elif inst[0] == 'p':
|
||||||
|
#print('Partner',i)
|
||||||
|
swap_items(programs,inst[1],inst[2])
|
||||||
|
else:
|
||||||
|
print(inst)
|
||||||
|
input()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for i in programs:
|
||||||
|
print(i,end='')
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
|
||||||
|
|
||||||
|
with open(input_f) as file:
|
||||||
|
for line in file:
|
||||||
|
instructions = line.rstrip().split(',')
|
||||||
|
|
||||||
|
programs = collections.deque(list(programs))
|
||||||
|
|
||||||
|
#print(programs)
|
||||||
|
#print(instructions)
|
||||||
|
print(len(instructions))
|
||||||
|
|
||||||
|
for r in range(0,1000000000):
|
||||||
|
for idx,i in enumerate(instructions):
|
||||||
|
inst = parse_input(i)
|
||||||
|
#print(idx,end=' ')
|
||||||
|
#print(i)
|
||||||
|
#rint(inst)
|
||||||
|
if inst[0] == 's':
|
||||||
|
#print('Spin', i)
|
||||||
|
programs.rotate(inst[1])
|
||||||
|
|
||||||
|
elif inst[0] == 'x':
|
||||||
|
#print('Exchange',i)
|
||||||
|
swap_pos(programs,inst[1],inst[2])
|
||||||
|
|
||||||
|
elif inst[0] == 'p':
|
||||||
|
#print('Partner',i)
|
||||||
|
swap_items(programs,inst[1],inst[2])
|
||||||
|
else:
|
||||||
|
print(inst)
|
||||||
|
input()
|
||||||
|
if r % 10000 == 0:
|
||||||
|
print(r)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for i in programs:
|
||||||
|
print(i,end='')
|
||||||
|
print()
|
Loading…
Reference in New Issue
Block a user