Caesar Cipher problem So difficult to solve
def find_best_shifts_rec(wordlist, text, start): """ Given a scrambled string and a starting position from which to decode, returns a shift key that will decode the text to words in wordlist, or None if there is no such key. Hint: You will find this function much easier to implement if you use recursion. wordlist: list of words text: scambled text to try to find the words for start: where to start looking at shifts returns: list of tuples. each tuple is (position in text, amount of shift) """ ### TODO. bestTuple = [] if start > len(text): return None else: new_text = text[start:] best_shift = find_best_shift(wordlist, new_text) #shiftpoint tuple_shift = [(start, best_shift)] new_words = apply_coder(new_text, build_decoder(best_shift)) splitWord = (new_words.split()) for letter in splitWord: if is_word(wordlist, letter) == True: bestTuple += tuple_shift else: return find_best_shifts_rec(wordlist, text, start+1) return bestTuple
for the recursion problem.. Since there is no solution I cannot match with it. it decodes in very weird way. I spent 4 hours for only this one function.. Any tips? Please help me
Try this, I can't claim credit for it though because I got my friend to solve this for me haha. ## for i in range(0, 27): ## s = text[0:start] + apply_shift(text[start:], i) ## words = s.split() ## counter = 0 ## for i in words: ## if i in wordlist: ## counter += 1 ## else: ## if counter > 1: ## find_best_shifts_rec(wordlist, text, text.find(i)+len(i)+1) ## return # when <start> is as long as the text, we've fully decoded the text # ie - len(text[:start] + text[start:]) equals len(text) if start >= len(text): # we've hit our base case, since we've fully decoded the text, there are no # more shifts needed, therefore return an empty list return [] #-------------------------------------------------------------------------------------------------------------- # attempt to decode the encoded text using each shift (0-27) shift = 0 while shift <= 27: decoded_text = apply_coder(text[start:], build_decoder(shift)) decoded_words = decoded_text.split() num_words_decoded = 0 # check how many valid words we've decoded while num_words_decoded < len(decoded_words) and is_word(wordlist, decoded_words[num_words_decoded]): num_words_decoded = num_words_decoded + 1 # if this shift resulted in at least one decoded word, this may be the start of a possible solution # attempt to decode the rest of the text if num_words_decoded > 0: #-------------------------------------------------------------------------------------------------------------- partially_decoded_text = text[:start] + decoded_text # we add 1 to account for the last space decoded_length = start + len(' '.join(decoded_words[:num_words_decoded])) + 1 # where the magic happens - attempt to decode the rest of the string remaining = find_best_shifts_rec(wordlist, partially_decoded_text, decoded_length) # if remaining *is* none, we know that the shift we applied on <text> is incorrect if remaining is not None: return [(start, shift)] + remaining shift = shift + 1 # no valid words were found when attempting to decode the text using shifts 0-27 return None
Join our real-time social learning platform and learn together with your friends!