При заданном списке цифр сохраняйте их по порядку, используя + - * / для получения определенного результата. - PullRequest
3 голосов
/ 08 июля 2011

Не уверен, если это было задано ранее, но не смог найти конкретное упоминание о проблеме такого типа.

Это вариант подмножества суммы и ранца.

Хотяпохожий вопрос , по-видимому, задавался раньше , но логика достаточно различна, чтобы гарантировать новый поток.

Параметры: Сумма указана, а также список целых чисел.Целые числа можно комбинировать любым количеством способов (например, 1 2 3 = 12, 3 или 1, 23 или 1, 2 3). Допускается 3 операции:

  • 1 сложение
  • 1 вычитание
  • 1 деление

Образец:

1 2 9 3 7 4 = 22

Решение:

(129 - 3) / 7 + 4 = 22

Существует ли классификация для этого типа упражнений?(например, подмножество-сумма и т. д.)

Некоторые мысли:

  1. Создание многомерного массива всех возможных числовых комбинаций.Поскольку разрешены только 3 оператора, массив будет содержать 3 столбца / элемента.

  2. Произвольно вставьте операторы в точках 1, 2 или 3 и перебором до достижения решения.

Это монументально далеко от элегантного решения.
Любое понимание будет приветствоваться.

Я, вероятно, закодирую это в Perl, но псевдокод, указатели илисинтаксис на любом языке был бы великолепен.Насмешливая насмешка из-за моей нехватки математики, в которой тоже круто;)

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 08 июля 2011

Я только что ответил на этот вопрос, но он был неправильно перенесен на другой сайт stackexchange: https://codegolf.stackexchange.com/questions/3019/getting-an-answer-from-a-string-of-digits/3027#3027

Существует ли классификация для этого типа упражнения?(например, подмножество-сумма и т., *, / и 10a+b / concat


Вот подход грубой силы в python.В каждом узле деревьев внизу возьмите декартово произведение возможностей слева и справа.Для каждой пары примените к ней все операторы, чтобы создать набор новых возможностей.Вы должны быть осторожны, чтобы не делать (1-2)3 = -13;Вы можете обойти эту проблему, создав объекты Digit.

Ниже приведена иллюстрация каталонских чисел, где каждый узел является оператором.Количество операций будет примерно Catalan(#digits-1) * #operators^(#digits-1).Если #digits=10, то нужно попробовать только около миллиарда.

enter image description here

Использование Как вывести все возможные сбалансированные скобки для выражения?можно написать:

#!/usr/bin/python3

import operator as op
from fractions import Fraction
Fraction.__repr__ = lambda self: '{}/{}'.format(self.numerator, self.denominator)

Digits = tuple

operators = {op.add, op.sub, op.mul, Fraction}

def digitsToNumber(digits):
    """
        (1,2,3) -> 123
        123 -> 123
    """
    if isinstance(digits, Digits):
        return sum(d * 10**i for i,d in enumerate(reversed(digits)))
    else: # is int or float
        return digits

def applyOperatorsToPossibilities(left, right):
    """
        Takes every possibility from the left, and every
        possibility from the right, and takes the Cartesian
        product. For every element in the Cartesian product,
        applies all allowed operators.

        Returns new set of merged possibilities, ignoring duplicates.
    """
    R = set() # subresults
    def accumulate(n):
        if digitsToNumber(n)==TO_FIND:
            raise Exception(n)
        else:
            R.add(n)

    for l in left:
        for r in right:
            if isinstance(l, Digits) and isinstance(r, Digits):
                # (1,2),(3) --> (1,2,3)
                accumulate(l+r)
            for op in operators:
                #  12,3 --> 12+3,12-3,12*3,12/3
                l = digitsToNumber(l)
                r = digitsToNumber(r)
                try:
                    accumulate(op(l,r))
                except ZeroDivisionError:
                    pass

    return R

def allReductions(digits):
    """
        allReductions([1,2,3,4])
        [-22, -5, -4, -3, -5/2, -1/1, -1/3, 0, 1/23, 1/6, 1/5, 1/3, 2/3, 1/1, 3/2, 5/3, 2, 7/2, 4/1, 5, 6, 7, 9, 15, 23, 24, 36, 123]
    """
    for reduction in set.union(*associations(
            digits, 
            grouper=applyOperatorsToPossibilities, 
            lifter=lambda x:{(x,)})
            ):
        yield digitsToNumber(reduction)

TO_FIND = None
INPUT = list(range(1,4))
print(sorted(allReductions(INPUT)))
0 голосов
/ 08 июля 2011

Простой подход грубой силы, который, кажется, работает достаточно хорошо.

Давайте используем RPN , чтобы избежать скобок.Разбейте входные данные на отдельные цифры и попробуйте вставить операторы (а именно: ничего, пробел и арифметические операторы) между цифрами, пока полученная строка не достигнет целевого значения.

Иллюстрация в javascript: http://jsfiddle.net/B5NdN/4.Я просто переключаюсь от 0 до 6 ^ (длина ввода), чтобы получить все возможные комбинации операторов, ваша задача может потребовать чего-то более сложного, но принцип остается.

...