コイン問題


20

バックグラウンド

Golfenistanの架空の国の公式通貨はfooであり、流通しているコインは3種類、3 foo、7 foo、8 fooのみです。これらのコインを使用して、4 fooなどの特定の金額を支払うことは不可能であることがわかります。それでも、十分な量をすべて形成できます。あなたの仕事は、コインでは形成できない最大量(この場合は5 foo)を見つけることです。これはコイン問題として知られています

入力

入力は、流通しているコインの価値を表す正の整数のリストです。次の2つのことが保証されています。L = [n1, n2, ..., nk]

  • の要素のGCD Lは1です。
  • L 番号1は含まれません。

ソートされていないか、重複している可能性があります(特別版のコインを考えてください)。

出力

のGCD Lは1 なので、十分に大きい整数mはすべて、その要素の非負の線形結合として表現できます。言い換えれば、

 m = a1*n1 + a2*n2 + ... + ak*nk 

一部の整数の場合。出力は、この形式では表現できない最大の整数です。ヒントとして、およびが(reference)の最大要素と最小要素である場合、出力は常により小さいことが知られています。ai ≥ 0(n1 - 1)*(nk - 1)n1nkL

ルール

完全なプログラムまたは関数を作成できます。最小のバイトカウントが優先され、標準の抜け穴は許可されません。あなたの言語がこのための組み込み操作を持っている場合、あなたはそれを使用してはいけません。回答を投稿する前にテストケースを評価できる必要があることを除いて、時間やメモリの効率に関する要件はありません。

このチャレンジを投稿した後、ユーザー@vihanはStack Overflowに完全な重複があることを指摘しました。このMetaディスカッションに基づいて、このチャレンジは重複として削除されません。ただし、SOバージョンの回答に基づくすべての回答は、オリジナルを引用し、コミュニティWikiのステータスを付与し、オリジナルの著者が回答をここに投稿したい場合は削除するようお願いします。

テストケース

[3, 7, 8] -> 5
[25, 10, 16] -> 79
[11, 12, 13, 14, 13, 14] -> 43
[101, 10] -> 899
[101, 10, 899] -> 889
[101, 10, 11] -> 89
[30, 105, 70, 42] -> 383
[2, 51, 6] -> 49

5
FrobeniusNumberMathematicaで。
alephalpha

3
よりよい上限の方法がありますが、中に見つかったこの論文確立することを(p - 1)(q - 1)上限として、pとはq集合の最小と最大の要素です。
orlp

2
実行時間やメモリ使用量に制限はありますか?
デニス

1
スタックオーバーフローでは、しばらく前にこのようなコードのゴルフの質問がありました
ダウンゴート

1
[2,3]妥当な時間内に他に何もできない13バイトのPythソリューションがあります。[2,5]メモリ内に約100万のPythonリストを作成します。
isaacg

回答:


4

Pyth、23バイト

ef!fqTs.b*NYQY^UTlQS*FQ

すべてのコインの積までのすべての値をチェックするため、非常に遅くなります。これはほとんど同じバージョンですが、1)コインのセットを互いに割り切れないものに減らし、2)最大値(max(coins) - 1) * (min(coins) - 1)(47バイト)のみをチェックします。

=Qu?.A<LiHdG+GHGQYef!fqTs.b*NYQY^UTlQS*thSQteSQ

説明

                   S            range 1 to
                    *FQ         product of input
 f                             filter by
               UT                range 0 to T 
              ^  lQ              cartesian power by number of coins
   f                            filter by
      s.b*NYQY                   sum of coin values * amounts
    qT                           equals desired number T
  !                             nothing matching that filter
e                             take last (highest) element

8

Perl、60 54 51バイト

50バイトのコード+ 1バイトのコマンドライン

$.*=$_,$r.=1x$_."|"}{$_=$.while(1x$.--)=~/^($r)+$/

ゴルフを続け、後で説明を投稿します。基本的なアプローチは、正規表現エンジンに文字列マッチングのハードワークを行わせることです。例えば、正規表現に類似の構築であろう^(.{3})*(.{7})*(.{8})*$と長さの文字列との照合が一致する入力の積から下降を失敗するまで。nn

引数の数が増えると、これは指数関数的に遅くなることに注意してください。

使用法:引数は、STDIN(改行で区切られている)から読み込まれます。次に例を示します。

printf "101\n10" | perl -p entry.pl

3

R84 78バイト

a1a2フロベニウスの量

a=scan();max((1:(b<-min(a)*max(a)))[-colSums(combn(outer(a,0:b),sum(!!a)))])

オンラインでお試しください!

常に極端な積よりも小さいため aの。その場合、その範囲内で可能なすべての組み合わせ(およびそれ以上)を組み合わせます。outer「*」を付けずに「colSumsapply(...、2、sum)」ではなく提案してくれたCole Beckに感謝します。

より高速ですが、より長い(2バイト)バージョンは、以下のみを考慮しmax(a)ます:

a=scan();max((1:(min(a)*(b<-max(a))))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

ほとんどの場合、あまりにも上で実行するためにログインするか、あまりにも多くのスペースとり少し短いバージョン(78バイト)のオンラインそれを試してみてはあります

a=scan();max((1:(b<-prod(a)))[-apply(combn(outer(a,0:b,"*"),sum(!!a)),2,sum)])

1

Python2、188の 187バイト

def g(L):
 M=max(L);i=r=0;s=[0]*M;l=[1]+s[1:]
 while 1:
    if any(all((l+l)[o:o+min(L)])for o in range(M)):return~-s[r]*M+r
    if any(l[(i-a)%M]for a in L):l[i]=1
    else:r=i
    s[i]+=1;i=(i+1)%M

2番目のインデントはSOで4つのスペースとしてレンダリングされます。これらはタブである必要があります。

実際には、ブルートフォースではなく「高速」ソリューションは、ここで説明する「Wilf's Method」を使用します


1

ジャバスクリプトES6、120の 130 126 128 127 125文字

f=a=>`${r=[1|a.sort((a,b)=>a-b)]}`.repeat(a[0]*a[a.length-1]).replace(/./g,(x,q)=>r[q]|a.map(x=>r[q+x]|=r[q])).lastIndexOf(0)

代替の126文字バージョン:

f=a=>{r=[1];a.sort((a,b)=>a-b);for(q=0;q<a[0]*a[a.length-1];++q)r[q]?a.map(x=>r[q+x]=1):r[q]=0;return r.join``.lastIndexOf(0)}

テスト:

"[3, 7, 8] -> 5\n\
[25, 10, 16] -> 79\n\
[11, 12, 13, 14, 13, 14] -> 43\n\
[101, 10] -> 899\n\
[101, 10, 899] -> 889\n\
[101, 10, 11] -> 89\n\
[30, 105, 70, 42] -> 383\n\
[2, 51, 6] -> 49".replace(/(\[.*?\]) -> (\d+)/g, function (m, t, r) {
  return f(JSON.parse(t)) == r
})

1
あなたは置き換えることができforEach(map(
Ypnypn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.