示例#1
0
input_1 = Vector(3, 1)
input_2 = [
    Vector(1, 1),
    Vector(3, 1),
    Vector(5, 1),
    Vector(7, 1),
    Vector(1, 2)
]


def trees_in_line(grid: Grid, step: Vector):
    bounds = Point(grid.width, grid.height)
    pos = Point(0, 0)
    trees = 0

    while pos.y < grid.height:
        pos %= bounds
        if not grid[pos].is_passible():
            trees += 1
        pos += step
    return trees


with open('2020/03/input.txt') as f:
    grid = Grid.from_list_of_strings([line.strip() for line in f.readlines()])
    print(f'We would encounter {trees_in_line(grid,input_1)} trees')
    print(
        f'If you multiply together the number of trees encountered on each of the listed slopes, we would encounter {prod([trees_in_line(grid,step) for step in input_2])} trees'
    )
示例#2
0
# https://adventofcode.com/2021/day/15

from fishpy.geometry.lattice import LatticePoint
from fishpy.geometry.vector2d import Vector2D
from fishpy.pathfinding.grid import Grid
from fishpy.pathfinding import Dijkstra
from fishpy.pathfinding.grid.expandablegrid import ExpandableGrid
from fishpy.pathfinding.location import Location

with open('2021/15/input.txt') as f:
    lines = [[int(char) for char in line]
             for line in f.read().rstrip().split()]

# Part 1

grid_1 = Grid.from_list_of_strings(lines)
adjacency_function = lambda point: LatticePoint.get_adjacent_points(
    point, lower_bound=grid_1.bounds[0], upper_bound=grid_1.bounds[1])
dijkstra = Dijkstra(LatticePoint(0, 0),
                    grid_1.size - LatticePoint(1, 1),
                    adjacency_function=adjacency_function,
                    heuristic_function=LatticePoint.manhattan_distance,
                    cost_function=lambda _, new: grid_1[new].rep)
print(dijkstra.search())

# Part 2

grid_2 = ExpandableGrid.blank(LatticePoint(1, 1), LatticePoint(0, 0))
grid_2_overlay = ExpandableGrid.from_list_of_strings(lines)
grid_2_layout = (5, 5)
for grid_x in range(grid_2_layout[0]):
示例#3
0
            continue
        seen.add(pt)
        size += 1

        for adj in pt.get_adjacent_points(lower_bound=LatticePoint(0, 0),
                                          upper_bound=grid.size):
            q.put(grid[adj])
    return size


with open('2021/09/input.txt') as f:
    lines = [line.rstrip() for line in f]
    grid_body = [[int(col) for col in line] for line in lines]

    total_risk = 0
    grid = Grid.from_list_of_strings(grid_body)
    # for loc in grid:
    #     total_risk += risk_level(grid,loc)
    # print('The total risk level is',total_risk)

    # seen = set()
    # scores = PriorityQueue(max_=True)
    # for loc in grid:
    #     loc:Location
    #     if loc.rep == 9 or loc in seen:
    #         continue
    #     scores.put(basin_size(grid,loc,seen))

    print(
        grid.flood_fill(start=Location(0, 0, Location.IMPASSABLE, rep=1),
                        predicate_function=lambda pt: pt.rep == 9))
示例#4
0
# https://adventofcode.com/2018/day/10


import re
from typing import List

from fishpy import physics
from fishpy.geometry import Point, Vector
from fishpy.pathfinding.grid import Grid

input_file = '2018/10/input.txt'

with open(input_file) as f:
    lights:List[physics.Object] = []
    for line in f:
        line = re.split('<|,|>',line)
        pos = Point(int(line[1]),int(line[2]))  
        vel = Vector(int(line[4]),int(line[5]))
        lights.append(physics.Object(pos,vel))
    
    step = 0
    for i in range(10710):
        for light in lights:
            light.step()
        step += 1
        if step % 1000 == 0:
            print(step)
    print(step)
    g = Grid.blank(Point(68,16),offset=Point(184,190)).conditional_walls(lambda obj: obj in {light.position for light in lights},char='#')
    print(g)
示例#5
0
# Written by Cameron Haddock
# Written as a solution for Advent of Code 2016

# https://adventofcode.com/2016/day/24


from fishpy.geometry import Point
from fishpy.mathematics.graphs import PathGraph
from fishpy.pathfinding import Dijkstra
from fishpy.pathfinding.grid import Grid

with open('2016/24/input.txt') as f:
    grid = Grid.from_list_of_strings(f.read().strip().split('\n'))
    nodes = grid.char_positions([str(i) for i in range(8)])

    G = PathGraph()
    for node in nodes:
        G.add_node(node)
        
    validate = lambda pt: grid[pt].is_passible()
    weight = lambda n1,n2: Dijkstra(nodes[n1][0],nodes[n2][0],Point.get_adjacent_points,validate,Point.manhattan_distance).search()
    G.add_weighted_edges_for_complete(weight)
    run1 = G.get_length_of_path(G.complete_travelling_salesman(start='0'))
    run2 = G.get_length_of_path(G.complete_travelling_salesman(start='0',end='0'))

    print(f'Starting from location 0, the fewest number of steps required to visit every non-0 number marked on the map at least once is {run1}')
    print(f'The fewest number of steps required to start at 0 and visit every non-0 number marked on the map at least once, then return to 0 is {run2}')
示例#6
0
        layer = []
        for y in range(BOUNDS.y):
            row = []
            for x in range(BOUNDS.x):
                if c := f.read(1):
                    row.append(c)
                else:
                    end = True
                    break
            if end:
                break
            layer.append(row)
        if end:
            break
        layers.append(
            Grid.from_list_of_strings([''.join(row) for row in layer]))

    # Verify image not corrupted
    min = (-1, 10**6)
    for i in range(len(layers)):
        zeros = len(layers[i].char_positions(['0'])['0'])
        if zeros < min[1]:
            min = (i, zeros)
    counts = layers[min[0]].char_positions(['1', '2'])
    print(len(counts['1']) * len(counts['2']))

    # Decode image
    final = []
    for y in range(BOUNDS.y):
        row = ''
        for x in range(BOUNDS.x):
示例#7
0
from fishpy.pathfinding import Dijkstra
from fishpy.utility.debug import profile, timer
from copy import copy


class LatticeHash(LatticePoint):
    def __hash__(self) -> int:
        return self.y * 100 + self.x

    @staticmethod
    def from_point(pt: LatticePoint):
        return LatticeHash(pt.x, pt.y)


with open('2021/23/input_2.txt') as f:
    grid = Grid.from_list_of_strings(f.read().splitlines())
wall_positions = grid.char_positions('# ')
walls = {
    LatticeHash.from_point(pos)
    for char in wall_positions for pos in wall_positions[char]
}
ROOM_SIZE = grid.height - 3


class Amphipod:
    MOVE_COST = {'A': 1, 'B': 10, 'C': 100, 'D': 1000}
    BANNED_POSITIONS = {
        LatticeHash(3, 1),
        LatticeHash(5, 1),
        LatticeHash(7, 1),
        LatticeHash(9, 1)
示例#8
0
    grid_copy = g.copy()
    for pt in g:
        adj = pt.get_adjacent_points(diagonals=True,
                                     lower_bound=g._offset,
                                     upper_bound=g._offset + g.bounds)
        count = len([a for a in adj if g[a].rep == '#'])
        if g[pt].rep == '.':
            if count == 3:
                grid_copy[pt].rep = '#'
        else:
            if count not in {2, 3}:
                grid_copy[pt].rep = '.'
    g = grid_copy
print('Result 1:', len([str(pt) for pt in g.char_positions('#')['#']]))

g = Grid.from_list_of_strings(layout, offset=Point(-3, -3))
side = len(layout[0]) + ITERATIONS * 2
min_, max_ = -side // 2 + 1, side // 2 + 1

mat = [[[[
    g[Point(x, y)].rep if z == w == 0 and Point(x, y) in g else '.'
    for x in range(min_, max_)
] for y in range(min_, max_)] for z in range(min_, max_)]
       for w in range(min_, max_)]
min_bound, max_bound = PointND([0, 0, 0, 0]), PointND([20, 20, 20, 20])
bounds_function = lambda pt: min_bound <= pt < max_bound

final_count = len(g.char_positions(['#'])['#'])
for i in range(ITERATIONS):
    print(f'Count after {i} rounds is {final_count}')
    mat_copy = deepcopy(mat)
示例#9
0
    def __init__(self,pos:Point,grid_serial:int):
        self._pos = pos
        self._grid_serial = grid_serial
        self.rack_id = pos.x + 10
        self.power = (pos.y * self.rack_id + grid_serial) * self.rack_id // 100 % 10 - 5

    def copy(self):
        return FuelCell(self._pos,self._grid_serial)

input = 9798
BOUNDS = Point(300,300)

values = [[FuelCell(Point(x,y),input) for x in range(BOUNDS.x)] for y in range(BOUNDS.y)]
# values = [[Location(x,y,Location.OPEN,rep=FuelCell(Point(x,y),input)) for x in range(BOUNDS.x)] for y in range(BOUNDS.y)]

g = Grid(values)
largest = (0,Point(0,0))
for x in range(BOUNDS.x-3):
    for y in range(BOUNDS.y-3):
        sg = g.subgrid(Point(x,y),Point(x+3,y+3))
        value = 0
        for pos in sg:
            value += pos.power
        current = (value,Point(x,y))
        largest = max(largest,current)
print(largest[1])



starting_size = 1
for s in range(starting_size,20):
示例#10
0
        return pos

class Bot:
    def __init__(self,dir:str,pos:int,track_length:int):
        self.dir = dir
        self.pos = pos
        self.track_size = track_length

    def step(self):
        if self.dir == 'c':
            self.pos = (self.pos + 1) % self.track_size
        elif self.dir == 'ac':
            self.pos = (self.pos - 1) % self.track_size

with open(input) as f:
    grid = Grid.from_list_of_strings([line.strip('\n') for line in f])
    for loc in grid:
        if loc.rep in '^v<>':
            u = loc.up() in grid and grid[loc.up()].rep in '|+'
            d = loc.down() in grid and grid[loc.down()].rep in '|+'
            l = loc.left() in grid and grid[loc.left()].rep in '-+'
            r = loc.right() in grid and grid[loc.right()].rep in '-+'
            v = u and d
            h = l and r
            if v and h:
                loc.rep = '+'
            elif v:
                loc.rep = '|'
            elif h:
                loc.rep = '-'
            else:
示例#11
0
# Written by Cameron Haddock
# Written as a solution for Advent of Code 2020

# https://adventofcode.com/2020/day/11

from fishpy.geometry import Point
from fishpy.pathfinding.grid import Grid

with open('2020/11/input.txt', 'r') as input_file:
    lines = [line.strip() for line in input_file]
grid1 = Grid.from_list_of_strings(lines, wall_char='')
grid2 = grid1.copy()

while True:
    copy = grid1.copy()
    for pt in copy:
        if pt.rep == '.':
            continue
        count_occupied = 0
        is_empty = pt.rep == 'L'
        for adj in pt.get_adjacent_points(diagonals=True,
                                          lower_bound=Point(0, 0),
                                          upper_bound=grid1.bounds):
            if grid1[adj].rep == '#':
                count_occupied += 1
        if is_empty and count_occupied == 0:
            pt.rep = '#'
        elif not is_empty and count_occupied >= 4:
            pt.rep = 'L'
    if grid1 == copy:
        break