Перерахунок проблеми монети за допомогою N монет та кожної номіналу


13

Проблема зміни монети дуже добре зафіксована. З огляду на нескінченний запас монет номіналів x_1в x_mвам потрібно знайти число комбінацій , які додають до y. Наприклад, дано x = {1,2,3}і у y = 4нас є чотири комбінації:

  1. {1,1,1,1}
  2. {1,1,2}
  3. {1,3}
  4. {2,2}

Вступ

Існує кілька варіантів проблеми зміни монети. У цьому варіанті у нас є два додаткові обмеження:

  1. Кожна конфесія повинна бути використана хоча б один раз.
  2. Всього потрібно використовувати фіксовану кількість монет.

Наприклад, з урахуванням x = {1,2,3}, y = 36а n = 15де nзагальна кількість монет, які необхідно використовувати, ми отримуємо чотири комбінації:

  1. {1,2,2,2,2,2,2,2,3,3,3,3,3,3,3} (1, 7 двійки, 7 трійки)
  2. {1,1,2,2,2,2,2,3,3,3,3,3,3,3,3} (2, 5 двійки, 8 трійки)
  3. {1,1,1,2,2,2,3,3,3,3,3,3,3,3,3} (3, 3 двійки, 9 трійки)
  4. {1,1,1,1,2,3,3,3,3,3,3,3,3,3,3} (4, 1 двійка, 10 трійки)

Виклик

Завдання полягає в тому, щоб написати функцію enumerateна обраній вами мові, яка перераховує всі комбінації, як описано вище:

  1. Список конфесій. Наприклад {1,5,10,25}. Ви можете використовувати або списки, або масиви.
  2. Невід'ємне ціле число, yяке позначає суму кожної комбінації.
  3. Невід’ємне ціле число, nяке позначає загальну кількість монет.

Порядок аргументів не має значення. Функції pointfree дозволені.

Виведенням enumerateфункції має бути список комбінацій. Кожна комбінація повинна бути унікальною, і вона має містити список nцілих чисел, до яких додається y. Кожна номінація повинна з’являтися принаймні один раз у кожній комбінації, і жодна комбінація не повинна бути відсутньою. Упорядкування цілих чисел та комбінацій не має значення. Ви можете використовувати або списки, або масиви для виводу.

Майте на увазі наступні крайові випадки:

  1. Якщо обоє yі nдорівнюють нулю, а список номіналів порожній, то вихід - це список однієї комбінації, порожня комбінація (тобто {{}}).
  2. В іншому випадку, якщо yдорівнює нулю, nдорівнює нулю або список номіналів порожній, то вихід - це список нульових комбінацій (тобто {}).
  3. Більш загально, якщо yменша сума номіналів або nменша за кількість номіналів, то вихід - це список нульових комбінацій.

Оцінка балів буде залежати від розміру всієї програми в байтах. Зауважте, що це включає в себе enumerateфункцію, допоміжні функції, заяви про імпорт тощо. Це не включає тестові випадки.


Досить впевнений, що я десь бачив цей виклик ...
Leaky Nun

Я сподіваюся, що це запитання не є дублюючим. Я не міг знайти те саме питання у Code Golf. Отже, я розмістив його.
Аадіт М Шах

@PeterTaylor Якщо yменша сума деномінацій, то в якийсь момент рекурсивного рішення ви досягнете базового випадку, коли список конфесій порожній. Отже, відповідь буде {}(тобто рішення не знайдено). Якщо nменше, ніж кількість конфесій, ви зрештою дістанетесь до базового випадку, де, n = 0але y != 0. Отже, відповідь знову буде {}.
Аадіт М Шах

@PeterTaylor Дійсно. Я міг би припустити занадто багато деталей щодо впровадження. Чи знаєте ви, як це виправити?
Аадіт М Шах

10
Я пропоную вам зняти прапор "Прийнято", поки не отримаєте робочу відповідь. І взагалі розумно почекати пару днів, перш ніж приймати.
Пітер Тейлор

Відповіді:


2

05AB1E, 20 байт

g-¹sã€{Ùvy¹«DO³Qiˆ}¯

Введення в наступному порядку: list of values, nr of coins, sum to reach.

Пояснення коротко

  1. Отримати всі перестановки списку монет довжиною: final length - length of unique coin list
  2. Додайте до цих списків унікальні монети.
  3. Якщо сума дорівнює шуканій сумі, збережіть список
  4. Виведіть усі збережені списки

Спробуйте в Інтернеті

Онлайн-компілятор не може обробляти велику кількість монет.


4

MATL , 22 байти

Z^!S!Xu!tsi=Z)"1G@m?@!

Порядок введення: масив номіналів, кількість взятих монет ( n), бажана сума ( y).

Кожна комбінація відображається в іншому рядку. Порожній вихід відображається як порожній рядок (так нічого).

Спробуйте в Інтернеті!

Код не вистачає пам'яті в онлайн-компіляторі для прикладу виклику, але працює в автономному режимі зі стандартним, досить сучасним комп'ютером:

>> matl
 > Z^!S!Xu!tsi=Z)"1G@m?@!
 > 
> [1 2 3]
> 15
> 36
1 1 1 1 2 3 3 3 3 3 3 3 3 3 3
1 1 1 2 2 2 3 3 3 3 3 3 3 3 3
1 1 2 2 2 2 2 3 3 3 3 3 3 3 3
1 2 2 2 2 2 2 2 3 3 3 3 3 3 3

Пояснення

Z^      % Implicitly input array of denomminations and number of coins n. Compute 
        % Cartesian power. This gives 2D array with each "combination"
        % on a different row
!S!     % Sort each row
Xu      % Deduplicate rows
!       % Transpose: rows become columns. Call this array A
ts      % Push a copy, compute sum of each column
i       % Input y (desired sum)
=       % Logical array that contains true if the "combination" has the desired sum
Z)      % Keep only those columns in array A
"       % For each column
  1G    %   Push array of denominations again
  @     %   Push current column
  m     %   Is each denomination present in the column?
  ?     %   If so
    @!  %     Push current column again. Transpose into a row
        %   End if
        % End for
        % Implicitly display stack contents

3

Python 3, 120 106 байт

from itertools import*
lambda d,t,l:[i+d for i in combinations_with_replacement(d,l-len(d))if sum(i+d)==t]

Анонімна функція, яка приймає введення пакету номіналів форми (x_1, x_2, x_3 ... , x_k), цільового значення та кількості монет через аргумент, та повертає список кортезів форми [(solution_1), (solution_2), (solution_3), ... (solution_k)].

Як це працює

Itertoolscombinations_with_replacementФункція ' використовується для створення всіх l-len(d)комбінацій номіналів із заміною. Додаючи dкожну з цих комбінацій, гарантується, що кожне найменування з’явиться хоча б один раз, а нова комбінація має довжину l. Якщо елементи комбінації дорівнюють t, комбінація додається до списку повернення як кортеж.

Спробуйте це на Ideone


Альтернативний метод для 108 байт

from itertools import*
lambda d,t,l:set(tuple(sorted(i+d))for i in product(d,repeat=l-len(d))if sum(i+d)==t)

Анонімна функція, яка приймає введення пакету номіналів форми (x_1, x_2, x_3 ... , x_k), цільового значення та кількості монет через аргумент і повертає набір кортезів форми {(solution_1), (solution_2), (solution_3), ... (solution_k)}.

Як це працює (інша версія)

Для цього використовується productфункція, itertoolsщоб створити всі l-len(d)розташування конфесій. Додаючи dкожну з цих комбінацій, гарантується, що кожне найменування з’явиться хоча б один раз, а нова комбінація має довжину l. Якщо елементи комбінації суму до t, комбінація сортується, перетворюється зі списку в кортеж і додається до зворотних кортежів. Нарешті, виклик setвидаляє всі дублікати.

Спробуйте його на Ideone (інша версія)


0

JavaScript (ES6), 135 байт

g=(a,n,y,r)=>n>0?y>0&&a.map((x,i)=>g(a.slice(i),n-1,y-x,[...r,x])):n|y||console.log(r)
(a,n,y)=>g(a,n-a.length,a.reduce((y,x)=>y-x,y),a)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.