I need to write this iterative function to do the same thing but it must be recursive.
def task1(string: str):
for i in range(len(string)):
if string[i] != string[len(string) - i - 1]:
return False
return True
This is what i tried but it does not work.
def task1_recursion(string: str):
print(string)
if len(string) > 1:
if string[0] == task1_recursion(string[1::1]):
return True
else:
return False
else:
return string
My code seems to one the last recursion return string "" and that makes it to return False.
Just check the tip and the tail, continue with the string without them:
def task1_recursion(string: str):
# recursion base condition (exit condition)
if len(string) <= 1:
return True
# unpack values
first, *_, last = string
# check if they are different
if first != last:
return False
# if not continue checking the remaining string
return task1_recursion(string[1:-1])
If I understand correctly you want to check if a string is symmetric with the code in task1. My solution is below:
def fct(s: str, i: int):
if len(s) <= 1 or i == len(s):
return True
return s[i] == s[len(s) - 1 - i] and fct(s, i + 1)
I tested and fct produces the same result as task1. It needs an additional parameter for the index though. But you can wrap it inside another function if you want the parameter to include only the input string. i is always set to 0 when you call the function, e.g. fct("ABCCBA", 0).
Related
I am trying to remove def function since we are not allowed to use that, but I don't know how to.
def is_one_away(first: str, other: str) -> bool:
# check lengths
if len(first) != len(other):
return False
error_count = 0
for i in range(len(first)):
if first[i] != other[i]:
error_count += 1
if error_count > 1:
return False
return True
That's the def function, but I'm trying to incorporate it into my actual code.
This is the part of the code that Im trying to incorporate it into.
if is_one_away(x, y):
similarity = True
Change the returned value to the value you're assigning to similarity.
Use break to end the loop instead of return.
if len(x) != len(y):
similarity = False
else:
for i in range(len(x)):
if x[i] != y[i]:
similarity = False
else:
similarity = True
There's no need for error_count, since you always return as soon as you find a non-match.
Problem Statement:
You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position. Return true if you can reach the last index, or false otherwise.
How can I change my code so that it returns immediately when I have found a path that works for this problem instead of going through all the recursive calls that I have made previously
def canJump(self, nums: List[int]) -> bool:
solve = [False]
def backtrack(i):
if solve[0] == True:
return
if i == len(nums)-1:
solve[0] = True
return
if i >= len(nums) or nums[i] == 0:
return
for x in range(1, nums[i]+1):
backtrack(i+x)
backtrack(0)
return solve[0]
General Form of a Recursive Function
The general form of a recursive function has two mutually exclusive types of conditions that can be met on each iteration of the recursion. These are either:
terminal conditions, or
non-terminal conditions.
Both types of condition contain a return statement.
Terminal Conditions
The return statement in terminal conditions typically takes the form return <value>.
The solution to the problem you are trying to solve requires two possible terminal conditions:
The case where you know you can reach the last index. return True
The case where you know you can NOT reach the last index. return False
Non-Terminal Conditions
The non-terminal condition will occur on iterations where neither of the terminal cases are met. In this situation, you will call the recursive function and return what it returns.
This answer covers terminal and non-terminal conditions in more detail.
Example
Consider a recursive function that sums the numbers of an array.
def sum(position, array, end):
if(position == end): # terminal condition
return 0
else: # non-terminal condition
return array[position] + sum(position+1, array, end)
Another Example
Depending on any constraints to your problem that I might have missed, a solution might be the following:
def jump(current_position, nums, finish_line):
"""
greedy algorithm:
choose the next position with the largest sum of (jump_range + index)
"""
jump_range = nums[current_position]
choice = current_position + jump_range
if(jump_range == 0): # terminal condition
return False
if(choice >= finish_line): # terminal condition
return True
else: # non-terminal condition
utility = 0
for next_position in range(current_position+1, jump_range+1):
next_jump_range = nums[next_position]
if(utility <= next_position + next_jump_range):
utility = next_position + next_jump_range
choice = next_position
return jump(choice, nums, finish_line)
input1 = [2,0,0,10,3]
input2 = [2,3,0,10,3]
current_position = 0
finish_line = len(input1)
print(jump(0, input1, finish_line)) # False
finish_line = len(input2)
print(jump(0, input2, finish_line)) # True
The most noteworthy difference from your solution is that return statements always return a value.
How can I change my code so that it returns immediately when I have found a path that works for this problem instead of going through all the recursive calls that I have made previously
One particularly straightforward way is to throw an exception, which will immediately unwind the stack.
def can_jump(nums: list[int]) -> bool:
if not nums:
return False
class _Success(Exception):
pass
def backtrack(i):
if i >= len(nums):
return
if i == len(nums) - 1:
raise _Success()
for x in range(1, nums[i] + 1):
backtrack(i + x)
try:
backtrack(0)
return False
except _Success:
return True
We create a local exception type called _Success that the backtracking search can throw to indicate that it found a solution.
If it never finds a solution, the backtrack function will simply return and the return False line will run. Otherwise, it will raise _Success() and then the return True line will run.
Could you please help me why the second method does not work in the class even though it works separately?
the question is
Develop a SuperStr class that inherits the functionality of the standard str type and contains 2 new methods:
a. is_repeatance(s) method, which takes 1 argument s and returns True or False depending on whether the current row can be obtained by an integer number of repetitions of the string s. Return False if s is not a string. Assume that the empty string contains no repetitions.
b. is_palindrom() method, which returns True or False depending on whether the string is a palindrome. Ignore the case of characters. The empty string is considered a palindrome.
my code:
class SuperStr:
def __init__(self, main_str):
self.main_str= main_str
def is_repeatance(self, s):
string = self.main_str
count = 0
is_repeated = False
if string == '':
return False
else:
for i in range(0, len(string)):
if string[i] == s:
count = count + 1
if count == 2:
is_repeated = True
return is_repeated
break
return is_repeated
def isPalindrome(str):
if str == '':
return True
else:
for i in range(0, int(len(str) / 2)):
if str[i] != str[len(str) - i - 1]:
return False
return True
str = SuperStr("welcome to the world of python programming")
print(str.is_repeatance('s'))
print(str.isPalindrome('saas'))
the result is https://drive.google.com/file/d/1dHXK8RJs7vlRovULrUPS5uxRkX_oDNRO/view?usp=sharing
the second method does not work but the first does
even though it works this way if it is alone
https://drive.google.com/file/d/1SBFnQ6OeDGtoTvo98SHeSdIbks8BTXnT/view?usp=sharing
What Avinash said in the comments should fix your problem. You need to include self in the method definition. e.g.
def isPalindrome(self, s):
if s == '':
return True
else:
for i in range(0, int(len(s) / 2)):
if s[i] != s[len(s) - i - 1]:
return False
return True
The error you have is...
TypeError: isPalindrome() takes 1 positional argument but 2 were given
The error is saying that isPalindrome() has been defined with 1 positional argument. In your case this is the str in the def isPalindrome(str):. When you call it using the instance object str.isPalindrome('saas'), python adds the object itself as the first argument, so the method is called with 2 arguments. The object str and the value 'saas'.
Notice also that your def is_repeatance(self, s): method has self as an argument and works fine.
I have an assignment, I have to make a python code that checks whether a string is a palindrome using a recursive function that returns a boolean, but I am not allowed to use reversed slicing nor loops, and I am not allowed to change the function format, here's my code but it returns True all the time
def is_palindrome(s):
res = []
s = ['']
if len(s) < 2:
return True
else:
rev_s = is_palindrome(s[1:]) + s[0]
res.append(rev_s)
if res == s:
return True
return False
You can check if the first and the last character of the given string are the same and then recursively check if the remaining string is a palindrome instead:
def is_palindrome(s):
return len(s) < 2 or s[0] == s[-1] and is_palindrome(s[1:-1])
I'm not sure if this counts as 'changing the function format', but here's my stab at a recursive version without slices:
def is_palindrome(s):
def is_palindrome_r(i, j):
if j <= i:
return True
if s[i] != s[j]:
return False
return is_palindrome_r(i + 1, j - 1)
return is_palindrome_r(0, len(s) - 1)
The inner function, is_palindrome_r, is the recursive function that takes two indexes, i and j. The last line sets the initial positions for these two indexes at 0 (the start of the string) and len(s) - 1 (the end of the string) and proceeds with the recursive logic. The recursive function has two exit conditions:
if j <= i we've reached the center of our palindrome. If we've gotten this far, we know all the other pairs of characters match and we don't need to do any more comparisons.
if the two characters pointed to by i and j do not match, it's definitely not a palindrome and we don't need to do any more comparisons.
Otherwise we don't yet know if the sequence is fully palindromic, so we we move our indexes one step inward (i + 1, j - 1) and go back to step 1.
No slicing used, just maintain the indices through the recursive calls
def is_palindrome(s):
return helper(s, 0, len(s)-1)
def helper(s, i, j):
if (i >= j):
return True
return s[i] == s[j] and helper(s, i+1, j-1)
If the mentioned function signature def is_palindrome(s) is the signature given by your teacher then no issue and there is no need to pass any extra parameter to achieve the goal.
Your teacher (or the one gave you this task is awesome) just wanted t check how do you handle this with only 1 parameter.
The concept is very simple, just change the type of argument (to list with 3 values) in second recursive call.
def is_palindrome(s):
if type(s) is str:
l = len(s)
if l == 0 or l == 1:
return True
else:
return is_palindrome([s, 0, -1])
else:
string, start, end = s # s is list here
if string[start] != string[end]:
return False
else:
if(start + 1 >= end - 1):
return True
return is_palindrome([s, start + 1, end - 1])
def main():
string1 = "abcba"
string2 = "abcde"
string3 = "AxxA"
print(is_palindrome(string1)) # True
print(is_palindrome(string2)) # False
print(is_palindrome(string3)) # True
main();
The following is not what you're looking for but may be you'll be looking for that in future.
>>> def is_palindrome(s):
... if s == "".join(reversed(s)):
... return True
... else:
... return False
...
>>> is_palindrome("ABA")
True
>>>
>>> is_palindrome("ABC")
False
>>>
>>> is_palindrome("XXZZXX")
True
>>>
>>> is_palindrome("##7")
False
>>>
>>> is_palindrome("1###1")
True
>>>
Thank you.
Im trying to write a recursive function that gets as an input a string and a char. the function return the first index appearance of the char in the string. If the char doesnt appear it returns None.
I have a problem only with returning None. In my case when the char isnt in the string the function throws an error, any advice?
def char_first_index(s,c):
if len_rec(s)==0:
return None
if s[0]==c:
return 0
return 1+ char_first_index(s[1:],c)
You are creating a new slice at each iteration, and you have to add 1 for each recursion. Instead, recurse on the index:
def char_first_index(s, c, index = 0):
if len(s) == index:
return None
if s[index] == c:
return index
return char_first_index(s, c, index + 1)
If the character is not in the input, your function tries to perform 1+None, hence the error. Try this instead:
def char_first_index(s,c):
if len_rec(s)==0:
return None
if s[0]==c:
return 0
answer = char_first_index(s[1:],c)
if answer is not None:
return 1+answer
else:
return answer
Firstly I'm assuming len_rec is a recursive function that gets the length of the string; you haven't written it so I've just changed it to len() for testing.
Secondly, I'm not sure how this function is supposed to handle the character not being in the string, as that will mean trying to add None to a number.
Here is an amended function that still uses your count idea, but handles the case of a None being returned:
def char_first_index(s,c):
if len(s)==0:
return None
elif s[0]==c:
return 0
else:
count = char_first_index(s[1:], c)
if count != None:
return count + 1
else:
return None