Created
May 20, 2023 09:22
-
-
Save plammens/da85ee64d47cba9f8e39eb82894ed437 to your computer and use it in GitHub Desktop.
Number of ways to cut pizza into identical-shaped pieces such that some do not touch the centre.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import itertools | |
import math | |
import typing | |
from collections import Counter | |
from sympy import factorint | |
def submultisets(multiset: Counter) -> typing.Iterable[Counter]: | |
for counts in itertools.product(*[range(count + 1) for count in multiset.values()]): | |
yield Counter({element: count for element, count in zip(multiset, counts)}) | |
def factors_to_number(factors: Counter) -> int: | |
return math.prod(factors.elements()) | |
def parker_ways_to_cut_pizza(pieces: int): | |
assert pieces % 2 == 0, "The number of pieces must be even." | |
factors = Counter(factorint(pieces)) | |
del factors[2] # We can only make odd-sized grins. | |
for submultiset in submultisets(factors): | |
grin_size = factors_to_number(submultiset) | |
number_of_grins = 2 * grin_size | |
pieces_per_grin = pieces // number_of_grins | |
# A 1-grin doesn't exist (or is a circle), and we need to cut each grin in more | |
# than one piece so that some of them do not touch the centre (Parker cut). | |
if grin_size == 1 or pieces_per_grin == 1: | |
continue | |
print( | |
f"{number_of_grins} {grin_size}-grins cut into {pieces_per_grin} pieces each" | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment