Skip to content

Commit 3ace4b2

Browse files
JustCallMeRayKatieLGrjones151jonaelliott-lgtm
authored
Group 1 code
Co-authored-by: Katie Gardner <KatieLG@users.noreply.github.com> Co-authored-by: rjones151 <rjones151@users.noreply.github.com> Co-authored-by: jonaelliott-lgtm <jonaelliott-lgtm@users.noreply.github.com>
1 parent a2fe6a0 commit 3ace4b2

2 files changed

Lines changed: 110 additions & 0 deletions

File tree

2025-11-26/Group-1/main.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""
2+
A polyomino is a 2D shape formed by joining squares along common edges,
3+
such that all squares are connected.
4+
5+
Output each possible polyomino (including every rotation),
6+
up to a size of 6,
7+
in any order.
8+
9+
Separate each polyomino by an empty line.
10+
11+
There should be a total of
12+
1 monomino, #
13+
2 dominoes, ## (and rotated)
14+
6 trominoes,
15+
19 tetrominoes,
16+
63 pentominoes,
17+
and 216 hexominoes.
18+
"""
19+
20+
from __future__ import annotations
21+
22+
from functools import cache
23+
from typing import NamedTuple, Sequence
24+
from dataclasses import dataclass
25+
26+
@dataclass
27+
class Vector:
28+
x: int
29+
y: int
30+
31+
def __hash__(self):
32+
return hash((self.x, self.y))
33+
34+
def __add__(self, other: Vector) -> Vector:
35+
return Vector(self.x + other.x, self.y + other.y)
36+
37+
def __iadd__(self, other: Vector) -> Vector:
38+
self.x += other.x
39+
self.y += other.y
40+
return self
41+
42+
def __sub__(self, other: Vector) -> Vector:
43+
return Vector(self.x - other.x, self.y - other.y)
44+
45+
def __isub__(self, other: Vector) -> Vector:
46+
self.x -= other.x
47+
self.y -= other.y
48+
return self
49+
50+
51+
52+
def normalise_coords(*coords: tuple[Vector]) -> frozenset[Vector]:
53+
"""adjust coords to a 0,0 base"""
54+
min_x = min(c.x for c in coords)
55+
min_y = min(c.y for c in coords)
56+
return frozenset({c - Vector(min_x, min_y) for c in coords})
57+
58+
@dataclass(frozen=True)
59+
class Polyomino:
60+
coords: frozenset[Vector]
61+
62+
def __repr__(self):
63+
"""Adjust to a (0,0) smallest, and then put hashes in coord positions"""
64+
norm = self.coords
65+
max_x = max(c.x for c in norm)
66+
max_y = max(c.y for c in norm)
67+
grid = [[" " for col in range(max_x+1)]for col in range(max_y+1)]
68+
for c in norm:
69+
grid[c.y][c.x] = "#"
70+
return "\n".join("".join(map(str, row)) for row in reversed(grid))
71+
72+
moves = [Vector(-1, 0), Vector(0, -1), Vector(1, 0), Vector(0, 1)]
73+
74+
def is_valid(move: Vector, poly: Polyomino) -> bool:
75+
...
76+
77+
@cache
78+
def generate(n: int) -> set[Polyomino]:
79+
"""Generate each polyomino and return the list"""
80+
if n == 1:
81+
return {
82+
Polyomino((Vector(0, 0),))
83+
}
84+
else:
85+
previous = generate(n-1)
86+
result: set[Polyomino] = set()
87+
88+
for poly in previous:
89+
for coord in poly.coords:
90+
for move in moves:
91+
new_coord = coord + move
92+
if new_coord not in poly.coords:
93+
result.add(Polyomino(coords=normalise_coords(*poly.coords, new_coord)))
94+
return result
95+
96+
97+
def print_polyominos(to_print : Sequence[Polyomino]):
98+
string_reprs = {str(p) for p in to_print}
99+
print(f"{len(string_reprs)=} == {len(to_print)=}")
100+
assert len(string_reprs) == len(to_print)
101+
for p in to_print : print(p, end="\n\n")
102+
print(len(to_print))
103+
104+
105+
if __name__ == "__main__":
106+
n = int(input("What rank? "))
107+
# n = 8
108+
print_polyominos(generate(n))
109+
110+

2025-11-26/Group-2/main.py

Whitespace-only changes.

0 commit comments

Comments
 (0)