Crossword puzzle solver

Write codeHard40 min

Your task

A puzzle tool fills a fixed crossword frame. grid_rows draws the frame one row at a time, every row the same width, where a hash marks a blocked square and a dot marks a square to be filled. A slot is a run of two or more dots bounded by a wall or a blocked square, read across a row or down a column, and every dot lies in at least one slot. Each slot takes one word from words, a word is used at most once, the word length must match the slot length, and two crossing slots must agree on the letter they share. The words are distinct and may outnumber the slots. Return the finished frame as its rows, and when several fillings work return the one whose rows, joined in order, come first alphabetically. A frame with no slots is already finished, so return it unchanged. Return an empty list when no filling works and when the frame has no rows. The frame is at most 5 by 5 and words holds at most 12 entries.

Examples

fill_crossword_slots(grid_rows: list[str], words: list[str]) -> list[str]
Example 1
Inputfill_crossword_slots(["..", ".."], ["at", "no", "an", "to"])
Output["an", "to"]
Example 2
Inputfill_crossword_slots(["...", ".#.", "..."], ["cat", "cow", "wet", "tot"])
Output["cat", "o#o", "wet"]
Example 3
Inputfill_crossword_slots(["...."], ["abcd", "abce"])
Output["abcd"]