diff --git a/2017/15/15.md b/2017/15/15.md new file mode 100644 index 0000000..9a1455d --- /dev/null +++ b/2017/15/15.md @@ -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). diff --git a/2017/15/debug-full-aoc-response.html b/2017/15/debug-full-aoc-response.html new file mode 100644 index 0000000..405594c --- /dev/null +++ b/2017/15/debug-full-aoc-response.html @@ -0,0 +1,112 @@ + + + + +Day 15 - Advent of Code 2017 + + + + + + +

Advent of Code

Frederik Baerentsen 30*

        //2017

+ + + +
+

You don't seem to be solving the right level. Did you already complete it? [Return to Day 15]

+
+ + + + + + \ No newline at end of file diff --git a/2017/15/solution.py b/2017/15/solution.py new file mode 100644 index 0000000..75f02dd --- /dev/null +++ b/2017/15/solution.py @@ -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) diff --git a/2017/16/16.md b/2017/16/16.md new file mode 100644 index 0000000..8306abd --- /dev/null +++ b/2017/16/16.md @@ -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). diff --git a/2017/16/solution.py b/2017/16/solution.py new file mode 100644 index 0000000..53a7800 --- /dev/null +++ b/2017/16/solution.py @@ -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() \ No newline at end of file