Применение арифметических операций над списком чисел без повторения в python - PullRequest
2 голосов
/ 24 сентября 2019

У нас есть следующий список Python: [1,2,3,10] Я хотел бы выполнить следующее: Создать функцию, которая берет в список и вычисляет из списка арифметических операций: ['+', '-', '/','*'], какие комбинации дают нам 6 какответ.Мы не хотим повторения, поэтому мы не хотим, чтобы 2*3 и 3*2 в нашем решении.Мы хотим перечислить номера, которые мы не использовали, так что это (1 и 10 здесь).То же самое для 2/1*3=6.0, 2*3/1=6.0, 3/1*2=6.0, 3*2/1=6.0 считаются эквивалентными, поскольку мы используем одни и те же числа независимо от операций и не использовали 10. Я хочу, чтобы функция была достаточно общей, чтобы я могла ее использоватьоттуда номера от 1 до 9. Ваша помощь приветствуется.Я попытался использовать itertools и перестановку, чтобы получить список всех возможных комбинаций, но это кажется ненужным и приводит к проблеме, что 2/1*3=6.0, 2*3/1=6.0, 3/1*2=6.0, 3*2/1=6.0 включены в список, и это трудно отфильтровать.

Пример, где я использовал itertools:


from itertools import chain, permutations

def powerset(iterable):
  xs = list(iterable)
  return chain.from_iterable(permutations(xs,n) for n in range(len(xs)+1) )

lst_expr = []
for operands in map(list, powerset(['1','2','3','10'])):
    n = len(operands)
    #print operands
    if n > 1:
        all_operators = map(list, permutations(['+','-','*','/'],n-1))
        #print all_operators, operands
        for operators in all_operators:
            exp = operands[0]
            i = 1
            for operator in operators:
                exp += operator + operands[i]
                i += 1

            lst_expr += [exp]

lst_stages=[]

for equation in lst_expr:
    if eval(equation) == 6:
        lst_stages.append(equation)
        eq = str(equation) + '=' + str(eval(equation))
        print(eq)

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

Мне нравится решение Саньяша, но я думаю, что это можно сделать более элегантно, используя комбинации операндов и перестановок, пока не будет найдено первое с правильным значением:

from itertools import chain, permutations, combinations


def powerset(iterable):
    xs = list(iterable)
    return chain.from_iterable(combinations(xs, n) for n in range(len(xs) + 1))

def get_first_perm_with_value(operands, operators, expected_value):
    if len(operands) == 0 or len(operands) == 0:
        return []

    all_operators = list(map(list, permutations(operators, len(operands) - 1)))
    all_operands = list(map(list, permutations(operands, len(operands))))

    for operator in all_operators:
        for operand in all_operands:
            result = [""] * (len(operand) + len(operator))
            result[::2] = operand
            result[1::2] = operator
            eq = ''.join(result)
            if int(eval(eq)) == expected_value:
                return [(f'{eq}={expected_value}', operands)]
    return []


lst_expr = []
for operands in map(list, powerset(['1', '2', '3', '10'])):
    lst_expr += get_first_perm_with_value(operands, ['+','-','*','/'], 6)

print(lst_expr)

Возвращает:

[('2*3=6', ['2', '3']), ('2*3/1=6', ['1', '2', '3']), ('1+10/2=6', ['1', '2', '10']), ('2*10/3=6', ['2', '3', '10']), ('2*3+1/10=6', ['1', '2', '3', '10'])]
1 голос
/ 24 сентября 2019

Здесь возможное решение.Нам нужно сохранить отсортированный кортеж используемых чисел, чтобы избежать дублирования, например, 2 * 3 и 3 * 2.

from itertools import chain, permutations

def powerset(iterable):
  xs = list(iterable)
  return chain.from_iterable(permutations(xs,n) for n in range(len(xs)+1) )

lst_expr = []
for operands in map(list, powerset(['1','2','3','10'])):
    n = len(operands)
    #print operands
    if n > 1:
        all_operators = map(list, permutations(['+','-','*','/'],n-1))
        #print all_operators, operands
        for operators in all_operators:
            exp = operands[0]
            numbers = (operands[0],)
            i = 1
            for operator in operators:
                exp += operator + operands[i]
                numbers += (operands[i],)
                i += 1

            lst_expr += [{'exp': exp, 'numbers': tuple(sorted(numbers))}]

lst_stages=[]
numbers_sets = set()

for item in lst_expr:
    equation = item['exp']
    numbers = item['numbers']
    if numbers not in numbers_sets and eval(equation) == 6:
        lst_stages.append(equation)
        eq = str(equation) + '=' + str(eval(equation))
        print(eq, numbers)
        numbers_sets.add(numbers)

Вывод:

2*3=6 ('2', '3')
1+10/2=6.0 ('1', '10', '2')
2/1*3=6.0 ('1', '2', '3')
...