Friday, March 29, 2013

Spoiler Alert (Sunday Puzzle From NPR)

This week's Sunday Puzzle challenge; which was due to be 
submitted yesterday at 3PM, and I missed the deadline :o( 
is:

Find a (the) five by five WORD SQUARE.
    A five letter word square consist of five five letter 
    words when written one after the other read the same 
    if you then read down the page (first letter of each 
    word is the first word, second letter of each word is 
    the second word etc...)

    The 'hint' for this weeks puzzel was the 'middle­-word' 
    is 'NASAL', and the ONLY vowel in each word is the 
    letter 'A'

    Another hint is a look at the following 
    four by four WORD SQUARE:

        SALT
        AFAR
        LAVA
        TRAP
.
.
.


(scroll down for solution - spoiler alert)

.
.
.

Here is a sentence made from the five words 
"Anna's and Alan's nyala, nasal, salsa." :) 
And here are the five words arranged in proper order.

    annas
    nyala
    nasal
    alans
    salsa


Note: I wrote a 'python­program' that searched 'the­list' 
of five letter words (8,938 words) and implemented a 
process that came up with the above five words :o).

# buildTheSquare
#
# Make A Word Square: Where middle row/col is 'nasal' 
# and only vowel in all words is 'a'
#   here is the five letter square
#   (0,0) (0,1) (-,n) (0,3) (0,4)
#   (0,1) (1,1) (-,a) (1,3) (1,4)
#   (-,n) (-,a) (-,s) (-,a) (-,l)
#   (0,3) (1,3) (-,a) (3,3) (3,4)
#   (0,4) (1,4) (-.l) (3,4) (4,4)
#
# - First create five lists:
#   [1] middle-letter-N-list
#   [2] middle-letter-A-list
#   [3] middle-letter-S-list (actually not needed)
#   [4] middle-letter-A-list (same as above)
#   [5] middle-letter-L-list  
# - Then follow this procedure
#   for each word in the 'middle-letter-N-list' 
    (And if we run out of words then there is NO 
    five letter word square)
#     set that word to be word-one
#     set the letters of that word to be the first 
      letter of each of the words, 2,3,4,5
#     set word-three to be 'nasal'
#     set the middle letter of each word to be 
      the letters 'n', 'a', 's', 'a', 'l'
#     for each word in the 'middle-letter-A-list' 
      (see if it will be word-two) 
      (if we run out of words then go to the next N word)
#       if the check the first letter for a match 
        from above fails try next word in this list
#       set the letters of the word to be the letters
#       .
#       . etcetera (see the code below) 
#       .
#
def buildTheSquare(midLtrNList, midLtrAList, 
midLtrSList, midLtrLList):
  print("enter buildTheSquare")
  #
  # for each word in the Middle-Letter-'N'-List 
    let it be 'word0'
  #
  for i, wordFromMidLtrNList in enumerate(midLtrNList):
    thisWord = []
    thisWord = list(wordFromMidLtrNList)
    word0 = []
    word0 = thisWord
    word1 = []
    word1 = list('--a--')
    word1[0] = word0[1]
    word2 = []
    word2 = list('nasal')
    word3 = []
    word3 = list('--a--')
    word3[0] = word0[3]
    word4 = []
    word4 = list('--l--')
    word4[0] = word0[4]
    #
    # for each word in the Middle-Letter-'A'-List 
      try to make it into 'word1'
    #
    for i,wordFromMidLtrAList in enumerate(midLtrAList):
      if wordFromMidLtrAList[0] != word1[0]:
        continue
      word1 = list(wordFromMidLtrAList)
      word3[1] = word1[3]
      word4[1] = word1[4]
      #
      # always pick 'nasal' from the 
        Middle-Letter-'S'-List for 'word2'
      #
      word2 = list('nasal')
      word3[2] = word2[3]
      word4[2] = word2[4]
      #
      # for each word in the Middle-Letter-'A'-List 
        try to make it into 'word3'
      # 
      for i,wordFromMidLtrAList in enumerate(midLtrAList):
        if wordFromMidLtrAList[0] != word3[0]:
          continue
        if wordFromMidLtrAList[1] != word3[1]:
          continue
        if wordFromMidLtrAList[2] != word3[2]:
          continue
        word3 = list(wordFromMidLtrAList)
        word4[3] = word3[4]
        #
        # for each word in the Middle-Letter-'L'-List 
          see if it can be 'word4'
        #
        for i,wordFromMidLtrLList in enumerate(midLtrLList):
          if wordFromMidLtrLList[0] != word4[0]:
            continue
          if wordFromMidLtrLList[1] != word4[1]:
            continue
          if wordFromMidLtrLList[2] != word4[2]:
            continue
          if wordFromMidLtrLList[3] != word4[3]:
            continue
          word4 = list(wordFromMidLtrLList)
          print ("Success!!")
          print ("word0 = {0}".format("".join(word0)))
          print ("word1 = {0}".format("".join(word1)))
          print ("word2 = {0}".format("".join(word2)))
          print ("word3 = {0}".format("".join(word3)))
          print ("word4 = {0}".format("".join(word4)))
          print ('done buildTheSquare')
          return
  print ("FAIL")
  print ('done buildTheSquare')

# build list with middle letters equal to 'n','a','s','a','l'
  and only containing the vowel 'a'
def buildIndividualWordLists(wodlist):
  print("enter buildIndividualWordLists")
  midLtrNList = []
  midLtrAList = []
  midLtrSList = []
  midLtrLList = []
  totalWordCount = 0
  for i, myWord in enumerate(wodlist):
    totalWordCount = totalWordCount + 1
    # only words with the vowel 'a'
    if ( (myWord.find('a')) == -1 or (myWord.find('e') != -1) or
         (myWord.find('i') != -1) or (myWord.find('o') != -1) or
         (myWord.find('u') != -1) ):
      continue
    # middle letter 'n', 'a', 's', 'l'
    if ( ('n' != myWord[2]) and ('a' != myWord[2]) and
         ('s' != myWord[2]) and ('l' != myWord[2]) ):
      continue
    # middle letter 'n'
    if ('n' == myWord[2]):
      midLtrNList.append(myWord)
      continue    
    # middle letter 'a'
    elif ('a' == myWord[2]):
      midLtrAList.append(myWord)
      continue    
    # middle letter 's'
    elif ('s' == myWord[2]):
      midLtrSList.append(myWord)
      continue    
    # middle letter 'l'
    else:
      midLtrLList.append(myWord)
      continue  
  print "total word count = {0}".format(totalWordCount)
  print "the number of middle letter N words wordCount = {0}".format(len(midLtrNList))
  print "the number of middle letter A words wordCount = {0}".format(len(midLtrAList))
  print "the number of middle letter S words wordCount = {0}".format(len(midLtrSList))
  print "the number of middle letter A words wordCount = {0}".format(len(midLtrAList))
  print "the number of middle letter L words wordCount = {0}".format(len(midLtrLList))
  buildTheSquare(midLtrNList, midLtrAList, midLtrSList, midLtrLList)
  print('Done buildIndividualWordLists')

# collectWords
#  Read Lines From The Input File And Build A List Of Words Found
#  Return The Built List
def collectWords( filename ):
  print('enter collectWords')
  wordlist = []
  f = open(filename)
  for line in f:
    wordlist.extend( line.split() )
  f.close()
  buildIndividualWordLists(wordlist)
  print('Done collectWords')

# Do It
if __name__ == "__main__":
  import sys
  myWords = []
  myWords = collectWords("5x5_Common_Five_Letter_Words.txt")
  print('Done main')