最も可能性のある数を転がさずに転がすことができるサイコロの数


26

問題

n=2サイコロから開始:

  • ロールnそれぞれ数1〜6も同様に可能性の高い各ダイ上でサイコロ、。
  • それらの合計がnサイコロの最も可能性の高い合計に等しいかどうかを確認し3.5*nます。
    • それらが等しい場合、終了します。
    • それ以外の場合は、印刷しnn+2サイコロで最初から繰り返します

コードはこの手順を正確に行う必要はありませんが、randomnessの定義に基づいて、確率的にそれと同等のランダム出力を与える必要があります。

プログラムは、すべての数値を独自の行に出力する必要があります。たとえば、プログラムが最大8個のサイコロを取得し、8個のサイコロで最も可能性の高い数を転がした場合、出力は次のようになります。

2
4
6

実行例

2つのサイコロで7、最も可能性の高い合計です。ロールされた数字が2とであったとしましょう3。次に、印刷します2

4つのサイコロで14、最も可能性の高い合計です。のは、出目がいたとしましょう342、と5。そして、合計は14なので、プログラムはここで終了します。

この場合の最終出力は"2"です。

ルール


この答えは、現状では非常に不明確です。入力がありますか、それともループとして入力なしから出力を生成することを意図していますか?ランダム性はありますか?ランダム性が関係しているようには見えません。
ハイパーニュートリノ

ところで、PPCGへようこそ!:)
HyperNeutrino

ありがとう、ごめんなさい、私はこれにとても新しいです。何がより明確になりますか?入力はありません。1つのダイスから始めて、できるだけ高い位置に上がる必要があります。
zoecarver

@pudilityだから、正しく理解すれば2, 4, 6, 8, ...、その反復で最も可能性の高い数に達するまで、毎回多くのサイコロを出力し続けることになっていますか?
ハイパーニュートリノ

5
フィードバックに基づいてチャレンジを編集していただきありがとうございます!記録のために、投稿する前に詳細を解決するためのチャレンジを投稿できる場所があります:サンドボックス
-FryAmTheEggman

回答:


17

Python 2、70バイト

from random import*
n=2
while eval("+randrange(6)-2.5"*n):print n;n+=2

オンラインでお試しください!

トリックはeval、次のような文字列を入力して合計を計算することです

'+randrange(6)-2.5+randrange(6)-2.5'

n表現のコピーを連結。randrange(6)乱数を出力[0,1,2,3,4,5]することによりシフトダウンされ、2.5の平均を持っています0。合計ifの場合0while条件は失敗し、ループは終了します。

別の使用方法mapは4バイト長くなりました。

from random import*
n=2
while sum(map(randrange,[6]*n))-2.5*n:print n;n+=2

私は、ゼロを意味するようにシフトされたダイスの長さが等しい式の束を見つけましたが、どれも短くありません

randrange(6)-2.5
randint(0,5)-2.5
randrange(6)*2-5
uniform(-3,3)//1

11
私はこれが好きです!主にそれが私が理解している唯一のものだからです。
zoecarver

7

MATL、13バイト

`@E6y&Yrs@7*-

オンラインでお試しください!

説明

`       % Do...while top of the stack is truthy
  @E    %   Push 2*k, where k is the iteration index starting at 1
  6     %   Push 6
  y     %   Duplicate 2*k onto the top of the stack
  &Yr   %   Array of 2*k integers distributed uniformly in {1, 2, ..., 6}
  s     %   Sum
  @7*   %   Push 7*k
  -     %   Subtract
        % End (implicit). If the top of the stack is non-zero, the loop
        % proceeds with the next iteration. Else the loop is exited.
        % Display stack (implicit)

6

ゼリー 19  14 バイト

リーキー修道女の助けを借りて-5バイト(カウントアップから再帰に移行)

‘‘6ṗX_3.L⁶S?Ṅß

改行で区切られた結果を印刷する完全なプログラム(余分なスペースと改行も印刷され、最後にプログラムエラーが印刷されます)。

オンラインでお試しください! -6個のサイコロがTIOを超えると、メモリ使用量が原因でこれが強制終了されますが、原則としては動作します-そのためには〜40秒かかります。

ここでは、それほど時間がかからず、それほど多くのメモリを必要としない、より使いやすい15バイトバージョンを利用できます

どうやって?

それぞれ3.5ずつ減少した面の合計がゼロになるまでさらに2つのサイコロを再帰的に転がし、そのサイコロの数を印刷します。

‘‘6ṗX_3.L⁶S?Ṅß - Main link: no arguments (implicit left=zero)
‘              - increment (initial zero or the previous result)
 ‘             - increment  (= # of dice to roll, n)
  6            - literal 6
   ṗ           - Cartesian power - all possible rolls of n 6-sided dice with faces 1-6
    X          - pick one of them
      3.       - literal 3.5
     _         - subtract 3.5 from each of the roll results
           ?   - if:
          S    -          sum the adjusted roll results (will be 0 for most common)
        L      - ...then: length (number of dice that were rolled)
         ⁶     - ...else: literal ' ' (causes error when incremented in next step)
            Ṅ  - print that plus a newline
             ß - call this link with the same arity (as a monad with the result)

うわー、それは非常に少ないバイトです。よくやった!数人が答えるまで、私はそれを受け入れることを保留しています。
zoecarver

うん、そうするにしても、受け入れる前にかなり長い間待つのは普通です。多くの人がそれを1、2週間与えます。
ジョナサンアラン

また、最後の反復だけでなく、すべての反復を出力することになっています。
zoecarver

ああ、私は古い編集に答えました-それは完全にそれを変更します、私は多くの方法でこの方法を使用することはできません。
ジョナサンアラン

ああ待ってくださいn、多分それは救助可能です。私はあなたが合計を意味すると思った:)
ジョナサンアラン

6

TI-BASIC、28バイト

2→N
While mean(randInt(1,6,N)-3.5
Disp N
N+2→N
End

説明

  • randInt(1,6,N) 1から6までのN個の乱数のリストを生成します
  • mean(randInt(1,6,N)-3.5 ロールの平均を3.5シフトダウンします
  • While 平均式がゼロ(最も可能性の高い合計)に等しくなるまで続きます

5

R、49バイト

n=2
while(sum(sample(6,n,T)-3.5)){print(n)
n=n+2}

sample(6,n,T)置換さnれた範囲から(擬似)ランダムサンプルを生成し1:6ます。各要素から3.5を引くsumと、最も一般的な値である場合にのみ、0(偽)の結果が得られます。

オンラインでお試しください!

奇数のサイコロをスキップします。


これは私にとって毎回80を出力するようです、バグですか?
zoecarver

@pudilityでは、最後にスペースを追加して再試行できます。入力/コードスニペットを毎回キャッシュしています
ジュゼッペ

3
@Giuseppe [設定]の下のTIOでキャッシュを無効にできます。
xnor

@xnorが言ったようにキャッシュを無効にした後、それは非常にうまくいった。答えてくれてありがとう!
-zoecarver

知っていた@xnor!将来的に知っておくと良い。
ジュゼッペ

4

Java 8、123 149 113108バイト

()->{for(int n=0,s=1,i;s!=n*7;){for(i=s=++n*2;i-->0;s+=Math.random()*6);if(s!=n*7)System.out.println(n*2);}}

または代わりに未使用のパラメーターを使用する場合は107バイトObject null

コメントの@Julesによって正しく指摘されたバグ修正用に+26バイト。-OliverGrégoireの素晴らしい思考の
おかげで-41バイト!

説明:

ここで試してみてください。

()->{                           // Method without parameter nor return-type
  for(int n=0,                  //  Amount of dice
          s=1,                  //  Sum
          i;                    //  Index
      s!=n*7;){                 //  Loop (1) as long as the sum doesn't equal `n`*7,
                                //  because we roll the dice per two, and 3.5*2=7
    for(i=s=++n*2;              //   Reset both the index and sum to `n`*2,
                                //   so we can use random 0-5, instead of 1-6
                                //   and we won't have to use `+1` at `Math.random()*6`
        i-->0;                  //   Inner loop (2) over the amount of dice
        s+=Math.random()*6      //    And increase the sum with their random results
    );                          //   End of inner loop (2)
    if(s!=n*7)                  //   If the sum doesn't equal `n`*7
      System.out.println(n*2);  //    Print the amount of dice for this iteration 
  }                             //  End of loop (1)
}                               // End of method

1
関数にエラーがあると思います。場合r等しい3.5*nプログラムは直接に終了すべきです。しかし、関数を正しく理解していれば、n終了する前に最後にもう一度印刷されます。
raznagul

@raznagul実際、それは追加の時間を印刷していませんでした。しかし、それはバグでした。以前の処理:ランダム1〜12(バグ1:2〜12でした)。これが7に等しいかどうかを確認します。7の場合:印刷せずに完了します。そうでない場合:サイコロを2回振る(バグ2、再び2の代わりに4のサイコロであったはずです); その後、2を出力し、n2ずつレイズします。したがって、2つのバグが含まれていました(2-12の代わりに1-12、2の代わりに2-> 2-> 4-> 6-> ... 4-> 6-> ...)。ただし、実際にに等しいSystem.out.println(n),n+=2場合rは行かないため、正しく印刷されていました3.5*n
ケビンCruijssen

2
「2〜12の乱数を選択して2つのサイコロを一度に回転させる」-これは確率的に2つのサイコロを転がして質問で必要に応じて数字を追加するのと同じではないため、正しい解決策ではありません。
ジュール

1
数バイト短くなりますが(113)、おそらくまだゴルフ可能です()->{for(int n=2,s=0,e=7,i;s!=e;n+=2,e+=7){for(i=n,s=n;i-->0;)s+=Math.random()*6;if(s!=e)System.out.println(n);}}。また、ジュールのコメントと私の説明に関しても正しい。nサイコロ、s合計、e予想、iインデックスです。最後に、合計はnaを回避するために開始され+1n回数、およびs!=e繰り返されます。これは、このケースを回避する方法がわからないからです。
オリビエグレゴワール

1
私はもう少しゴルフをしました;) ()->{for(int i=0,s=1,j;s!=i*7;){for(j=s=++i*2;j-->0;)s+=Math.random()*6;if(s!=i*7)System.out.println(i*2);}}
オリビエグレゴワール

3

05AB1E22 20バイト

Emignaのおかげで-2バイト

[YF6L.RO}7Y*;ïQ#Y=ÌV

オンラインでお試しください!

説明

[YF6L.RO}7Y*;ïQ#Y=ÌV
[                    # Infinite loop start
 YF     }            # Y times... (Y defaults to 2)
   6L.R               # Push a random number between 1 and 6 (why does this have to be so looooong ._.)
       O              # Sum
         7Y*;ï       # Push 3.5 * Y as an int
              Q      # Is it equal to 3.5 * Y?
               #     # If so: Quit
                Y    # Push Y
                 =   # Print without popping
                  ÌV # Set Y to Y + 2

1
O後に移動する.R場合は、)とを削除できますs
エミグナ

3

R、 48 44 42バイト

5バイトの改善 ジュゼッペの答えを

while(sum(sample(6,F<-F+2,1)-3.5))print(F)

これFは、デフォルトで割り当てられている変数であるという事実を使用します。この変数FALSEは強制0的にインクリメントされてから、カウンタ変数を初期化する必要がなくなります。


1
もちろん、あなたが呼び出すことで2つのバイトを保存することができますsample(6)代わりにsample(1:6)....まだ44ですが、44を消さcodegolf.stackexchange.com/a/82343/67312
ジュゼッペ

@Giuseppeもちろん、ありがとう!今、答えを編集しました。
rturnbull

2

PHP、75バイト

for($d=2;(++$i*7/2-$r+=rand(1,6))||$i<$d;)$i%$d?:$d+=1+print"$d
".$r=$i="";

オンラインでお試しください!


1
5^2/++$i*$d+=rand()%6ループのわずかに短い条件です。また、最初の「サイコロ」が「1」の場合(最初の0が生成される$d)、現在のループは誤って終了すると思います。
user59178

@ user59178素晴らしいアイデアですが、ゼロによる除算エラーになる可能性があるため、修正する必要があります。この場合、停止する前にあなたは正しい私のソリューションです、それは間違っています。
ヨルクヒュルサーマン

45バイトの回答は、結果の分布が質問と同じではないため無効ですこちらを参照してください。あなたの42バイトの答えも間違った分布を使用していると思います。たとえば、2つのサイコロの合計が2と7である可能性が高いと仮定しているようです。

@Pakkはい、45バイトの回答は無効です。42バイトバージョンで何が起こるか、あなたの考えは間違っていると思います。拡張版をご覧くださいオンラインでお試しください!
ヨルクヒュルサーマン

@JörgHülsermannその拡張バージョンは、私が言うことを確認します。適切な実装では、$ iの値が大きいほど、$ r / $ iの値は3.5に近くなりますが、それはまったく発生しません。私は9984のサイコロで平均1.16を獲得しましたが、統計的には非常にありそうもないことです。


1

Mathematica、47バイト

For[n=1,Tr@RandomInteger[5,2n++]!=5n,Print[2n]]

LLlAMnYPから-5バイト


1

05AB1E、17バイト

[N·ÌD6Lã.R7;-O_#,

オンラインでお試しください!

説明

[                   # loop over N in 0...
 N·Ì                # push N*2+2
    D               # duplicate
     6L             # push range [1 ... 6]
       ã            # cartesian product (combinations of N*2+2 elements in range)
        .R          # pick one at random
          7;-       # subtract 3.5 from each dice roll
             O_#    # if sum == 0 exit loop
                ,   # otherwise print the copy of N*2+2

1

バッチ、109バイト

@set/an=%1+2,s=n*5/2
@for /l %%i in (1,1,%n%)do @call set/as-=%%random%%%%%%6
@if %s% neq 0 echo %n%&%0 %n%

むしろ迷惑なのrandomは、魔法の環境変数です。したがって、通常はforループが開始される前に発生する、環境の拡張時にのみランダムな値に置き換えられます。callループを通過するたびに発生しますが%、ループの前に展開が発生しないように記号を二重にする必要があります。楽しみは、結果を6でモジュロ化するためです。これには実際の%符号が必要であり、今度は2倍にする必要があります。結果は6つの連続した%sです。


1

JavaScript(ES2015)、 75 78バイト

f=(n=2)=>[...Array(n)].reduce(a=>a+Math.random()*6|0,n)==3.5*n?'':n+`
`+f(n+2)

改行で区切られた結果の文字列を出力します

編集:シャギーのおかげでバイトを節約し、2で機能を開始するために4バイトを追加しました

説明

f=n=>
  [...Array(n)]                // Array of size n
    .reduce(                   // Combine each item
      a=>a+Math.random()*6|0,  // Add a random roll between 0 and 5 for each item
    n)                         // Start at n to correct rolls to between 1 and 6
    ==3.5*n                    // Compare total to most probable roll total
  ? ''                         // If true, end
  : n+'\n'+f(n+2)              // Otherwise, output n and continue

f=(n=2)=>[...Array(n)].reduce(a=>a+Math.random()*6|0,n)==3.5*n?'':n+`
`+f(n+2)

let roll = _ => document.getElementById('rolls').innerHTML = f();
document.getElementById('roll-button').onclick = roll;
roll();
<button id="roll-button">Roll</button>
<pre id="rolls"></pre>


2
の代わりに、バッククォートで囲まれたリテラル改行を使用して、バイトを保存します'\n'
シャギー

これはで始まりませんn=2。代わりに、関数が呼び出されるときにサイコロの開始番号を指定する必要があります。
MT0

1

php-89文字

$r=0;$n=2;while($r!=$n*3.5){$r=$i=0;while($i<$n){$r+=rand(1,6);$i++;}print $n."
";$n+=2;}

最初にする必要はない $r=0;使用echoの代わりにprint $n."として書き込みすることができ"$n、いくつかのバイトを保存する前に、ループの後で何かを行うことができますかしながらループの代わりのために
ヨルグ・Hülsermann


1

ハスケル 133 132バイト

import System.Random;import Control.Monad
s k=do n<-replicateM k$randomRIO(1,6);if sum n==7*div k 2 then pure()else do print k;s(k+2)

以下のコメントの提案については、@ Laikoniに感謝します。


1.)インポートはバイトカウントでカウントする必要があります。2)return()に短縮することができるpure()putStrLn$showを短縮することができますprint
ライコニ

すぐに修正します。おかげで
ダビデSpataro

いくつかのさらに小さなもの:div k 2 thenありdiv k 2thendo print k;s(k+2)ありprint k>>s(k+2)ます。
ライコニ

1

オクターブ55バイト

n=2;
while mean(randi(6,n,1))-3.5!=0
n
n=n+2;
end

Andrewarchiの答えに触発されました。誰かがそれを短くするためのポインタを持っているなら、彼らは大歓迎です。


うわー、TI-BASICとOctaveは驚くほど似た構文を持っています
andrewarchi

@andrewarchi Octave(オンライン版は私が使用しているものです)は、プログラミングに関しては基本の基本です。
ミクサン


0

QBIC、40バイト

{[1,r|g=g+_r1,6|]~g=r*3.5|_X\g=0?r┘r=r+2

これは、文字通り、チャレンジが要求することを行います。配布を正しく行う最短の方法のようです。

説明

{          DO infinitely
[1,r|      FOR a=1, a<=r (at start, r == 2), a++
g=g+       Add to g (0 at start)
  _r1,6|   a random number between 1 and 6 incl.
]          NEXT
~g=r*3.5   IF the result of all dice rolls equals the expected value
|_X        THEN quit
\g=0       ELSE, reset the dice total
?r┘        PRINT the number of dice used
r=r+2      and add 2 dice.
           END IF and LOOP are courtiously provided by QBIC at EOF.


0

JavaScript(ES6)-69文字

r=n=>n?r(n-1)+(Math.random()*6|0)-2.5:0;f=(n=2)=>r(n)?n+`
`+f(n+2):""

console.log(f())

説明

r=n=>                                     # Roll n dice
     n?                                   # If there is a dice left to roll
       r(n-1)                             #   Roll n-1 dice
             +(Math.random()*6|0)         #   Add a random number from 0 .. 5
                                 -2.5     #   Subtract 2.5 so sum of average is 0
                                     :0   # Else total is 0

そして:

f=(n=2)=>                                 # Start with n = 2
         r(n)                             # Roll n dice
             ?n+"\n"+f(n+2)               # If non-zero then concatenate n, newline and
                                          #    result for n+2 dice
                           :""            # If zero (average) terminate.

0

CALC2 0.7、119の 118 111バイト

using"runtime";for(n=2,d=0;d!=3.5*n;Console.WriteLine(n),n+=2)for(i=d=0;i++<n;)d+=Math.Int(Random().Next(1,7));

なし:

using "runtime";
var d = 0;
var r = Random();
for(var n = 2; d != 3.5 * n; Console.WriteLine(n), n += 2)
{
    d = 0;
    for(var i = 0; i < n; i++)
        d += Math.Int(r.Next(1,7));
}

Math.Int()なしでも実行できましたが、残念ながら0.7ではRandom()。Next()関数にはバグがあり、それらはすべてintではなくdoubleを返します。修正されましたが、この質問が投稿されてからです。私は何も勝つつもりはありませんが、ちょっと、素晴らしいコンセプトの証明です。

編集:

  • 使用と「ランタイム」の間の不要なスペースを削除しました(-1バイト)

編集2:

  • var rを削除し、必要な場所に新しいランダムを作成しました(-4バイト)

  • i = 0、d = 0をi = d = 0に変更(-2バイト)

  • チェック後にiをインクリメント(-1バイト)


0

ルビー、52バイト

s=x=2;(s=0;p x.times{s+=rand(6)-2.5};x+=2)while s!=0

説明

s=x=2;                                                # sum=2, x=2
      (                                  )while s!=0  # while sum != 0:
       s=0;                                           #  reset the sum
           p                                          #  print
             x.times{              };                 #  repeat x times:
                     s+=                              #   Add to sum:
                        rand(6)                       #    random int in 0..5
                               -2.5                   #    subtract average
                                                      #  (implicitly return x for printing)
                                     x+=2             #  Increment x by 2

オンラインでお試しください!


@Pakk s=0は、ループの先頭との使用に注意してくださいx.times。これは、合計が毎回リセットされてからxサイコロが振られることを意味します。コードの説明を書きます。
バリューインク

あなたは正しいです、私は私の結論で速すぎました。

0

Javascript、87文字

for(n=2;eval('+'.repeat(n).replace(/./g,x=>x+(Math.random()*6|0)))!=2.5*n;n+=2)alert(n)

console.log代わりにテストalert

for(n=2;eval('+'.repeat(n).replace(/./g,x=>x+(Math.random()*6|0)))!=2.5*n;n+=2)console.log(n)
console.log('Done')


0

lua、102バイト

function r(n,t) for d=1,n do t=t+math.random(1,6)end return t==n*3.5 or print(n)or r(n+2,0)end r(2,0)

またはより読みやすいバージョン

function r(n,t) --recursive function does its magic, t is given to safe usage bytes(no local)
    for d=1,n do --roll n dice and count them up to the total (t)
         t =t+math.random(1,6)
    end 
    return t==n*3.5 or --check if t==n*3.5. If it is then it ends
           print(n) or --t != n*3.5 thus print n. print returns nil
           r(n+2,0) --both the check and the return value from print are false thus r gets executed.
end 
r(2,0) --start the process

96バイトのよりチートなバージョン

function r(n,t,m)t=t+m(1,6)+m(1,6)return t==n*3.5 or print(n)or r(n+2,t,m)end r(2,0,math.random)

これは最初のものとほとんど同じように機能しますが、以前の呼び出しからのロールを再利用します。このため、forループを削除できます。両方ともlua 5.2でテストされています



-1

PHP、51バイト

$r=2;$n=2;while(rand(0,6)-2.5*$r){print $n;$n=$n+2;}

出力が常に2の場合、これは有効な答えではありません

whileループ内で$ nを出力すると、2,4,6,8,10 .....
Shiva

2
それでも、これが質問の要件にどのように従うのかわかりません。「$ n」と「n」の2つの変数を使用します。「n」は未定義であるため、ゼロに設定されます。効果的に、あなたがすることは偶数を印刷することであり、次の偶数を印刷する5/6のチャンスがあります。これは、数学的には問題の分布と同等ではありません。

Typo、nは常に2である必要があり、コードが更新されました。
シヴァ

それでも質問が尋ねるものではありません...今、あなたはサイコロを投げています。サイコロが5の場合は停止し、5でない場合は次の偶数を書き込んで続行します。数学的には、以前のバージョンのコードで行ったことと同じです。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.