Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This is incredibly hackish, and was my first experiment with python.
- # It's once off throwaway code, ugly as hell, unoptimised, but it works!
- #
- # Run the script with two arguments:
- # the input file with the scratchie ticket info
- # the number of words you wish to find on said cards (N)
- # The script will then try try to find a combination of the hidden letters
- # that will result N words being found.
- #
- # See https://danielkinsman.wordpress.com/2011/03/26/reverse-engineering-scratchie-tickets/
- #
- # Example card input file:
- # fzdviwrloychtsbkmxnu area fiasco fist dab unfeeling estuary onset eyeball hustle eke arid cede buttress all forbear yolk awful aside song oat tone
- # slmdhibjxaquzocfwpgk sky foible prelude panda linseed fortnight elk angora refuse adze soap air down young two opal imitate era brunette eddy knee
- # rvpfguhzybmlcwdknios wily eschew edge yes operation whisker altar peasant rhythm tee whey swap solitary yew enlarge rate crest stunt grow woe rose
- # fadpyoqlvjmbitwsugcx sun instil license mitre freesia platitude nay pagoda equate fond slim pie plea nifty two clef retrace off tungsten exam yard
- # ixpwrvlmabhdnfjgckuo keel peanut tide tip albatross granule close eyelash mutiny day knit ogre parakeet lap pinball echo after nomad dash tie easy
- # thukdxspfabemvywgqco apt crease lexicon suite freesia portfolio men recede pacify give axis rap role timid toe clef rookery egg accustom neat nice
- import sys
- import string
- def getUniqueLetters(stringy):
- found = ''
- for khr in stringy:
- if found.find(khr) < 0:
- found += khr
- return found
- def countBinary1s(num):
- count = 0
- while num > 0:
- if num % 2 == 1:
- count += 1
- num /= 2
- return count
- def constructPossibilityUsingBitmask(mask, alphabet):
- result = ''
- index = 0
- while mask > 0:
- if mask % 2 == 1:
- result += alphabet[index]
- mask /= 2
- index += 1
- return result
- def stringnuke(stringy, victims):
- return stringy.translate(string.maketrans('',''), victims)
- class ScratchieCard(object):
- letterCount = 20
- letters = None
- words = None
- #Format of "entry" parameter: letters(20 char string, no space) word word word...
- def __init__(self, entry = None):
- if(entry == None):
- return
- entries = entry.split()
- self.letters = entries[0]
- self.words = list()
- for i in range(1, 22):
- self.words.append(entries[i])
- def wordsFound(self, lLetters = None):
- if(lLetters == None):
- lLetters = self.letters
- if len(lLetters) != 20:
- raise ValueError('there must be exactly 20 scratchie letters')
- found = 0
- for word in self.words:
- if len(stringnuke(word, lLetters)) == 0:
- found += 1
- return found
- def generateMatchingLetters(self, numMatch, wordcat):
- matches = list()
- musthaves = getUniqueLetters(wordcat)
- leftovers = stringnuke('abcdefhijklmnopqrstuvwxyz', musthaves)
- #print 'must ', musthaves, 'left ', leftovers
- comboCount = 0
- for i in range(1, pow(2, len(leftovers))):
- if countBinary1s(i) == 20 - len(musthaves):
- comboCount += 1
- pobby = musthaves + constructPossibilityUsingBitmask(i, leftovers)
- if self.wordsFound(pobby) == numMatch:
- #print pobby + ' is a match.'
- matches.append(pobby)
- #print str(comboCount) + ' possible letter combinations found for wordcat (' + wordcat + ').'
- #print str(len(matches)) + ' ' + str(numMatch) + ' word matches found amongst these.'
- #sys.stdout.flush()
- return matches
- def generateNMatchLetterList(self, numMatch):
- matchingCombinations = list()
- #this is extremely ugly, but it works and i'm too lazy to do it better
- if numMatch == 1:
- for i in range(0, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- if numMatch == 2:
- for i in range(0, 20):
- for j in range(i+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 3:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 4:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- for l in range(k+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k] + self.words[l])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 5:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- for l in range(k+1, 20):
- for m in range(l+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k] + self.words[l] + self.words[m])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 6:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- for l in range(k+1, 20):
- for m in range(l+1, 20):
- for n in range(m+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k] + self.words[l] + self.words[m] + self.words[n])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 7:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- for l in range(k+1, 20):
- for m in range(l+1, 20):
- for n in range(m+1, 20):
- for o in range(n+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k] + self.words[l] + self.words[m] + self.words[n] + self.words[o])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 8:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- for l in range(k+1, 20):
- for m in range(l+1, 20):
- for n in range(m+1, 20):
- for o in range(n+1, 20):
- for p in range(o+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k] + self.words[l] + self.words[m] + self.words[n] + self.words[o] + self.words[p])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 9:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- for l in range(k+1, 20):
- for m in range(l+1, 20):
- for n in range(m+1, 20):
- for o in range(n+1, 20):
- for p in range(o+1, 20):
- for q in range(p+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k] + self.words[l] + self.words[m] + self.words[n] + self.words[o] + self.words[p] + self.words[q])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- elif numMatch == 10:
- for i in range(0, 20):
- for j in range(i+1, 20):
- for k in range(j+1, 20):
- for l in range(k+1, 20):
- for m in range(l+1, 20):
- for n in range(m+1, 20):
- for o in range(n+1, 20):
- for p in range(o+1, 20):
- for q in range(p+1, 20):
- for r in range(q+1, 20):
- matchingLetters = self.generateMatchingLetters(numMatch, self.words[i] + self.words[j] + self.words[k] + self.words[l] + self.words[m] + self.words[n] + self.words[o] + self.words[p] + self.words[q] + self.words[r])
- for letts in matchingLetters:
- matchingCombinations.append(letts)
- return matchingCombinations
- # Main method, first arg input file, second number of words to find
- if __name__ == '__main__':
- fInput = open(sys.argv[1], 'r')
- wordsToFind = int(sys.argv[2])
- for line in fInput:
- print line
- card = ScratchieCard(line)
- print str(card.wordsFound()) + ' words found on card.'
- sys.stdout.flush()
- print str(len(card.generateNMatchLetterList(wordsToFind))) + ' ' + str(wordsToFind) + ' word letter combinations found for this card.'
- sys.stdout.flush()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement