wordclock/gen.py

136 lines
2.9 KiB
Python
Raw Permalink Normal View History

# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Generate the word to offset mapping for the clock."""
2018-11-30 17:38:29 +01:00
import pprint
import itertools
def parse_board(board: str) -> list:
return board.strip().split('\n')
def gen_order(w, h):
i = 0
lr = True
for y in range(h):
cells = [i + x for x in range(w)]
if not lr:
cells.reverse()
yield cells
i += len(cells)
lr = not lr
def gen_dict(fname: str):
with open(fname) as f:
for line in f:
for word in line.split():
yield word.lower().replace("'", "")
def gen_words(board, dictonary):
for y, row in enumerate(board):
for x in range(len(row)):
for j in range(x, len(row)):
word = row[x:j + 1]
if word in dictonary:
yield x, y, word
def gen_ranges(words, order):
for x, y, word in words:
row = order[y]
l, r = row[x], row[x + len(word) - 1]
yield word, min(l, r)
def gen_word_map(ranges):
return {x: y for x, y in ranges}
BOARD2 = """
ItsIs.AMPM
TwentyFIVE
QuarterTen
ToPast.One
TwoFourSix
Three.Five
SevenEight
NineEleven
TenTwelve.
"""
BOARD = """
ITSISASAMPM
ACQUARTERDC
TWENTYFIVEX
HALFSTENFTO
PASTERUNINE
ONESIXTHREE
FOURFIVETWO
EIGHTELEVEN
SEVENTWELVE
TENSEOCLOCK
"""
def pack(words, width=11):
best = None
for p in itertools.permutations(words):
rows = []
row = ''
for word in p:
if len(row) + len(word) <= width:
row += word
else:
rows.append(row)
row = word
rows.append(row)
if best is None:
best = [rows]
elif len(rows) <= len(best[0]):
best = [rows]
yield rows
def fill(words, width=11):
todo = words
rows = []
while todo:
row = ''
t = []
for word in todo:
if len(row) + len(word) <= width:
row += word
else:
t.append(word)
rows.append(row)
todo = t
return rows
def main():
board = parse_board(BOARD.lower())
order = list(gen_order(len(board[0]), len(board)))
d = set(gen_dict('/usr/share/dict/words'))
d.add('twentyfive')
words = list(gen_words(board, d))
ranges = gen_ranges(words, order)
word_map = {x: y for x, y in ranges}
print('RANGES = %s' % word_map)
main()