Shop OBEX P1 Docs P2 Docs Learn Events
Friday Quiz #5 (REAL PRIZE!) — Parallax Forums

Friday Quiz #5 (REAL PRIZE!)

Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
edited 2017-03-26 06:44 in General Discussion
Okay boyz 'n' girlz, this is a tough one, so fasten your seat belts!

I've given laser-cut wooden sliding tile puzzles as gifts recently. One, in particular, involves sliding letter tiles in a 4x4 grid to form eight common English words: 4 across (left-to-right), with 4 down (top-to-bottom), simultaneously. There are 15 tiles and a grid of 16 letters that they slide over. So there's always a blank space over the grid of letters, whose revealed letter is part of the answer. (Only one person has solved it, so far.)

But I'm going to make it easy on you guys. Rather than requiring the tiles to slide, you can just place them atop the grid, however you wish, to solve the puzzle.

Whoever posts the first correct solution as a 4x4 grid of common English words will receive an original wooden version of the sliding tile puzzle, sent for free by postal mail anywhere in the world (except to countries that the U.S. government prohibits me to send stuff).

Here are the tiles and the underlying grid:

tile_puzzle.gif

Unlike with the other Friday puzzles, I will not be posting an answer if no one gets it after a certain amount of time. It's up to one of you to do that and to reap the reward.

Knock yourselves out!

-Phil
692 x 388 - 25K

Comments

  • ceptimusceptimus Posts: 135
    edited 2017-03-26 17:58
    First one I've found - valid dictionary words but not common ones:
    N A G S
    E C r U
    W H I M
    T Y P O
    

    ecru [adjective] very light brown in colour, as raw silk, unbleached linen, etc.
  • What happened Phil give up on antiques and go to brain teasers?
  • ceptimus wrote:
    First one I've found - valid dictionary words but not common ones:
    Amazing! That's the correct answer. How did you do it so quickly?

    PM me your mailing address, and I'll send you your prize.

    -Phil
  • MikeDYur wrote:
    What happened Phil give up on antiques and go to brain teasers?

    I had expected it to be programming exercise.

    -Phil
  • ercoerco Posts: 20,257
    Nice puzzle and solution! Congrats ceptimus on such a speedy win. I knew there some clever folks here, but that was amazingly fast.

    While we're on word puzzles, I'll mention a favorite of mine. Heard it from a radio station and I won concert tickets many moons ago. Take the word:

    SPARKLING

    and remove one letter to leave a legit word intact. No rearranging letters. Keep removing one letter, leaving a legit word, all the way down to one letter.

    Go forth and multiply subtract.
  • ceptimusceptimus Posts: 135
    edited 2017-03-26 17:47
    Some more with (very) obscure words:
    G I M P
    E C O L <- L is the missing tile
    S H W A
    T U N Y
    
    G I M P
    U N A L <- L is the missing tile
    S C Y E
    T H O W
    
    T Y P W
    H U r E
    I C O N
    G A M S
    
    U N C T
    M A r O
    P I E S
    H G W Y
    

    Oops. Didn't read the posts above! This was a search with a bigger dictionary that includes abbreviations like hgwy for 'highway'.
  • MikeDYur wrote:
    What happened Phil give up on antiques and go to brain teasers?

    I had expected it to be programming exercise.

    -Phil


    Leave it to me to do it the hard way. ;)
  • ceptimusceptimus Posts: 135
    edited 2017-03-26 17:56
    ceptimus wrote:
    First one I've found - valid dictionary words but not common ones:
    Amazing! That's the correct answer. How did you do it so quickly?

    PM me your mailing address, and I'll send you your prize.

    -Phil
    Thanks! :blush: I've written programs for solving puzzles before - things like polyominoes - most are just tweaks on a recursive search.

    Also I had a ready made list of words for my online word ladder (doublets) solver.

    So I quickly hacked a program together in C# and let it do the hard work. :D
  • ercoerco Posts: 20,257
    Phil & ceptimus: You could probably make a profit selling a bawdy version of this slide puzzle with non-PC four-letter words. :)
  • ceptimusceptimus Posts: 135
    edited 2017-03-26 20:04
    Here's the code:
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    
    namespace PhiPiQuiz
    {
        class Program
        {
            static HashSet<String> _2letter = new HashSet<string>();
            static HashSet<String> _3letter = new HashSet<string>();
            static HashSet<String> _4letter = new HashSet<string>();
            static char[] grid;
            static char[] tiles = { 'a', 'c', 'e', 'g', 'h', 'i', 'm', 'n', 'o', 'p', 's', 't', 'u', 'w', 'y', ' ' };
            static char[] under = { 'r', 'f', 'b', 'd', 'b', 'j', 'r', 'l', 'l', 'v', 'd', 'f', 'd', 'k', 'l', 'r' };
            static bool[] used;
            static int posn = 0;
            static int solutions = 0;
    
            static void show()
            {
                for (int i = 0; i < 16; i++)
                {
                    Console.Write(grid[i]);
                    Console.Write(' ');
                    if ((i - 3) % 4 == 0)
                    {
                        Console.Write("\n");
                    }
                }
                Console.Write("\n");
            }
    
            static bool checkRow() // row check - only check current row as any rows above will already have been checked
            {
                int length = posn % 4 + 1;
                if (length == 1) return true; // there are four letter words starting with each letter of the alphabet
                int start = (posn / 4) * 4;
                string word = "";
                for (int i = start; i <= posn; i++)
                {
                    word += grid[i];
                }
                word = word.ToLower();
    
                if (length == 2) return _2letter.Contains(word);
                else if (length == 3) return _3letter.Contains(word);
                return _4letter.Contains(word);
            }
    
            static bool checkCol() // column check - only check current column as any columns to left will already have been checked
            {
                int start = posn % 4;
                int length = (posn - start) / 4 + 1;
                if (length == 1) return true; // there are four letter words starting with each letter of the alphabet
                string word = "";
                for (int i = start; i <= posn; i += 4)
                {
                    word += grid[i];
                }
                word = word.ToLower();
                if (length == 2) return _2letter.Contains(word);
                else if (length == 3) return _3letter.Contains(word);
                return _4letter.Contains(word);
            }
    
            static void fit()
            {
                if (posn == 16) // solution found
                {
                    Console.WriteLine("Solution {0}:", ++solutions);
                    show();
                    return;
                }
    
                for (int choice = 0; choice < 16; choice++)
                {
                    if (used[choice]) continue;
    
                    used[choice] = true;
                    grid[posn] = choice == 15 ? under[posn] : (char)(tiles[choice] - 32);
                    if (checkRow() && checkCol()) // check if currently fitted letters might form valid words
                    {
                        posn++;
                        fit();
                        posn--;
                    }
                    grid[posn] = under[posn];
                    used[choice] = false;
                }
            }
    
    
    
            static void Main(string[] args)
            {
                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();
    
                char[] delimiterChars = { ' ', '\n', '\t' };
    
    #if true // swap to false for bigger word list
                string fourLetterWords = System.IO.File.ReadAllText(@"fourLetterWords.txt");
                string[] words = fourLetterWords.Split(delimiterChars);
    #else
                string wordsFile = System.IO.File.ReadAllText(@"words.txt");
                string[] allWords = wordsFile.Split(delimiterChars);
                int count = 0;
                for (int i = 0; i < allWords.Length; i++)
                    if (allWords[i].Length == 4)
                        count++;
    
                string[] words = new string[count];
                count = 0;
                for (int i = 0; i < allWords.Length; i++)
                    if (allWords[i].Length == 4)
                        words[count++] = allWords[i];
    #endif
                Console.WriteLine("Words in dictionary:{0}\n", words.Length);
    
                // build one HashSet for the four letter words; another for three-letter starts to the words; and a third for the two-letter starts
                // it's much faster to check if a word exists in a HashSet than to search through an array of words
                foreach (string word in words)
                {
                    word = word.ToLower(); // some words in the bigger dictionary have capital letters
                    _4letter.Add(word);
                    string s = word.Substring(0, 3);
                    if (!_3letter.Contains(s)) _3letter.Add(s);
                    s = s.Substring(0, 2);
                    if (!_2letter.Contains(s)) _2letter.Add(s);
                }
    
                grid = new char[16];
                used = new bool[16];
    
                for (int i = 0; i < 16; i++)
                {
                    grid[i] = under[i];
                    used[i] = false;
                }
    
                posn = 0;
                
                fit();
    
    
                stopWatch.Stop();
                TimeSpan ts = stopWatch.Elapsed;
                string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                    ts.Hours, ts.Minutes, ts.Seconds,
                    ts.Milliseconds / 10);
                Console.WriteLine("Solutions found: {0}  in run time: {1}\nPress Enter to close", solutions, elapsedTime);
                Console.ReadLine(); // wait for return to be pressed before closing console
            }
        }
    }
    

    Here's the output:
    Words in dictionary:4030
    
    Solution 1:
    N A G S
    E C r U
    W H I M
    T Y P O
    
    Solutions found: 1  in run time: 00:00:01.66
    Press Enter to close
    

    Amazing how fast computers are. Less than two seconds run time, and that on a fairly lowly AMD A8-5500 @ 3.2 GHz. With the bigger 6759-word dictionary, it took 10.8 seconds to find and display the 5 solutions.

    I've attached the fourLetterWords.txt file if anyone wants to try it out for themselves - you need to put that file in the same folder where you compile your program. It should work okay with most versions of Visual Studio - you just need to start a new project as a c# console application and paste the above listing in - I'm using the (free) Visual Studio Community 2015 edition on this PC - I suppose I should really update it to a newer free version.
  • @ erco


    SPARKLING
    SPARLING (fish)
    SPARING
    SPRING
    PRING (vertical movement)
    RING
    RIN (Japanese money)
    IN
    I

    Dave
  • ceptimusceptimus Posts: 135
    edited 2017-03-26 20:30
    Another way.

    sparkling
    sparking
    sparing
    paring
    pring - sound made by a bell
    ping
    pig
    pi
    i
  • ceptimus,

    Thanks for sharing your code! 'Tis truly a tour de force -- in short order, too!

    For all of you lexophiles out there, this puzzle's solution is a heterogram, which means that no letter is used more than once. 4x4 English heterograms are quite rare. A 5x5 is reputed to be impossible. But think about it: 26 letters in the alphabet, and you'd have to use all but one of them. Plus, with six possible vowels, almost every one would have to be shared between two words.

    -Phil
  • ercoerco Posts: 20,257
    PRING?
    RIN?

    Dunno nuttin' 'bout doze. Here's what I did...

    Sparkling
    Sparking
    Sparing
    Spring
    Sprig
    Prig
    Pig
    Pi
    I
  • yep
    Sparkling
    Sparking
    Sparing
    Spring
    Sprig
    Prig
    Pig
    Pi
    I


    much nicer

    dave
  • You guys have it all wrong! Here's my list:

    Sparkling (a way of describing a decent gin and tonic)
    Parkling (one of those very small cars that you can't see when you think there's a space available)
    Arkling (a small ark, able to hold two of only few species)
    Arking (how Noah is said to have spent the rainy season once)
    Aking (what city folks are after a strenuous workout)
    Akin (what country folks are after a strenuous workout)
    Kin (thos'ns that convention says you have to include in your will, even if you don't want to)
    Ki (prefix to "yi yippy ki yay")
    K (what you text when you mean "yes")

    -Phil
  • ercoerco Posts: 20,257
    You guys have it all wrong! Here's my list:

    Ki (prefix to "yippy ki yay")

    -Phil

    By that logic, Fo is also a real word... :)

    As in Fee fi fo fum, mods...

  • ceptimusceptimus Posts: 135
    edited 2017-04-04 09:55
    I received my prize from Phil in the mail this morning :smile: Thanks Phil!

    It's beautifully made with interlocking pieces that can't fall out. Instructions and additional information are laser engraved on the back.

    PhiPiPuzzle.jpg

    It would be an interesting exercise to write a program to search for similar puzzles with unique solutions. If no one else wishes to tackle it, I may have a go myself after a couple of weeks (I'm deep into a different programming project right now).

    With a sliding block puzzle like this there is parity involved - exactly half of the positions that can be obtained by freely swapping blocks can be obtained by sliding the blocks, and the remaining half of the 'free swap' positions can't be reached. The classic example is the '15 puzzle' with fifteen sliding blocks numbered 1 to 15: by taking out and swapping, say, the '14' and '15' blocks, the conventional solution arrangement becomes unreachable. When computer searching for solutions then any odd number of block swaps gives an unreachable position and any even number of swaps generates a position that can be reached.

    With Phil's letter version of the puzzle, this opens up the possibility of using two sliding blocks with the same letter - that would mean that there would never be any tantalizing solutions that could be reached by freely placing the blocks but not by sliding them. :smile:

    640 x 622 - 107K
  • ercoerco Posts: 20,257
    Beautimus, ceptimus!
  • That is gorgeous.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2017-04-04 18:37
    You're welcome, ceptimus! 'Glad it arrived safely.

    Regarding the parity issue, I made sure to assemble the puzzle originally with the solution in view, then to slide the blocks in order to scramble them. If I had placed the blocks in the puzzle at random, there would have been a 50% chance that it be unsolvable.

    Also, I had to redo the first of these puzzles I constructed. I had made the mistake of laying out the blocks to be laser cut in solution-order. Then I realized that the woodgrain pattern would be a dead giveaway to someone paying attention. So I had to scramble the blocks in CorelDraw before cutting them out.

    -Phil
Sign In or Register to comment.