This was one of the rare days, maybe the first one this year, where my code ran bug-free and gave the correct answer right when I ran it for the first time.
The hardest part was to formalize the fences:
Before I abstracted the directions as tuples in part 2, I hard-coded them and had a lot of code duplication.
import sys def extension(lines, i, j, x, acc): if not 0 <= i < len(lines): return set() if not 0 <= j < len(lines[i]): return set() if lines[i][j] != x: return set() if (i, j) in acc: return set() acc.add((i, j)) acc.update(extension(lines, i-1, j, x, acc)) acc.update(extension(lines, i+1, j, x, acc)) acc.update(extension(lines, i, j-1, x, acc)) acc.update(extension(lines, i, j+1, x, acc)) return acc def price(region): area = len(region) perimeter = area * 4 for i, j in region: if (i-1, j) in region: perimeter -= 1 if (i+1, j) in region: perimeter -= 1 if (i, j-1) in region: perimeter -= 1 if (i, j+1) in region: perimeter -= 1 return area * perimeter with open(sys.argv[1]) as f: lines = f.readlines() lines = [line.strip() for line in lines] s = 0 visited = set() for i in range(len(lines)): for j in range(len(lines[i])): if (i, j) in visited: continue region = extension(lines, i, j, lines[i][j], set()) s += price(region) visited.update(region) print(s)
import sys def extension(lines, i, j, x, acc): if not 0 <= i < len(lines): return set() if not 0 <= j < len(lines[i]): return set() if lines[i][j] != x: return set() if (i, j) in acc: return set() acc.add((i, j)) acc.update(extension(lines, i-1, j, x, acc)) acc.update(extension(lines, i+1, j, x, acc)) acc.update(extension(lines, i, j-1, x, acc)) acc.update(extension(lines, i, j+1, x, acc)) return acc def price(region): area = len(region) facing = {} facing[(-1, 0)] = set() facing[(+1, 0)] = set() facing[(0, -1)] = set() facing[(0, +1)] = set() for (i, j) in region: for ((diri, dirj), tiles) in facing.items(): if (i+diri, j+dirj) not in region: tiles.add((i, j)) sides = 0 for ((diri, dirj), tiles) in facing.items(): while len(tiles) != 0: i, j = tiles.pop() n = 1 while (i+n*dirj, j+n*diri) in tiles: tiles.remove((i+n*dirj, j+n*diri)) n += 1 n = 1 while (i-n*dirj, j-n*diri) in tiles: tiles.remove((i-n*dirj, j-n*diri)) n += 1 sides += 1 return area * sides with open(sys.argv[1]) as f: lines = f.readlines() lines = [line.strip() for line in lines] s = 0 visited = set() for i in range(len(lines)): for j in range(len(lines[i])): if (i, j) in visited: continue region = extension(lines, i, j, lines[i][j], set()) s += price(region) visited.update(region) print(s)
2024-12-12
text/gemini; lang=en
This content has been proxied by September (ba2dc).