I'm trying already for some days to solve this problem without any success.
About this problem:
Given a sequence '2 2 4 4'.
We take consecutively 2 numbers from the sequence, For example: 2 2 ,2 4, 4 4.
If the sum of the 2 numbers is an number divisible by 2 we replace the 2 numbers and put the result of the 2 numbers for example: (2+2 = 4, 4/2 = 2) so the new sequence is (2 4 4), but here I should find all possible sequences. If no possible to find an even number that is dividable by 2, so we return the sequence.
A picture of how should it be
The red rectangles are the sequence that I cannot get :(
my code:
def recFunc(n):
for i in range(len(n)):
if i+1 <= len(n)-1: #control out of range
if ((n[i] + n[i+1]) % 2 == 0):
newnum = int((n[i] + n[i+1])/2)
n[i:i+2] = [newnum]
return recFunc(n)
else:
if i+1 == len(n)-1:
return [n]
else:
continue
def main(s):
s = s.split()
integers = [int(x) for x in s]
final = recFunc(integers)
print(final)
main('2 2 4 4')
What I did here is ,converted the sequence to integers , sent them to a new function. That I should receive all sequences recursively.
I iterated on the sequence and taking the first number by n[i] and the second n[i+1] (and controlling if I can have the second number to not get out of range).
The final result should be ordered in increasing mode of the size sequence, if the length of the 2 sequence is that same so we order by the first number of the sequence.
At the end I should receive ['3', '2 3', '3 4', '2 3 4']
Below is my recursive solution, based on your diagram, which can handle '30 20 10 30 6 6' without stack issues. Data conversion, sorting and redundancy reduction are handled by the main()
routine. The sub_sequence()
function takes an array and returns an array of arrays that match the logic of your diagram:
def sub_sequence(array):
solutions = []
length = len(array)
changed = False
if length > 1:
for index in range(len(array) - 1):
prefix, pair, postfix = array[:index], array[index:index + 2], array[index + 2:]
total = sum(pair)
if total % 2 == 0:
solutions.extend(sub_sequence([*prefix, total // 2, *postfix]))
changed = True
if length < 2 or not changed:
solutions.append(array)
return solutions
def main(string):
unsorted_redundant_sub_sequences = sub_sequence([int(number) for number in string.split()])
unsorted_non_redundant_strings = set(" ".join(map(str, sequence)) for sequence in unsorted_redundant_sub_sequences)
sorted_non_redundant_strings = sorted(unsorted_non_redundant_strings, key=lambda x: (len(x), x))
print(sorted_non_redundant_strings)
main('30 20 10 30 6 6')
OUTPUT
> python3 test.py
['18', '19', '19 6', '25 6', '25 10', '25 14', '30 13', '30 15', '30 17', '30 13 6', '30 17 6', '30 15 12', '30 15 18']
>
I created a few functions to accomplish the goal:
least_check
that give a True
/ False
as to whether or not the sequence is a "least" (eg '2 4'
would return False
, while '3 4'
would return True
) find_leasts
which is the recursive function that breaks a sequence down to the the next level in the tree shown in the question (eg '2 2 4 4'
would break down to '2 4 4'
, '2 3 4'
, and '2 2 4'
) until it reaches all "leasts" main
which creates a list of all the "leasts" yield
ed from the find_leasts
function, and removes any duplicates (eg example sequence has '3'
twice) and returns the list of unique "leasts" Answer:
def least_check(n):
check_list = [int(x) for x in n.split(' ')]
for a, b in zip(check_list[:-1], check_list[1:]):
if (a + b) % 2 == 0:
return False
return True
def find_leasts(n):
if len(n.split(' ')) == 1:
yield n
for i in range(len(n.split(' '))-1):
s = [int(x) for x in n.split(' ')]
if (s[i] + s[i+1]) % 2 == 0:
s[i] = int((s[i] + s[i+1]) / 2)
s.pop(i+1)
sub_n = ' '.join(str(j) for j in s)
if least_check(sub_n):
yield sub_n
else:
yield from find_leasts(sub_n)
def main(s):
all_leasts = [x for x in find_leasts(s)]
unique_leasts = list(set(all_leasts))
return unique_leasts
seq = '2 2 4 4'
print(sorted(main(seq), key=len))
Result:
['3', '2 3', '3 4', '2 3 4']
Update:
The above solution has many split()
s and ' '.join()
s in order to avoid the recursive function modifying a list reference (a list name is a pointer to its memory address - if needed, see this site for further explanation) from a depth other than the current scope.
When looking at the error received on a '30 20 10 30 6 6'
sequence and considering that playing with the max recursion via sys.setrecursionlimit is not recommended , I re-evaluated whether or not recursion was even necessary - and determined it is not.
Here are the functions used in the iterative solution:
least_check
- same as original answer break_down
- takes a list and breaks it down to all lists down one level in the tree (eg '2 2 4 4'
would break down to '2 4 4'
, '2 3 4'
, and '2 2 4'
) least_lister
- iterates through the queue of lists that are potential leasts, until all lists in least_lists
are leasts main
- does all split()
and ' '.join()
operations and removes duplicates before returning results Iterative Solution:
def least_check(check_list):
for a, b in zip(check_list[:-1], check_list[1:]):
if (a + b) % 2 == 0:
return False
return True
def break_down(s, ret):
for i in range(len(s)-1):
if (s[i] + s[i+1]) % 2 == 0:
bd_list = s.copy()
bd_list[i] = int((bd_list[i] + bd_list[i+1]) / 2)
bd_list.pop(i+1)
ret.append(bd_list)
def least_lister(n):
least_lists = []
if least_check(n):
least_lists.append(n)
else:
i = 0
break_down(n, least_lists)
while i < len(least_lists):
if least_check(least_lists[i]):
i+=1
else:
break_down(least_lists[i], least_lists)
least_lists.pop(i)
return least_lists
def main(s):
s_list = [int(x) for x in s.split(' ')]
all_leasts = least_lister(s_list)
unique_leasts = list(set([' '.join(str(j) for j in i) for i in all_leasts]))
return unique_leasts
seq = '30 20 10 30 6 6'
print(sorted(main(seq), key=len))
Iterative Result:
['18', '19', '19 6', '25 6', '25 10', '25 14', '30 13', '30 15', '30 17', '30 13 6', '30 17 6', '30 15 12', '30 15 18']
List Reference Example
def add_to_list(n):
n.append(len(n))
print(n)
a = [0, 1]
add_to_list(a)
print(a)
List Reference Example Output:
[0, 1, 2]
[0, 1, 2]
Let's see this problem step by step.
First : Sum the first number of the array with the second one,
divide by two the result,
create a new array with the new values,
if it's even
then call recursive on the new arrey
Else put the new arrey in a static data structure
Second : At the first point we need to see all the index,
Put everything in a cycle starting with index I = 0 to length-2
Third : work on the static array, sort it as you want and print the result.
I'm not good with python but I hope this pseudo code will help you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.