Iteriertes Würfeln


12

Bei einem gegebenen Eingang nwo 3 <= n <= 25, die folgenden Schritte aus , beginnend mit einem einzelnen n-seitige Gesenk (Flächen im Bereich [1, n], inklusive):

  1. Drucken Sie das Ergebnis des nWürfelns der aktuellen Würfel im Spiel in der Form kdn: X(wo Xist das Ergebnis und kist die Anzahl der Würfel im Spiel).
  2. Wenn die Anzahl der Würfel Xgrößer oder gleich n/2der Anzahl der Würfel im Spiel ist, füge einen Würfel hinzu. Sonst entferne einen Würfel.
  3. Wenn die Anzahl der Würfel gleich 0oder ist n, halten Sie an. Fahren Sie andernfalls mit Schritt 1 fort.

Beispielläufe (beachten Sie, dass die Ausgabe in Klammern zur Erklärung dient und nicht erforderlich ist):

6-seitig:

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

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)

Regeln

  • Die Ausgaben müssen exakt im Format vorliegen kdn: X, wobei die einzelnen Rollen durch Zeilenumbrüche voneinander getrennt sein müssen
  • Sie müssen tatsächlich das Würfeln mehrerer Würfel simulieren. Das einfache Zurückgeben einer zufälligen Ganzzahl im Bereich [1, n](einschließlich) multipliziert mit der Anzahl der aktuell gespielten Würfel ist nicht zulässig, da dies das Werfen mehrerer Würfel nicht genau simuliert.
  • Standardlücken sind verboten
  • Das ist , also gewinnt die kürzeste Antwort in Bytes

Bestenliste

Das Stapel-Snippet am Ende dieses Beitrags generiert die Rangliste aus den Antworten a) als Liste der kürzesten Lösungen pro Sprache und b) als Gesamtrangliste.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

## Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

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

Wenn Sie mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder wenn Sie die Strafen für Interpreter-Flags separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:

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

Sie können den Namen der Sprache auch als Link festlegen, der dann im Snippet angezeigt wird:

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


Ich finde das verwirrend. Beispielantwort, bitte?
Hipe99

Beispiel Antwort , wie die Beispiele kurz und bündig sind.
Hipe99

Deine Bearbeitung geklärt. Vielen Dank!
Hipe99

16
Sind Sie sicher, dass Sie rechnen? Ein konventioneller d6 hat einen durchschnittlichen Wurf von 3,5.
Peter Taylor

11
Alle Durchschnittswerte in Ihren Beispielen scheinen falsch zu sein
edc65

Antworten:



3

Mathematica, 95 89 80 Zeichen

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 danke für deine vorschläge. Echokann leider keine reihenfolge von eingaben nehmen wie das Printtut.
shrx

Oh, guter Punkt.
Martin Ender

3

PHP, 164 121 112 113 109 Bytes

Endgültige Version, das verspreche ich. Verbessert mit Titus Vorschlag:

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

BEARBEITEN: Zusätzliches Byte zur Formatierung hinzugefügt. Ich habe vergessen, dass es eine IF gibt, die dank dem Löschen des "add / sub" -Textes ein ternärer Operator sein könnte:

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

Die Ausgabe sieht jetzt so aus:

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

EDIT: Dank @Manatwork, hat mir viel gespart! Neue und verbesserte Version:

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

Vorheriger Eintrag:

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

Wirft separate Würfel, gibt Folgendes aus:

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

Und so heißt es: d(6, 1);

Muss das Suffix Addund angegeben werden Sub? Dies ist aus Ihrer Frage nicht ersichtlich.


Die Anforderung lautet "Beachten Sie, dass die Ausgabe in Klammern zur Erklärung dient und nicht erforderlich ist". Dieser Weg scheint kürzer: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 Danke, du hast sehr geholfen!
Steenbergh

Das if kann immer noch ein ternäres sein und ein Byte speichern. Und das Umbauen der Zunahme / Abnahme kann zwei Bytes sparen:$y-=$r/$y>$x/2?:-1
Titus

2

Python 3, 125

3 Bytes gespart dank 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

Ziemlich einfach, wirft ein paar Würfel und überprüft den Durchschnitt. Hier ist noch nichts Besonderes.
Es muss mit einem int aufgerufen werden. Also, x(6)wird so etwas produzieren:

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 Byte

Vielen Dank an @ user81655 und @Jupotter, dass sie mir ein paar Bytes gespart haben.

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

Demo

Dies funktioniert nur in ES6-kompatiblen Browsern (derzeit einschließlich Firefox und Edge, möglicherweise mit Chrome und Opera mit aktivierten experimentellen JavaScript-Funktionen):

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>


Sie können die Variable whilein eine forSchleife ändern , mit |0abrunden ~~()und stattdessen einige Anweisungen verschieben, um die Klammern zu entfernen und einige Bytes zu sparen. Du darfst es auch zu einer anonymen Funktion machen (nein f=). 103 Bytes: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 Danke. Aus irgendeinem Grund hat Ihre Version eine Menge irrelevanter Ausgaben erzeugt, so dass ich die console.login die andere forSchleife verschoben habe (kostet mich 1 Zeichen mehr als Ihre). Immer noch auf 106
rink.attendant.6

Ich habe das gerade geschrieben, ohne es zu testen, also bin ich froh, dass es größtenteils funktioniert hat. :)
user81655

Sie können ein Zeichen gewinnen, indem Sie die k&&k!=nBedingung durch den Vergleich k%n!=0
ersetzen

@ Jupotter Danke, k%nfunktioniert noch besser;)
rink.attendant.6

1

CJam, 45 Bytes

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

Probieren Sie es online aus.

Implementiert die Spezifikation ziemlich wörtlich (einschließlich der mathematisch falschen "Mean Roll" -Formel). Wie erwartet, unten an CJam das Original GolfScript Programm portieren ein paar Bytes gespeichert durch kürzere integrierten Befehlsnamen ( mr, ound gstatt rand, putsund do).

GolfScript, 51 Bytes

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

Hier ist mein ursprünglicher GolfScript-Eintrag. Bemerkenswerte Golf-Tricks beinhalten die Verwendung der Zahl 1als eine bequem vorinitialisierte Variable , um die aktuelle Anzahl der zu würfelnden Würfel zu speichern. (Die CJam-Version verwendet stattdessen X, die CJam auf den Wert 1 initialisiert.)


Ps. Als ich den Titel sah, wollte ich das ursprünglich in AnyDice beantworten . Aber es stellt sich als eine schreckliche Wahl für diese Herausforderung heraus, und ich denke nicht, dass es überhaupt technisch möglich ist, diese Spezifikation so zu implementieren, wie sie gegeben ist.

Das Problem ist, dass AnyDice eine domänenspezifische Sprache zum Schreiben ist deterministischer Programme zur Berechnung von Würfelwurfstatistiken ist. Während die möglichen Ergebnisse einer Rolle Inspektion und tun bedingte Rollen auf ihnen basiert ist möglich über Rekursion, gibt es keine Möglichkeit , eine tatsächliche Zufälligkeit zu erzeugen. Während Sie diese Folge von Würfeln in AnyDice simulieren können, erhalten Sie als Ergebnis lediglich Statistiken über die Anzahl der Würfel, bis der Prozess endet, oder die Verteilung der Ergebnisse in einem bestimmten Schritt.

Alles, was gesagt hat, Nach allem hier der nächste, den ich in AnyDice bekommen könnte :

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

Dies ist kein besonders golferischer Code, da dies eine Übung in der Sinnlosigkeit zu sein schien. Standardtricks für das Klammersprachengolf, wie das Verkürzen von Funktionsnamen und das Eliminieren unnötiger Leerzeichen, sollten das meiste Golfpotential sowieso ausschöpfen.

Der wichtigste Trick dabei ist, dass :nAnyDice die Funktion automatisch auswertet , wenn Sie in AnyDice eine Funktion aufrufen, die eine Zahl erwartet (wie in der Funktionsdefinition angegeben), und ihr stattdessen einen Würfel (dh eine Wahrscheinlichkeitsverteilung) übergeben alle möglichen Werte des Würfels und kombiniert die Ergebnisse zu einem neuen Würfel.

Hier ist ein Screenshot der Ausgabe (im Balkendiagrammformat) für die ersten drei Rollen:

AnyDice-Screenshot

(Beachten Sie, dass die Spalte "0" in jedem Diagramm die Wahrscheinlichkeit angibt, dass die Iteration aufgrund der Anzahl der Würfel, die entweder 0 oder N treffen , vor dem aktuellen Wurf gestoppt wurde . Dies ist eine bequeme Möglichkeit, die Stoppbedingung darzustellen, da Natürlich ergibt das Rollen von 0dN immer 0).


1

R, 103 Bytes

Eine recht unkomplizierte Implementierung. Würfelwürfe werden von gemacht 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)}

Testlauf

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

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 Bytes

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)

Das meiste sollte selbsterklärend sein - es wird ein tatsächlicher Zeilenumbruch in der printZeichenfolge verwendet, anstatt printlnein Byte zu speichern. rand(1:n,N)erzeugt Nzufällige ganze Zahlen zwischen 1 und n.


1

Ruby, 93 90 82 Zeichen

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

Probelauf:

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 Bytes (nicht konkurrierend)

: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

Erläuterung:

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 Bytes

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

Laufen Sie mit php -r '<code>' <N>

Nervenzusammenbruch

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.