N個のコインと各金種を使用したコイン変更問題の列挙


13

硬貨釣銭の問題は非常によく文書化されています。宗派のコインの無限の供給を考えるx_1x_m、あなたまで追加の組み合わせの数を見つける必要がありますy。例えば、与えられたx = {1,2,3}y = 4我々は4つの組み合わせがあります。

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

前書き

コイン交換の問題にはいくつかのバリエーションがあります。このバリエーションでは、2つの追加の制限があります。

  1. すべての額面を少なくとも1回使用する必要があります。
  2. 正確に固定された数のコインを合計で使用する必要があります。

例えば、与えられたx = {1,2,3}y = 36そしてn = 15どこnに使用しなければならないコインの総数であり、我々は4つの組み合わせを取得します:

  1. {1,2,2,2,2,2,2,2,3,3,3,3,3,3,3} (1個、7個の2個、7個の3個)
  2. {1,1,2,2,2,2,2,3,3,3,3,3,3,3,3} (2個、5個の2個、8個の3個)
  3. {1,1,1,2,2,2,3,3,3,3,3,3,3,3,3} (3個、3個の2個、9個の3個)
  4. {1,1,1,1,2,3,3,3,3,3,3,3,3,3,3} (4個、1個の2個、10個の3個)

チャレンジ

課題は、enumerate上記のすべての組み合わせを列挙する、選択した言語で関数を作成することです。

  1. 宗派のリスト。たとえば{1,5,10,25}。リストまたは配列のいずれかを使用できます。
  2. yすべての組み合わせの合計を示す負でない整数。
  3. nコインの総数を示す負でない整数。

引数の順序は関係ありません。ポイントフリー機能が許可されています。

enumerate関数の出力は、組み合わせのリストでなければなりません。各組み合わせは一意である必要があり、合計がのn整数のリストである必要がありますy。すべての額面は、各組み合わせで少なくとも1回出現する必要があり、組み合わせが欠落してはなりません。整数と組み合わせの順序は関係ありません。出力にはリストまたは配列を使用できます。

次のエッジケースに注意してください。

  1. 両方の場合yとがnゼロであり、金種のリストが空で、出力が1つの組み合わせのリストである、空の組み合わせ(すなわち、{{}})。
  2. そうでなければ、yがゼロ、ゼロ、nまたは金種のリストが空の場合、出力はゼロの組み合わせのリスト(つまり{})になります。
  3. より一般的にyは、金種の合計よりも小さい場合、または金種nの数よりも少ない場合、出力はゼロの組み合わせのリストになります。

スコアリングは、バイト単位のプログラム全体のサイズに基づきます。これには、enumerate関数、ヘルパー関数、インポートステートメントなどが含まれることに注意してください。テストケースは含まれません。


かなり確信して私は...この挑戦のどこかを見てきました
漏れ修道女

この質問が重複していないことを願っています。Code Golfで同じ質問を見つけることができませんでした。したがって、私はそれを投稿しました。
Aadit Mシャー

@PeterTaylor yが宗派の合計よりも小さい場合、再帰解のある時点で、宗派のリストが空の基本ケースに到達します。したがって、答えは{}(つまり、解決策が見つからない)になります。場合はn以下の宗派の数よりも、あなたは最終的にどこのベースケースに達するだろうn = 0けどy != 0。したがって、答えは再びになります{}
Aadit Mシャー

@PeterTaylor確かに。実装の詳細についてあまりにも多くのことを想定していたかもしれません。それを修正する方法を知っていますか?
Aadit Mシャー

10
有効な回答が得られるまで、「Accepted」フラグを削除することをお勧めします。そして一般的に、受け入れる前に数日待つのが賢明です。
ピーターテイラー

回答:


2

05AB1E、20バイト

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

入力が順序であります:list of valuesnr of coinssum 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]

formの金種のタプル(x_1, x_2, x_3 ... , x_k)、ターゲット値、および引数を介したコインの数の入力を受け取り、form のタプルのリストを返す匿名関数[(solution_1), (solution_2), (solution_3), ... (solution_k)]

使い方

Itertoolscombinations_with_replacement関数はl-len(d)、金種のすべての組み合わせを置き換えて生成するために使用されます。dこれらの組み合わせのそれぞれに追加することにより、各金種が少なくとも1回現れること、および新しい組み合わせの長さが保証され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)

formの金種のタプル(x_1, x_2, x_3 ... , x_k)、ターゲット値、および引数を介したコインの数の入力を受け取り、form のタプルのセットを返す匿名関数{(solution_1), (solution_2), (solution_3), ... (solution_k)}

仕組み(他のバージョン)

これはproduct関数from itertoolsを使用してl-len(d)、金種のすべての配置を生成します。dこれらの組み合わせのそれぞれに追加することにより、各金種が少なくとも1回現れること、および新しい組み合わせの長さが保証され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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.