Group Abstract Group Abstract

Message Boards Message Boards

"Solving" a word combination lock

Posted 9 years ago

Maybe "solve" isn't quite the right word, but it still got me 90% of the way there...

My 7-year-old has one of those "word" locks for his bicycle — a cable lock whose combination has four dials, each with 10 different letters on it. Unfortunately, he didn't use the lock for several months, and when he tried to open it this morning he realized he had forgotten his combination.

We tried the obvious candidates: "poop," "burp," and so on. But nothing worked. I tried a few different physical hacks, but likewise without any success. But then I had an idea: we knew he had chosen a real word for his combination, and not just a random combination of 4 letters... so if I could generate a list of all the possible words you could make with the lock, maybe he'd spot something that would jar his memory.

I started out by typing the letters on each dial into a note on my phone, and emailed it to myself. Then I pasted that into Mathematica and assigned it to a variable:

In[10]:= letters = "B F r m d t s w p l  
E l o I a u y r w h  
K s n t m r e l a o 
L y p e t s m k g d ";

Then a little string processing:

In[11]:= dials = (ToLowerCase /@ StringSplit[#]) & /@ 
StringSplit[letters, "\n"]

Out[11]= {{"b", "f", "r", "m", "d", "t", "s", "w", "p", "l"}, {"e", 
"l", "o", "i", "a", "u", "y", "r", "w", "h"}, {"k", "s", "n", "t", 
"m", "r", "e", "l", "a", "o"}, {"l", "y", "p", "e", "t", "s", "m", 
"k", "g", "d"}}

Then get all the possible combinations of letters, taking one letter from each dial, and join them into strings:

In[12]:= tup = Tuples[dials];    
In[13]:= strings = StringJoin /@ tup;

And last, select all the words recognized by the internal spelling dictionary:

In[14]:= words = Select[strings, DictionaryWordQ];

So I ended up with a list of 843 words that we could easily scan through together... and amazingly enough, the forgotten combination happened to be within the first few dozen words of the resulting list.

In[17]:= Shallow[words]
Out[17]//Shallow= {"best", "bent", "bend", "bets", "berm", "berk", \
"berg", "beep", "beet", "bees", <<833>>}
POSTED BY: Alan Joyce
4 Replies

Another option is to sort words by their frequency of occurrence in the English language using WordFrequencyData:

sortedWords = SortBy[words, -WordFrequencyData[#] &]

This gives the following result:

 Shallow[sortedWords]     
{that,from,were,they,more,will,them,time,some,what,<<833>>}

We can then further say that it is more likely that the word will be a Noun or a Verb, so we can obtain just those using WordData as follows:

nounsAndVerbs=Select[sortedWords,Or@@(MemberQ[{"Noun","Verb"},#]&/@WordData[#][[All,2]])&]

Despite all of this, I would be very surprised if "were" were the most common password used by kids for their bikes

Shallow[nounsAndVerbs]
{were,will,time,like,must,well,work,make,part,long,<<735>>}
POSTED BY: Danny Finn
POSTED BY: Marco Thiel

enter image description here - another post of yours has been selected for the Staff Picks group, congratulations !

We are happy to see you at the top of the "Featured Contributor" board. Thank you for your wonderful contributions, and please keep them coming!

POSTED BY: EDITORIAL BOARD

I once did something similar! But then I also used FindShortestTour to move through all of them using the least amount of dial-movements (using periodicity to your advantage).... So in your example the 'distance' between B and p (first dial) would just be two; not 8.

quite a lot of 4 letter words btw!

POSTED BY: Sander Huisman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard