Esempio n. 1
0
	def neighbors(x: int, y: int) -> Set[Coord]:
		retVal = []
		if x > 0:
			retVal.append(Coord(x-1, y))
		if x < 127:
			retVal.append(Coord(x+1, y))
		if y > 0:
			retVal.append(Coord(x, y-1))
		if y < 127:
			retVal.append(Coord(x, y+1))
		return retVal
Esempio n. 2
0
def part1(inp: Set[Coord], cycles: int, size: int, p2 = False) -> int:
	while cycles > 0:
		current = inp.copy()
		next_set = set()
		for point in current:
			c = 0
			for n in point.full_neighbors():
				c2 = 0
				if n in current:
					c += 1
				elif 0 <= n.x < size and 0 <= n.y < size:
					c2 = [p for p in n.full_neighbors() if p in current]
					if len(c2) == 3:
						next_set.add(n)
			if c in [2, 3]:
				next_set.add(point)
		cycles -= 1
		inp = next_set.copy()
		if p2:
			inp.update({Coord(0, 0), Coord(0, 99), Coord(99, 99), Coord(99, 0)})
	return len(inp)
Esempio n. 3
0
def part1(inp: List[str]) -> str:
    retVal = ''
    retVal2 = 1
    loc = Coord(inp[0].index("|"), 0)
    max_y = len(inp)
    max_x = len(inp[0])
    direction = "s"
    directions = {
        "n": Coord(0, -1),
        "s": Coord(0, 1),
        "w": Coord(-1, 0),
        "e": Coord(1, 0)
    }
    opposites = {"n": "s", "s": "n", "w": "e", "e": "w"}
    loc = loc + directions[direction]
    uppers = list(string.ascii_uppercase)
    while max_x > loc.x >= 0 and max_y > loc.y >= 0:
        spot = inp[loc.y][loc.x]
        # print(loc)
        if spot == "+":
            # find which direction is next
            for k, v in directions.items():
                if k != direction and k != opposites[direction]:
                    n = inp[loc.y + v.y][loc.x + v.x]
                else:
                    n = ''
                if n in ["|", "-"]:
                    direction = k
                    break
                    # print(f"New direction: {direction}")
        elif spot == " ":
            # assert 0 == 1, f"We've strayed off the trail! {retVal}"
            return retVal, retVal2
        elif spot in uppers:
            retVal += spot
        elif spot == 'E':
            print(spot)
        loc = loc + directions[direction]
        retVal2 += 1
    return retVal, retVal2
Esempio n. 4
0
def part2(inp: str) -> int:
	
	def neighbors(x: int, y: int) -> Set[Coord]:
		retVal = []
		if x > 0:
			retVal.append(Coord(x-1, y))
		if x < 127:
			retVal.append(Coord(x+1, y))
		if y > 0:
			retVal.append(Coord(x, y-1))
		if y < 127:
			retVal.append(Coord(x, y+1))
		return retVal
	

	grid = part1(inp)
	grouped = []
	groups = 0
	x = y = 0
	while x < 128:
		while y < 128:
			if grid[y][x] == "1":
				point = Coord(x, y)
			else:
				y += 1
				continue
			if point not in grouped:
				groups += 1
			else:
				y += 1
				continue
			edges = [point]
			group = [point]
			while True:
				new_edges = []
				for p in group:
					try:
						new_edges.extend([z for z in neighbors(p.x, p.y) if grid[z.y][z.x] == "1" and z not in group and z not in new_edges])
					except IndexError:
						print(new_edges)
						return
				if not new_edges:
					break
				edges = new_edges.copy()
				group.extend(edges)
			grouped.extend(group)
			y += 1
		x += 1
		y = 0
	assert sum(x.count('1') for x in grid) == len(grouped), "Not all items were grouped"
	return groups
Esempio n. 5
0
def part2(inp: List[str]) -> int:
    on = {Coord(x, y): 0 for x in range(1000) for y in range(1000)}
    for line in inp:
        if line.count(" ") == 3:
            command, start, th, end = line.split()
        else:
            commanda, commandb, start, th, end = line.split()
            command = commanda + commandb
        start = [int(x) for x in start.split(',')]
        end = [int(x) for x in end.split(',')]
        if command == "toggle":
            for c in light_section(start, end):
                on[c] += 2
        elif command == "turnoff":
            for c in light_section(start, end):
                if on[c] > 0:
                    on[c] -= 1
        else:
            for c in light_section(start, end):
                on[c] += 1
    return sum(x for x in on.values())
Esempio n. 6
0
			if c in [2, 3]:
				next_set.add(point)
		cycles -= 1
		inp = next_set.copy()
		if p2:
			inp.update({Coord(0, 0), Coord(0, 99), Coord(99, 99), Coord(99, 0)})
	return len(inp)




TEST_DATA = """.#.#.#
...##.
#....#
..#...
#.#..#
####.."""


if __name__ == "__main__":
	import os, timeit
	FILE_DIR = os.path.dirname(os.path.abspath(__file__))
	with open(os.path.join(FILE_DIR, "day18.input")) as f:
		DATA = f.read().strip()
	DATA = DATA.split("\n")
	LIGHTS = {Coord(x, y) for y in range(len(DATA)) for x in range(len(DATA)) if DATA[x][y] == "#"}
	print(f"Part one: {part1(LIGHTS, 100, len(DATA))}") # not 9996, too high;
	LIGHTS = {Coord(x, y) for y in range(len(DATA)) for x in range(len(DATA)) if DATA[x][y] == "#"}
	LIGHTS.update({Coord(0, 0), Coord(0, 99), Coord(99, 99), Coord(99, 0)})
	print(f"Part two: {part1(LIGHTS, 100, len(DATA), True)}")
	# print(f"Time: {timeit.timeit('', setup='from __main__ import ', number = 1)}")
Esempio n. 7
0
def light_section(start: List[int], end: List[int]) -> Set[Coord]:
    for x in range(start[0], end[0] + 1):
        for y in range(start[1], end[1] + 1):
            yield Coord(x, y)