Kod golf: Topları dağıtma (I)


12

Meydan okuma

Bu görevde, her topun en az bir topu olan A toplarını B hücrelerine dağıtabileceğimiz yol sayısını hesaplamış olursunuz.

A ve B girişleri bir boşluk ile ayrılmış tek bir satırda verilir, girişler EOF ile sonlandırılır.

Çözümlerinizi burada kontrol etmek isteyebilirsiniz .

Giriş

0 0
1 0
12 4
6 3
18 17
20 19
15 13
18 9
20 20
17 14
9 2
14 13
18 11

Çıktı

1
0
14676024
540
54420176498688000
23112569077678080000
28332944640000
38528927611574400
2432902008176640000
21785854970880000
510
566658892800
334942064711654400

Kısıtlamalar

  • Her A ve B ayırt edilebilir.
  • 0 <= A, B <= 20
  • İstediğiniz herhangi bir dili kullanabilirsiniz
  • En kısa çözüm kazanır!

1
Zaman sınırları var mı?

@Tim Nordenfur: Güncellendi :-)
Quixotic

Bu bağlantı benim için geçersiz.
mellamokb

3
@Debanjan SPOJ'dan soruları buraya yapıştırma fikrinden hoşlanmıyorum. İnsanlar orada rekabet etmek için kodlarını veriyorlar ve bu onlar için haksızlık olur.
fR0DDY

1
@Debanjan, senin başvurusuna bakın ve size yükseltmek MathWorld (Denklem. 5 söylüyor S(n,0)olup 1olmadığını n=0ve 0aksi). İsterseniz, Stirling2'nin üstel Riordan grubunun ilişkisel alt grubunda olduğunu daha güçlü ifade için bir referans bulabilirsiniz.
Peter Taylor

Yanıtlar:


4

JavaScript (90 93 )

function f(a,b){n=m=r=1;for(i=b;i>0;n*=-1){r+=n*m*Math.pow(i,a);m=m*i/(b-i--+1)}return--r}

http://jsfiddle.net/RDGUn/2/

Açıkçası, APL gibi herhangi bir matematik tabanlı dil sözdizimi ayrıntısı ve yerleşik matematiksel yapıların eksikliği nedeniyle beni yenecek :)

Düzenle Ayrıca, işleve geçirilen parametreler dışında girdiyle ilgili herhangi bir işleve sahip değilim, standart girdinin JavaScript ile nasıl kullanılacağından emin değilim ...

Düzenleme: Taşı i--içine m=m*ifadesi; hareket n*=-1halinde for; r=1ödevleri birleştirmeye başlayın ve dönüşte yabancı olanları kaldırın. (3 karakter kaydedin)


Spidermonkey kabuğunu kullanabilirsiniz - en azından readlineve print. Burada başkalarının ne kullandığını bilmiyorum.
Jesse Millikan

@Jesse: İlginç. Yine de kaybedeceğim lol.
11:11, mellamokb

promptve alertJavaScript'in "standart" io'larıdır, çünkü JavaScript ile hiçbir zaman engelleme io'yu kullanmamanıza rağmen, tipik engelleme io çağrılarıdır.
zzzzBov

4

Golfscript - 56 50 49 48 41 40 38 37 karakter

n%{~),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;}/

Not: Bu, birden çok girdi satırını işler, hızlıdır (test senaryolarını yapmak için 1/8 sn) ve herhangi bir yasal girdi için kesilmez.

(İlk sürüm aynı zamanda ilk Golfscript programımdı; kaçırdığım birkaç numaraya işaret ettiği için eBusiness sayesinde).

Bunu da faydalı bir eğitim postası yapmak için, nasıl çalıştığının bir açıklaması. Tekrar ile başlıyoruz f(n, k) = k * (f(n-1, k) + f(n-1, k-1)). Bu, kombine olarak , her bir kova en az bir top içerecek şekilde nayırt edilebilir toplar yerleştirmek için, ilk top ( ) kiçin kkovalardan k *birini seçip ardından en az bir top ( f(n-1, k)) içereceğini söyleyerek anlaşılabilir. yoksa olmaz ( f(n-1, k-1)).

Bundan kaynaklanan değerler bir ızgara oluşturur; alarak nsatır endeks olarak ve ksütun indeksi olarak ve 0'dan hem indeksleme başlatıldığında

1   0   0   0    0    0   0 ...
0   1   0   0    0    0   0 ...
0   1   2   0    0    0   0 ...
0   1   6   6    0    0   0 ...
0   1  14  36   24    0   0 ...
0   1  30 150  240  120   0 ...
0   1  62 540 1560 1800 720 ...
.   .   .   .    .    .   . .
.   .   .   .    .    .   .  .
.   .   .   .    .    .   .   .

Yani programa dönersek,

n%{~ <<STUFF>> }/

girdiyi satırlara böler ve her satır için yığını değerlendirir nve kyığına koyar ve sonra <<STUFF>>aşağıdaki gibi çağrı yapar :

),{!}%\{0.@{.@+2$*@)@}/;;]}*)p;

Bu , söz konusu ızgaranın th satırının ilk k+1girişlerini hesaplar n+1. Başlangıçta yığın n k.
),verir yığın bölgesinin n [0 1 2 ... k]
{!}%yığınını verir n [1 0 0 ... 0]olduğu yerde k0s.
\{ <<MORE STUFF>> }*getiren nüstüne ve ona biz yürütme sayısını yapar <<MORE STUFF>>.
Yığımız şu anda tablonun [f(i,0) f(i,1) ... f(i,k)]
0.@bir satırıdır: bu diziden önce birkaç 0 koyar. Birincisi olacak jve ikincisi olacak f(i,j-1).
{ <<FINAL LOOP>> }/dizinin elemanları arasında dolaşır; her biri için yığının üstüne koyar ve sonra döngü gövdesini yürütür.
.@+2$*@)@almak ... j f(i,j-1) f(i,j)ve vermek için sıkıcı yığın manipülasyonu ... j*(f(i,j-1)+f(i,j)) j+1 f(i,j)
;;]soldan çıkark+1 f(i,k)ve her şeyi bir dizi halinde toplar, bir sonraki döngü için hazır.
Son olarak, ntablonun th satırını oluşturduğumuzda
)p;, son öğeyi alır, yazdırır ve satırın geri kalanını atar.

Gelecek nesiller için bu prensipte üç 38 karakterlik çözüm:
n%{~),{!}%\{0.@{.@+@.@*\)@}/;;]}*)p;}/
n%{~),{!}%\{0:x\{x\:x+1$*\)}/;]}*)p;}/
n%{~),{!}%\{0.@{@1$+2$*\@)}/;;]}*)p;}/


1
Yeni başlayanlar için oldukça iyi, birkaç olası küçük ölçekli azaltma var, hemen buluyorum [0]-> 1,, zip sonrası boşluk sadece kaldırılabilir ve k yerine bir operatörde saklarsanız diğer alan çıkarılabilir. Henüz kodunuzda adım atmadım, ancak bazı noktalarda bir diziye koymadan sadece bir değer kullanarak kaçabileceğinizden şüpheleniyorum.
aaaaaaaaaaaa

1
+ 1, Golfscript'i anlamıyorum ama bu yeterince hızlı ve yine de çok kısa görünüyor.
Quixotic

@ eBusiness ve @Peter Taylor: Farklı bir kayda göre .. Golfscript'i öğrenmesi kolay bir ölçekte ne kadar derecelendiriyorsunuz?
Quixotic

@Debanjan, zaten bildiklerinize bağlı. Yığın tabanlı işlevsel bir dildir. Daha önce fonksiyonel bir dil kullandım (SML - artı OO dillerinde fonksiyonel tarzda kod yazdım) ve daha önce yığın tabanlı dilleri (Jasmin, PostScript ile birleştirilmiş Java bayt kodu) kullandım, bu yüzden tek engel Karşılaştığım operatörlerin neler olduğunu öğrenmek. Sadece Algol ailesinden dilleri (C, Java, vb.) Biliyorsanız, aynı anda atlamak için üç engeliniz olacaktır.
Peter Taylor

@Debanjan - Göründüğünden çok daha kolay, hemen kod yazmaya başlayabilirsiniz, ancak elbette tüm küçük hileleri öğrenmek biraz zaman alıyor.
aaaaaaaaaaaa

3

J, 40

4 :'|-/x(^~*y!~])i.1x+y'/&.".;._2(1!:1)3 

Örneğin

4 :'-/((x^~|.@:>:)*y&(!~))i.y'/x:".>{.;:(1!:1)3
15 13
28332944640000

Tüm test durumları için <1 sn.

Düzenlemeler

  • (52 → 47)-/ Alternatif yerine azaltmak (1 _1)*(JB'nin fikri)
  • (47 → 53) Fark edilmiş çok hatlı giriş gereksinimi: - /
  • (53 → 48) Binomların simetrisinden yararlanın.
  • (48 → 48) Yapıştırın!
  • (48 → 41)
  • (41 → 40) Artışı + dönüştürün1x+

1
Hey! Bu benim fikrimdi! O :-)
JB

Tamam, o zaman çalarım 1x+, ama bu sadece 1 karakter geri alır, oysa sen 5 tane aldın!
JB

3

Yaygın Lisp (83)

(defun b (x y)
  (if (= (* x y) 0)
      (if (= (+ x y) 0) 1 0)
      (* y (+ (b (decf x) y) (b x (1- y)))))))

Temel vakaları test etmenin daha kısa bir yolu olmalı gibi görünüyor, ancak bana hazırlıksız bir şey olmuyor.


3

J, 38-42

Etkileşimli diller ve çıktı sunumu konusundaki katı tercihlerinize bağlı olarak, J çözümlerinden seçiminizi yapın:

  • 38 en kısa interaktif: 4 :'|-/(!&y*^&x)i.1x+y'/&".;._2(1!:1)3
    Jconsole'u başlatın, girin, ardından girişi yapıştırın (Cd ile bitirin). Çıktının boşlukla ayrıldığını fark edeceksiniz (J bir vektör dilidir, tüm girişte hesaplamayı bir bütün olarak gerçekleştirir ve varsayılan sunumu tek bir satırda olan 1D vektörü olarak döndürür). Bence bu problemin ruhu sunum değil hesaplamadır. Ancak bunun yerine yeni satırlara sahip olmak konusunda ısrar ediyorsanız:
  • 39 uzun interaktif: 4 :'|-/(!&y*^&x)i.1x+y'/&.".;._2(1!:1)3
    Değiştirme Yaz'ı ( &birlikte) Under ( &.) olan sunum ayrı satırlarda biter dizeleri bir vektör döndürür.
  • 42 toplu iş modu: 4 :'echo|-/(!&y*^&x)i.1x+y'/&".;._2(1!:1)3
    Komut satırından şu şekilde çalıştır$ jconsole balls.ijs < balls.in

Buna oy verdiyseniz , Eelvex'in çözümüne de bir miktar kredi vermek isteyebilirsiniz .


&.Etkileşimli modda düzgün çalışması için bir Under seçeneğine ihtiyacınız vardır .
Eelvex

@Eelvex "doğru" olarak farklı bir yoruma sahip olmalısınız. Jconsole'u başlatıyorum, kodu yapıştırıyorum, girdiyi yapıştırıyorum, Cd ve çıktıyı alıyorum. Gerek yok. Seninki nedir?
JB

Bizim kodları kombine: 4 :'|-/(!&y*^&x)i.1x+y'/&.".;._2(1!:1)3. 39 karakter.
Eelvex

Echo veya Under olmadan çıktıyı yalnızca bir satırda alıyorum (birden çok satır yerine).
Eelvex

@Eelvex gerçekten, ama bu kesinlikle yasak değil.
JB

3

GolfScript - 45 38 36 karakter

Orta kuvvette kirli uygulama nüks ilişkisi ( 38 36 karakter):

n%{~{.2$*{\(.2$f\2$(f+*}{=}if}:f~p}/

Peter Taylors çözümünden çaldığım yineleme ilişkisi şöyle:

f(x, y) = y * ( f(x-1, y) + f(x-1, y-1) )

Değişkenlerden herhangi biri 0 ise özel durumlarda.

Uygulamam önceki sonuçları yeniden kullanmaz, bu nedenle sıfır işlevlerinden birine ulaşılmadığı sürece her işlev çağrısı iki yeni çağrıyı çağırır. Bu, makinemde 30 saniye süren en kötü 2 ^ 21-1 işlev çağrısı verir.

Hafif kuvvet serisi çözümü (45 karakter):

n%{~.),0\{.4$?3$,@[>.,,]{1\{)*}/}//*\-}/p;;}/

2

J, 55 karakter

(wd@(4 :'(y^x)--/(!&y*^&x)|.i.y')/@".@,&'x');._2(1!:1)3
  • Mevcut test senaryolarını geçer. Ben düşünüyorum ben matematik anlamak ...
  • j602, yalnızca konsol (wd ). Stdin üzerinde giriş, stdout üzerinde çıkış.

Bash test komut dosyası:

jconsole disballs.ijs <<END
12 4
6 3
END

Bu j6xx ne yapıyor wd?
JB

Gerçekten j602 demek istedim ... Sanırım j601 de. Olarak echotanımlanır 0 0&$@(1!:2&2). Bunun ne anlama geldiğinden emin değilim, ancak satır sonu ile güzel baskı sıralaması 1 öğe gibi bir şey yapıyor. (Şu anda 4 yerine 2 kullandığını fark ediyorum ... Sanırım hala konsol modunda stdout'a gidiyor.)
Jesse Millikan

Bu kodu çalıştırmakta sorun yaşıyorum. Sadece konsola mı yazarım?
mellamokb

@mellamokb Program disballs.ijs ve j602 / bin / jconsole için doğru yol olarak kaydedilmiş yukarıdaki test komut dosyası gibi bir şey kullanıyorum.
Jesse Millikan

@Jesse: Bunu pencerelerde çalıştırıyorum. Ben olsun << was unexpected at this time. Üzgünüm J girişine yeniyim, hep konsol modunda kullandı.
15'te mellamokb

2

Golfscript - 26 karakter

Uyarı: 12 4 kasasının çok fazla belleğe ihtiyacı var (aşağıdaki cevap kadar olmasa da) ve çalışması biraz zaman alıyor

~:)\?:x,{x+)base(;.&,)=},,

Açıkçası bu cevabın bazı sorunları var, ama burada bırakacağım çünkü yorumlar buna atıfta bulunuyor ve mellamokb'un cevabı buna dayanıyor.

Golfscript - 24 karakter

Uyarı: 12 4 kasasının çok fazla belleğe ihtiyacı var ve çalışması biraz zaman alıyor

~:o)\?,{o)base[0]-,o=},,

2
Bu kodu nasıl bulduğunuzu anlayamıyorum, sadece bu yöntem büyük girişler için bellek tükenmekle kalmayacak, aynı zamanda artış operatörlerinin ne için iyi olduğunu da anlayamıyorum. Aslında 6 3 için hedefi vurmak şans dışında bir şey gibi görünüyor.
aaaaaaaaaaaa

Bu palyaço değil, bu benim karım!
Jesse Millikan

2
Golfscript'i anlamıyorum ama dediğin gibi, senin yaklaşımın çok yavaş.
Quixotic

3
@mellamokb, nasıl çalışması gerekiyordu üzerinde çalışmak için size iyi :) Bu hatayı düzeltmek için sadece 2 ekstra karakter aldı. Şimdi en kısa kodun doğru olabileceği ancak pratik olmayabileceği karanlık alandayız. Code-golf delicesine verimsiz cevaplarla doludur, ancak mikrosaniyeler ve saniyeler arasında genellikle önemli değildir. Bu aşırı bir durum ( çok fazla bellek). Debanjan, cevapların daha hızlı olması gerektiğini belirtti, ancak bu site SPOJ değil , bu soru code-golf olarak etiketlendi
gnibbler

1
@gnibbler, 0 0üretmelidir 1; 0 kherhangi biri için küretmek gerekir 0; n 1için n > 0üretmelidir 1.
Peter Taylor

2

Python 140 Karakterleri

import sys
f=lambda n,k:(n and k and n>=k and k*(f(n-1,k-1)+f(n-1,k)))or(n+k==0 and 1)or 0
for l in sys.stdin:print f(*(map(int,l.split())))

2

dc, 100 karakter

[0q]s5[1q]s6[l2l3>5l3 0>5l2 0=6l2 1-S2l3dS3 1-S3l1xL3s9l1xL2s9+L3*]s1[?z0=5S3S2l1xL3L2+s9fs9l4x]ds4x

Ne yazık ki, dc ideone tarafından desteklenmiyor gibi görünüyor. Sıkıştırılacak bir veya iki karakter olabilir, ama yatma vakti.

Not: Bu, birden fazla girdi satırını destekler, 20 19( hatta lanet, Perl, çözümümde hata ayıkladığım zaman!) Bile doğru çıktıyı vermek için yeterli hassasiyete sahiptir ve için doğru çıktıyı verir 0 0.

Nabb'ın önerileri, en azından

[0q]sZ[1q]sI[?z0=ZSkSn[lnlk>Zlk0>Zln0=Iln1-SnlkdSk1-SklFxLks9lFxLns9+Lk*]dsFxfs9l4x]ds4x

kayıt yığınlarında önemsiz bırakma pahasına (ve milyarlarca cevabı hesaplarsak hafızamız tükenir).


Kayıtlar her zaman tek karakterdir (kodu daha okunabilir hale getirecek herhangi bir karakter kullanabilirsiniz), bu l11nedenle ayrıştırılır l1 1( yine de hassasiyeti değiştirmeyecekseniz Ktek bir karakter belirteci olarak kullanabilirsiniz 0). Giriş döngüsünü olarak değiştirebilirsiniz ?[...?z1=4]. Makroyu kayıt defterinde satır içine alabilirsiniz 1. Ve muhtemelen genel olarak daha fazla karakter kaydedebilirsiniz, ancak onu anlamak için daha kısa olmasını bekleyeceğim.
Nabb

@ Nabb, ah, adam sayfasını yeterince dikkatli okumadım. Sadece 8 veya 9 kayıt kullanıyorum, bu yüzden yanlış anlaşılmamın sonuçlarıyla karşılaşmadım. Teşekkürler.
Peter Taylor

1

Golf Yazıları (28 31 37 )

~):$\.($\?:@;?,{@+}%{$base$,\-[0]=},,

Değiştirilmesi, gnibblerbireyin GolfScript çözeltisi. Bence bu çalışma çözümü - [3,2], [4,2], [6,3] ve [9,2] ile doğru cevaplarla test edildi. (Kullandığım $ve @değişkenler için etrafında yer sıkılaştırmak için baseanahtar kelime).

Şu gnibbleranki çözümü ile ilgili iki sorun var .

  1. [0] 'ı çıkardıktan sonra uzunluğu kontrol etmek bir çözümü garanti etmez, çünkü 4 topun tümü aynı hücrede olmasına rağmen [4, 1] giriş [4,2] için geçerli olacaktır (1). Bu yüzden tüm basamakların kullanıldığını kontrol etmek için değiştirdim, yani dizi 1-2 içeriyor, bu yüzden her hücre en az bir top içeriyor.
  2. Giriş [4,2] durumunda, 0-27 sayılarının temel-3 biçimi 4 basamaktan küçüktür ve en soldaki 0'lar dahil değildir. Yani [1,1] teknik olarak gerçekte [0,0,1,1] olmasına rağmen geçerli bir çözüm olarak dahil edilir, yani ilk iki top hiçbir yere yerleştirilmez. Her girişe 3 ^ 3 (k ^ n girişleri dizisine genel olarak k ^ n-1) ekleyerek düzeltirim, böylece ilk girişler taban-k biçiminde ve son olarak en az n basamağa sahip olacak şekilde yukarı kaydırılır girişler yine de otomatik olarak geçersiz olur ve çözümü etkilemez (çünkü ikinci basamak her zaman 0 olacaktır).

Düzenle

~:@\?:$,{$+}%{@base(;@,\-,0=},,

`~:@\?:$,{$+@base(;@,\-,0=},,`

Daha iyi bir çözüm! Arttırmaya gerek yok, sadece tüm sayıları ekleyin, böylece [1] ile başlayacaklar ve ilk basamağı dekonksiyon yaptıktan sonra hiçbir rakam eksik olmayacak (0'ların sol dolgusu dahil). Bu çözüm çalışmalı ve yukarıdaki aynı girişlerle test edilmiştir. Ayrıca çok daha hızlıdır, çünkü diziyi oluşturmak için üs almadan önce artmıyoruz (ancak daha büyük giriş için aynı performans / bellek probleminden muzdarip).

Düzenleme : gnibblerEk $bir adım yerine filtrenin içine ekleme ekleme fikrini kullanın . (3 karakter kaydedin).


Girdi kesiliyor 0 0.
Peter Taylor

Ayrıca yalnızca bir giriş satırını işliyor gibi görünüyor.
Peter Taylor

Ve n 1herhangi bir n için kırılır, asılmasına neden olur. hmm ..
mellamokb

1
sayıları taban 1'e dönüştürmek bunu yapacak :)
gnibbler

@gnibbler: Öneriniz var mı? Bu davaları yakalamak için başlangıçta bazı if ifadeleri atmam gerekecek mi? Bu şekilde çok fazla yer kaybedeceğim gibi görünüyor.
mellamokb

0

05AB1E , 19 bayt

#D`ULX.Œʒ€gßĀ}gs_P+

NOT: Son derece yavaş ve zaten zaman aşımına uğradı 12 4. Yine de amaçlandığı gibi çalışıyor. Tüm test senaryoları için makul bir sürede çalışan alternatif bir yöntem bulup bulamayacağımı göreceğim. Tüm test senaryolarını bir saniyeden daha kısa sürede çalıştıran çok daha hızlı bir sürüm için aşağıya bakın.

Çevrimiçi deneyin veya birkaç küçük (daha küçük) test vakasını doğrulayın .

Açıklama:

#               # Split the (implicit) input-string by spaces
 D              # Duplicate it
  `             # Push both values to the stack
   U            # Pop and store the second value in variable `X`
    L           # Create a list in the range [1,n] for the first value
     X        # Create a list of all possible ways to divide this list into `X` partitions
                # (including empty sublists, so we'll have to filter them out:)
        ʒ       # Filter this list of lists of partition-lists by:
         g     #  Get the length of each partition-list
           ß    #  Get the minimum length
            Ā   #  Truthify; 0 remains 0 (falsey); anything else becomes 1 (truthy)
             }g # After the filter, take the length to get the amount left
 s              # Swap so the duplicated input-list is at the top of the stack again
  _             # Check for each value if they're equal to 0 (1 if truthy; 0 if falsey)
   P            # Take the product of the two to check if both input-values are 0
    +           # And add it to the earlier calculated product (edge case for [0,0] = 1)
                # (After which the result is output implicitly)

05AB1E , 29 bayt

İşte TIO'da yaklaşık 0,5 saniyede tüm test senaryoları için çalışan çok daha hızlı bir sürüm:

Î#R`V©LRvyYmX*NÈ·<*+Xy*®y->÷U

Port of @mellamokb 's JavaScript yanıtı , bu yüzden onu oyladığınızdan emin olun!

Çevrimiçi deneyin veya tüm test senaryolarını doğrulayın .

Açıklama:

Î                    # Push (result=) 0 and the input
 #                   # Split the input by spaces
  R`                 # Push the values to the stack reversed
    V                # Pop and store the first value in variable `Y`
     ©               # Store the second value in variable `®` (without popping)
      LRv            # Loop `y` in the range [`®`,1], with index `N` in the range [0,`®`):
         yYm         #  Calculate `y` to the power `Y`
            X*       #  Multiply it by `X`
                     #  (Note: `X` is 1 before setting it to another value initially)
              NÈ     #  Check if index `N` is even (1 if truthy; 0 if falsey)
                ·<   #  Double it; and decrease it by 1 (1 if truthy; -1 if falseY0
                  *  #  Multiply it to the earlier number
                   + #  And add it to the result
         Xy*         #  Push `X` multiplied by `y`
         ®y->        #  Push `®` - `y` + 1
             ÷       #  Integer divide them
              U      #  Pop and store it as new variable `X`
                     # (output the result at the top of the stack implicitly after the loop)

NOT: 0 0Bu durumda kenar durumu için çalışır ( Lyerleşik yöntemi bir liste oluşturacağından , bu yöntemi kullandığım JavaScript yanıtının aksine) [0,1].

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.