def get_grid(part_b=False): grid = defaultdict(int) keys = {} doors = {} start_points = [] # read input lines = parseMod.readCSV_row('data/18maze.csv') for row in range(len(lines)): temp = [] for item in lines[row]: temp.append(item) lines[row] = temp mid_y = (len(lines) - 1) // 2 # find the center mid_x = (len(lines[0]) - 1) // 2 if part_b: # if part B, modify the input lines[mid_y - 1][mid_x - 1:mid_x + 2] = "@#@" lines[mid_y][mid_x - 1:mid_x + 2] = "###" lines[mid_y + 1][mid_x - 1:mid_x + 2] = "@#@" for y, line in enumerate(lines): for x, c in enumerate( line ): # go through each character in i, add position and item to point if not wall if c != '#': p = Point(x, y) grid[p] = 1 if c == '@': start_points.append(p) elif c != '.': o = ord(c) if o >= 97: keys[o - 97] = p else: doors[o - 65] = p # track locations total_start_points = len(start_points) keys = {k + total_start_points: v for k, v in keys.items()} doors = {k + total_start_points: v for k, v in doors.items()} return grid, keys, doors, start_points, x, y
for t in range(3): counts[t] += 1 if array[j][i] == types[t] else 0 return counts def get_value(array): # compute value of area by multiplying tree by lumberyard count trees, lumberyards = 0, 0 for row in array: trees += row.count('|') lumberyards += row.count('#') return trees*lumberyards woods = parseMod.readCSV_row('data/18map.csv', '\n') for i, line in enumerate(woods): woods[i] = [c for c in line] # simulate forest, tracking wood values values = list() for time in range(800): # 800 should be enough to find the pattern copy_woods = deepcopy(woods) for y in range(len(woods)): for x in range(len(woods[0])): adj = check_adj(x, y, copy_woods) if copy_woods[y][x] == '.' and adj[1] >= 3: woods[y][x] = '|' elif copy_woods[y][x] == '|' and adj[2] >= 3: woods[y][x] = '#' elif copy_woods[y][x] == '#' and not (adj[1] >= 1 and adj[2] >= 1):
self.registers[ 4] += 1 # occurs after each outer loop iteration, starts checking against larger self.pc = 13 # exit inner loop continue # execute normal op cmd = self.opcode[line[0]] if str(line[0]).isnumeric() else line[0] self.registers[line[3]] = self.executions[cmd](line) # reassign pc if self.ip != -1: self.pc = self.registers[self.ip] self.pc += 1 instr = parseMod.readCSV_row('data/19program.csv', '\n') program = [] for i in instr: i = i.split() program.append([i[0], int(i[1]), int(i[2]), int(i[3])] if len(i) > 2 else [i[0], int(i[1])]) computer = Computer(copy.deepcopy(program)) computer.process() print("part 1 registers: ", computer.registers) computer2 = Computer(copy.deepcopy(program)) computer2.registers = [1, 0, 0, 0, 0, 0] computer2.process() print("part 2 registers: ", computer2.registers)
# Advent of Code 2018 - Day 12 # Author: Rachael Judy # Date: 12/24/2020 # Purpose: Perform extension of generations of plants (after generation 97 sum increases by 80 each generation # - print your pattern results to get your own increment) - look for ADJUST comment for things to change import copy import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod inp = parseMod.readCSV_row('data/12pattern.csv', '\n') # ADJUST inc = 80 # ADJUST initial = ['.' for _ in range(500)] + list( inp[0][15:]) + ['.' for _ in range(500)] rules = {} for line in inp[1:]: rules[line.split()[0]] = line.split()[2] def calc_value(generations, initial): base = inc * (generations - (generations if generations <= 100 else 100)) for i in range(generations if generations <= 100 else 100): current_config = copy.deepcopy(initial) for shift in range(2, len(initial) - 2): current_config[shift] = rules[''.join(initial[shift - 2:shift + 3])]
# Advent of Code 2018 - Day 17 # Author: Rachael Judy # Date: 12/27/2020 # Purpose: Simulate spread of water in a basin section and what remains after water stops import os, sys import re sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod # parse input data to points data = parseMod.readCSV_row('data/17map.csv', '\n') exploded = [] for ln in data: m = re.match(r'x=(-?\d+), y=(-?\d+)\.\.(-?\d+)', ln) if m: exploded.extend((int(m.group(1)), y) for y in range(int(m.group(2)), 1 + int(m.group(3)))) continue m = re.match(r'y=(-?\d+), x=(-?\d+)\.\.(-?\d+)', ln) if m: exploded.extend((x, int(m.group(1))) for x in range(int(m.group(2)), 1 + int(m.group(3)))) continue # for use later, get min and maxes miny = min(y for (x, y) in exploded) maxy = max(y for (x, y) in exploded) minx = min(x for (x, y) in exploded) maxx = max(x for (x, y) in exploded)
# Author: Rachael Judy # Date: 12/14/2020 # Purpose: Part 1 - apply bitmasks to value where 0 and 1 overwrite and x leaves # Part 2 - apply bitmask to address where 0 leaves, 1 overwrites, and x switches to every possible import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod # SET phase phase = 2 # read instructions lines = parseMod.readCSV_row('data/14masks.csv', '\n') mem = {} if phase == 1: # go through each line for instr in lines: content = instr.split(' ') # parse mask if content[0] == 'mask': mask_0 = 0x0000000000000000 mask_1 = 0x0000000000000000 # create mask for each stage for digit, bit in enumerate(content[2]): if bit == '1': # set to ones mask_0 = mask_0 | (1 << (35 - digit)) mask_1 = mask_1 | (1 << (35 - digit))
import sys import re from collections import defaultdict, Counter sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod def parse_line(regex, line): m = regex.match(line) if m: return int(m.group(1)) # Store the events and sort them chronologically events = parseMod.readCSV_row('data/4shifts.csv', '\n') events.sort() # Init regex for line parsing guard_id_re = re.compile(r'^\[.*\] Guard #(\d+) begins shift$') mins_re = re.compile(r'^\[\d+-\d+-\d+ \d+:(\d+)\].*$') # Parse the events and increment the counts for minutes each guard was asleep guards = defaultdict(Counter) for event in iter(events): if 'begins shift' in event: current_id = parse_line(guard_id_re, event) elif 'falls asleep' in event: start = parse_line(mins_re, event) elif 'wakes up' in event: end = parse_line(mins_re, event)
import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod class Cart: # cart has direction, position, intercept def __init__(self, r, c, d, inter): self.r = r self.c = c self.d = d self.inter = inter G = parseMod.readCSV_row('data/13tracks.csv', '\n') for line in range(len(G)): G[line] = [c for c in G[line]] # up, right, down, left DR = [-1, 0, 1, 0] DC = [0, 1, 0, -1] left = lambda d: (d + 3) % 4 right = lambda d: (d + 1) % 4 # create carts carts = [] for r in range(len(G)): for c in range(len(G[r])): if G[r][c] == '^': G[r][c] = '|'
for row in range(border, len(bugs) - border): for spot in range(border, len(bugs[0]) - border): if bugs[row][spot] == '#' and adjacencies[row][spot] != 1: bugs[row][spot] = '.' # becomes empty if not one bug elif bugs[row][spot] == '.' and (adjacencies[row][spot] == 1 or adjacencies[row][spot] == 2): bugs[row][spot] = '#' bio_score += (pow(2, exponent) * (bugs[row][spot] == '#')) exponent += 1 return bio_score # read input into arrays bugs = parseMod.readCSV_row('data/24bugs.csv') for row in range(len(bugs)): temp = [] for item in bugs[row]: temp.append(item) bugs[row] = temp if part == 1: # surround with comma border for x in range(len(bugs)): bugs[x].insert(0, '|') bugs[x].append('|') bugs.insert(0, ['|' for i in range(len(bugs[0]))]) bugs.append(['|' for i in range(len(bugs[0]))]) # create adj calculations
# Advent of Code 2018 - Day 10 # Author: Rachael Judy # Date: 12/23/2020 # Purpose: Find where the stars align to letters and the time they do. Takes some squinting import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod inp = parseMod.readCSV_row('data/10stars.csv', '\n') position_dict = [] for i in inp: x = int(i[10:16]) y = int(i[18:24]) velx = int(i[36:38]) vely = int(i[40:42]) position_dict.append([x, y, velx, vely]) # look for spot where they're closest over every move, 75 seems to do the trick for t in range(100000): min_x = min([x for x, y, _, _ in position_dict]) max_x = max([x for x, y, _, _ in position_dict]) min_y = min([y for x, y, _, _ in position_dict]) max_y = max([y for x, y, _, _ in position_dict]) W = 75 if min_x + W >= max_x and min_y + W >= max_y:
# checks on 4D adjacencies, virtually identical to 3 def check_adj_4d(x, y, z, w): global new_grid adj = 0 adjacency_objects = [[i, j, k, l] for i in [x - 1, x, x + 1] for j in [y - 1, y, y + 1] for k in [z - 1, z, z + 1] for l in [w - 1, w, w + 1]] for p in adjacency_objects: adj += (new_grid[p[3]][p[2]][p[1]][p[0]] == '#') return adj - (new_grid[w][z][y][x] == '#') layer_0 = parseMod.readCSV_row('data/17activity.csv') # part 1 global grid, new_grid # set up initial state grid = [[['.' for i in range(22)] for j in range(22)] for k in range(15)] for x in range(7, 7 + len(layer_0[0])): for y in range(7, 7 + len(layer_0)): grid[7][y][x] = layer_0[y - 7][x - 7] # do iterations for it in range(6): new_grid = copy.deepcopy(grid) for z in range(6 - it, 9 + it): for y in range(1, len(grid[0]) - 1): for x in range(1, len(grid[0][0]) - 1):
y_dot = y + 2 else: # up x_dot = x y_dot = y - 1 # if this portal point has not been found, add it to the dictionary if len(name) == 2 and name in portals and len(portals[name]) < 2 and portals[name][0] != (x_dot, y_dot): portals[name].append((x_dot, y_dot)) elif len(name) == 2 and name not in portals: # if no dictionary entry for this name yet portals[name] = [] portals[name].append((x_dot, y_dot)) # read in as grid - using the modded input global maze, portals maze = parseMod.readCSV_row('data/20maze.txt', '\n') # phase 1 - portals jump to each other directly - virtually identical to part 2 with the addition of layering if phase == 1: G = nx.Graph() portals = {} # key will be name, will have list of two children for locations of portal # go through maze and collect the useful points, populate the graph for y, row in enumerate(maze): for x, char in enumerate(row): if char == '.': G.add_node((x, y)) # add self if x+1 < len(maze[0]) and maze[y][x+1] == '.': # check right G.add_edge((x, y), (x+1,y))
# Author: Rachael Judy # Date: 12/4/2020 # Purpose: Find best asteroid to put base on that can see most others - go based on slope # There's got to be a better way to do this - complexity O(iterations^4) # Map Depiction - coordinates as astMap[y][x] # 0,0_________________ # | +x # | # # # | # # | # b # | # # | +y import parseMod astMap = parseMod.readCSV_row('data/10asteroids.csv') # part 1 maxAst = 0 bestCoord = (0, 0) bestSlopes = [] # check all coordinates in grid for best option for y in range(len(astMap)): for x in range(len(astMap[0])): # keep an ordered list of the slopes on both sides numSeen = 0 slopesXP = [] slopesXN = [] # if asteroid, consider as base if astMap[y][x] == '#':
import parseMod # builds regex recursively for input rule def build_re(r_num): rule = rules_dict[r_num] if rule == 'a' or rule == 'b': # if it needs to match the character, place in string return rule if len(rule) == 1: # if only one option, just add the rules content return "".join(map(build_re, rule[0])) else: # if multiple paths to follow, add every option to the regex - no memory needed return "(?:" + "|".join("".join(map(build_re, r)) for r in rule) + ")" # get input input_lines = parseMod.readCSV_row('data/19rules.csv', '\n') # set rules with each rule having either list of alternatives of rules or character to match rules_dict = dict() for i, rule in enumerate(input_lines): if len(rule) > 20: break rule_break = rule.split() recursive_rules, temp = [], [] for char in rule_break[1:]: if char.isnumeric(): # append the rule number temp.append(int(char)) elif char == '|': # start a new list recursive_rules.append(temp) temp = [] else: # letter in quotes found
while not_seen and 0 <= row + j < len(seating) and 0 <= col + i < len( seating[0]): # if a seat is found, add an adjacency if occupied if seating[row + j][col + i] == 'L' or seating[row + j][col + i] == '#': not_seen = False adj = seating[row + j][col + i] == '#' i += inci j += incj return adj # get input seating = parseMod.readCSV_row('data/11seats.csv') # add a border of "floor" around so to eliminate corner adj complications for row in range(len(seating)): seating[row] += '.' seating[row] = '.' + seating[row] seating.insert(0, '') seating.append('') for i in range(len(seating[1])): seating[0] += '.' seating[len(seating) - 1] += '.' # display initial arrangement for row in seating: print(row)
# Advent of Code 2020 - Day 22 # Author: Rachael Judy # Date: 12/22/2020 # Purpose: Play card game like war (part 1) and recursive version that involves subgame with smaller deck (part 2) import copy import os import sys import queue sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod hands = parseMod.readCSV_row('data/22decks.csv', '\n') # basic War def part_1(player_queues): while not player_queues[0].empty() and not player_queues[1].empty(): play = [player_queues[0].get(), player_queues[1].get()] winner = play[1] > play[0] player_queues[winner].put(play[winner]) player_queues[winner].put(play[1 - winner]) return winner # recursive War def part_2(player_lists): memory = set()
lambda line: int(line[1] == self.registers[line[2]]), 'eqri': lambda line: int(self.registers[line[1]] == line[2]), 'eqrr': lambda line: int(self.registers[line[1]] == self.registers[line[2]] ) } def process(self): for line in self.instructions: cmd = self.opcode[line[0]] if str(line[0]).isnumeric() else line[0] self.registers[line[3]] = self.executions[cmd](line) # process input inp = parseMod.readCSV_row('data/16data.csv', '\n') line_ptr = 0 checks = [ ] # contains a list with (opcode, before registers, after conditions) while parse_check(inp, line_ptr, checks): # gets all the checks line_ptr += 3 program = [] # tuple of op code, A, B, C for line in inp[line_ptr:]: # collects the actual program line = line.split() program.append((int(line[0]), int(line[1]), int(line[2]), int(line[3]))) # create a computer, process the checks and keep lists of ones being used by each opcode computer = Computer([]) opcode_options = {
# check if more work is available for w in workers: if w.available <= t: for x in sorted(G.nodes): # remaining nodes ready = True for c in list(G.predecessors(x)): if c not in order: ready = False break if ready and x not in in_progress: # worker found work w.available = t + 61 + ord(x) - ord( 'A') # t to be available again w.working_on = x # task to work on in_progress.append(w.working_on) break if len(order) == 26: # have full string break print(f"part {phase}") print("order: ", order) print("time: ", t) print() # input lines = parseMod.readCSV_row('data/7steps.csv', '\n') work(1, lines) # execute phase 1 work(2, lines) # execute phase 2
transfersY = 0 # set to zero each time check for j in range(len(predY)): transfersY += 1 # if match found, store the total steps and get out of loop if predX[i] == predY[j]: found = True transfersX += transfersY break if found: break return transfersX # read from file orbits = parseMod.readCSV_row('data/6orbits.csv') # create dictionary of relationships # key will be planet and value will be predecessor planetDict = dict() planetDict['COM'] = None for relationship in orbits: keyValue = relationship.split(')') planetDict[keyValue[1]] = keyValue[0] # get orbits and transfers from you to santa totalOrbits = getTotalOrbits(planetDict) transfer = countTransfers(planetDict['YOU'], planetDict['SAN'], planetDict) # display print("Total Orbits", totalOrbits)
# Advent of Code 2020 - Day 24 # Author: Rachael Judy # Date: 12/24/2020 # Purpose: Find the initial pattern from the set of instructions and then flip tiles based on adjacencies import copy import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod inp = parseMod.readCSV_row('data/24tiles.csv', '\n') # dictionary of dim by dim - row under would be dim -1 then dim again dim = 200 # gets next index of interest based on direction do_next = { 'nw': lambda x: x - dim, 'ne': lambda x: x - dim + 1, 'w': lambda x: x - 1, 'e': lambda x: x + 1, 'sw': lambda x: x + dim - 1, 'se': lambda x: x + dim } # read each line of the input and follow the instructions from keypoint to tile black_tiles = set() for line in inp: ptr = 0
# Advent of Code 2020 - Day 12 # Author: Rachael Judy # Date: 12/12/2020 # Purpose: Find Manhattan distance to ship with ship based directions and waypoint based directions import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod # get directions directions = parseMod.readCSV_row('data/12directions.csv', '\n') # part 1 position = [0, 0] orientation = 1 # start east - 0, 1, 2, 3 == N, E, S, W for dir in directions: # set absolute position position[0] += int(dir[1:]) * ((dir[0] == 'E') - (dir[0] == 'W')) position[1] += int(dir[1:]) * ((dir[0] == 'N') - (dir[0] == 'S')) # set orientation for i in range(int(int(dir[1:]) / 90)): orientation = (orientation + ((dir[0] == 'R') - (dir[0] == 'L'))) % 4 # move in orientation position[1] += int(dir[1:]) * ((orientation == 0) - (orientation == 2)) * (dir[0] == 'F') position[0] += int(dir[1:]) * (
import parseMod # find trees on route def countTrees(map, xStep, yStep): x = 0 y = 0 count = 0 while y < len(map): if map[y][x] == '#': # trees marked with hashtag count += 1 x = (x+xStep) % len(map[0]) y += yStep return count # read in map to array map = parseMod.readCSV_row('data/3maps.csv') # compute trees on given paths x = countTrees(map, 1, 1) y = countTrees(map, 3, 1) # from stage one z = countTrees(map, 5, 1) w = countTrees(map, 7, 1) v = countTrees(map, 1, 2) print("Single:", y) print("Combo:", v*w*x*y*z)
# Advent of Code 2020 - Day 5 # Author: Rachael Judy # Date: 12/5/2020 # Purpose: Find the highest boarding pass ID (binary) and the missing one import sys, os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod # get passes plane = parseMod.readCSV_row('data/5boarding.csv') # find lowest and highest id ids = [] lowest = 1000 highest = 0 for seat in plane: # get row row = 0 exp = len(seat[0:-3]) for letter in seat[:-3]: exp -= 1 row += ((letter == 'B') * 2**exp) # get column col = 0 exp = len(seat[-3:]) for letter in seat[-3:]: exp -= 1 col += ((letter == 'R') * 2**exp)
else: # if not one of the operators, throw the number on the num_stack for use with the op num_stack.append(int(s)) # execute the final set L->R without parenthesis to guide the precedence while len(op_stack) > 0: op = op_stack.pop() num1 = num_stack.pop() num2 = num_stack.pop() result = operations[op](num1, num2) num_stack.append(result) return num_stack.pop() # the final result lines = parseMod.readCSV_row('data/18math.csv', '\n') # existing operations operations = { '+': lambda num1, num2: num1 + num2, '*': lambda num1, num2: num1 * num2 } # part 1 operator_precedence = {'+': 1, '*': 1, '(': 0} evals = [] # store the evaluation of each line for equation in lines: evals.append(eval(equation, operator_precedence)) print("Part 1: ", sum(evals))
# Advent of Code 2018 - Day 25 # Author: Rachael Judy (c) rjudy1 # Date: 12/28/20 # Purpose: Count constellations formed by stars less than 3 Manhattan from others in their group import networkx as nx import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod stars = parseMod.readCSV_row('data/25stars.csv') for i, line in enumerate(stars): stars[i] = tuple(int(x) for x in line.split(',')) # build graph with edges meeting conditions, get number of connected components manhattan = lambda a, b: sum(abs(x - y) for x, y in zip(a, b) ) # function returns manhattan dist constellations = nx.Graph() for star1 in stars: for star2 in stars: if manhattan(star1, star2) <= 3: constellations.add_edge(star1, star2) print("Constellations: ", (nx.number_connected_components(constellations)))
# Date: 12/22/2020 # Purpose: Find largest non infinite area closest to one point # and largest area less than 10000 manhattan distances from all points import copy import numpy as np import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod # set phase phase = 1 lines = parseMod.readCSV_row('data/6coords.csv', '\n') coordinates = [] for line in lines: line = line.split() coordinates.append((int(line[0].strip(',')), int(line[1]))) # offset by 200 to ensure we have a wide area if phase == 1: # check each point in the grid for closest - don't include equidistant points grid = [[(600, 600) for j in range(375)] for i in range(375)] grid = np.array(grid) repeat_use = {} for y1 in range(len(grid)): for x1 in range(len(grid[0])): for x, y in coordinates: if abs(x1-x) + abs(y1-y) < abs(x1-grid[y1][x1][0]) + abs(y1-grid[y1][x1][1]): grid[y1][x1] = (x, y)
self.tile_pattern.reverse() self.joins[0], self.joins[2] = self.joins[2], self.joins[0] # rotate at whatever the requested angle is def rotate(self, angle): # rotates the angle given for _ in range(int(angle/90)): self.tile_pattern = list(zip(*self.tile_pattern[::-1])) for r in range(len(self.tile_pattern)): # fix a tuple thing self.tile_pattern[r] = list(self.tile_pattern[r]) self.joins[0], self.joins[1], self.joins[2], self.joins[3] \ = self.joins[3], self.joins[0], self.joins[1], self.joins[2] input_tiles = parseMod.readCSV_row('data/20tiles.csv', '\n') # tile dictionary will be id to Tile object tile_dict = {} tile = [] for row in input_tiles: row_on_tile = [] if row.startswith('Tile'): # save id id = int((row.split())[-1].strip(':')) else: # is a row of the tile for letter in row: # build row and tile row_on_tile.append(letter) tile.append(row_on_tile) if len(tile) == len(row): # end when tile is square tile_dict[id] = Tile(tile, id)
# Advent of Code 2018 - Day 24 # Author: Rachael Judy (c) rjudy1 # Date: 12/28/20 # Purpose: Play war with the immune system - hacky, some borrowed code because I haven't had time to fix it yet import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod inp = '\n'.join(parseMod.readCSV_row('data/24game.csv')).strip().replace( 'points with', 'points () with') # help parse attacks = ['slashing', 'fire', 'bludgeoning', 'radiation', 'cold'] # parsing def parse_dmg(ss): # parse damage dtype = ss[ss.rfind(" ") + 1:] dnum = int(ss[:ss.rfind(" ")]) return [0 if ty != dtype else dnum for ty in attacks] def parse_res(ss): # parse resistance tp = [1, 1, 1, 1, 1] for p in ss.split("; "): if len(p) == 0: continue mul = 1 if p[:4] == "weak":
# Advent of Code 2020 - Day 21 # Author: Rachael Judy # Date: 12/21/2020 # Purpose: Sort through the ingredients list for ones that are allergen free and then compile the alphabetical # by allergen list of ingredients import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod ingredients_list = parseMod.readCSV_row('data/21ingredients.csv', '\n') # parse input to allergens dictionary allergen_dict = {} # will have allergen : list of list of ingredients for food in ingredients_list: allergens = food[food.index("(") + len("contains "):-1].split() ingredients = food[:food.index("(")].split() for a in range( len(allergens)): # strip off the spare commas in allergen list allergens[a] = allergens[a].strip(",") for alle in allergens: # create dictionary entry for allergen if alle not in allergen_dict: allergen_dict[alle] = [ingredients] else: allergen_dict[alle].append(ingredients) all_set = set() # for all ingredients
# Advent of Code 2018 - Day 23 # Author: Rachael Judy (c) rjudy1 # Date: 12/28/20 # Purpose: 3d manhattan spheres in space - find number inside biggest sphere and closest point in max number of spheres import networkx as nx import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import parseMod # parse input into tuples inp = parseMod.readCSV_row('data/23drones.csv') bots = [] for line in inp: line = line.split(',') bots.append((int(line[0][5:]), int(line[1]), int(line[2].strip('>')), int(line[3][3:]))) X, Y, Z, RADIUS = 0, 1, 2, 3 ORIGIN = (0, 0, 0, 0) manhattan = lambda a, b: abs(a[X] - b[X]) + abs(a[Y] - b[Y]) + abs( a[Z] - b[Z]) # function returns manhattan dist # part 1 largest_radius_bot = max(bots, key=lambda bot: bot[RADIUS]) print( 'part 1:', sum((manhattan(largest_radius_bot, bot) <= largest_radius_bot[RADIUS])