4 # formats: ipynb,py:light
8 # format_version: '1.5'
9 # jupytext_version: 1.11.1
11 # display_name: Python 3 (ipykernel)
16 # # Honeycomb letter puzzle
17 # Solving the puzzle as posted on [FiveThirtyEight](https://fivethirtyeight.com/features/can-you-solve-the-vexing-vexillology/), also solved by [David Robinson](http://varianceexplained.org/r/honeycomb-puzzle/).
22 from dataclasses
import dataclass
27 with
open('enable1.txt') as f
:
28 words
= [line
.strip() for line
in f
]
30 words
= set(w
for w
in words
32 if len(frozenset(w
)) <= 7
35 word_sets
= collections
.defaultdict(set)
37 letters
= frozenset(w
)
38 word_sets
[letters
].add(w
)
43 for l
in string
.ascii_lowercase
:
50 def decode(letter_bits
):
52 for l
in string
.ascii_lowercase
:
59 def subset(this
, that
):
60 return this
& that
== this
63 @dataclass(frozen
=True, init
=False)
68 def __init__(self
, mandatory
, letters
):
69 object.__setattr
__(self
, 'mandatory', encode(mandatory
))
70 object.__setattr
__(self
, 'letters', encode(letters
))
73 return f
'{"".join(decode(self.mandatory))}|{"".join(sorted(decode(self.letters) - set(decode(self.mandatory))))}'
76 def present(target
, honeycomb
):
77 return (subset(honeycomb
.mandatory
, target
)
78 and subset(target
, honeycomb
.letters
))
81 def score(present_set
):
83 for w
in word_sets
[present_set
]:
88 if len(present_set
) == 7:
89 score
+= len(word_sets
[present_set
]) * 7
93 scored_sets
= {s
: score(s
) for s
in word_sets
}
94 encoded_scored_sets
= {encode(s
): scored_sets
[s
] for s
in scored_sets
}
97 def raw_score_honeycomb(honeycomb
):
98 return sum(sc
for letters
, sc
in scored_sets
.items()
99 # if honeycomb.mandatory in letters
100 # if letters.issubset(honeycomb.letters)
101 if present(letters
, honeycomb
)
105 def score_honeycomb(honeycomb
):
106 return sum(sc
for letters
, sc
in encoded_scored_sets
.items()
107 # if honeycomb.mandatory in letters
108 # if letters.issubset(honeycomb.letters)
109 if present(letters
, honeycomb
)
113 pangram_sets
= [s
for s
in word_sets
.keys() if len(s
) == 7 if 's' not in s
]
115 with
open('pangaram_words.txt', 'w') as f
:
116 for s
in pangram_sets
:
117 for w
in word_sets
[s
]:
123 # for ps in pangram_sets:
125 # ps_honeycombs.append(Honeycomb(mandatory=mand, letters=ps))
127 ps_honeycombs
= [Honeycomb(mandatory
=mand
, letters
=ps
)
128 for ps
in pangram_sets
132 partitioned_scored_sets
= {encode(l
): {s
: encoded_scored_sets
[s
]
133 for s
in encoded_scored_sets
134 if subset(encode(l
), s
)}
135 for l
in string
.ascii_lowercase
}
138 def partitioned_score_honeycomb(honeycomb
):
139 return sum(sc
for letters
, sc
in partitioned_scored_sets
[honeycomb
.mandatory
].items()
140 if subset(letters
, honeycomb
.letters
)
146 best_honyecomb
= max(ps_honeycombs
, key
=partitioned_score_honeycomb
)
147 print(best_honyecomb
, partitioned_score_honeycomb(best_honyecomb
))
151 # best_honyecomb = max(ps_honeycombs, key=score_honeycomb)
152 # print(best_honyecomb, score_honeycomb(best_honyecomb))
155 # cProfile.run('max(ps_honeycombs, key=score_honeycomb)')
159 # cProfile.run('max(ps_honeycombs, key=partitioned_score_honeycomb)')