Минимальное количество чисел для суммирования ровно n

15

Первый вопрос здесь, не кричите на меня, если это дубликат или плохой вызов.

Вступление

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

Вызов

Учитывая массив целых чисел, которые меньше или равны n, выведите или верните минимальное количество чисел из массива, которые в сумме точно n.

Вы можете написать функцию или полную программу.

вход

Вы можете смело предполагать 0 <= n < 2^31.

Возьмите массив или список любого вида ( vectorдля C ++ или Java LinkedListдопускается) вместе с nнеобязательным параметром length, который указывает длину массива.

Вы также можете принять входные данные в виде строки, разделенной пробелами, отделенной nзапятой или пробелом:

1 5 7 3 7 3 6 3 2 6 3,10

1 5 7 3 7 3 6 3 2 6 3 10

если проще.

Выход

Выведите или верните минимальное количество чисел из массива, которые в сумме составляют в точности n. Используя приведенный выше пример:

1 5 7 3 7 3 6 3 2 6 3,10

Ваша программа должна напечатать:

2

так как минимальное количество чисел, сумма до 10это 2( 7и 3).

В случае, если решения не существует, выведите или верните либо отрицательное значение, 0«Без решения» (хотя это не было бы разумно), (как предложено), либо любое другое ложное значение, за исключением пустой строки.

Пример ввода и вывода

Входные данные:

1 5 7 3 7 3 6 3 2 6 3,10
143 1623 1646 16336 1624 983 122,18102
5 6 9,12

Выход:

2
3
-1

счет

Это код-гольф, поэтому выигрывает самый короткий код в байтах.

Главный ответ будет принят на Рождество.

TheCoffeeCup
источник
Я отредактировал вашу спецификацию, потому что мы обычно разрешаем одни и те же методы ввода / вывода для функций и программ; увидеть консенсус здесь . Не стесняйтесь откатиться, если вы не согласны.
lirtosiast
Можем ли мы вывести результаты falseдля случаев без решений?
ETHproductions
@ETHproductions Конечно, добавим это.
TheCoffeeCup
Считаете ли вы пустой вывод Falsey, поскольку в Pyth пустая строка - False?
lirtosiast
@ThomasKwa Мне не нравятся пустые строковые выходные данные, но вы можете включить это как "если бы х был разрешен ..." в вашем ответе ...
TheCoffeeCup

Ответы:

7

Pyth, 12 11 байтов

lhafqsTQyEY

Это принимает nв качестве первой строки ввода и список во второй строке.

lhafqsTQyEY     (Implicit: Q = 1st line of input; E = 2nd line)
         E      The list
        yE      Powerset (sorted by increasing length; empty set first)
   f            Filter by lambda T:
     sT         sum(T)
    q                  ==
       Q                  Q
   fqSTQyE      Sublists that sum to Q, sorted by increasing length
  a       Y     append an empty array (in case none match)
lh              take the length of the first element (0 for empty array)

Попробуй это здесь .

lirtosiast
источник
1
Ваш код и ваше объяснение не совпадают.
Исаак
@isaacg Теперь исправлено.
lirtosiast
5

Джапт , 30 21 18 байт

Оказалось, что был гораздо более эффективный метод. ;)

Uà f_x ¥V} ml n- g

Проверьте это онлайн!(Примечание: n-было изменено n@X-Y}на совместимость)

Это принимает входные данные в виде массива, разделенного пробелами или запятыми, за которым следует число. Выходыundefined для тестовых случаев без решений.

Uà f_  x ¥ V} ®   l} n- g
UàfmZ{Zx ==V} mZ{Zl} n- g

            // Implicit: U = input array, V = input integer
Uà fZ{   }  // Generate all possible combinations of U, then filter to only items Z where
Zx ==V      //   the sum of Z is equal to V.
mZ{Zl}      // Map each remaining combination to its length.
n-          // Sort by subtraction; smaller items end up in the front.
g           // Take the first item.
            // Implicit: output last expression

Я не могу поверить, что я не думал об этой версии, когда я первоначально написал это ...

С тех пор было сделано несколько оптимизаций, которые здесь пригодятся:

  • U в начале программы обычно можно опустить.
  • Ãэто ярлык для .
  • n теперь по умолчанию сортирует числа правильно.

Каждый из них снимает байт, всего 15:

à f_x ¥VÃml n g

Проверьте это онлайн!

ETHproductions
источник
Это 25 байтов, а не 21.
Альберт Реншоу
1
@AlbertRenshaw Japt поддерживает кодировку IEC_8859-1 , согласно которой каждый из этих символов равен 1 байту. Вы можете сохранить эту программу в виде текстового файла в кодировке IEC_8859-1, а затем загрузить его в онлайн-переводчик .
ETHproductions
Ах, хорошо! Спасибо за сообщение
Альберт Реншоу
1

Mathematica, 73 65 байт

Min[Length/@Select[IntegerPartitions[#2,#2,#],Sort@#==Union@#&]]&

Чистая функция, возвращает, если нет решения.

LegionMammal978
источник
1

Python 3, 128 байт

Это не так хорошо, как хотелось бы, но я поработаю над этим позже.

from itertools import*
def s(a,n):
 for i in range(len(a)):
  for j in permutations(a,i+1):
   if sum(j)==n:return i+1
 return 0
Sherlock9
источник
1

Mathematica, 45 байт

Min@Cases[Subsets@#,i_/;Tr@i==12:>Length@#2]&
alephalpha
источник
1

CJam, 34 байта

0q~_,2,m*\f.*{:+1$=},\;0f-{,}$0=,+

Попробуйте онлайн . Формат ввода - это сумма, за которой следует список значений, например:

18102 [143 1623 1646 16336 1624 983 122]

Обратите внимание, что это вызовет исключение, если решение не найдено. Исключение переходит к stderr, когда CJam запускается из командной строки, а правильный результат ( 0) по-прежнему выводится на стандартный вывод. Так что это соответствует консенсусу, установленному в Должны ли быть разрешены выходы с ошибкой?

Код может выглядеть длиннее, чем вы ожидаете. Основная причина в том, что CJam не имеет встроенного для генерации комбинаций. Или, по крайней мере, это мое оправдание, и я придерживаюсь его.

Объяснение:

0       Push 0 result for exception case.
q~      Get and interpret input.
_,      Copy and get length of input value list.
2,      Push [0 1].
m*      Cartesian power. This generates all possible lists of 0/1 values with the
        same length as the input value list.
\       Swap input value list to top.
f.*     Apply element-wise product of input value list with all 0/1 lists.
        We now have all combinations of values, with 0 in place of unused values.
{       Start filter block.
  :+      Sum values.
  1$      Copy target sum to top.
  =       Compare.
},      Filter.
\;      Swap target sum to top and discard.
0f-     Remove 0 values. We now have all solution lists.
{,}$    Sort by length.
0=      Get first solution, which after sorting is the shortest.
        This will raise an exception if the list of solutions is empty, bailing
        out with the initial 0 on the stack.
,       Get length of solution.
+       Add the 0 we initially pushed for the exception case.
Рето Коради
источник
1

JavaScript (ES6), 84 байта

f=(a,n,m=1e999,x)=>n&&a.map((v,i)=>(x=[...a],x.splice(i,1),x=f(x,n-v)+1)<m?m=x:0)&&m

объяснение

Принимает Arrayиз Numberс и в Numberкачестве аргументов. Возвращает число, Infinityесли нет результата. Это рекурсивная функция, которая вычитает nи удаляет каждый элемент из массива один за другим до n == 0.

f=(a,n,m=1e999,x)=> // m and x are not passed, they are here to declare them in the local
                    //     scope instead of globally, initialise m to Infinity
  n&&               // if n == 0, return 0
  a.map((v,i)=>     // iterate over each number in a
    (x=[...a],      // x = copy of a
    x.splice(i,1),  // remove the added number from the array
    x=f(x,n-v)+1)   // x = result for the numbers in this array
      <m?m=x:0      // set m to minimum result
  )
  &&m               // return m

Тестовое задание

Этот тест устанавливает mв Infinityдальнейшем вместо как аргумент по умолчанию , чтобы заставить его работать в Chrome (а не только Firefox).

user81655
источник
1

Haskell, 72 байта

import Data.List
n#l=head$sort[length x|x<-subsequences l,sum x==n]++[0]

Возвращает, 0если нет решения.

Пример использования: 10 # [1,5,7,3,7,3,6,3,2,6,3]-> 2.

Найти все подсписки входного списка, lкоторые имеют сумму n. Возьмите длину каждого такого подсписка и отсортируйте. Добавить0 и возьмите первый элемент.

Если список одноточечно разрешен для производства, например [2], мы можем сэкономить 7 байт: n#l=minimum[length x|x<-subsequences l,sum x==n]. В случае отсутствия решения, пустой список[] возвращается .

Ними
источник