# Scrabblescrapers

An entry in Fortnightly Topic Challenge #48: Unusual tag mix

In this puzzle, you are given a 5x5 grid that you need to populate with a word square, so that the rows and columns form words (as defined by the UKACD dictionary), from left to right, and top to bottom, respectively. The clues given on the outside of the grid are Skyscrapers-style. Looking into the grid from the clue, the clue indicates the number of letters you can "see", where the "height" of a letter is defined by its English Scrabble value. As with Skyscrapers, a letter blocks the view of any letter behind it whose value is less than or equal it.

Solver Notes

• No words with punctuation can be used.
• No blank "wild" cells are allowed.
• You may use as many of any letters as you wish.
• This puzzle is meant to be solved with the aid of a computer. There is a solution path that does not involve exhaustive search, but I recommend automating lookups from the dictionary in some form.

The grid:

Text Version

  2 1 3 2 1
-----------
3| | | | | |1
-----------
3| | | | | |1
-----------
3| | | | | |3
-----------
2| | | | | |2
-----------
1| | | | | |2
-----------
1 3 2 1 3


## Process

I really wanted to try and solve this as manually as I could, but seeing how many possibilities there were after my first attempt (2997 for one row!), I soon realized this was almost impossible, so I fully automated (brute-forced) this solution.

### Dictionary Setup

I first processed the dictionary to filter all the five-letter words with only letters (no spaces or punctuation) and remove accents (to allow for mapping to letter scores) and saved this to a text file for later.

### Code Setup

First, I created a mapping of each letter to its score. I also created a function that would take a string and return a tuple based on its "skyscraper value" from either side, so a word from the first row would return (3, 1). I then created a list for the possible words for each skyscraper tuple found on the grid. I also set up lists to store the possible words for each row and each column.

### The Solve

Then, in a while loop that would print out the results on a keyboard interrupt (this code could have been cleaner), I wrote code that would iterate through each row. For each column, it would take the possible words for that row and make a set of the possible letters that could be in that column in the row (eg. if the possible words for a row were "tried", "tease", and "wrote", then the possible letters for the first column in that row would be "t" and "w"). It would then filter each column to keep only words that matched the possible letters for each column. I then repeated this, swapping rows and columns, and printed how many possible words there were for each row and column. Once I saw there was only one possibility for each row and column, I got that sweet, sweet answer!

### First Attempt

Trying to solve it at least a little bit manually, I made code to count how many possible rows there were with possible word in each column (satisfying the skyscrapers) that matched each letter (eg. "tests" in the first row would be satisfied by "toast", "egret", "salve", "taser", and "savor" in the corresponding columns). Running this once gave the following number of possibilities for the rows: 131, 258, 2, 2997, 310. This meant the middle row had to be "Egypt" or "schmo" (which it was).

I kept iterating over this process, eventually switching to columns and finding the possible letters for each spot in the column and filtering those out, similar to what I did in my final solution. I think my main issue was that I only used one list for all lines with a given skyscraper value (sky31 contained the possible words for the first and second rows), which meant there was some overlap. Eventually I ended up with "d" in the first column of the fifth row (which doesn't match the final solution), and filtering rows/columns to match that led to some rows and/or columns (I don't remember which) that no longer had any valid words meeting the new criteria. I tried filtering all but that specific case, but similar issues kept happening, so instead of trying to figure them out, I refactored my code to get the fully automated solve that got me the answer.

• @JeremyDover Let me know if I should add more information, but for now, I'm going to bed (it seems the best puzzling happens around 2AM XD) Jan 30 at 7:00
• This is the correct answer! This is plenty of explanation of how you did it, and certainly the reduction and alternation you describe is a component of the approach. But there are some logical steps you could use to greatly narrow the search space...any thoughts? Jan 30 at 13:23
• I added an explanation of my first attempt, which left only two possible words for one of the rows, but eventually this attempt broke down, so I switched to fully automating it Jan 30 at 16:19