Question Desc: Sherlock considers a string to be valid if all characters of the string appear the same number of times. It is also valid if he can remove just 1 character at 1 index in the string, and the remaining characters will occur the same number of times. Given a string s, determine if it is valid. If so, return YES, otherwise return NO.
def isValid(s):
lst = []
temp = []
for i in s:
y = i
lst.append(y)
st = set(lst)
for j in st:
count = s.count(j)
temp.append(count)
temp.sort()
print(temp)
b=temp[-1]-temp[-2]
ele = temp[0]
chk=True
for item in temp:
if ele!=item:
chk=False;
break;
if(chk==True):
print('YES')
break;
elif(b==1):
print('YES')
break;
else:
print('NO')
break;
For some reason , irrespective of my input , the answer seems to be YES. Can someone tell me where am I going wrong.
Link to the question
PS - You don't need an account to view the question , just click anywhere on the screen.
It's because of the initial values you've set for your variables. On the very first step of your iteration through temp you'll find that ele == item (because both are temp[0]), and then subsequently that chk == True (because you set it so). After the first step it'll print yes and break immediately.
Related
def checkPattern(x, string):
e = len(string)
if len(x) < e:
return False
for i in range(e - 1):
x = string[i]
y = string[i + 1]
last = x.rindex(x)
first = x.index(y)
if last == -1 or first == -1 or last > first:
return False
return True
if __name__ == "__main__":
x = str(input())
string = "hello"
if checkPattern(x, string) is True:
print('YES')
if checkPattern(x, string) is False:
print('NO')
So basically the code is supposed to identify a substring when the number of characters between the substring's letters don't matter. string = "hello" is supposed to be the substring. While the characters in between don't matter the order still matters so If I type "h.e.l.l.o" for example it's a YES, but if it's something like "hlelo" it's a NO. I sorta copied the base of the code and I'm still a little new to python so sorry if the question and code aren't clear.
Assuming I understand, and the input hlelo is No and the input h.e..l.l.!o is Yes, then the following code should work:
def checkPattern(x, string):
assert x and string, "Error. Both inputs should be non-empty. "
count_idx = 0 # index which counts where you are.
for letter in x:
if letter == string[count_idx]:
count_idx += 1 # increment to check the next string
if count_idx == len(string):
return True
# pattern was found if counter found matches equal to string length
return False
if __name__ == "__main__":
inp = input()
string = "hello"
if checkPattern(inp, string) is True:
print('YES')
if checkPattern(inp, string) is False:
print('NO')
Explaination: Regardless of the input string, x, you want to loop through each character of the search-string hello, to check if you find each character in the correct order. What my solution does is that it counts how many of the characters h, e, l, l, o it has found, starting from 0. If it finds a match for h, it moves on to check for a match for e, and so on. Ultimately, if you search through the entire string x, and the counter does not equal to the length of the search string (i.e. you could not find all the hello characters), it returns false.
EDIT: Small debug in the way the return worked. Instead returns if ever the counter goes over the length. Also added more examples given in comments
Here is my solution to this problem:
pattern = "hello"
def patternCheck(word, pattern) -> bool:
plist = list(pattern)
wlist = list(word)
for p in plist:
if p in wlist:
for _ in range(wlist.index(p) , -1, -1):
wlist.pop(_)
else:
return False
return True
print(patternCheck("h.e.l.l.o", pattern))
print(patternCheck("aalohel", pattern))
print(patternCheck("hhhhheeelllooo", pattern))
Explanation
First we convert our strings to a list
plist = list(pattern)
wlist = list(word)
Now we check using a for loop if every element in our pattern list is in the word list.
for p in plist:
if p in wlist:
If yes then we remove all the elements from index 0 to the index of that element.
for _ in range(wlist.index(p) , -1, -1):
wlist.pop(_)
We are removing elements in decreasing order of there indices to protect ourself from the IndexError: pop index out of range.
If the for loop ends normally then there was a match and we return True. Else if the element was not found in the word list in the first place then we return false as there is no match.
Here I want to remove any vowels which repeat consecutively. But it shows error as "list out of index".
So I tried break if last element in list is reached, but still won't work.
Here is the code I tried:-
a=[]
b=str(input("enter the string"))
a=b.split(',')
c=['a','e','i','o','u']
for i in c:
for j in range(0,len(a)):
if (a[j+1] == a[len(a)]) is True:
break;
elif ((a[j] == a[j+1]) & (a[j+1] == i)) is True:
del[j]
e.join(a)
print(e)
Please show me how to solve this problem, or any other problem if in there.
How about maintaining a stack for consecutive vowels? whenever you see non-vowel string re-initialize the stack list and when you see vowels but are not consecutive you just add to the final list
stack=[]
new_list=[]
vowel=['a','i','o','u','e']
for i in your_string: # replace your string with actual string
if i not in vowel:
if len(stack) == 1:
new_list.append(stack[0])
new_list.append(i)
stack = []
else:
stack.append(i)
if len(stack) == 1:
new_list.append(stack[0])
You get a list out of index error because you are indexing at a value not in a
if (a[j+1] == a[len(a)]) is True:
a[len(a)] does not exist, arrays are zero indexed so they start from 0. An array with 5 items has index 0,1,2,3,4
the line should be:
if (a[j+1] == a[len(a) - 1]) is True:
Also 'is True' is redundant, so further refined:
if a[j+1] == a[len(a) - 1]:
Also is del[j] an error? should it be del a[j]?
If this is the case, the program will run into further errors as you are iterating over the entire Original size of the array but deleting values during this iteration, so it will look for items that no longer exist.
First detail is this: if (a[j+1] == a[len(a)]) is True: from what I understood this is to break the code when it is necessary. But that is completely unnecessary. Instead you should fix the number of iterations in the beginning, which should be for j in range(0,len(a)-1):
Another problem is that you aren't really iterating through the letters, just each comma separated phrases. If you put "Hello, World" you aren't checking the letters, you check "Hello" and " World". You might as well remove b and let a just be the raw input.
Since a would then be a string, to erase the i-th letter of a string you can use the function below.
def remove_jth(word, j):
word = word[:j] + word[j+1:]
Finally since you are using range, it will build a "list" that has the size len(a) when you start the for, but as you remove vowels, the length of a gets shorter and the range you had at the beginning will be to much. If you fix all of these things you should have it right
You can do it this way:
a=[]
b=str("a,a,a,b,e,e,e,c,x,d")
a=b.split(',')
c=['a','e','i','o','u']
j = 0
for i in c:
while j < len(a)-1:
if a[j] == a[j+1] and a[j] == i:
del a[j]
else:
j = j+1
j=0
Use a while loop to check through the list and delete consecutive duplicates. Then reset the the while loop back to zero and run through the list again.
Using a for loop will not work,if you are deleting items in the list that is being used to iterate over.
b=str("a,a,a,b,e,e,e,c,x,d") was just used to test the code.
To print the results you can just do print(a) it will print the list out.
I used this Stack Overflow post as reference.
I edited it to suit you:
result=original.replace('a','').replace('e',''),replace('i','').replace('o','').replace('u','')
original is your input string and result is your output string.
t=input()
st=""
vow=['a','e','i','o','u']
st+=t[0]
for i in range(1,len(t)):
if(t[i].lower() in vow):
if(t[i-1].lower() not in vow and i-1>=0):
st+=t[i]
else:
st+=t[i]
print(st)
my code for finding longest substring in alphabetical order using python
what I mean by longest substring in alphabetical order?
if the input was"asdefvbrrfqrstuvwxffvd" the output wil be "qrstuvwx"
#we well use the strings as arrays so don't be confused
s='abcbcd'
#give spaces which will be our deadlines
h=s+' (many spaces) '
#creat outputs
g=''
g2=''
#list of alphapets
abc='abcdefghijklmnopqrstuvwxyz'
#create the location of x"the character the we examine" and its limit
limit=len(s)
#start from 1 becouse we substract one in the rest of the code
x=1
while (x<limit):
#y is the curser that we will move the abc array on it
y=0
#putting our break condition first
if ((h[x]==' ') or (h[x-1]==' ')):
break
for y in range(0,26):
#for the second character x=1
if ((h[x]==abc[y]) and (h[x-1]==abc[y-1]) and (x==1)):
g=g+abc[y-1]+abc[y]
x+=1
#for the third to the last character x>1
if ((h[x]==abc[y]) and (h[x-1]==abc[y-1]) and (x!=1)):
g=g+abc[y]
x+=1
if (h[x]==' '):
break
print ("Longest substring in alphabetical order is:" +g )
it doesn't end,as if it's in infinite loop
what should I do?
I am a beginner so I want some with for loops not functions from libraries
Thanks in advance
To avoid infinite loop add x += 1 in the very end of your while-loop. As a result your code works but works wrong in general case.
The reason why it works wrong is that you use only one variable g to store the result. Use at least two variables to compare previous found substring and new found substring or use list to remember all substrings and then choose the longest one.
s = 'abcbcdiawuhdawpdijsamksndaadhlmwmdnaowdihasoooandalw'
longest = ''
current = ''
for idx, item in enumerate(s):
if idx == 0 or item > s[idx-1]:
current = current + item
if idx > 0 and item <= s[idx-1]:
current = ''
if len(current)>len(longest):
longest = current
print(longest)
Output:
dhlmw
For your understanding 'b'>'a' is True, 'a'>'b' is False etc
Edit:
For longest consecutive substring:
s = 'asdefvbrrfqrstuvwxffvd'
abc = 'abcdefghijklmnopqrstuvwxyz'
longest = ''
current = ''
for idx, item in enumerate(s):
if idx == 0 or abc.index(item) - abc.index(s[idx-1]) == 1:
current = current + item
else:
current = item
if len(current)>len(longest):
longest = current
print(longest)
Output:
qrstuvwx
def sub_strings(string):
substring = ''
string +='\n'
i = 0
string_dict ={}
while i < len(string)-1:
substring += string[i]
if ord(substring[-1])+1 != ord(string[i+1]):
string_dict[substring] = len(substring)
substring = ''
i+=1
return string_dict
s='abcbcd'
sub_strings(s)
{'abc': 3, 'bcd': 3}
To find the longest you can domax(sub_strings(s))
So here which one do you want to be taken as the longest??. Now that is a problem you would need to solve
You can iterate through the string and keep comparing to the last character and append to the potentially longest string if the current character is greater than the last character by one ordinal number:
def longest_substring(s):
last = None
current = longest = ''
for c in s:
if not last or ord(c) - ord(last) == 1:
current += c
else:
if len(current) > len(longest):
longest = current
current = c
last = c
if len(current) > len(longest):
longest = current
return longest
so that:
print(longest_substring('asdefvbrrfqrstuvwxffvd'))
would output:
qrstuvwx
The aim of the program is to print the longest substring within variable s that is in alphabetical order.
s ='abchae'
currentlen = 0
longestlen = 0
current = ''
longest = ''
alphabet = 'abcdefghijklmnopqrstuvwxyz'
for char in s:
for number in range(0,len(s)):
if s[number] == char:
n = number
nxtchar = 1
alphstring = s[n]
while alphstring in alphabet == True and n+nxtchar <= 5:
alphstring += s[n+nxtchar]
nxtchar += 1
currentlen = len(alphstring)
current = alphstring
if currentlen > longestlen:
longest = current
print longest
When run, the program doesn't print anything. I don't seem to see what's wrong with the code. Any help would be appreciated.
I'd use regex for this
import re
string = 'abchae'
alphstring = re.compile(r'a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*', re.I)
longest = ''
for match in alphstring.finditer(string):
if len(match.group()) > len(longest):
longest = match.group()
print(longest)
Output:
abch
Note: The flag re.I in the regex expression causes the regex to ignore case. If this is not the desired behavior you can delete the flag and it will only match lowercase characters.
Like Kasramvd said, I do not understand the logic behind your code. You sure your code can run without raise IndentationError? As I concerned, the following part (the second row, have wrong indentation).
for number in range(0,len(s)):
if s[number] == char:
n = number
If you fixed that indentation error, you can run you code without error, and the last row (print longest) does work, it just does not work as you expect, it only prints a blank line.
I think I understood what you meant.
First you need to fix the indentation problem in your code, that would make it run:
for number in range(0,len(s)):
if s[number] == char:
n = number
Second, that condition will return two numbers 0 and 4 since a appears two times in s. I believe you only want the first so you should probably add a break statement after you find a match.
for number in range(0,len(s)):
if s[number] == char:
n = number
break
Finally, alphstring in alphabet == True will always return False. Because alphabet will never be True, you need parentheses to make this work or remove the == True.
ex: while (alphstring in alphabet) == True and n+nxtchar <= 5:
I believe that you were looking for the string abch which is what I managed to obtain with these changes
This is my solution:
result = ""
s = 'abchae'
alphabet = 'abcdefghijklmnopqrstuvwxyz'
max_length=0
for i in range(len(s)):
for j in range(len(s)):
if s[i:j] in alphabet and len(s[i:j])>max_length:
max_length = len(s[i:j])
result = s[i:j]
print result
I have to do this exercise without using library function. So far I have reached here:-
string = input("Enther The String :")
substring = input("Enter the substring :")
count = 0
for i in range(len(string)):
if string[i:i+len(substring)] == substring:
if string[i+len(substring)] == ' ':
count += 1
else:
count = 0
print(count)
But, let us say if the sub-string is 'bob' and the string is 'bob cat bob cat bobs cat', the program still counts 'bob' in 'bobs' and I don't want that. Also this code always returns 0. Please help! Thanks!
the program still counts 'bob' in 'bobs'
It doesn't.
Also this code always returns 0
This is because of your else clause.
else:
count = 0
You're resetting the count here. That's not what you want; if the next character isn't a space, you don't want to do anything at all. Remove the whole else clause.
You have an additional bug you haven't noticed. If string ends with substring, the following test:
if string[i+len(substring)] == ' ':
will attempt to read past the end of the string and throw an IndexError. Try to solve this problem on your own first.
As you're allowed to use slicing, so you can use that to check whether the character before/after the substring is a space or empty string, if it is then increment count by 1. Note that slices never raise exception, even for out of range indices.
def sub_str_count(s, sub_str):
le = len(sub_str)
count = 0
for i in range(len(s)):
if s[i:i+le] == sub_str and s[i-1:i] in ('', ' ') and \
s[i+le:i+le+1] in ('', ' '):
count += 1
return count
Exception handling based version of the above code:
def check(s, ind):
"""
Check whether the item present at this index is a space or not.
For out of bound indices return True.
For negative indices return True.
"""
if ind < 0:
return True
try:
return s[ind] == ' '
except IndexError:
return True
def sub_str_count(s, sub_str):
le = len(sub_str)
count = 0
for i in range(len(s)):
if s[i:i+le] == sub_str and check(s, i-1) and check(s, i+le):
count += 1
return count