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