Skip to content

Instantly share code, notes, and snippets.

@jtaxen
Last active December 21, 2019 10:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jtaxen/e66aa053cf4b75a67febb1a04416a8c8 to your computer and use it in GitHub Desktop.
Save jtaxen/e66aa053cf4b75a67febb1a04416a8c8 to your computer and use it in GitHub Desktop.
Henriks korsord
"""
Vågrätt:
1. En tvåpotens (det vill säga 2n).
7. Har samma siffersumma som vågrätt 15.
8. Talet siffersumma är lika med talets sifferprodukt.
10. Det minsta talet vars alla siffror är jämna som är delbart med vågrätt 7.
12. En delare till lodrätt 5.
14. Ett kvadrattal (det vill säga n2).
15. Alla siffrorna i talet är likadana.
16. Lodrätt 2, ökat med 111.
Lodrätt:
2. Talet siffersumma är lika med talets sifferprodukt.
3. Ett primtal i kvadrat.
4. Vågrätt 8 + vågrätt 14 + vågrätt 15 + vågrätt 16 + lodrätt 5 + lodrätt 11
5. Delbart med vågrätt 12.
6. Lodrätt 2 baklänges multiplicerat med vågrätt 16 baklänges, baklänges.
8. Vågrätt 15 + vågrätt 15 + vågrätt 15 + siffersumman för vågrätt 15
9. Delare till lodrätt 8.
11. Vågrätt 16 dubblat.
13. Ett kvadrattal.
"""
from math import sqrt
from functools import reduce
class Crossword:
def __init__(self):
across = [1, 7, 8, 10, 12, 14, 15, 16]
down = [2, 3, 4, 5, 6, 8, 9, 11, 13]
self.clues = ['a%i' % a for a in across] + ['d%i' % d for d in down]
for c in self.clues:
setattr(self, c, None)
def verify(self):
"""Run all clue tests and list the ones that fail. Return True if no test fails."""
results = []
for clue in self.clues:
clue_method = getattr(self, 'clue_%s' % clue)
clue_value = getattr(self, clue)
try:
result = clue_method()
except (ValueError, TypeError):
result = False
result_string = 'Clue %s:%s\t....%s' % (clue, clue_value, result)
print(result_string)
results.append(result)
if all(results):
print('All clues are consistent')
else:
print('%i clues are not consistent' % results.count(False))
return all(results)
def set(self, clue, value):
"""Verify that the value of a clue is consistent
and set it if it is. If not, raise InconsistencyError.
param clue: Name of the clue as string
param value: Value to assign if it is consistant with the clue
"""
attribute = getattr(self, clue)
checker = getattr(self, 'clue_%s' % clue)
if checker(value):
try:
setattr(self, clue, value)
except (ValueError, TypeError):
raise InconsistencyError(clue)
else:
raise InconsistencyError(clue)
@classmethod
def _digit_sum(cls, x):
"""Return the sum of the digits of x"""
return sum(int(c) for c in str(x))
@classmethod
def _digit_product(cls, x):
"""Return the product of the digits of x"""
return reduce(lambda x, y: x * y, [int(i) for i in str(x)])
@classmethod
def _is_even(cls, x):
"""Return True if x if even"""
return x % 2 == 0
@classmethod
def _digit_list(cls, x):
"""Return the digits of x as a list"""
return [int(i) for i in str(x)]
@classmethod
def _is_prime(cls, x):
"""Return True if x if a prime"""
return all(x % i == 0 for i in range(2, x))
@classmethod
def _is_square(cls, x):
"""Return True if x is a square number"""
return int(sqrt(x))**2 == x
@classmethod
def _flip_backwards(cls, x):
"""Reverse the order of the digits of x"""
return int(str(x)[::-1])
def clue_a1(self, x=None):
"""En tvåpotens (det vill säga 2n)"""
if not x:
x = self.a1
return x == 0 or bin(x).count('1') == 1
def clue_a7(self, x=None):
"""Har samma siffersumma som vågrätt 15"""
if not x:
x = self.a7
return self._digit_sum(x) == self._digit_sum(self.a15)
def clue_a8(self, x=None):
"""Talets siffersumma är lika med talets sifferprodukt"""
if not x:
x = self.a8
return self._digit_sum(x) == self._digit_product(x)
def clue_a10(self, x=None):
"""Det minsta talet vars alla siffror är jämna som är delbart med vågrätt 7"""
if not x:
x = self.a8
return all(self._is_even(i) for i in self._digit_list(x)) and x % self.a7 == 0
def clue_a12(self, x=None):
"""En delare till lodrätt 5"""
if not x:
x = self.a12
return self.d5 % x == 0
def clue_a14(self, x=None):
"""Ett kvadrattal (det vill säga n2)"""
if not x:
x = self.a14
return int(sqrt(x))**2 == x
def clue_a15(self, x=None):
"""Alla siffrorna i talet är likadana"""
if not x:
x = self.a15
x = self._digit_list(x)
return all(i == x[0] for i in x)
def clue_a16(self, x=None):
"""Lodrätt 2, ökat med 111"""
if not x:
x = self.a16
return x == self.d2 + 111
def clue_d2(self, x=None):
"""Talets siffersumma är lika med talets sifferprodukt"""
if not x:
x = self.d2
return self._digit_sum(x) == self._digit_product(x)
def clue_d3(self, x=None):
"""Ett primtal i kvadrat"""
return self._is_prime(int(sqrt(x))) and self._is_square(x)
def clue_d4(self, x=None):
"""Vågrätt 8 + vårätt 14 + vågrätt 15 + vågrätt 16 + lodrätt 5 + lodrätt 11"""
if not x:
x = self.d4
return x == self.a8 + self.a14 + self.a15 + self.a16 + self.d5 + self.d11
def clue_d5(self, x=None):
"""Delbart med vågrätt 12"""
if not x:
x = self.d5
return x % self.a12 == 0
def clue_d6(self, x=None):
"""Lodrätt 2 baklänges multiplicerat med vågrätt 16 baklänges, baklänges"""
if not x:
x = self.d6
return self._flip_backwards(self._flip_backwards(self.d2) * self._flip_backwards(self.a16)) == x
def clue_d8(self, x=None):
"""Vågrätt 15 + Vågrätt 15 + Vågrätt 15 + siffersumman för vågrätt 15"""
if not x:
x = self.d8
return 3 * self.a15 + self._digit_sum(self.a15) == x
def clue_d9(self, x=None):
"""Delare till lodrätt 8"""
if not x:
x = self.d9
return self.d8 % x == 0
def clue_d11(self, x=None):
"""Vågrätt 16 dubblat"""
if not x:
x = self.d11
return 2 * self.a16 == x
def clue_d13(self, x=None):
"""Ett kvadrattal"""
if not x:
x = self.d13
return self._is_square(x)
class InconsistencyError(Exception):
"""Raise if an assigned value to a clue is not consistnet with the clue's requirement"""
def __init__(clue, collides_with=None):
message = '%s is inconsistent' % clue
if collides_with:
collides_message = ' with clues %s' % ','.join(collides_with)
message += collides_with
super().__init__(message)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment