This commit is contained in:
FrederikBaerentsen 2024-11-25 20:17:15 +01:00
parent 1616379e39
commit 6aaae91ea6
5 changed files with 513 additions and 0 deletions

138
2017/15/15.md Normal file
View 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).

View 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">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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
View 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
View 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
View 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()