diff --git a/2022/full/day11.txt b/2022/full/day11.txt new file mode 100644 index 0000000..01f2a51 --- /dev/null +++ b/2022/full/day11.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 57 + Operation: new = old * 13 + Test: divisible by 11 + If true: throw to monkey 3 + If false: throw to monkey 2 + +Monkey 1: + Starting items: 58, 93, 88, 81, 72, 73, 65 + Operation: new = old + 2 + Test: divisible by 7 + If true: throw to monkey 6 + If false: throw to monkey 7 + +Monkey 2: + Starting items: 65, 95 + Operation: new = old + 6 + Test: divisible by 13 + If true: throw to monkey 3 + If false: throw to monkey 5 + +Monkey 3: + Starting items: 58, 80, 81, 83 + Operation: new = old * old + Test: divisible by 5 + If true: throw to monkey 4 + If false: throw to monkey 5 + +Monkey 4: + Starting items: 58, 89, 90, 96, 55 + Operation: new = old + 3 + Test: divisible by 3 + If true: throw to monkey 1 + If false: throw to monkey 7 + +Monkey 5: + Starting items: 66, 73, 87, 58, 62, 67 + Operation: new = old * 7 + Test: divisible by 17 + If true: throw to monkey 4 + If false: throw to monkey 1 + +Monkey 6: + Starting items: 85, 55, 89 + Operation: new = old + 4 + Test: divisible by 2 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 7: + Starting items: 73, 80, 54, 94, 90, 52, 69, 58 + Operation: new = old + 7 + Test: divisible by 19 + If true: throw to monkey 6 + If false: throw to monkey 0 diff --git a/2022/python/day08.py b/2022/python/day08.py index d52f630..6d1f43b 100644 --- a/2022/python/day08.py +++ b/2022/python/day08.py @@ -1,8 +1,9 @@ from pprint import pprint as pp -from shared import get_fname +import shared import matrix + def part1(mx): SIZE=len(mx) MAX_IDX = SIZE -1 @@ -125,10 +126,61 @@ def part2(mx): high_score = score print(high_score) +def part2_with_fixes(mx): + SIZE=len(mx) + MAX_IDX = SIZE -1 + data = matrix.matrix_of_size(SIZE, SIZE) + data = matrix.set_matrix_dict(data) + + high_score = 0 + + for row in range(SIZE): + for col in range(SIZE): + data[row][col] = { "value": mx[row][col]} + + for row, _row in enumerate(mx): + for col, _val in enumerate(mx[row]): + lineofsight = matrix.line_of_sight(mx, row, col) + + data[row][col]["u"] = lineofsight["U"] + data[row][col]["l"] = lineofsight["L"] + data[row][col]["d"] = lineofsight["D"] + data[row][col]["r"] = lineofsight["R"] + + # Calculate score + score = 1 # identity yoooo + val = data[row][col]['value'] + # Get the score of visible trees in each direction + for direction in ("u","l","d","r"): + in_line = data[row][col][direction] + if not in_line: + # we're on an edge + score = 0 + break + + line_score = 0 + for idx, tree in enumerate(in_line): + # for every tree, check if its as tall or taller, + # stop countig after that + line_score += 1 + if tree >= val: + break + score = score * line_score + if score > high_score: + high_score = score + print(high_score) + def main(): - mx = matrix.load_matrix_file(get_fname(8)) - part1(mx) - part2(mx) + mx = matrix.load_matrix_file(shared.get_fname(8)) + with shared.elapsed_timer() as elapsed: + part1(mx) + print(elapsed()) + with shared.elapsed_timer() as elapsed: + part2(mx) + print(elapsed()) + with shared.elapsed_timer() as elapsed: + part2_with_fixes(mx) + print(elapsed()) diff --git a/2022/python/day11.py b/2022/python/day11.py new file mode 100644 index 0000000..c440418 --- /dev/null +++ b/2022/python/day11.py @@ -0,0 +1,125 @@ +import shared +from scanf import scanf +import matrix +from dataclasses import dataclass +from typing import Callable +import operator + + +@dataclass +class Monkey: + number: int + items: list + div: int + t: int + f: int + by: int + op: operator + inspect_count: int = 0 + + + +def load_monkeys(lines): + monkeys = [] + count = 0 + for line in lines: + if line.lstrip().startswith("Starting"): + items = list(map(int, line.split(": ")[-1].split(","))) + elif line.lstrip().startswith("Operation"): + op = line.split(": ")[-1] + try: + by = int(line.split(" ")[-1]) + except ValueError: + by = None # know None means by self + if '*' in op: + operand = operator.mul + elif '+' in op: + operand = operator.add + elif line.lstrip().startswith("Test"): + div = int(line.split(" ")[-1]) + elif line.lstrip().startswith("If true"): + true = int(line.split(" ")[-1]) + elif line.lstrip().startswith("If false"): + false = int(line.split(" ")[-1]) + monkey = Monkey( + number=count, + items=items, + op=operand, + by=by, + div=div, + t=true, + f=false + ) + monkeys.append(monkey) + count+=1 + return monkeys + +def part1(lines): + monkeys = load_monkeys(lines) + for monkey in monkeys: + print(monkey) + + for current_round in range(20): # TODO: WHILE + for monkey in monkeys: + for item in monkey.items: + monkey.inspect_count += 1 + if monkey.by is None: + # Self + item = monkey.op(item, item) + else: + item = monkey.op(item, monkey.by) + print(item,monkey.by, monkey.op) + item = item // 3 + print(item) + if item % monkey.div == 0: + to = monkey.t + else: + to = monkey.f + monkeys[to].items.append(item) + monkey.items = [] + print("-----current round", current_round) + + counts = list(sorted([monkey.inspect_count for monkey in monkeys])) + print(counts) + total = counts[-1] * counts[-2] + print(total) + + + + +def part2(lines): + monkeys = load_monkeys(lines) + for monkey in monkeys: + print(monkey) + + for current_round in range(10000): # TODO: WHILE + for monkey in monkeys: + for item in monkey.items: + monkey.inspect_count += 1 + if monkey.by is None: + # Self + item = monkey.op(item, item) + else: + item = monkey.op(item, monkey.by) + if item % monkey.div == 0: + to = monkey.t + else: + to = monkey.f + monkeys[to].items.append(item) + monkey.items = [] + print("-----current round", current_round) + + counts = list(sorted([monkey.inspect_count for monkey in monkeys])) + print(counts) + total = counts[-1] * counts[-2] + print(total) + + +def main(): + rows = [row for row in shared.load(11)] + #part1(rows) + part2(rows) + + +if __name__ == "__main__": + main() diff --git a/2022/python/matrix.py b/2022/python/matrix.py index b732a03..6efd5a5 100644 --- a/2022/python/matrix.py +++ b/2022/python/matrix.py @@ -1,8 +1,14 @@ +from collections import defaultdict + +from typing import List, Dict, Tuple split_word_to_int_list = lambda y: [int(w) for w in y] split_line_to_int_list = lambda y: [int(w) for w in y.split(" ") if w] def rotate(m, right=True): # -90 + """ + Takes a matrix, and rotates all of the values 90 degrees to the left + """ x = list(zip(*m[::-1])) if right: return x @@ -10,6 +16,9 @@ def rotate(m, right=True): # -90 def load_matrix_file(name, func=None): + """ + Open a file and split all space separated word lists to integers as a matrix + """ with open(name, "r") as f: my_file = [] for line in f: @@ -99,9 +108,57 @@ def get_neighbor_coords(matrix, c, r, diagonals=True): pass # okay we out of bounds boizzzz return neighbors +def line_of_sight_coords(matrix, row,col) -> Dict[str,List[Tuple[int,int]]]: + """ + Takes a matrix, a row, and a column + calculates the coordinates to the edge for all four cardinal directions -def get_column(matrix, col): - pass + returns a dict with a list of tuple coordes TRAVELING AWAY from the + requested coordinate + """ + height, width = get_size(matrix) + + col_ids = list(range(0, height)) + row_ids = list(range(0, width)) + + up_ids,down_ids = list(reversed(col_ids[:col])), col_ids[col+1:] + left_ids,right_ids = list(reversed(row_ids[:row])), row_ids[row+1:] + + left = [(r,col) for r in left_ids] + right = [(r,col) for r in right_ids] + up = [(row,c) for c in up_ids] + down = [(row,c) for c in down_ids] + + return { + 'U':up, + 'L':left, + 'D':down, + 'R':right, + } + +def line_of_sight(mx, row, col): + """ + renders a line of sight coord calculation, into the values + """ + coords = line_of_sight_coords(mx, row, col) + los = defaultdict(list) + for k, ids in coords.items(): + for _row, _col in ids: + los[k].append(mx[_row][_col]) + return los + + + +def get_size(matrix): + height = len(matrix) + width = len(matrix[0]) + return height, width + +def row_col_from_int(matrix, x): + h,w = get_size(matrix) + col = x % w + row = x // h + return row,col def matrix_of_size(width, height, default=0): @@ -114,13 +171,10 @@ def set_matrix_dict(m): return m -def get_size(matrix): - height = len(matrix) - width = len(matrix[0]) - return height, width - - def pmx(*matrices, pad=True, space=True): + """ + print a matrix of integers, zero turns to `.` for clarity + """ if len(matrices) > 1: matrices = list(zip(*matrices)) for row in matrices: @@ -142,6 +196,9 @@ def pmx(*matrices, pad=True, space=True): print("".join([f(x) for x in c])) def ppmx(*matrices, pad=True, space=True): + """ + print a matrix of anything, Falsy values turns to `.` for clarity + """ if len(matrices) > 1: matrices = list(zip(*matrices)) for row in matrices: diff --git a/2022/python/shared.py b/2022/python/shared.py index 6ca3b93..06fe888 100644 --- a/2022/python/shared.py +++ b/2022/python/shared.py @@ -1,3 +1,5 @@ +from contextlib import contextmanager +from timeit import default_timer from pathlib import Path spl = lambda y: [int(w) for w in y] @@ -56,3 +58,13 @@ def rotate(WHAT, times=1): for x in range(times): what = list(zip(*what[::-1])) return what + + + +@contextmanager +def elapsed_timer(): + start = default_timer() + elapser = lambda: default_timer() - start + yield lambda: elapser() + end = default_timer() + elapser = lambda: end-start diff --git a/2022/samples/day11.txt b/2022/samples/day11.txt new file mode 100644 index 0000000..477d33b --- /dev/null +++ b/2022/samples/day11.txt @@ -0,0 +1,28 @@ +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 +