Golf Golfu yapabilir misin?


53

Rasgele 18 delikli bir golf sahası oluşturmanız gerekmektedir.

Örnek çıktı:

[3 4 3 5 5 4 4 4 5 3 3 4 4 3 4 5 5 4]

Kurallar:

  • Programınız tam 18 delik için delik uzunluklarının bir listesini çıkarmalıdır
  • Her deliğin uzunluğu 3, 4 veya 5 olmalıdır
  • Delik uzunlukları tüm kurs için 72'ye kadar eklemelidir
  • Programınız, sıfır olasılıksız bazı olasılıklarla mümkün olan her delik konfigürasyonunu üretebilmelidir (her konfigürasyonun olasılıklarının eşit olması gerekmez, ancak bu durumda ekstra kudos talep etmekten çekinmeyin)

3
Lütfen onaylayın, 44152809 çözümler?
bebek-tavşan

1
Tam çözüm sayısını da merak ediyorum, ancak bunun 44 milyondan fazla olması gerektiğini düşünüyorum ... (matematikçi değilim, ancak: | 1 (5) / 1 (3) = 306 olasılık (17 * 18) | 2 (5) / 2 (3) = 69360 sahip (17 * 17 * 16 * 15) | 3 (5) / 3 (3) = 11182080 sahip (16 * 16 * 16 * 15 * 14 * 13) |
NRGdallas 26:12

11
@ baby-rabbit: 44,152,809 çözümlerini kaba kuvvet numaralandırması ile onaylayabilirim. Ortalama tam da başlangıcı: Ayrıca, doğrudan bu şekilde hesaplanabilir 4ve sadece olasılıklar vardır 3, 4ya 5, olası çözüm sınıfları {vardır no 3's or 5's, one 3 and one 5, two 3's and two 5's,, ... nine 3's and nine 5's}. Bu hesaplanabilir nCr(18,0)*nCr(18,0) + nCr(18,1)*nCr(17,1) + nCr(18,2)*nCr(16,2) + ... + nCr(18,9)*nCr(9,9) = 44,152,809. Bu, yaklaşık 11.4%olarak tüm olası kombinasyonların geçerli çözümleri olduğu anlamına gelir (44,152,809 / 3^18).
mellamokb

2
sum(factorial(18)/factorial(x)/factorial(y)/factorial(z) for x in range(25) for y in range(25) for z in range(25) if 3*x+4*y+5*z == 72 and x+y+z == 18)verir44152809L
Sanjeev Murty

Yanıtlar:


29

k ( 18 17 16 karakter)

Orijinal yaklaşıma geri dönersek, iyileştirme için CS'ye kredi verin.

(+/4-){3+18?3}/0

Diğer yaklaşım (17 karakter), J çözümü ile aynı yöntem, CS için H / T

4+a,-a:9?2 -18?18

Eski versiyon:

(72-+/){18?3+!3}/0

Yığın taşmasına duyarlı değildir ve sabit miktarda alanda çalışır.


CS için H / T nedir?
Gareth


Bu program K yorumlayıcımda bir hata keşfetmeme yardımcı oldu , teşekkürler! Niladların (görmezden geldikleri) tek bir argümana uygulanabileceğini daha önce fark etmemiştim.
JohnE


15

J, 20 18 17 karakter

(?~18){4+(,-)?9#2

Bu, 9 rastgele basamağın 0 veya 1 olması ve eklenmeden önce ihmal edilmesi dışında, önceki yanıtla aynı şekilde çalışır. Bu kadar çok var demektir -1olduğu gibi ler 1ler. 4 eklemek bana her seferinde 72'ye kadar ekleyen bir 3s, 4s ve 5s listesi verir .

Önceki cevap:

({~?~@#)3+(,2-])?9#3

İlk 9 deliği rasgele oluşturur ?9#3, sonra (,2-])final 9'u elde etmek için bunları kopyalar ve tersine çevirir (3'ü 5'e 5 ve 5'i 3'e çevirir ). delik başına ortalama toplam 4 ve 4x18 = 72 olacaktır. Daha sonra ({~?~@#)her kombinasyonun mümkün olmasını sağlamak için sonucu rastgele karıştırır .


aslında {3,5,4,4,4 ...} 'ı üretmeyeceksin, tüm sonucu karıştırmakta daha iyi olursun
mandal ucube

@rachetfreak İyi nokta. Şimdi düzenleyeceğim.
Gareth

13

MS-DOS altında 16-bit x86 makine kodu - 45 byte

HexDump:

0E5F576A12595188ECE44088C3E44130D8240374F400C4AAE2EF595E80FC2475DFAC0432CD29B020CD29E2F5C3

Base64 kodlanmış ikili:

Dl9XahJZUYjs5ECIw+RBMNgkA3T0AMSq4u9ZXoD8JHXfrAQyzSmwIM0p4vXD

Bazı yorumlar ile gerçek kaynak kodu:

 bits 16
 org 0x100

again:
 push cs               ; Save whatever CS we get.
 pop di                ; Use CS:DI as our course buffer..
 push di               ; Save for later use in the print loop
 push 18               ; We need 18 holes for our golf course.
 pop cx                ; ch = 0, cl = 18.
 push cx               ; Save for later use.
 mov ah, ch            ; Zero out ah.
generate_course:
 in al, 0x40           ; Port 0x40 is the 8253 PIT Counter 0.
 mov bl, al            ; Save the first "random" value in bl.
 in al, 0x41           ; Port 0x41 is the 8253 PIT Counter 1.
 xor al, bl            ; Add some more pseudo randomness.
 and al, 3             ; We only need the two lower bits.
 jz generate_course    ; If zero, re-generate a value, since we need only 3, 4, 5 holes.
 add ah, al            ; Sum in ah register.
 stosb                 ; Store in the course buffer.
 loop generate_course  ; Loop for 18 holes.
 pop cx                ; cx = 18.
 pop si                ; si = course buffer.
 cmp ah, 36            ; 72 holes?
 jne again             ; No, re-generate the whole course.

print:                 ; Yup, we have a nice course.
 lodsb                 ; Load the next hole.
 add al, '2'           ; Add ASCII '2' to get '3', '4' or '5'
 int 0x29              ; Undocumented MS-DOS print function.
 mov al, ' '           ; Print a space too for better readability.
 int 0x29              ; Print the character.
 loop print            ; Print the whole course.
 ret                   ; Return to the beginning of the PSP where a INT 0x20 happen to be.

nasm 18h.asm -o 18h.com32-bit Windows sürümünden MS-DOS (veya Dosbox) veya NTVDM ile derleyin ve çalıştırın.

Örnek çıktı:

4 5 4 5 4 5 3 4 3 4 3 4 4 5 4 3 5 3

3
assembler seviyorum ...
woliveirajr 27:12

13

Mathematica 71 68 66 60

Tally'nin önerisi ile kaydedilen 6 karakterle.

RandomSample@RandomChoice@IntegerPartitions[72, {18}, {3, 4, 5}]

{5, 4, 3, 3, 5, 3, 5, 5, 3, 3, 4, 5, 3, 5, 4, 4, 5, 3}

Tüm olası sonuçlar mümkündür, ancak eşit derecede muhtemel değildir.


analiz

IntegerPartitions[72, {18}, {3, 4, 5}]

72 'nin 10 olası bölümünün tümünü (izinler değil, kombinasyonlar) 3, 4 ve 5' den oluşan 18 element oluşturur.

bölümler


RandomChoice bunlardan birini seçer.

RandomSample bu seçimin bir permütasyonunu döndürür.


Hehe, hemen hemen aynı cevabı göndermek üzereydim, sadece RandomInteger yerine RandomChoice kullanıyordum. Bence bunu yaparak 4 karakter daha tıraş edebilirsiniz.
Tally

Tally, teşekkürler. Öneriniz yardımcı oldu.
DavidC,

8

R - 41

x=0;while(sum(x)!=72)x=sample(3:5,18,T);x

# [1] 5 3 5 3 3 3 3 3 5 4 5 4 5 4 4 5 5 3

Algoritma @ sgrieve'ninkine benzer.


Yukarıda belirtilen ile aynı sorun - hiçbir şey 18 delikten geçmesini engellemez.
gt6989b

3
Bu bir sorun değil, bu durumda sample komutu her zaman 18 değer üretir.
sgrieve

8

GolfScript (26 karakter)

{;0{3rand.3+@@+(}18*])}do`

Ilmari'nin çözümüyle ilgili bazı belirgin benzerlikler var, fakat aynı zamanda bazı belirgin farklılıklar var. Özellikle, ortalama par 4 olduğu gerçeğinden yararlanıyorum.


Kahretsin, ama bu kesinlikle orada döngü koşulu ile akıllı bir hiledir. {;0{3.rand+.@+}18*])72-}doKendi kendime geldim ama oradan nasıl daha kısa sürede çıkarılacağını çözemedim. +1.
Ilmari Karonen

7

Python 77

kod

from numpy.random import*;l=[]
while sum(l)!=72:l=randint(3,6,18)
print l

Çıktı

[3 4 4 5 3 3 3 5 4 4 5 4 5 3 4 4 5 4]

İthalat bu çözümü gerçekten öldürüyor. 3 ile 5 arasında 18 sayı üretmek için numpy kullanır ve listenin toplamı 72'ye eşit olana kadar listeler oluşturmaya devam eder.


18 delik oluşturmadan önce programın 72 seviyesine ulaşmasını engelleyen nedir? 72'yi atlamasını engelleyen nedir?
DavidC

3
Kod her zaman 18 delik üretecek, sonra toplamın 72'ye eşit olup olmadığını kontrol edecektir. Örneğin, 16 delikten sonra toplam 72 ise, yine de 2 delik daha üretecek, böylece toplamı 72'nin üzerine itecek ve testi başaramayacaktır.
sgrieve

7

GolfScript, 27 karakter

{;18{3.rand+}*].{+}*72-}do`

Sgrieve'nin Python çözümü ile aynı ret örnekleme yöntemini kullanır. Dolayısıyla, her geçerli çıktı aslında eşit derecede muhtemeldir.


7

Q (25 karakter)

Orijinal (27)

while[72<>sum a:18?3 4 5];a

Örnek çıktı

4 4 3 3 4 5 4 3 4 5 5 3 5 5 5 4 3 3

Biraz daha kısa (25)

{72<>sum x}{x:18?3 4 5}/0

7

JavaScript, 66 64 61 karakter

TwoScoopsofPig (PHP) ve Joe Tuskan (JS) 'dan büyük bir ilham aldı.

for(a=[s=0];s!=72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0);a

for(a=[s=0];s-72;)for(s=i=0;i<18;s+=a[i++]=Math.random()*3+3|0)a

for(a=s=[];s;)for(i=18,s=72;i;s-=a[--i]=Math.random()*3+3|0)a

2
s!=72s-72bir karakter kaydetmek olabilir . Ve son yarı-kolon ;abaşka bir karakter için de gerekli değildir.
Joe Tuskan

for(i=x;i;i--)2 karakter kazanmadan önce hiç görmedim for(i=0;i<x;i++), teşekkürler adamım!
Matematik chiller

7

Python 2,70 bayt

from random import*
print sample(([3,5]*randint(0,9)+[4]*99)[:18],18)
Düzenle:

İşte sgrieve çözümüne benzer bir tane daha:

Python 2, 73 bayt + eşit olasılık

from random import*
a=[]
while sum(a)-72:a=sample([3,4,5]*18,18)
print a

5

JavaScript, 116 99 65 bayt

for(i=0,h=[];i<18;)h[i++]=5;while(h.reduce(function(a,b){return a+b})!=72){i=Math.random()*18|0;h[i]=[3,4,4][i%3]}h;

h=[0];while(h.reduce(function(a,b){return a+b})-72)for(i=0;i<18;h[i++]=[3,4,5][Math.random()*3|0])h

while(i%18||(a=[i=s=0]),s+=a[i++]=Math.random()*3+3|0,s-72|i-18)a

1
Bunu Chrome 21'de çalıştırdığımda anladım i is not defined.
mellamokb

5

Python, 128 120 116 karakter

import random,itertools
random.choice([g for g in itertools.product(*(range(3,6)for l in range(18))) if sum(g)==72])

import ifadeler hala uzunluk katiller (ad alanına 2 işlev almak için sadece 23 karakter)

umarım yakın gelecekte sonuçlara ihtiyacınız yoktur, çünkü bu kod ilk önce rastgele seçmeden önce olası tüm çözümleri değerlendirir. belki de bu sorunun en yavaş çözümü.

Her bir konfigürasyonun eşit olasılığı için fazladan kudos talep ediyorum ...


4
import random,itertools
yerçekimi

haklısın, bu işleri biraz kısaltır.
Adrien Plisson

Diğer ipuçları: import random as r,itertools as io zaman kullanmak rve iyerine randomve itertools. Kullanım 18*[0]yerine range(18)ve [3,4,5,6]yerine range(3,6):)
Alex L

python 3 kullanıyorum: bir liste anlama bir jeneratördür ve uzunluğu yoktur, bu choice()fonksiyonla kullanımını yasaklar . bu kodu bu kadar yavaş yapan da budur ...
Adrien Plisson 26:12

1
üzgünüm, liste anlama ve üretecin ifadesini karıştırdım (yineleyicinin daha iyi performans göstermesinden dolayı genellikle jeneratör ifadesinin lehine liste anlamadan kaçınırım). gerçekten, python3'te bile hala bazı karakterleri kaldırabilirim ... @Alex doğru yaptı.
Adrien Plisson

4

PHP - 77 Karakter

<?while(array_sum($a)!=72){for($i=0;18>$i;){$a[++$i]=rand(3,5);}}print_r($a);

Sgrieve'nin çözümü gibi, bu 18 delikten oluşan bir liste oluşturur, toplamı kontrol eder ve ya basar ya da reddeder ve tekrar dener. İşin garibi, iki çözümümüz aynı uzunluktadır.

Can sıkıcı bir şekilde, PHP herhangi bir ad kısaltmasına sahip dizi işlevleri sunmuyor. Array_sum ve print_r beni öldürüyor. Önerilerinizi bekliyoruz.


1
Kıvırcık parantez burada gerekli değildir ve toplamı olabilir +=. <?while($s!=72)for($s=$i=0;18>$i;$s+=$a[++$i]=rand(3,5));print_r($a);
grawity

Ben mantık koymak hiç düşünmemiştim - Bu kullanışlı içinde döngü çağrısının (ve toplamı için bir sayıcı için değil biraz aptal hissediyorum).
TwoScoopsofPig

Teşekkürler - ama aslında "gerekmeyen kaşlı ayraçlar" derken demek istediğim şey bu değil; onları orijinal kodunda da while(array_sum($a)!=72)for($i=0;18>$i;)$a[++$i]=rand(3,5);
çıkarabilirdin

Bundan daha katı bir php.ini'ye karşı koşmam dışında, işte golf oynadığım için; diş tellerinin eksik / uyumsuz olmasından şikayet etmiyor. Normalde yapardım.
TwoScoopsofPig

Bu garip; 5.4.7 ile E_ALL | E_STRICT, hiçbir zaman eksik olmadığından şikayet etmez {}(PHP'nin sözdizimi açıkça izin verdiği için).
Grawity

4

Yakut 1.9 (62 karakter)

a=Array.new(18){[3,4,5].sample}until(a||[]).inject(:+)==72
p a

Raylar (55 karakter)

In $ rails c(herhangi bir Raylar klasöründe) repl:

a=Array.new(18){[3,4,5].sample}until(a||[]).sum==72
p a

Not: Kullanmak eğer Ruby 1.8 ile çalışır shuffle[0]yerine sample.


2
Kadar boşluğa mı ihtiyacınız var?
Kaz

@Kaz Haklısın, gerekli değil. :) Şimdi 62 karakter.
js-coder

1
(1..18).map{rand(3)+3}Rastgele diziyi elde etmek için kullanabilirsiniz ;)
epidemian

4

Lisp ( 78 69 karakter)

(((c () (mapcar (lambda (x) (+ 3 (rastgele 3)))) (marka listesi 18)))) (((= ('+ c uygulayın)) 72) c) yapın

(do((c()(loop repeat 18 collect(+ 3(random 3)))))((=(apply'+ c)72)c))

Sgrieve'nin Python çözümüne çok benziyor.

C ile NIL olarak başlayın, 72 toplamını kontrol edin, c için do"artırma fonksiyonu" 3 ile 5 arasında 18 sayıdan oluşan bir liste oluşturur, tekrar 72 için kontrol edin, köpürün, durulayın, tekrarlayın.

Birlikte golf oynamak dove loopgüzel bir şekilde oynamak ferahlatıcı .


3

C (123 karakter) - verimlilik çalışması

Wc'den geçtikten sonra 10 saniye içinde 44152809 çözüm üretecek ...

char s[19];g(d,t){int i;if(d--){for(i=51,t-=3;i<54;i++,t--)if(t>=3*d&&t<=5*d)s[d]=i,g(d,t);}else puts(s);}main(){g(18,72);}

Oh, pekala - soruyu doğru okumamıştım - ama tüm çözümleri ürettiğimizden sonra eşit olasılıkla rastgele bir tane seçmek bir senaryo çalışmasıdır: P


3

Clojure - 55

(shuffle(mapcat #([[4 4][3 5]%](rand-int 2))(range 9)))

Oldukça eğlenceli bir püf noktası .... problemin matematiksel yapısını kullanarak 5 par deliği kadar 3 par deliği olması gerekir.


3

Python 83

import random as r;x=[]
while sum(x)!=72:x=[r.randint(3,5) for i in 18*[0]]
print x

Sgrieve'nin çözümü gibi, ama hissiz

Adrien Plisson'ın çözümü: 120-> 108 karakter

import random as r,itertools as i
r.choice([g for g in i.product(*([3,4,5,6]for l in 18*[0]))if sum(g)==72])

MATLAB 53

x=[];
while sum(x)~=72
x=3+floor(rand(1,18)*3);
end
x

Çıktı :

x = 4 3 4 4 4 4 5 4 4 3 4 4 3 5 5 5 4 5


Güzel bir yaklaşım, ancak randi([3,5],1,18)yerine yazarak 4 bayt tasarruf edebilirsiniz3+floor(rand(1,18)*3)
brainkz

3

Java (61 karakter)

while(s!=72)for(i=0,s=0;i<18;i++)s+=3+(int)(Math.random()*3);

Örnek çıktı:

5 4 3 4 5 3 4 4 3 5 4 4 4 4 3 4 4 5

Java uzmanı değilim, ancak s ve i'nin bir bildirimi ve System # println (..) 'a bir tür çağrı gelmemeli mi?
hiergiltdiestfu

Bu sadece bir kod pasajı, bir program değil. Ve aslında @JoeIbanez 'C versiyonuna çok benziyor.
Franz D.

2

C (94 karakter)

int h[18],s=0,i;
while(s!=72)for(i=s=0;i<18;s+=h[i++]=rand()%3+3);
while(i)printf("%d ",h[--i]);

s=01. satırda şansı nedir çünkü başlatılmamış int 72 eşit olacaktır, gerekmeyebilir? Ben sadece başlatılmamış değerleri C düzleminde okumayı sevmiyorum. Ayrıca, bu muhtemelen rand()işlevin tohumlanmasını gerektirir .

çıktı

3 3 3 4 5 5 3 3 4 5 5 4 3 4 5 5 5 3 

Yani, temelde, 72'ye eşit olana kadar 3 ila 5 arasında değişen 18 sayıdan oluşan rasgele dizelerden geçeceksiniz. İyi bir şey verimlilik bir zorunluluk değildir.
KeithS

5
@KeithS Adil olmak gerekirse, bu sorunun cevabının çoğunluğunun yaptığı budur.
Gareth 25:12

2

Bash kabuk betiği (65 karakter)

shuf -e `for x in {0..8}
do echo $((r=RANDOM%3+3)) $((8-r))
done`

( shuf , GNU coreutils paketinden geliyor. Ayrıca, teşekkürler Gareth.)


2

C # (143 boşluksuz):

()=>{
  var n=new Math.Random().Next(10);
  Enumerable.Range(1,18)
    .Select((x,i)=>i<n?3:i>=18-n?5:4)
    .OrderBy(x=>Guid.NewGuid())
    .ForEach(Console.Write);
}

new Guid()boş bir GUID oluşturur. Gerçekten benzersiz bir GUID oluşturmak için statik bir yöntem çağırmanız gerekir Guid.NewGuid.
Rotsor

İki tane bire bir hata var (tabiri caizse): Karşılaştırmalar tersi değil, i <n ve i> = 18-n olmalıdır. Ve x + 1 yerine x-1 yerine 5 ve 3'ü kullanarak boyutu azaltabilirsiniz. Ve sonra Enumerable.Repeat Enumerable.Range tarafından değiştirebilirsiniz.
Mormegil

Düzenlenen; hala 143 karakter
KeithS

Hiçbir yoktur Math.Random, bu kadar System.Random.
CodesInChaos

Başka bir C # yaklaşımı (143 karakter):var r=new Random();for(;;){var e=Enumerable.Range(1,18).Select(i=>r.Next(3,6)).ToList();if(e.Sum()==72){e.ForEach(i=>Console.Write(i));break;}}
thepirat000


2

Perl, 74

{@c=map{3+int rand 3}(0)x18;$s=0;$s+=$_ for@c;redo unless$s==72}print"@c"

Alternatif çözüm:

@q=((3,5)x($a=int rand 9),(4,4)x(9-$a));%t=map{(rand,$_)}(0..17);print"@q[@t{sort keys%t}]"

2

TXR (99 karakter)

@(bind g@(for((x(gen t(+ 3(rand 3))))y)(t)((pop x))(set y[x 0..18])(if(= [apply + y]72)(return y))))

Bu ifade, 3 ila 5 arasında rastgele sayıların sonsuz bir tembel listesini oluşturur:

(gen t (+ 3(rand 3)))  ;; t means true: while t is true, generate.

Mantığın geri kalanı, bu listenin ilk 18 öğesinin 72'ye kadar eklenip eklenmediğini kontrol eden basit bir döngüdür. Değilse, bir öğe çıkarır ve tekrar dener. forDöngü örtülü bir blok içerir nilve bu (return ...)döngü sona ve değeri döndürmek için kullanılabilir.

99 karakter uzunluğunun, gerekli olan sonlandırıcı bir yeni satır içerdiğini unutmayın.


(T) 'nin () ile değiştirilmesine izin veren bir taahhütte bulundum. :)
Kaz

2

APL 12

4+{⍵,-⍵}?9⍴2

Dizin orijininin 0 olarak ayarlanmış olduğunu, yani dizilerin 0'dan başladığını unutmayın ⎕IO←0.


Soru, mümkün olan her konfigürasyonu üretebilecek bir program sorar. Sizinki simetrik olanları üretebilir. Örneğin 555455555333333343'ü üretemezsiniz, en azından bana öyle geliyor.
Moris Zucca,

2

R, 42 bayt

a=0;while(sum(a)-72)a=sample(3:5,18,r=T);a

sample, varsayılan olarak, olası değerler arasında eşit bir şekilde çizer (burada 3 4 5). r=Tanlamına gelir replace=TRUEve yerine örnek ile izin verir.


2

CJam, 17 14 bayt

CJam bu mücadeleden daha yeni, ancak bu yine de en kısa cevap değil, bu yüzden gerçekten önemli değil.

Z5]Amr*I4e]mrp

Burada test et.

Toplamda 72 olanı korumak için her birinin 3eşleştirilmesi gerekir 5. Yani burada nasıl çalışır:

Z5]            e# Push [3 5].
   Amr         e# Get a random number between 0 and 9.
      *        e# Repeat the [3 5] array that many times.
       I4e]    e# Pad the array to size 18 with 4s.
           mr  e# Shuffle the array.
             p e# Print it.
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.