Мінімальна кількість чисел підсумовувати рівно 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

Оцінка балів

Це код-гольф, тому найкоротший код у байтах виграє.

Верхня відповідь буде прийнята на Різдво.


Я відредагував вашу специфікацію, тому що ми зазвичай дозволяємо однакові методи вводу / виводу для функцій та програм; дивіться консенсус тут . Не соромтеся відкочуватися, якщо не погоджуєтесь.
lirtosiast

Чи можемо ми випустити falseдля справ, у яких немає рішення?
ETHproductions

@ETHproductions Звичайно, додасть це.
TheCoffeeCup

Чи вважаєте ви порожній вихід фальси, оскільки порожній рядок - фальси в Pyth?
lirtosiast

@ThomasKwa Мені не подобаються пусті рядкові виходи, але ви можете включити це у відповідь як "якби x було дозволено ..."
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)

Спробуйте тут .


1
Ваш код та ваше пояснення не збігаються.
isaacg

Виправлено @isaacg.
ліртосіаст

5

Japt , 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

Перевірте це в Інтернеті!


Це 25 байт, а не 21.
Альберт Реншо

1
@AlbertRenshaw Japt підтримує кодування IEC_8859-1 , під яким кожен з цих символів має 1 байт. Ви можете зберегти цю програму як закодований текстовим файлом IEC_8859-1, а потім завантажити її в онлайн-перекладач .
ETHproductions

Ах, приємно! Дякуємо, що повідомили мене
Альберт Реншо

1

Математика, 73 65 байт

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

Чиста функція, повертається, якщо немає рішення.


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


1

CJam, 34 байти

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

Спробуйте в Інтернеті . Формат введення - це сума, що супроводжується списком значень, наприклад:

18102 [143 1623 1646 16336 1624 983 122]

Зауважте, що це може призвести до виключення, якщо рішення не знайдено. Виняток стосується stderr, коли CJam запускається з командного рядка, а правильний результат ( 0) все ще друкується до stdout. Тож це відповідає консенсусу, встановленому в Чи слід дозволити виходити з помилкою?

Код може виглядати довше, ніж ви очікували. Основна причина полягає в тому, що 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).


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]. У разі відсутності рішення порожній список []повертається.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.