Yinelenen Zar Atma


12

Bir giriş nverildiğinde 3 <= n <= 25, tek ntaraflı bir kalıptan başlayarak (aralıktaki yüzler [1, n]dahil) aşağıdaki adımları uygulayın :

  1. Geçerli ntaraflı zarları oyunda yuvarlamanın sonucunu formda yazdırın kdn: X( Xsonuç ve koyunda zar sayısı).
  2. Eğer Xdaha büyük ya da eşit olan n/2oyundaki zar sayısı kez, bir kalıp ekleyin. Aksi takdirde, bir kalıbı çıkarın.
  3. Oyundaki zar sayısı 0veya değerine eşitse n, durdurun. Aksi takdirde, 1. adıma gidin.

Örnek çalışmalar (parantez içindeki çıktının açıklama amaçlı olduğunu ve gerekli olmadığını unutmayın):

6-taraflı:

1d6: 4 (avg: 3.0, add)
2d6: 6 (avg: 6.0, add)
3d6: 9 (avg: 9.0, add)
4d6: 16 (avg: 12.0, add)
5d6: 13 (avg: 15.0, remove)
4d6: 9 (avg: 12.0, remove)
3d6: 5 (avg: 9.0, remove)
2d6: 7 (avg: 6.0, add)
3d6: 11 (avg: 9.0, add)
4d6: 14 (avg: 12.0, add)
5d6: 17 (avg: 15.0, add)

9-taraflı:

1d9: 7 (avg: 4.5, add)
2d9: 14 (avg: 9.0, add)
3d9: 18 (avg: 13.5, add)
4d9: 18 (avg: 18.0, add)
5d9: 28 (avg: 22.5, add)
6d9: 26 (avg: 27.0, remove)
5d9: 28 (avg: 22.5, add)
6d9: 34 (avg: 27.0, add)
7d9: 33 (avg: 31.5, add)
8d9: 30 (avg: 36.0, remove)
7d9: 29 (avg: 31.5, remove)
6d9: 35 (avg: 27.0, add)
7d9: 32 (avg: 31.5, add)
8d9: 42 (avg: 36.0, add)

kurallar

  • Çıktılar tam olarak formatta olmalı kdn: Xve satırlar her ruloyu ayırmalıdır
  • Aslında birden fazla zar yuvarlayarak simüle etmelisiniz; sadece [1, n](zar dahil) aralıkta rastgele bir tamsayı döndürmekte olan zarların oyunda zar sayısıyla çarpılmasına izin verilmez, çünkü çoklu zarları doğru bir şekilde taklit etmez.
  • Standart boşluklar yasaktır
  • Bu , bu yüzden bayttaki en kısa cevap kazanıyor

Liderler Sıralaması

Bu yazının altındaki Yığın Parçacığı, a) her dil için en kısa çözüm listesi ve b) genel bir lider panosu olarak cevaplardan lider tablosunu oluşturur.

Yanıtınızın göründüğünden emin olmak için lütfen aşağıdaki Markdown şablonunu kullanarak yanıtınızı bir başlıkla başlatın:

## Language Name, N bytes

Ngönderiminizin büyüklüğü nerede . Puanınızı artırmak varsa, olabilir onları içinden vurarak, başlığa eski hesapları tutmak. Örneğin:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Başlığınıza birden fazla sayı eklemek istiyorsanız (örneğin, puanınız iki dosyanın toplamı olduğu veya yorumlayıcı bayrak cezalarını ayrı olarak listelemek istediğiniz için), gerçek puanın başlıktaki son sayı olduğundan emin olun :

## Perl, 43 + 2 (-p flag) = 45 bytes

Dil adını, daha sonra snippet'te görünecek bir bağlantı da yapabilirsiniz:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


Bunu kafa karıştırıcı buluyorum. Örnek cevap, lütfen?
Hipe99

Örnek cevap , örnekler kısa olduğu için.
Hipe99

Düzenlemeniz netleştirildi. Teşekkürler!
Hipe99

16
Aritmetik işleminizden emin misiniz ? Geleneksel bir d6'nın ortalama rulosu 3.5'tir.
Peter Taylor

11
Örneklerinizdeki tüm ortalamalar yanlış görünüyor
edc65

Yanıtlar:



3

Mathematica, 95 89 80 karakter

For[k=1,0<k<#,If[Print[k,d,#,": ",x=Tr[{1,#}~RandomInteger~k]];x<k/2#,k--,k++]]&

Ungolfed

For[
  k = 1,
  0 < k < #,
  If[
    Print[k, d, #, ": ", x = Tr[{1, #}~RandomInteger~k]];
    x < k/2 #,
    k--,
    k++
  ]
] &

1
@ MartinBüttner önerileriniz için teşekkür ederiz. Echomaalesef Printyaptığı gibi bir dizi girdi alamıyor .
shrx

Oh, güzel nokta.
Martin Ender

3

PHP, 164 121 112 113 109 bayt

Son versiyon, söz veriyorum. Titus'un önerisi kullanılarak iyileştirildi:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$y+=$r/$y>$x/2?:-1;$y<$x&&$y?d($x,$y):0;}

EDIT: Biçimlendirme için fazladan bir bayt eklendi. İçerisinde "add / sub" metnini bırakarak üçlü bir operatör olabilecek bir EĞER olduğunu unuttum:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}

Çıktı şimdi şöyle görünüyor:

1d6: 5
2d6: 11
3d6: 8
2d6: 11
3d6: 7
2d6: 4
1d6: 5

EDIT: @Manatwork sayesinde beni çok kurtardı! Yeni ve geliştirilmemiş sürüm:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x=$r\n";if($r/$y>$x/2)$y++;else$y--;if($y<$x&&$y){d($x,$y);}}

Önceki giriş:

function d($x,$y){for($i=0;$i<$y;$i++)($r+=rand(1,$x));$s=$y."d$x=$r, ";if($r/$y>$x/2){$y++;$s.="add";}else{$y--;$s.="sub";}echo $s."\n";if($y<$x&&$y>0){d($x,$y);}}`

Ayrı kalıpları yuvarlar, bunu verir:

1d6=6, add
2d6=7, add
3d6=11, add
4d6=14, add
5d6=15, sub
4d6=15, add
5d6=18, add

Ve buna şöyle denir: d(6, 1);

Görüntülüyor Addve Subzorunlu soneki? Bu, sorunuzdan belli değil.


Gereksinim “parantez içindeki çıktının açıklama amaçlı olduğunu ve gerekli olmadığını unutmayın” diyor. Bu şekilde daha kısa görünüyor:function d($x,$y=1){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x, $r↵";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}
manatwork

@manatwork Teşekkürler, gerçekten çok yardımcı oldunuz!
steenbergh

İf hala bir üçlü olabilir ve bir bayt tasarruf sağlar. Ve artış / düşüşün yeniden modellenmesi iki bayt tasarruf edebilir:$y-=$r/$y>$x/2?:-1
Titus

2

Python 3, 125

DSM sayesinde 3 bayt tasarruf etti.

def x(d):
 import random;c=1
 while 0<c<d:r=sum(map(random.randint,[1]*c,[d]*c));print('%id%i: %i'%(c,d,r));c+=2*(r>=d*c/2)-1

Oldukça basit, bir demet zar atar ve ortalamayı kontrol eder. Henüz burada çok süslü bir şey yok.
Bir int ile çağrılması gerekir. Yani, x(6)böyle bir şey üretecek:

1d6: 5
2d6: 10
3d6: 8
2d6: 7
3d6: 11
4d6: 8
3d6: 13
4d6: 19
5d6: 13
4d6: 15
5d6: 22

.


2

JavaScript (ES6), 97 102 106 112 bayt

@ User81655 ve @Jupotter'a birkaç bayt kaydettiğiniz için teşekkürler.

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// 102 bytes:
f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=0;++i<=k;)x+=1+Math.random()*n|0}

// Previous attempt, 112 bytes
f=n=>{k=1;while(k&&k!=n){for(x=i=0;i++<=k;)x+=1+~~(Math.random()*n);console.log(k+`d${n}: `+x);k+=x<k*n/2?-1:1}}

gösteri

Bu yalnızca ES6 uyumlu tarayıcılarda çalışır (şu anda Firefox ve Edge içeren, muhtemelen Chrome ve Opera'da deneysel JavaScript özellikleri etkinken):

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// Snippet stuff
console.log = x => {
  document.getElementById('O').innerHTML += x + `<br>`;
}

document.getElementById('F').addEventListener('submit', e => {
  document.getElementById('O').innerHTML = ``
  f(document.getElementById('I').valueAsNumber)
})
<form id=F action=# method=get>
  <label>
    Number of faces: 
    <input type=number min=3 max=25 value=9 required id=I>
  </label>
  <button>Play</button>
  
  <div>
    <output id=O></output>
  </div>
</form>


whileBir fordöngüyü değiştirebilir, |0yerine yuvarlayabilir ~~()ve birkaç bayt taşıyabilirsiniz, böylece birkaç bayt kaydetmek için köşeli parantezleri kaldırabilirsiniz. Ayrıca, anonim bir işlev yapmanıza izin verilir (hayır f=). 103 bayt:n=>{for(k=1;k&&k!=n;k+=x<k*n/2?-1:1)for(x=i=0;i++<=k;console.log(k+`d${n}: `+x))x+=1+Math.random()*n|0}
user81655

@ user81655 Teşekkürler. Bazı nedenlerden dolayı, sürümünüz çok fazla yabancı çıktı oluşturdu, bu yüzden console.logdiğer fordöngüye taşındım (bana seninkinden 1 karakter daha pahalı). Hala 106
rink.attendant.6

Bunu test etmeden yazdım, bu yüzden çoğunlukla işe yaradığına sevindim. :)
user81655

k&&k!=nKarşılaştırma ile koşulu değiştirerek bir karakter kazanabilirsinizk%n!=0
Jupotter

@Jupotter Teşekkürler, k%ndaha da iyi çalışır;)
rink.attendant.6

1

CJam, 45 bayt

ri:M;{X__{Mmr+}*[X'dM':S5$N]o_+XM*<_+(-:XM%}g

Çevrimiçi deneyin.

Spesifikasyonu kelimenin tam anlamıyla uygular (matematiksel olarak yanlış "ortalama atış" formülü dahil). Beklendiği gibi, CJam için aşağıdaki orijinal GolfScript programı taşıma nedeniyle yerleşik komut isimleri (daha kısa bayt bir demet kurtardı mr, ove gyerine rand, putsvedo ).

GolfScript, 51 bayt

~:&;{1..{&rand+}*[1"d"&": "4$]puts.+1&*<.+(-:1&%}do

İşte orijinal GolfScript girişim. Dikkat çeken golf hileleri , sayının 1, haddelenecek zar sayısını saklamak için uygun şekilde önceden başlatılmış bir değişken olarak kullanılmasını içerir. (Bunun yerine CJam sürümü kullanır X, CJam 1 değerini başlatır.)


Ps. Başlığı görünce, aslında bunu AnyDice'de cevaplamak istedim . Ancak bu meydan okuma için korkunç bir seçim olduğu ortaya çıktı ve bu spesifikasyonu verilen şekilde uygulamak için teknik olarak kullanmanın bile mümkün olduğunu düşünmüyorum.

Sorun AnyDice zar haddeleme istatistikleri hesaplamak için deterministik programlar yazmak için etki alanına özgü bir dildir . Bir rulonun olası sonuçlarını incelemek ve bunlara dayalı koşullu rulolar yapmak mümkün olmakla birlikte , özyineleme yoluyla herhangi bir gerçek rastgelelik üretmenin bir yolu yoktur. Bu nedenle, AnyDice'de bu zar atma sırasını simüle edebilmenize rağmen, çıktı olarak alabileceğiniz tek şey, örneğin, işlem bitene kadar rulo sayısı veya belirli bir adımda sonuçların dağılımı gibi şeylerle ilgili istatistiklerdir.

Bütün bunlar, AnyDice'de alabileceğim en yakın şey :

N: 6
K: 1
function: clip X:n { result: X * (X < N) }
function: adjust X:n { result: [clip X + ((XdN)*2 >= X*N)*2-1] * (X > 0) }
loop I over {1..20} {
  output K named "dice in roll [I]"
  output KdN named "outcome of roll [I]"
  K: [adjust K]
}

Bu özellikle golf kodu değil, çünkü bu boşuna bir egzersiz gibi görünüyordu. Fonksiyon adlarının kısaltılması ve gereksiz boşlukların ortadan kaldırılması gibi standart parantez dili golf hileleri yine de golf potansiyelinin çoğunu tüketmelidir.

Burada kullanılan önemli numara :n, AnyDice'de bir sayı ( işlev tanımında belirtildiği gibi) bekleyen bir işlev çağırdığınızda ve bunun yerine bir kalıp (yani bir olasılık dağılımı) ilettiğinizde, AnyDice'in işlevi mümkün olan her şey için otomatik olarak değerlendirmesidir. değerler kalıbın birleştirmektedir ve yeni kalıp içine sonuçlanır.

İlk üç rulo için çıktının (çubuk grafik biçiminde) bir ekran görüntüsü:

AnyDice ekran görüntüsü

(Not Her bir grafikte, "0" sütunu, yineleme dolayı isabet zar sayısı, durduruldu olasılığını gösterir ya da yana, 0 ya da N, mevcut rulo önce. Bu durdurma koşulunu temsil etmek için uygun bir yol olması umulur Tabii ki 0dN yuvarlanması her zaman 0 verir.)


1

R, 103 Bayt

Oldukça basit bir uygulama. Zar ruloları ile yapılır sum(sample(n,i)).

i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}

Test sürüşü

> i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}
1: 9
2: 
Read 1 item
1d9: 9
2d9: 14
3d9: 10
2d9: 14
3d9: 9
2d9: 9
3d9: 12
2d9: 7
1d9: 9
2d9: 11
3d9: 17
4d9: 18
5d9: 25
6d9: 29
7d9: 33
8d9: 43
9d9: 45
> 

1

CoffeeScript, 106 99 bayt

f=(n,k=1)->(x=k;x+=Math.random()*n|0for[k..0];console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

# Previous attempt, 106 bytes
f=(n,k=1)->(x=i=0;x+=1+Math.random()*n//1while++i<=k;console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

Ungolfed

f = (n, k = 1) ->
 (x = k
 x += 1 + Math.random() * n | 0 for [k..0]
 console.log k + "d#{n}: " + x
 k += x < k * n / 2 && -1 || 1
 ) while k % n

1

Julia, 77 bayt

n->(N=1;while 0<N<n k=sum(rand(1:n,N));print(N,"d$n: $k
");N+=1-2(2k<N*n)end)

Bunların çoğu kendi kendini açıklayıcı olmalıdır - bir baytı kaydetmek için printkullanmak yerine dizede gerçek bir satırsonu kullanılır println. 1 ile arasında rastgele tamsayılar rand(1:n,N)üretir .Nn


1

Ruby, 93 90 82 karakter

->n{d=s=2
puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}

Örnek çalışma:

2.1.5 :001 > -->n{d=s=2;puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}[6]
1d6: 5
2d6: 10
3d6: 6
2d6: 5
1d6: 5
2d6: 8
3d6: 15
4d6: 18
5d6: 22

0

QBIC , 83 bayt (rakip olmayan)

:c=a{e=0[1,q|e=e+_rq,a|]?!q$+@d|!+a$+@:|+!e$~e<c/2|q=q-1\q=q+1]c=q*a~q=a|_X]~q=0|_X

Açıklama:

q                    Tracks the number of dice (is implicitly 1 at the start)
:                    Takes input from a CMD line parameter
[1,q|e=e+_rq,a|]     Rolls the dice separately
?!q$+@d|!+a$+@:|+!e$ Prints the roll result (requires an unfortunate amount of casting...)
~e<c/2|q=q-1\q=q+1]  Checks whether to increase or decrease
~q=a|_X]~q=0|_X      Tests the amount of dice and quits on either boundary.

0

PHP, 104 bayt

for($n=$argv[$k=1];$k&&$k<$n;print$k."d$n: $x\n",$k-=$x<$n*$k/2?:-1)for($x=$i=0;$i++<$k;)$x+=rand(1,$n);

Şununla koş: php -r '<code>' <N>

Yıkmak

for($n=$argv[$k=1];     // import input, init number of dice
    $k&&$k<$n;          // while 0<$k<$n
    print$k."d$n: $x\n",    // 2. print results
    $k-=$x<$n*$k/2?:-1      // 3. remove or add a die
)
    for($x=$i=0;$i++<$k;)   // 1. roll dice separately
        $x+=rand(1,$n);         // sum up results
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.