day11 part1 - part 2 is stub only
This commit is contained in:
parent
fbdfd773e9
commit
7874d21e18
55
2022/full/day11.txt
Normal file
55
2022/full/day11.txt
Normal file
@ -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
|
@ -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())
|
||||
|
||||
|
||||
|
||||
|
125
2022/python/day11.py
Normal file
125
2022/python/day11.py
Normal file
@ -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()
|
@ -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:
|
||||
|
@ -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
|
||||
|
28
2022/samples/day11.txt
Normal file
28
2022/samples/day11.txt
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user