Both of these pieces of code do the same thing, which is they check if the words in the list magazine_words are sufficient to make up the message dictated by the words in the list note_words . However the first piece of code takes a lot more time to execute, which doesn't let it run for large inputs. Why is that? Since both solutions use single for-loops, shouldn't they have the same complexity, i.e. take about the same time to run?
First solution:
lengths = input().split ()
m = int(lengths[0])
n = int(lengths [1])
magazine_words = input ().split()
note_words = input ().split()
def checkMagazine(m,n,magazine_words,note_words):
flag = "Yes"
for ind in range (n):
if not (note_words[ind] in magazine_words):
flag = "No"
break
else:
magazine_words.remove(note_words[ind])
return flag
print (checkMagazine(m,n,magazine_words,note_words))
Second solution:
def ransom_note(magazine, ransom):
rc = {} # dict of word: count of that word in the note
for word in ransom:
if word not in rc:
rc[word] = 0
rc[word] += 1
for word in magazine:
if word in rc:
rc[word] -= 1
if rc[word] == 0:
del rc[word]
if not rc:
return True
return False
m, n = map(int, input().strip().split(' '))
magazine = input().strip().split(' ')
ransom = input().strip().split(' ')
answer = ransom_note(magazine, ransom)
if(answer):
print("Yes")
else:
print("No")```
magazine_words.remove(note_words[ind]) is secretly another loop - this has to loop through all of magazine_words until it finds note_words[ind], each time you call it.
Related
Write a program to input the lines of text, print them to the screen after converting them to lowercase. The last line prints the number of input lines.
The program stops when it encounters a line with only zero.
Requirements: use infinite loop and break . statement
here's my code but it's saying Input 9 is empty
a = 1
l = 0
while a != 0:
a = input()
a.lower()
print(a)
l+=1
example inputs
TbH
Rn
ngL
bRb
0
I'd suggest this, it's a combination of these 2 comments, sorry
count = 0
while True:
a = input()
if a == '0':
break
else:
print(a.lower())
count += 1
print(count)
This may accomplish what you are trying to achieve:
def infinite_loop():
while True:
user_input = input('enter a value:\n> ')
if user_input == '0':
break
else:
print(user_input.lower())
if __name__ == '__main__':
infinite_loop()
There a few errors in your original code, here is some suggestions and fixes. This post is try to follow your code as much as it can, and point the changes needed.
Please see the comments and ask if you have any questions.
count = 0 # to count the lines
while w != '0': # input's string
w = input().strip() # get rid of \n space
word = w.lower() # convert to lower case
print(word)
count += 1
# while-loop stops once see '0'
Outputs: (while running)
ABBA
abba
Misssissippi
misssissippi
To-Do
to-do
0
0
I am trying to make a hangman game and I am running into trouble with the display. I have a loop that is supposed to put the correctly guessed letters in the right places, however it only shows the correct location for one letter at a time. I thought it would be helpful to save the result of the previous iteration, and then display that, but I am not sure how to do that.
import random,time
hanglist = []
answerlist = []
file_var = open("wordlist.100000")
for n in file_var:
hanglist.append(file_var.readline())
word = random.choice(hanglist)
print("word is",word)
guesses = 10
while guesses != 0:
print("guess a letter")
answer = input()
answerlist.append(answer)
if answer in word:
m = list(word)
for n in m:
if n == answer:
print(answer, end = '')
else:
print('_', end = '')
else:
print("close, but not exactly")
guesses -= 1
And here are the outputs
word is fabric
guess a letter
f
f______guess a letter
a
_a_____guess a letter
To solve your issue just replace if n==answer to if n in answer. But, from the above code, I can see code can't handle these issues:
If the user guesses the same word again and again
After 4 guesses are done and total word is guessed, then code should break out of the loop, which it is not happening.
While reading line, it need to strip the '\n' otherwise its really hard
My code addresses these issue:
import random,time
hanglist = []
answerlist = []
file_var = open("wordlist.100000")
for n in file_var:
# strips the '/n' at the end
hanglist.append(file_var.readline().rstrip())
word = random.choice(hanglist)
print("word is",word)
guesses = 10
while guesses!=0:
print("guess a letter")
answer = input()
if answer in answerlist:
continue
answerlist.append(answer)
if answer in word:
# to print entire word guessed till now- with current and previous iterations
word_print = ''
for n in word:
# to print all the last state occurences
if n in answerlist:
word_print += n
else:
word_print += '_'
print(word_print,end='')
# word is correctly guessed
if '_' not in word_print:
break
else:
print("close, but not exactly")
guesses = guesses-1
Your issue is with
if n == answer:
print(answer,end = '')
else:
print('_', end = '')
which only compares each letter with the current guess, answer. Instead, if you use
if n in answerlist:
print(n, end = '')
else:
print('_', end = '')
it will show the letter if that letter is in the list of their previous guesses.
Additionally: the previous m= list(word) is not necessary, as for n in word: is valid.
I'm pretty new to python and I'm having trouble with my
if then else statements and I only get is "no repeating vowels" which mean my rep_vowel is still returning 0
so the program rules are as follows.
if no vowel appears next to itself (e.g. hello), then print:
no vowel repeats
if exactly one vowel is repeated in sequence at least once (e.g. committee) then print a message that indicates which vowel repeats:
only vowel e repeats
if more than one vowel repeats (e.g. green door) then print:
more than one vowel repeats
ignore upper case - lower case differences: assume all the input is always lowercase
answer = input("Enter a string: ")
rep_vowel = 0
i = 0
length_Answer = len(answer)
next_string = 1
curChar = answer[0+rep_vowel]
for i in range(0,length_Answer):
if answer[0 + i] in ["a","e","i","o","u"]:
i =+ 1
next_string = answer[0+i+i]
if next_string == answer:
rep_vowel =+ 1
if rep_vowel == 0:
print("no repeating vowles")
elif rep_vowel > 1:
print("more than 1 repeating vowels")
else:
print ("the letter "+ str(curChar) +" repeats")
You have a few mistakes so i'll try to address several of them:
You do a lot of [0 + something] indexing, which is useless, since 0 + something always equals to something, so yo should just do indexing with [something]
Changing the value of i with i += 1 is bad because you are already increasing it as part of the loop
All you have to do to find a match is simply match the current letter to the next one, if both are the same and they are also vowels, you've found a match.
You are initializing unnecessary variables such as i = 0 only to have them overridden in the next lines
Adding all of those together:
answer = input("Enter a string: ")
vowels = "aeiou"
repeats = [] # this list will hold all repeats of vowels
for i in range(len(answer) - 1): # i'll explain the -1 part at the end
if answer[i] in vowels and answer[i] == answer[i + 1]:
repeats.append(answer[i])
if len(repeats) == 0:
print("no repeating vowles")
elif len(repeats) > 1:
print("more than 1 repeating vowels")
else:
print("the letter " + repeats[0] + " repeats")
This still doesn't take every possible input into account, but it should get you started on a final solution (or perhaps that's enough). For example, input of teest will give the correct result but the input of teeest doesn't (depends on your definition of correct).
About the len(answer-1) range, that's only to make sure we don't go out of bounds when doing answer[i + 1], so we're stopping on the next to last letter instead.
Firstly, you have to indent your code.
to say if (condition) then do print('hello') you write it this way:
if condition:
print('hello')
Secondly, you are using i =+ 1 which is the same as i=1
I think you meant i +=1 which is i = i+1
Finally, I suggest this code:
answer = input("Enter a string: ")
vowel_repeated_count = 0
length_Answer = len(answer)
i=0
while (i <length_Answer-1):
#we check if it's a vowel
if answer[i] in ["a","e","i","o","u"]:
#we check if it's followed by the same vowel
if answer[i+1] == answer[i]:
#increment the vowel_repeated_count
vowel_repeated_count +=1
#we save the vowel for the display
vowel = answer[i]
#we skip the other same repeated vowels
#example: abceeed, we skip the third e
while (answer[i] == vowel and i < length_Answer-1):
i +=1
#we add this incrementation because we're in a while loop
i +=1
if vowel_repeated_count == 0:
print("no repeating vowles")
elif vowel_repeated_count == 1:
print("the letter "+ str(vowel) +" repeats")
else:
print ("more than 1 repeating vowels")
You have some logical errors. It's time consuming to edit that. You can try this, I have modified your code. Hope it will work for you. I have commented beside every important line.
answer = input("Enter a string: ")
is_found = {} #a dictionary that will hold information about how many times a vowel found,initially all are 0
is_found["a"]=0
is_found["e"] = 0
is_found['i']=0
is_found['o']=0
is_found['u']=0
vowels =["a","e","i","o","u"]
for i in range(0,len(answer)):
if answer[i] in vowels:
is_found[answer[i]] = is_found[answer[i]]+1 # if a vowel found then increase its counter
repeated=0 #let 0 repeated vowel
previously_repeated=False #to trace whether there is a previously repeated character found
curChar=None
for key,value in is_found.items(): #iterate over dictionary
if previously_repeated and value>1: #if a vowel found and previously we have another repeated vowel.
repeated=2
elif previously_repeated==False and value>1: # we don't have previously repeated vowel but current vowel is repeated
curChar=key
previously_repeated=True
repeated=1
if repeated== 0:
print("no repeating vowles")
elif repeated> 1:
print("more than 1 repeating vowels")
else:
print ("the letter "+ str(curChar) +" repeats")
There is no need to increment your counter i. In your for loop, it will increment itself each time it goes through the for loop. Also, you need a variable to keep track of how many times the vowel repeats.
answer = input("Enter a string: ")
rep_vowel = 0
length_Answer = len(answer)
vowelList=["a","e","i","o","u"]
vowelRepeated = []
#this will go from i=0 to length_Answer-1
for i in range(length_Answer):
if (answer[i] in vowelList) and (answer[i+1] in vowelList):
if (answer[i] == answer[i+1]):
vowelRepeated.append(answer[i])
repVowel += 1
if rep_vowel==0:
print("no repeating vowels")
elif rep_vowel==1:
print("only one vowel repeated:")
print(vowelRepeated)
else:
print("multiple vowels repeated:")
print(vowelRepeated)
for such counting, I will prefer to use a dictionary to keep the counting number. Your code has been modified for your reference
answer = input("Enter a string: ")
length_Answer = len(answer)
count = dict()
for i in range(length_Answer):
if answer[i] in ["a","e","i","o","u"]:
if answer[i+1] == answer[i]:
if answer[i] in count:
count[answer[i]] += 1
else:
count[answer[i]] = 1
rep_vowel = len(count)
if rep_vowel == 0:
print("no repeating vowles")
elif rep_vowel > 1:
print("more than 1 repeating vowels")
else:
for k in count:
vowel = k
print("the letter " + vowel + " repeats")
You have a few issues with your solution :
1) You never use curChar, i'm guessing you wanted to enter the next_string value into it after the '==' statement.
2) You compare your next_string to answer, this will always be a false statement.
3) Also no need to use [0+i], [i] is good enough
Basically what you want to do is this flow :
1) Read current char
2) Compare to next char
3) If equal put into a different variable
4) If happens again raise a flag
Optional solution :
vowel_list = ["a","e","i","o","u"]
recuring_vowel_boolean_list = [answer[index]==answer[index+1] and answer[index] in vowel_list for index in range(len(answer)-1)]
if not any(recuring_vowel_boolean_list ):
print("no repeating vowels")
elif (recuring_vowel_boolean_list.count(True) > 1):
print("More then 1 repeating vowels")
else:
print("The letter {} repeats".format(answer[recuring_vowel_boolean_list.index(True)]))
This is a problem from HackerRank. My implementation as shown below passes most of the test but for the tests that it fails, it states that it is taken too long. After looking at other submissions, I found that another user's implementation (credit to saikiran9194) passes all tests almost immediately. I really am having trouble understanding why his solution is the most efficient at scale.
My Implementation:
m, n = map(int, input().strip().split(' '))
magazine = input().strip().split(' ')
ransom = input().strip().split(' ')
yesNo = "Yes"
for i in ransom:
if(ransom.count(i) > magazine.count(i)):
yesNo = "No"
print(yesNo)
More Time Efficient Implementation
def ransom_note(magazine, ransom):
rc = {} # dict of word: count of that word in the note
for word in ransom:
if word not in rc:
rc[word] = 0
rc[word] += 1
for word in magazine:
if word in rc:
rc[word] -= 1
if rc[word] == 0:
del rc[word]
if not rc:
return True
return False
m, n = map(int, input().strip().split(' '))
magazine = input().strip().split(' ')
ransom = input().strip().split(' ')
answer = ransom_note(magazine, ransom)
if(answer):
print("Yes")
else:
print("No")
It's the difference between list.count and dict.__getitem__ (rc[word]). list.count is O(n) whereas dict.__getitem__ is O(1) due to, as you mention, hashing.
Source: https://wiki.python.org/moin/TimeComplexity
list.count has linear complexity, so your code has quadratic complexity overall, doing linear work in each iteration of the loop. By putting the lists in a dict first, it only needs O(1) to get the count for a certain letter.
You can just wrap those lists into collections.Counter (not tested):
m, n = map(int, input().strip().split())
magazine = Counter(input().strip().split())
ransom = Counter(input().strip().split())
yesNo = "Yes"
for i in ransom:
if(ransom[i] > magazine[i]):
yesNo = "No"
print(yesNo)
Or shorter using any
yesno = "No" if any(random[i] > magazine[i] for i in ransom) else "Yes"
So my code gets two words, and checks if one is the anagram of another one.
However doesn't work if multiple letters are exchanged, although I tried to account for that.
storedword = input("Enter your primary word \t")
global word
word = list(storedword)
word3 = input("Enter anagram word \t")
word3lowercase = word3.lower()
anaw = list(word3lowercase)
counter = int(0)
letterchecker = int(0)
listlength = len(word)
newcounter = int(0)
if len(anaw) != len(word):
print ("not anagram")
if len(anaw) == len(word):
while counter < listlength and newcounter < listlength:
tempcount = 0
if anaw[counter] == word[newcounter]:
temp = word[newcounter]
word[newcounter] = word[tempcount]
word[tempcount]=temp
letterchecker +=1
counter +=1
tempcount +=1
newcounter = int(0)
else:
newcounter +=1
if counter == len(word):
print ("anagram")
else:
print ("not anagram")
I think it's gone somewhere wrong after the if len(anaw) section, for example if the primary word is "hannah", and the secondary word is "hannnn", it thinks it's an anagram.
There is much simpler logic that can be implemented here, even without using sorted and such. Let's assume you have a function anagram:
def anagram(word1, word2):
if len(word1) != len(word2):
return False
def char_count(word):
char_count = {}
for c in word:
char_count[c] = char_count.get(c, 0) + 1
return char_count
cr1 = char_count(word1)
cr2 = char_count(word2)
return cr1 == cr2
You can test this with:
>>> print(anagram("anagram", "aanragm"))
True
>>> print(anagram("anagram", "aangtfragm"))
False
And for future readers, a super simple pythonic solution might be using Counter:
from collections import Counter
>>> Counter(word1) == Counter(word2)
Or using sorted:
>>> sorted(word1) == sorted(word2)
newcounter = int(0)
This is the line that causes the trouble (in the while loop).
Because of it you start checking the word from the beginning again.
I think you want it to be newcounter=letterchecker.
Since already used characters are put to the front of word they are ignored if you start with letterchecker
Tell me if it works
Edit:Checked with example given, seems to work.
Without using sort you could use the following approach. It removes a letter from an array of a characters of the second word. The words are only anagrams if there are no letters left (and the words are the same length to start with and have a length larger than zero):
word1="hannah"
word2="nahpan"
chars1= list(word1)
chars2= list(word2)
if len(chars1)==len(chars2) and len(chars1)>0:
for char in chars1:
if char not in chars2:
break
chars2.remove(char)
if len(chars2)==0:
print "Both words are anagrams"
else:
print "Words are not anagrams"
[EDIT THIS IS JUST FOR PALINDROMES I CANT READ]
Here is something a bit more simple:
storedword = input("Enter your primary word \t")
word3 = input("Enter anagram word \t")
if storedword == word3[::-1]:
print "Is Anagram"
else:
print "Is not anagram"