Print only one list in recursion - python

In the following code, I return the integer value for the amount of consecutive numbers in a given string.
def consecutive_length(S):
if S == '':
return 0
if len(S) == 1:
return 1
if S[0] == S[1]:
return 1 + consecutive_length(S[1:])
return 1
def compress(S):
if S == '':
return 0
cons_length = consecutive_length(S)
return [cons_length] + [compress(S[cons_length:])]
When I run this print statement, the following is returned:
>>> print (compress('1111000000001111000111111111111111'))
[4, [8, [4, [3, [15, 0]]]]]
Where I really want the following to be returned:
>>> print (compress('1111000000001111000111111111111111'))
[4, 8, 4, 3, 15]

An alternative to your method is to use itertools.groupby():
from itertools import groupby
s = '1111000000001111000111111111111111'
answer = [len([digit for digit in group[1]]) for group in groupby(s)]
print(answer)
Output
[4, 8, 4, 3, 15]

Here you go:
def consecutive_length(S):
if S == '':
return 0
if len(S) == 1:
return 1
if S[0] == S[1]:
return 1 + consecutive_length(S[1:])
return 1
def compress(S):
if S == '':
return []
cons_length = consecutive_length(S)
return [cons_length] + compress(S[cons_length:])

When you return a list, [what_is_returned] will be a nested list, but when you return an integer, it will be just a list. Instead, (in compress()) ,always return a list, and remove the brackets when you use what it returns:
def consecutive_length(S):
if S == '':
return 0
if len(S) == 1:
return 1
if S[0] == S[1]:
return 1 + consecutive_length(S[1:])
return 1
def compress(S):
if S == '':
return []
cons_length = consecutive_length(S)
return [cons_length] + compress(S[cons_length:])

Related

Python Function "Not Defined" in VSCODE [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 days ago.
This post was edited and submitted for review 2 days ago.
Improve this question
class Hand:
def __init__(self, hand):
self.hand = hand
def rank_to_index_converter(rank):
if rank == 2:
return 0
elif rank == 3:
return 1
elif rank == 4:
return 2
elif rank == 5:
return 3
elif rank == 6:
return 4
elif rank == 7:
return 5
elif rank == 8:
return 6
elif rank == 9:
return 7
elif rank == 10:
return 8
elif rank == 'J':
return 9
elif rank == 'Q':
return 10
elif rank == 'K':
return 11
elif rank == 'A':
return 1
else:
raise ValueError
def suit_to_index_converter(suit):
if suit == 'C':
return 0
elif suit == 'D':
return 1
elif suit == 'H':
return 2
elif suit == 'S':
return 3
else:
raise ValueError
def is_consecutive(hand):
### BEGIN YOUR SOLUTION
first = 0
string = ""
count = 0
for x in hand:
#print(x[0])
if x[0] == ("J"):
if first != 10 and (count != 0):
return False
string = x[0]
elif x[0] == ("Q"):
if string != "J" and (count != 0):
return False
string = x[0]
elif x[0] == ("K"):
if string != "Q" and (count != 0):
return False
string = x[0]
elif x[0] == ("A"):
if string != "K" and (count != 0):
return False
string = x[0]
elif x[0] != ("J" or "Q" or "K" or "A"):
if (x[0] != (first + 1)) and (count != 0):
if (hand[0][0] != "A"):
return False
first = x[0]
count = count + 1
return True
def is_suit(hand):
suit = hand[0][1]
for x in hand:
if x[1] != suit:
return False
return True
def is_flush(hand):
return is_suit(hand) and not is_consecutive(hand)
def is_four_of_a_kind(hand):
count = 0
pair_num = 0
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
for x in lst:
if x == 4:
return True
return False
def is_full_house(hand):
count = 0
pair_num = 0
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
three_pair = False
pair = False
for x in lst:
if x == 3:
three_pair = True
if x == 2:
pair = True
if three_pair and pair:
return True
return False
def is_flush(hand):
count = 0
while count < (len(hand) - 2):
if hand[count][1] != hand[count + 1][1]:
return False
count += 1
return True
def is_straight(hand):
if is_consecutive(hand) and not is_suit(hand):
return True
return False
def is_three_of_a_kind(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
three_pair = False
for x in lst:
if x == 3:
three_pair = True
if three_pair and not is_full_house(hand) and not is_suit(hand):
return True
return False
def is_two_pair(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
two_pair = False
counter = 0
switch = 0
while counter != len(lst):
if lst[counter] == 2:
switch = 1
if lst[counter] == 2 & switch == 1:
two_pair = True
if two_pair and not is_full_house(hand) and not is_suit(hand) and not is_four_of_a_kind(hand) and not is_three_of_a_kind(hand):
return True
return False
def is_pair(hand):
lst = [0 for i in range(13)]
for x in hand:
index = rank_to_index_converter(x[0])
lst[index] += 1
pair = False
for x in lst:
if x == 2:
pair = True
if pair and not is_full_house(hand) and not is_suit(hand):
return True
return False
def maximum_value(hand):
sum = 0
for x in hand:
sum += rank_to_index_converter(x[0])
return sum
The is_full_house function uses the rank_to_index_converter function. The rank_to_index_converter function is defined above the is_full_house function. Why am I receiving an error that the rank_to_index_converter function is not defined?
I am lost on where to proceed; therefore, I haven't tried anything, besides copying and pasting the rank_to_index_converter function into the is_full_house function; however, it is more convenient if the rank_to_index_converter is a separate function. That is why I want to solve this issue.

Number of times two charachters appear between two strings, only 1 function, and only parameters are the 2 strings

I want to count the number of times both a and b occur, in both strings together, using recursion in Python.
For example, if the input was ('aabb', 'bbba'), the output would be (3,5) because there are three a's and five b's total.
What I have tried:
def counting(string1, string2):
if not string1:
return 0
elif string1[0]=='a':
return 1+counting(string[1:],string2)
else:
return counting(string[1:],string2)
def counting(string1, string2):
def counting_recurse(string_total):
if not string_total:
return (0, 0)
elif string_total[0]=='a':
a_count, b_count = counting_recurse(string_total[1:])
return (1+a_count, b_count)
elif string_total[0]== 'b':
a_count, b_count = counting_recurse(string_total[1:])
return (a_count, b_count +1 )
else:
return counting_recurse(string_total[1:])
return counting_recurse(string1 + string2)
This works on your example. Does this solve your scenario?
You can recurse until both strings are empty.
def counting(string1, string2):
if string1 or string2:
a, b = counting(string1 and string1[1:], string2 and string2[1:])
count = lambda x: (string1 and string1[0] == x or 0) + (string2 and string2[0] == x or 0)
return (a + count('a'), b + count('b'))
return (0, 0)
print(counting('aabb', 'bbba'))
This seems like a simpler solution
Explanation
If you've reached end of string, then return (0,0) for a count and b count
Otherwise, you add 1 + a_count if first character is a otherwise you add 0 + a_count.
Similarly, you add 1 + b_count if first character is b otherwise you add 0 + b_count.
a_count is defined as the first value in tuple(), b_count is the second value()
def counting_recurse(combine_string):
if not combine_string:
return (0, 0)
return (int(combine_string[0]=='a') +counting_recurse(combine_string[1:])[0],
int(combine_string[0]=='b') +counting_recurse(combine_string[1:])[1])
string1 = 'aabb'
string2 = 'bbba'
counting_recurse(string1+string2)
Output
(3, 5)
def counting(stri, char):
if len(stri) == 0:
return 0
elif stri[0] == char:
return 1 + counting(stri[1:], char)
else:
return counting(stri[1:], char)
def count(str1, str2):
return (counting(str1,'a'),counting(str2,'b'))
print("aabb","bbba")
Looks like having two strings as arguments to the function is unnecessarily complicated, since you count across both strings anyway. So why not simply define the recursive function for a single string and call it on the concatenation of the two strings you're interested in, e.g.
def count_ab(s):
if not s:
return 0, 0
first_a = int(s[0] == 'a')
first_b = int(s[0] == 'b')
further_a, further_b = count_ab(s[1:])
return first_a + further_a, first_b + further_b
count_ab('aabb' + 'bbba')
(3, 5)
The following works:
def non_recursive_imp2(*args: str) -> tuple:
sargs = tuple(map(str, args))
a_count = 0
b_count = 0
for sarg in sargs:
for ch in sarg:
if ch == "a":
a_count += 1
elif ch == "b":
b_count += 1
return (a_count, b_count)
import operator
def recursive_count(inpuht:str, _:str):
inpuht += _
if len(inpuht) < 2:
if inpuht == "a":
return (1, 0)
elif inpuht == "b":
return (0, 1)
return (0, 0)
else:
left_str = inpuht[:len(inpuht)//2]
right_str = inpuht[len(inpuht)//2:]
left_count = recursive_count(left_str, "")
right_count = recursive_count(right_str, "")
return tuple(map(operator.add, left_count, right_count))
However, it is easier to write code for a non-recursive implementation:
NON-RECURSIVE IMPLEMENTATIONS:
def non_recursive_imp(x:str, y:str) -> tuple:
merged = x + y
a_count = 0
b_count = 0
for ch in merged:
if ch == "a":
a_count +=1
elif ch == "b":
b_count +=1
return (a_count, b_count)

Fibonacci that takes a list of numbers and returns their fibonacci number

I am trying to implement a function that will print a number of fibonacci numbers. For example if my input was fibonacci([0,1,2,3], the output would be 0,1,1,2.
I am not sure how to proceed.
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
return fibonacci(n - 1) + fibonacci(n-2)
while True:
n.append(n)
print(fibonacci[5,10,11])
You can refactor your code a bit and get:
def fibonacci(lst):
def getTerm(n):
if n == 0:
return 0
elif n == 1:
return 1
return getTerm(n - 1) + getTerm(n-2)
return [getTerm(x) for x in lst]
Gives output:
>>> fibonacci([0,1,2,3])
[0, 1, 1, 2]
>>> fibonacci([5,10,11])
[5, 55, 89]
Avoiding redundant computations:
def fibonacci(indices):
fibs = {}
set_of_indices = set(indices)
f0 = fibs[0] = 0
f1 = fibs[1] = 1
for i in range(2,max(indices)+1):
f2 = f0+f1
if i in set_of_indices:
fibs[i] = f2
f0,f1=f1,f2
return [fibs[i] for i in indices]

Itertools ( groupby function ) with python 3.5

Im trying to figure what is going wrong with my code. Im trying to get right result but it's come out always random answer. Let's says for example I shuffle [ V, V, V, A, V ] I want the result to be [4, 1] but it comes out as [2, 1, 2]. Can you help me ?
class Combinaison:
types_cartes = [
Carte.AS, Carte.ROI, Carte.DAME, Carte.VALET, Carte.DIX, Carte.NEUF
]
def __init__(self, des=None):
self.nb_lancers = 1
if des is None:
self.des = self._lancer_des(5)
else:
self.des = des
def determiner_type_combinaison_sans_as(self):
valeurs = [len(list(group)) for key, group in groupby(des)]
valeurs.sort(reverse=True)
sequence1 = [0, 1, 2, 3, 4]
sequence2 = [1, 2, 3, 4, 5]
if valeurs == sequence1 or valeurs == sequence2:
return " straight "
elif valeurs[0] == 5:
return " five of a kind "
elif valeurs[0] == 4:
return " four of a kind "
elif valeurs[0] == 3:
if valeurs[1] == 2:
return " Fullhouse "
else:
return " three of a kind"
elif valeurs[0] == 2:
if valeurs[1] == 2:
return " two pairs"
else:
return " one pair"
else:
return " nothing good, reshuffle"
class Carte(Enum):
"""Énumeration des types de cartes."""
AS = 0
ROI = 1
DAME = 2
VALET = 3
DIX = 4
NEUF = 5
def __str__(self):
if self == Carte.AS:
return "A"
if self == Carte.ROI:
return "R"
if self == Carte.DAME:
return "D"
if self == Carte.VALET:
return "V"
if self == Carte.DIX:
return "X"
if self == Carte.NEUF:
return "9"
You need to sort before you groupby. It splits an iterable by equality. It does not accumulate groups.
valeurs = [len(list(group)) for key, group in groupby(sorted(des))]
But it might be better to use the collections.Counter:
valeurs = Counter(des).values()

python loops instead of recursion

I am a newbie in python .
Guys I have written one function which checks that the list is palindrome or not but I wanted to replace it with pure looping statements .Do u have any solution or do I have to use recursive function compulsorily .
import json
def reverse(x):
if isinstance(x, list):
return [reverse(x) for x in x[::-1]]
return x
def palindrome(x):
return x == reverse(x)
st=raw_input("Enter List : ")
lst=json.loads(st)
print palindrome(lst)
check this...
>>> def palindrome(n):
return n == n[::-1]
>>> palindrome('chk')
False
>>> palindrome('chc')
True
>>>
Check this out:
def is_palindrome(lst):
n = len(lst)
p, q = 0, n - 1
while p <= q:
pitem, qitem = lst[p], lst[q]
if isinstance(pitem, list) and isinstance(qitem, list):
if len(pitem) != len(qitem):
return False
if p == q:
lst[p:p+1] = pitem
q = p + len(pitem) - 1
else:
lst[p:p+1] = pitem
q += len(pitem) - 1
lst[q:q+1] = qitem
q += len(qitem) - 1
continue
elif pitem != qitem:
return False
p += 1;
q -= 1
return True
Above code also passes for nested list:
assert is_palindrome([1, 2, 3, 2, 1])
assert not is_palindrome([[0, 1]])
assert not is_palindrome([[0, 1, 1]])
assert is_palindrome([[0, 1, 0]])
assert is_palindrome([1, [1, 2], 3, [2, 1], 1])
You can do it with a simple loop:
def is_palindrome(s):
n = len(s)
for i in range(n / 2):
if s[i] != s[n - 1 - i]:
return False
return True
It's worth to mention, that above function uses only n / 2 comparisons and the below solution uses n comparisons:
def is_palindrome(s):
return s == s[::-1]
def palindrome(x):
q = [x]
while q:
x = q.pop()
if isinstance(x, list) and x:
if isinstance(x[0], list) and isinstance(x[-1], list):
q.append(x[0] + x[-1])
elif x[0] != x[-1]:
return False
q.append(x[1:-1])
elif isinstance(x, str):
q.append(list(x))
return True
def palindrome(x):
q = [x]
while q:
x = q.pop()
if isinstance(x, (str, list)):
for i in range(len(x) + 1 // 2):
if isinstance(x[i], list) and isinstance(x[-i-1], list):
q.append(x[i] + x[-i-1])
elif x[i] != x[-i-1]:
return False
return True
>>> palindrome('cat')
False
>>> palindrome('yay')
True
>>> palindrome([1, 2,3,[2],1])
False
>>> palindrome([1, [2,3,[4]],[[4],3,2],1])
True
>>> palindrome([[2,3], [2,3]])
False

Categories

Resources