死ぬための準備?


22

バックグラウンド

卓上ロールプレイングゲームでのennuiのソースの1つは、多くのサイコロを含むロールを扱うことです。崩壊呪文を唱えることは瞬間的かもしれませんが、40個のサイコロを振って合計することは確かではありません!

これを処理するためのいくつかの提案は、rpg.stackexchange.comで説明されています。ただし、ローラープログラムの使用やサイコロの平均化など、ゲームの楽しさやコントロールの感覚を失わせるものもあります。4個のサイコロを転がして合計に10を掛けるなど、その他の場合は結果がはるかに揺れます(サイコロの平均は反対方向に作用します)。

この質問は、平均結果(平均)またはそのスイング(分散)変更せずに、サイコロの数を減らす方法に関するものです。

表記法と数学

この質問では、次の表記を使用してサイコロを振ります。

  • n d k(40d6など)は、k面のダイスのnロールの合計を指します。
  • n d k * c(4d6 * 10など)は、結果に定数cを乗算することを表します。
  • ロール(4d6 * 10 + 40d6など)と定数(4d6 + 10など)を追加することもできます。

単一のダイスロールの場合、次のことを示すことができます。

  • 平均:E [1d k ] =(k + 1)/ 2
  • 分散:Var(1d k)=(k-1)(k + 1)/ 12

平均と分散の基本的な特性を使用して、さらに次のことを推測できます。

  • 平均:E [ m d k * a + n d l * b + c ] = am .E [1d k ] + bn。[1d l ] + c
  • 分散:Varの(M個の D K * + N D L * B + C = A ²。M .Var(1D K)+ B ²。N .Var(1D L

仕事

3つの整数nk、およびrが与えられた場合、プログラムは、以下の制約で、最大でrロールでn d kを近似する方法を出力する必要があります。

  • 解の平均と分散はn d kと同じでなければなりません。
  • 解決策は、より多くのロールがよりスムーズな分布を生成するため、r以下の可能な最大数のロールを含む必要があります。
  • ボーナスを目指している場合を除き、ソリューションをkサイドダイスのみに制限する必要があります(以下を参照)。
  • 解決策がない場合(rが小さすぎるため)、プログラムは文字列 "I AM A SEXY SHOELESS GOD OF WAR!"を出力する必要があります。
  • パラメータは、スペースで区切られた単一の文字列として渡されます。
  • あなたは1≤と仮定することができるN ≤100、1≤ RNとそのkが 4、6、8、10、12及び20(テーブルトップで使用される標準的なダイス)の一つです。
  • 出力は、表記法で説明されている形式(4d6 * 10 + 5など)で、+ sの前後にオプションのスペースがありますが、それ以外の場所はありません。単位乗数もオプションです。4d6* 1と4d6の両方が有効です。

STDIN(または最も近い代替)、コマンドライン引数、または関数引数を介して入力を取得して、プログラムまたは関数を作成できます。結果はSTDOUT(または最も近い代替)に出力されるか、文字列として返されます。

>> "10 6 10"
10d6
>> "10 6 4"
2d6*2+2d6+14
>> "10 6 3"
1d6*3+1d6+21
>> "10 6 2"
1d6*3+1d6+21
>> "10 6 1"
I AM A SEXY SHOELESS GOD OF WAR!

得点

最短のコードが優先されます。標準ルールが適用されます。

ボーナス

-33%(減算の前に切り捨て)k以外の有効なサイコロを含むソリューションも返す場合(上記の有効な値は4、6、8、10、12、20)そうすることを選択した場合、適切な場合は常にそのようなソリューションを返し、複数のタイプのダイを使用するソリューションを処理する必要があります。例:

>> "7 4 3"
3d6+7

6
+1 OotS参照用。;)(まあ、それは本当に素晴らしい挑戦だからです。)
マーティン・エンダー

1
この$ \ LaTeX $の新しい機能を使用して、この質問を修正することもできますか?
orlp

2
@UriZarfaty:LaTeXを使用するように数式を更新しました。大丈夫だと思います。気に入らない場合は、投稿をロールバックするだけで、以前の状態に戻ります。
アレックスA.

1
残念ながら、今のところ再び非アクティブ化されるため、LaTeX編集をロールバックしました。
マーティンエンダー

1
#SadPanda-これは、「こんにちは。私の名前はイニゴモントーヤです。あなたは私の父を殺しました。死ぬ準備をします。」へのコードチャレンジリファレンスになると思っていました。
scunliffe

回答:


5

GolfScript(163 143 133バイト)

~@:^\?,{^base 0-}%{0\{.*+}/^=},.{{,}$-1=..&{[[1$[1$]/,(3$@]'d*+'1/]zip}%^@{-}/@)*.2/\1&'.5'*}{];'I AM A SEXY SHOELESS GOD OF WAR!'}if

オンラインデモ

サイコロの種類を混在させない場合、問題nr2乗以下の合計として表現kすることになり、最後の定数の計算を除いて無関係です。この答えの大部分は、目的の形式で結果を表現するために必要な簿記です。実際の計算は^\?,{^base}%{0\{.*+}/^=},、乗算係数を見つけることaですb等。そして、^@{-}/@)*.2/定数を算出しました。

解剖

~                # Stack: n k r
@:^\?,{          # Store n in ^, and for 0 to n**r
  ^base 0-       #   convert to base n and remove 0s.
}%               # Stack: k [arrays of up to r values from 1 to n-1]
{0\{.*+}/^=},    # Filter them to arrays whose sum of squares is n,
                 #   i.e. to multipliers which have the right variance
.{               # If any multiplier array passes the filter...
  {,}$-1=        #   Pick one with the greater number of rolls
                 #   Stack: k [multipliers]
  ..&{           #   Map each distinct multiplier a...
    [[           #     Gather in nested array for later zip
      1$[1$]/,(  #       Split a copy of the multipliers around a to count the as
                 #       Let's denote that count as m
                 #       Stack: k [multipliers] a [ [ m
      3$@        #       Copy k and rotate the a inside the nested array
     ]           #       Stack: k [multipliers] [ [m k a]
      'd*+'1/    #       Push an array ['d' '*' '+'] and close nested array
    ]zip         #       Giving [[m 'd'] [k '*'] [a '+']]
                 #       which will be printed as mdk*a+
  }%             #   Stack: k [multipliers] [string representations of dice]
  ^@{-}/@)*      #   Compute (n - sum(multipliers)) * (k + 1)
                 #   That's twice the constant we need to add to fix the mean
  .2/\1&'.5'*    #   And convert it to a renderable form, including .5 if needed
}{               # Otherwise clear the stack and push the error message
  ];'I AM A SEXY SHOELESS GOD OF WAR!'
}if

1

Python、 487 461 452-33%= 303バイト

誰もそうしなかったので、ここではさまざまな種類のサイコロを処理するソリューションがあります。他のソリューションと同様に、可能なソリューションの範囲を生成し、それらをフィルタリングします。(k + 1)(k-1)= k ^ 2-1であり、仕様に2つの半抜け穴があるという事実を使用します(おっと!):冗長形式0d k * a(保存するすべての5バイト!)、および実行時間の制限の欠如(指定されたすべての例を実行しますが、かなり迅速に遅くなります)。

from itertools import*
N,K,R=map(int,input().split())
S=lambda l:sum([x[0]for x in l])
s=[x for x in product(*[[(n,k,a)for n in range(N*(K**2-1)/((k**2-1)*a**2)+1)]for a in range(1,N+1)for k in[4,6,8,10,12,20]if a**2<=N])if sum([n*(k**2-1)*a**2 for n,k,a in x])==N*K**2-N and S(x)<=R]
if s:s=max(s,key=S);print"+".join(["%sd%s*%s"%x for x in s]+[str(int(N*(K+1)/2.-sum([n*a*(k+1)/2.for n,k,a in s])))])
else:print"I AM A SEXY SHOELESS GOD OF WAR!"

よりきれいな出力の場合、次のif x[0]後に追加し"%sd%s*%s"%x for x in sます。

>> "7 4 3"
3d6+7
>> "10 6 3"
1d6*1+1d8*1+1d8*2+18
>> "10 6 2"
1d6*1+1d6*3+21
>> "10 6 1"
I AM A SEXY SHOELESS GOD OF WAR!
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.