Iterowane Rzut Kości


12

Biorąc pod uwagę wejście nw których 3 <= n <= 25należy wykonać następujące czynności, począwszy od pojedynczego n-sided matrycy (twarze w zakresie [1, n]włącznie):

  1. Wydrukuj wynik nrzutu aktualnymi kostkami w grze, w formie kdn: X(gdzie Xjest wynikiem i kliczbą kości w grze).
  2. Jeśli Xjest większa lub równa n/2liczbie kości w grze, dodaj kość. W przeciwnym razie usuń kostkę.
  3. Jeśli liczba kości w grze jest równa 0lub n, zatrzymaj się. W przeciwnym razie przejdź do kroku 1.

Przykład działa (zauważ, że dane wyjściowe w nawiasach podano w celu wyjaśnienia i nie są wymagane):

6-stronny:

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-stronny:

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)

Zasady

  • Dane wyjściowe muszą być dokładnie w formacie kdn: X, z nowymi liniami oddzielającymi każdą rolkę
  • Musisz faktycznie symulować wyrzucanie wielu kości; zwykłe zwracanie losowej liczby całkowitej z zakresu [1, n](włącznie) pomnożonej przez liczbę kości aktualnie w grze jest niedozwolone, ponieważ nie symuluje to dokładnie rzucania wieloma kostkami.
  • Standardowe luki są zabronione
  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach

Tabela liderów

Fragment kodu na dole tego postu generuje tabelę wyników na podstawie odpowiedzi a) jako lista najkrótszych rozwiązań dla każdego języka oraz b) jako ogólna tabela wyników.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

## Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

Jeśli chcesz umieścić w nagłówku wiele liczb (np. Ponieważ twój wynik jest sumą dwóch plików lub chcesz osobno wymienić kary za flagi tłumacza), upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku:

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

Możesz także ustawić nazwę języka jako link, który pojawi się we fragmencie:

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


Uważam to za mylące. Przykładowa odpowiedź, proszę?
Hipe99

Przykładowa odpowiedź , ponieważ przykłady są zwięzłe.
Hipe99

Twoja edycja została wyjaśniona. Dzięki!
Hipe99

16
Czy jesteś pewien swojej arytmetyki? Konwencjonalny d6 ma średni wynik 3,5.
Peter Taylor,

11
Wszystkie średnie w twoich przykładach wydają się błędne
edc65

Odpowiedzi:



3

Mathematica, 95 89 80 znaków

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

Nie golfił

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

1
@ MartinBüttner dzięki za sugestie. Echoniestety nie może przyjmować sekwencji danych wejściowych tak jak Printrobi.
shrx,

Dobra racja.
Martin Ender,

3

PHP, 164 121 112 113 109 bajtów

Ostateczna wersja, obiecuję. Ulepszono dzięki sugestii Tytusa:

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

EDYCJA: Dodano dodatkowy bajt do formatowania. Zapomniałem, że jest tam JEŻELI, który dzięki upuszczeniu tekstu „dodaj / pod” może być operatorem potrójnym:

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

Wyjście wygląda teraz następująco:

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

EDYCJA: Dzięki @Manatwork bardzo mnie uratował! Nowa i ulepszona wersja:

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

Poprzedni wpis:

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

Rzuca oddzielne matryce, wysyła to:

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

I tak się nazywa: d(6, 1);

Czy wyświetlanie sufiksu Addi jest Subobowiązkowe? Nie jest to jasne z twojego pytania.


Wymaganie mówi „zauważ, że dane wyjściowe w nawiasach służą jako objaśnienie i nie są wymagane”. Ta droga wydaje się krótsza: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 Dzięki, naprawdę bardzo pomogłeś!
steenbergh

If może nadal być trójskładnikiem, oszczędzając jeden bajt. A przemodelowanie wzrostu / zmniejszenia może zaoszczędzić dwa bajty:$y-=$r/$y>$x/2?:-1
Tytus

2

Python 3, 125

Zaoszczędź 3 bajty dzięki DSM.

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

Całkiem proste, rzuca wiązką kości i sprawdza średnią. Nie ma tu jeszcze nic wyszukanego.
To musi być wywołane z int. Wyprodukuje więc x(6)coś takiego:

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 bajtów

Dzięki @ user81655 i @Jupotter za uratowanie mi kilku bajtów.

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

Próbny

Działa to tylko w przeglądarkach zgodnych z ES6 (w tym momencie obejmuje Firefox i Edge, prawdopodobnie z Chrome i Opera z włączonymi eksperymentalnymi funkcjami JavaScript):

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>


Można zmienić whiledo forpętli, okrągły dół z |0zamiast ~~()i przejść kilka stwierdzeń, dzięki czemu można usunąć wsporniki zaoszczędzić kilka bajtów. Możesz także uczynić to funkcją anonimową (nie f=). 103 bajty: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 Dzięki. Z jakiegoś powodu twoja wersja stworzyła wiele zewnętrznych wyników, więc przeniosłem się console.logdo drugiej forpętli (kosztowało mnie 1 znak więcej niż twoja). Nadal
spadłem

Właśnie to napisałem bez testowania, więc cieszę się, że w większości działało. :)
user81655,

Możesz zdobyć jedną postać, zastępując k&&k!=nwarunek porównaniemk%n!=0
Jupotter

@Jupotter Dzięki, k%ndziała jeszcze lepiej;)
rink.attendant.6

1

CJam, 45 bajtów

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

Wypróbuj online.

Implementuje specyfikację dosłownie (w tym matematycznie niepoprawną formułę „średniego rzutu”). Zgodnie z oczekiwaniami, przenoszenie oryginalny program GolfScript poniżej CJam zapisane kilka bajtów ze względu na krótszy wbudowaną nazw poleceń ( mr, oi gzamiast rand, putsi do).

GolfScript, 51 bajtów

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

Oto mój oryginalny wpis w GolfScript. Do znaczących sztuczek golfowych należy użycie tej liczby 1jako wygodnie wstępnie zainicjowanej zmiennej do przechowywania bieżącej liczby kości do rzucenia. (Zamiast tego używana jest wersja CJam X, którą CJam inicjuje na wartość 1.)


Ps. Widząc tytuł, pierwotnie chciałem odpowiedzieć na to w AnyDice . Ale okazuje się, że jest to okropny wybór dla tego wyzwania i nie sądzę, aby technicznie możliwe było użycie go do wdrożenia tej specyfikacji, jak podano.

Problem polega na tym, że AnyDice jest językiem specyficznym dla domeny do pisania deterministycznych programów do obliczania statystyk rzucania kostkami. Podczas sprawdzania możliwych wyników rzutu i wykonywania rzutów warunkowych na ich podstawie jest możliwe poprzez rekurencję, nie ma sposobu na wygenerowanie faktycznej losowości. Podczas gdy można symulować tę sekwencję rzutów kostką w AnyDice, wszystko, co można uzyskać, to dane statystyczne dotyczące takich rzeczy, jak, powiedzmy, liczba rzutów do zakończenia procesu lub rozkład wyników na danym etapie.

Wszystko, co powiedziałem, oto najbliższe, jakie mogłem uzyskać w AnyDice :

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

Nie jest to szczególnie golfowy kod, ponieważ wydawało się to ćwiczeniem na próżno. Standardowe sztuczki golfowe, takie jak skracanie nazw funkcji i eliminowanie niepotrzebnych białych znaków, powinny i tak wyczerpać większość potencjału golfowego.

Kluczową sztuczką stosowaną tutaj jest to, że kiedy wywołujesz funkcję oczekującą liczby (jak wskazuje :ndefinicja funkcji) w AnyDice i przekazujesz jej matrycę (tj. Rozkład prawdopodobieństwa), AnyDice automatycznie ocenia funkcję dla wszystkich możliwych wartości kości i łączy wyniki w nową kostkę.

Oto zrzut ekranu wyników (w formacie wykresu słupkowego) dla pierwszych trzech rolek:

Zrzut ekranu AnyDice

(Należy zauważyć, że kolumna „0” na każdym wykresie wskazuje prawdopodobieństwo zatrzymania iteracji z powodu liczby kości uderzających albo o 0, albo N przed bieżącym rzutem. Zdarza się, że jest to wygodny sposób na przedstawienie warunku zatrzymania, ponieważ oczywiście zebranie 0dN zawsze daje 0.)


1

R, 103 bajtów

Dość prosta implementacja. Rzuty kostką są wykonywane przez 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)}

Testowe uruchomienie

> 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 bajtów

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

Nie golfił

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 bajtów

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)

Większość z nich powinna być zrozumiała - w ciągu jest używana rzeczywista nowa linia printzamiast printlnzapisywania bajtu. rand(1:n,N)produkuje Nlosowe liczby całkowite od 1 do n.


1

Ruby, 93 90 82 znaków

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

Przykładowy przebieg:

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 bajty (niekonkurujące)

: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

Wyjaśnienie:

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 bajty

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

Biegnij z php -r '<code>' <N>

awaria

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.