Bozuk Para Sorunu


20

Arka fon

Gölfenistan'ın hayali ulusunun resmi para birimi foo ve dolaşımda sadece üç çeşit para var: 3 foos, 7 foos ve 8 foos. Bu paraları kullanarak 4 foo gibi belirli miktarların ödenmesinin mümkün olmadığı görülebilir. Bununla birlikte, yeterince büyük miktarlar oluşturulabilir. İşiniz, madeni para sorunu olarak bilinen madeni paralarla (bu durumda 5 foos) oluşturulamayan en büyük miktarı bulmaktır .

Giriş

Girişiniz, dolaşımdaki paraların değerlerini temsil eden pozitif tamsayıların bir listesidir . Bu konuda iki şey garanti edilir:L = [n1, n2, ..., nk]

  • Öğelerinin GCD'si L1'dir.
  • L 1 sayısını içermiyor.

Sıralanmamış olabilir ve / veya kopyalar içerebilir (özel sürüm paraları düşünün).

Çıktı

GCD'si L1 olduğundan, yeterince büyük her tamsayı m, elemanlarının negatif olmayan bir doğrusal kombinasyonu olarak ifade edilebilir; diğer bir deyişle,

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

bazı tamsayılar için . Çıktınız, bu formda ifade edilemeyen en büyük tamsayıdır . Bir ipucu olarak, çıkış daima daha az olduğu bilinmektedir halinde, ve maksimal ve minimal elemanları ( referans ).ai ≥ 0(n1 - 1)*(nk - 1)n1nkL

kurallar

Tam bir program veya işlev yazabilirsiniz. En düşük bayt sayısı kazanır ve standart boşluklara izin verilmez. Dilinizde bunun için yerleşik bir işlem varsa, onu kullanamayabilirsiniz. Yanıtınızı göndermeden önce test senaryolarını değerlendirebilmeniz dışında, zaman veya bellek verimliliği için herhangi bir gereklilik yoktur.

Bu meydan okumayı gönderdikten sonra user @vihan, Stack Overflow'un tam bir kopyası olduğunu belirtti . Bu Meta tartışmasına dayanarak , bu meydan okuma kopya olarak silinmeyecektir; ancak, SO sürümüne dayalı tüm cevapların orijinalleri belirtmesi, Topluluk Wiki durumu vermesi ve orijinal yazarın yanıtlarını buraya göndermek istediği takdirde silinmesini rica ediyorum.

Test Durumları

[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

6
FrobeniusNumberMathematica'da.
alephalpha

3
Bulunan daha üst bağlanmış bir yolu yoktur bu yazıda kurar o (p - 1)(q - 1)üst nerede bağlı olarak pve qsetin en küçük ve en büyük unsurdur.
orlp

2
Çalışma süresinin veya bellek kullanımının sınırları var mı?
Dennis

1
Stack Overflow üzerinde bir süre önce böyle bir kod golf sorusu vardı
Downgoat

1
[2,3]Makul bir sürede yapabileceğim 13 baytlık bir Pyth çözümüm var ve başka bir şey yok. [2,5]bellekte yaklaşık bir milyon Python listesi oluşturur.
isaacg

Yanıtlar:


4

Pyth, 23 bayt

ef!fqTs.b*NYQY^UTlQS*FQ

Tüm madeni paraların ürününe kadar olan tüm değerleri kontrol ettiği için çok yavaştır. İşte neredeyse aynı olan bir sürüm, ancak 1) para kümesini birbirleri tarafından bölünemeyenlere azaltır ve 2) sadece (max(coins) - 1) * (min(coins) - 1)(47 bayta) kadar olan değerleri kontrol eder :

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

açıklama

                   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 bayt

50 bayt kodu + 1 bayt komut satırı

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

Golf oynamaya devam edecek ve daha sonra bir açıklama gönderecektir. Temel yaklaşım, normal ifade motorunun dize eşleşmesi ile zor işi yapmasına izin vermektir. Örneğin, benzer bir düzenli ifade inşa edecek ^(.{3})*(.{7})*(.{8})*$uzunlukta bir dizi karşı ve eşleme girişlerinin üründen alçalır maç için başarısız kadar.nn

Argüman sayısı arttıkça bunun katlanarak yavaşlayacağını unutmayın.

Kullanım: Bağımsız değişkenler STDIN'den (yeni satır ayrılmış) okunur, örneğin:

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

3

R , 84 78 bayt

Keyfi bir kopya girişi için, bir1,bir2,..., Frobenius'un miktarı ile verilir

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

Çevrimiçi deneyin!

çünkü her zaman aşırı ürünün çarpımından daha küçüktür. birben's. O zaman bu aralıktaki tüm olası kombinasyonları (ve daha fazlasını) birleştirme meselesidir. Cole Beck'e outer"*" olmadan önerdiği ve colSums`` uygula (..., 2, toplam) '' yerine önerdiği için teşekkürler .

Daha hızlı ancak daha uzun (iki bayt olarak) bir sürüm yalnızca max(a)şunları göz önünde bulundurur :

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

En sık çalıştırmak için oturum çok sürer veya çok fazla boşluk biraz daha kısa versiyonu (78 bayt) çevrimiçi Deneyin olduğunu

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

1

Python2, 188 187 bayt

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

İkinci girinti SO üzerinde 4 boşluk olarak oluşturulur, bunlar sekmeler olmalıdır.

Aslında bruteforce değil 'hızlı' bir çözüm, burada tarif edildiği gibi 'Wilf Yöntemi'ni kullanır .


1

JavaScript ES6, 120 130 126 128 127 125 karakter

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)

Alternatif 126 karakter versiyonu:

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)}

Ölçek:

"[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
BunuforEach(map(
Ypnypn

0

Ruby , 108 bayt

->a{b=[0];m=a.min
(1..1.0/0).map{|n|c=p
a.map{|x|c|=(b!=b-[n-x])}
c&& b<<=n
return n-m if b[-m]&&b[-m]>n-m}}

Çevrimiçi deneyin!

açıklama

->a{                                         input list
    b=[0];                                      list of representable integers
        m=a.min                                     minimum input
    (1..1.0/0).map{|n|                       n in range 1..
        c=p                                    c = false
          a.map{|x|c|=(b!=b-[n-x])}              check if n goes in b
            c&& b<<=n                                   put n in b
              return n-m if b[-m]&&b[-m]>n-m}}            return if m values in a row
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.