diff --git a/2017/20/20.md b/2017/20/20.md index 3b8dac1..c9afe0a 100644 --- a/2017/20/20.md +++ b/2017/20/20.md @@ -55,8 +55,6 @@ term? Your puzzle answer was `258`. -The first half of this puzzle is complete! It provides one gold star: \* - ## \-\-- Part Two \-\-- {#part2} To simplify the problem further, the GPU would like to remove any @@ -94,8 +92,14 @@ destroyed at the time and place marked `X`. On the next tick, particle *How many particles are left* after all collisions are resolved? -Answer: +Your puzzle answer was `707`. -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](20/input). diff --git a/2017/20/solution.py b/2017/20/solution.py index 1a791f3..a5dee49 100644 --- a/2017/20/solution.py +++ b/2017/20/solution.py @@ -1,5 +1,6 @@ #!/bin/python3 -import sys,re,math +import sys,re,math, numpy as np +from collections import Counter, defaultdict from pprint import pprint sys.path.insert(0, '../../') from fred import get_re,list2int @@ -35,33 +36,62 @@ if part == 1: # Part 2 # # # ######################################### + +def calculate_position_xyz(initial_position, velocity, acceleration): + + velocity += acceleration + + new_position = initial_position + velocity # + (0.5 * acceleration * time**2) + return np.array(new_position) + +def find_duplicate_indices(data): + value_to_indices = defaultdict(list) + for index, value in data.items(): + value_tuple = tuple(value) + value_to_indices[value_tuple].append(index) + + duplicate_indices = [index for indices in value_to_indices.values() if len(indices) > 1 for index in indices] + return duplicate_indices + if part == 2: - continue + with open(input_f) as file: + for line in file: + lines.append(get_re(r"^p=<(.*)>.*v=<(.*)>.*a=<(.*)>$",line.rstrip())) - #pprint(lines) + for ldx,l in enumerate(lines): + lines[ldx] = [np.array(list2int(l.group(1).split(','))), np.array(list2int(l.group(2).split(','))), np.array(list2int(l.group(3).split(',')))] - # magnitude = [] + particles = [] - # def calculate_magnitude(vector): - # return math.sqrt(sum(component ** 2 for component in vector)) + iterations = 10000 - # def find_slowest_as_time_infinite(vectors): - # min_acceleration = float('inf') - # slowest_item = None - - # for i, (_, a) in enumerate(vectors): - # acceleration_magnitude = calculate_magnitude(a) - # if acceleration_magnitude < min_acceleration: - # min_acceleration = acceleration_magnitude - # slowest_item = i - - # return slowest_item + last_val = 0 + range_since_last = 0 - # vectors = [] + for iter in range(iterations): + if len(lines) != last_val: + last_val = len(lines) + else: + range_since_last += 1 - # for i in lines: - # v = list2int(i.group(2).split(',')) - # a = list2int(i.group(3).split(',')) - # vectors.append((v,a)) - # print(find_slowest_as_time_infinite(vectors)) + if range_since_last > 100: # we dont want to run forever + break + + positions = {} + length = len(lines) + duplicates = [] + + for ldx in range(length): + pos = [] + p,v,a = lines[ldx] + + pos = calculate_position_xyz(p, v, a) + positions[ldx] = pos + lines[ldx][0] = pos + + duplicates = find_duplicate_indices(positions) + + if len(duplicates) > 0: + lines = [item for i, item in enumerate(lines) if i not in duplicates] + print(len(lines)) diff --git a/2017/20/test.py b/2017/20/test.py new file mode 100644 index 0000000..e4e4ba9 --- /dev/null +++ b/2017/20/test.py @@ -0,0 +1,38 @@ +import re +from collections import namedtuple + +Particle = namedtuple('Particle', ['pos', 'vel', 'acc']) + +def parse_particle(line): + pos_match = re.search('p=<(-?\d+),(-?\d+),(-?\d+)>', line) + position = int(pos_match.group(1)), int(pos_match.group(2)), int(pos_match.group(3)) + vel_match = re.search('v=<(-?\d+),(-?\d+),(-?\d+)>', line) + velocity = int(vel_match.group(1)), int(vel_match.group(2)), int(vel_match.group(3)) + acc_match = re.search('a=<(-?\d+),(-?\d+),(-?\d+)>', line) + acceleration = int(acc_match.group(1)), int(acc_match.group(2)), int(acc_match.group(3)) + return Particle(position, velocity, acceleration) + +def move_particle(particle): + new_v = tuple(v + a for v, a in zip(particle.vel, particle.acc)) + new_p = tuple(p + v for p, v in zip(particle.pos, new_v)) + return Particle(new_p, new_v, particle.acc) + +def manhattan(particle): + return sum(abs(k) for k in particle.pos) + +if __name__ == '__main__': + particles = [parse_particle(line) for line in open('input')] + + orig = particles.copy() + + for _ in range(1000): + particles = [move_particle(p) for p in particles] + print(particles.index(min(particles, key=manhattan))) + + particles = orig.copy() + for _ in range(1000): + if len(set(p.pos for p in particles)) < len(particles): + positions = [p.pos for p in particles] + particles = [part for part, pos in zip(particles, positions) if positions.count(pos) == 1] + print(len(particles)) + particles = [move_particle(p) for p in particles] diff --git a/README.md b/README.md index 7f3807e..c7fc045 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,21 @@ ## 2017 + + |├───┬┴┴┴┤└──o┌┘└┤ FC├─*o────────┴──┘├┴┴┴┴┬──┘| 21** + |│o┬─┤ ├────┤┌─┤ LP├─┘┌──|(────────┤ ├──*| 20* + |└─┘o┤ ├─┐o─┘└─┤ UT├─┐└───┬┴┴┴┴┴┬┐ *┤1├──┘| 19** + |┌───┤ ├─┴─────┤ XR├─┴────┤ ├┘└┤ 2├──*| 18** + |└┐o─┴┬┬┬┴───────┴┬┬┬┴──────┤ MAGI├*─┤ v├┌─┘| 17** + |V├─────┘o───────────┐*─────┤ CSMK├┘ ┌┤├└─┐| 16** + |└┴──┤[]├────────────┘└─────┴┬┬┬┬┬┴*│└┬┬┬┬┴──┘| 15** + |*────────────────┬────∧∧∧───┤|├───┘└┐└──────┐| 14** + |├──┐o────────────┘┌────|(────*o─────┴───────┤| 13** + |└─o└───────┬──────┼┴┴┴┴┬────o└──────────*o──┘| 12** + |*─────────┐└──┤|├─┤ AC├──∧∧∧──────────┐└───┐| 11** + |├───────┐┌┘┌┴┴┴┴┬─┤ D0├────────────*┌o└────┤| 10** + |└─o┌────┘└─┤ t ├─┤ vD├┌─────o*────┘└──────┘| 9** + |┌──┘┌──────┤ e ├─┤ TE├┘┌─────┘┌───────────*| 8** |│┌──o┌─┴┤ OP├──┘│o───┬───────┤ t├──┐*──────┤| 7** |│└──┐└──┴┬┬┬┴───┘┌───┘o─oTo──┤ ├──┘└───*┌─┘| 6** |└───┴───────────┐└────────┐*─┴┬┬┬┴──┤[]├─┘└─o| 5**