Created
March 30, 2017 04:30
-
-
Save Kwisses/582e7823b5993450bd36a42cbe5f5d8e to your computer and use it in GitHub Desktop.
[Daily Challenge #139 - Intermediate] - Telephone Keypads - r/DailyProgrammer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ***** DAILY CHALLENGE #139 - INTERMEDIATE ***** | |
# (Intermediate): Telephone Keypads | |
# | |
# Telephone Keypads commonly have both digits and characters on them. This | |
# is to help with remembering & typing phone numbers (called a Phoneword), | |
# like 1-800-PROGRAM rather than 1-800-776-4726. This keypad layout is also | |
# helpful with T9, a way to type texts with word prediction. | |
# | |
# Your goal is to mimic some of the T9-features: given a series of digits | |
# from a telephone keypad, and a list of English words, print the word or | |
# set of words that fits the starting pattern. You will be given the number | |
# of button-presses and digit, narrowing down the search-space. | |
# | |
# Formal Inputs & Outputs | |
# | |
# Input Description | |
# | |
# On standard console input, you will be given an array of digits (0 to 9) | |
# and spaces. All digits will be space-delimited, unless the digits | |
# represent multiple presses of the same button (for example pressing 2 | |
# twice gives you the letter 'B'). | |
# | |
# Use the modern Telephone Keypads digit-letter layout: | |
# | |
# 0 = Not used | |
# 1 = Not used | |
# 2 = ABC | |
# 3 = DEF | |
# 4 = GHI | |
# 5 = JKL | |
# 6 = MNO | |
# 7 = PQRS | |
# 8 = TUV | |
# 9 = WXYZ | |
# | |
# You may use any source for looking up English-language words, though this | |
# simple English-language dictionary is complete enough for the challenge. | |
# | |
# Output Description | |
# | |
# Print a list of all best-fitting words, meaning words that start with the | |
# word generated using the given input on a telephone keypad. You do not | |
# have to only print words of the same length as the input (e.g. even if the | |
# input is 4-digits, it's possible there are many long words that start | |
# with those 4-digits). | |
# | |
# Sample Inputs & Outputs | |
# | |
# Sample Input | |
# | |
# 7777 666 555 3 | |
# | |
# Sample Output | |
# | |
# sold | |
# solder | |
# soldered | |
# soldering | |
# solders | |
# soldier | |
# soldiered | |
# soldiering | |
# soldierly | |
# soldiers | |
# soldiery | |
# | |
# Challenge++ | |
# | |
# If you want an extra challenge, accomplish the same challenge but without | |
# knowing the number of times a digit is pressed. For example "7653" could | |
# mean sold, or poke, or even solenoid! You must do this efficiently with | |
# regards to Big-O complexity. | |
# ----------------------------------------------------------------------------- | |
class Phoneword(object): | |
"""Class for Phoneword.""" | |
def __init__(self, button_presses): | |
"""Initialize class parameters and data. | |
Args: | |
button_presses (str): Keypad presses. | |
""" | |
# Button presses as a string | |
self.button_presses = button_presses | |
# Filenames | |
self.keypad_file = "keypad.txt" | |
self.words_file = "words.txt" | |
# Get and set class data | |
self.keypad_info = self.get_lines(self.keypad_file) | |
self.words = self.get_lines(self.words_file) | |
self.keypad = self.set_keypad() | |
# Class lists | |
self.letters = [] | |
self.best_words = [] | |
@staticmethod | |
def get_lines(filename): | |
"""Get lines from filename. | |
Args: | |
filename (str): Name of file to be read. | |
Returns: | |
list: Contains lines from filename. | |
""" | |
with open(filename) as f: | |
lines = f.readlines() | |
lines = [' '.join(line.split()) for line in lines] | |
return lines | |
def set_keypad(self, limit=4, symbol=" = "): | |
"""Set keypad dict from data in self.keypad_info. | |
Args: | |
limit (int): Total number of letters per button. | |
symbol (str): Symbol to use to split data in self.keypad_info. | |
Returns: | |
dict: Number, letters key, value pairs. | |
""" | |
keypad = {} | |
for line in self.keypad_info: | |
digit, letters = line.split(symbol) | |
# Prevents misuse of keypad assignment | |
if len(letters) <= limit: | |
keypad[digit] = letters | |
else: | |
keypad[digit] = None | |
return keypad | |
def find_best_words(self): | |
"""Find all words that start with joined self.letters. | |
Returns: | |
list: Best words (words that start with start_word). | |
""" | |
start_word = ''.join(self.letters) | |
for word in self.words: | |
if start_word in word[:len(start_word)]: | |
self.best_words.append(word) | |
return self.best_words | |
def get_best_words(self): | |
"""Get best words (words that start with joined self.letters). | |
Returns: | |
list: Contains all words that start with joined self.letters. | |
""" | |
for button in self.button_presses.split(): | |
number, presses = button[0], len(button)-1 | |
letter = self.keypad[number][presses] | |
self.letters.append(letter.lower()) | |
return self.find_best_words() | |
def main(): | |
"""Print word in best_words from Phoneword object.""" | |
button_presses = "7777 666 555 3" | |
phoneword = Phoneword(button_presses) | |
best_words = phoneword.get_best_words() | |
for word in best_words: | |
print(word) | |
if __name__ == "__main__": | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
0 = Not used | |
1 = Not used | |
2 = ABC | |
3 = DEF | |
4 = GHI | |
5 = JKL | |
6 = MNO | |
7 = PQRS | |
8 = TUV | |
9 = WXYZ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
[Daily Challenge #139 - Intermediate] from the DailyProgrammer subreddit. Telephone Keypads.
Note: Omitted words.txt file as it contains over 77,000 English words.
Reference: https://www.reddit.com/r/dailyprogrammer/comments/1sody4/12113_challenge_139_intermediate_telephone_keypads/