Skip to content

Commit

Permalink
27
Browse files Browse the repository at this point in the history
  • Loading branch information
villares committed Oct 28, 2024
1 parent e56a830 commit b36c972
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 0 deletions.
Binary file added 2024/sketch_2024_10_27/free.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions 2024/sketch_2024_10_27/polyomino.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""
Based on a talk by Hamish Campbell
https://pyvideo.org/kiwi-pycon-2013/polyominoes-an-exploration-in-problem-solving-w.html
"""

from collections import namedtuple

import py5

Square = namedtuple('Square', 'x y')

class Polyomino(object):

REMOVE_MIRRORED = False

def __init__(self, iterable):
self.squares = tuple([Square(*s) for s in sorted(iterable)])

def __repr__(self):
return f'{self.__class__.__name__}({repr(self.squares)})'

def __iter__(self):
return iter(self.squares)

def __len__(self):
return len(self.squares)

def __eq__(self, other):
return hash(self) == hash(other)

def __lt__(self, other):
return self.squares < other.squares

def __hash__(self):
"""
Determine the hash (an integer "key/id" number)
it is the smaller number (hash) of the square tuples
of itself and its 3 rotated siblings
"""
p = self.translate()
h = hash(p.squares)
for _ in range(3):
p = p.rotate().translate()
h = min(h, hash(p.squares))
if self.REMOVE_MIRRORED:
f = self.flip().translate()
h = min(h, hash(f.squares))
for _ in range(3):
f = f.rotate().translate()
h = min(h, hash(f.squares))
return h

def rotate(self):
"""Return a Polyomino rotated clockwise"""
return Polyomino((-y, x) for x, y in self)

def flip(self):
"""Return a Shape flipped"""
return Polyomino((-x, y) for x, y in self)


def translate(self):
"""Return a Polyomino Translated to 0,0"""
minX = min(s.x for s in self)
minY = min(s.y for s in self)
return Polyomino((x - minX, y - minY) for x, y in self)

def raise_order(self):
"""Return a list of higher order Polyonominos evolved from self"""
polyominoes = []
for s in self:
adjacents = (adjacent for adjacent in (
(s.x + 1, s.y),
(s.x - 1, s.y),
(s.x, s.y + 1),
(s.x, s.y - 1),
) if adjacent not in self)
for adjacent in adjacents:
polyominoes.append(
Polyomino(list(self) + [adjacent])
)
return polyominoes

# def render(self):
# """
# Returns a string map representation of the Polyomino
# """
# p = self.translate()
# order = len(p)
# return ''.join(
# ['\n{}'.format(''.join(["X" if (x, y) in p.squares else "-"
# for x in range(order)]))
# for y in range(order)]
# )

def draw(self, w, c=False):
"""
draw
"""
p = self.translate()
#order = len(p)
with py5.push_matrix():
py5.color_mode(py5.HSB)
for i, (x, y) in enumerate(p.squares):
if c:
py5.fill(i * 24, 255, 200)
py5.rect(x * w, y *w, w, w)

Binary file added 2024/sketch_2024_10_27/sketch_2024_10_27.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions 2024/sketch_2024_10_27/sketch_2024_10_27.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from collections import Counter

import py5 # check out https://py5coding.org

from polyomino import Polyomino # Based on a talk by Hamish Campbell

M = 20 # margin
w = 5 # component square size


def setup():
py5.size(1850, 750)
py5.background(0)
# Polyomino.REMOVE_MIRRORED = True # generates 369 free octominoes
polyominoes = get_polyominoes(8, up_to=False) # 704 one-sided octominoes
print(len(polyominoes))

x, y = M, M
for i, p in enumerate(sorted(polyominoes, key=long), 1):
with py5.push_matrix():
py5.translate(x, y)
p.draw(w, c=True)
x += len(p) * w + w
if x > py5.width - w * len(p):
x = M
y += len(p) * w
if y > py5.height:
print(f'{i} of {len(polyominoes)}')
break

py5.save_frame('a.png')

def long(p):
xs, ys = zip(*p.squares)
return max(max(xs) - min(xs), max(ys) - min(ys))

def get_polyominoes(target, up_to=False):
order = 1
polyominoes = set([Polyomino(((0,0),))])
all_p = set([])
while order < target:
order += 1
next_order_polyominoes = set()
for polyomino in polyominoes:
next_order_polyominoes.update(polyomino.raise_order())
polyominoes = next_order_polyominoes
all_p.update(next_order_polyominoes)
if up_to:
return all_p
return polyominoes


py5.run_sketch()

10 changes: 10 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ Here are listed some of the tools I have been using more recently:
2024 \| [<b>2023</b>](2023.md) \| [<b>2022</b>](2022.md) \| [<b>2021</b>](2021.md) \| [<b>2020</b>](2020.md) \| [<b>2019</b>](2019.md) \| [<b>2018</b>](2018.md)


---

### sketch_2024_10_27

![sketch_2024_10_27](https://raw.githubusercontent.com/villares/sketch-a-day/main/2024/sketch_2024_10_27/sketch_2024_10_27.png)

[sketch_2024_10_27](https://github.com/villares/sketch-a-day/tree/main/2024/sketch_2024_10_27) [[py5](https://py5coding.org/)]

704 one-sided octominoes, using code inspired by a great talk by Hamish Campbell https://pyvideo.org/kiwi-pycon-2013/polyominoes-an-exploration-in-problem-solving-w.html

---

### sketch_2024_10_26
Expand Down

0 comments on commit b36c972

Please sign in to comment.