側面図からサイコロの値を決定する


52

ダイスの左と右の値を整数(1〜6)として取り、値を先頭に返すプログラムまたは関数を作成します。

サイコロのレイアウト:

    +---+
    | 1 |
+---+---+---+---+
| 2 | 3 | 5 | 4 |
+---+---+---+---+
    | 6 |
    +---+

  ,^.
<´ 5 `>  <-- Top value
|`._,´|
.6 | 4,  <-- Side values
 `.|,´

入力する6 4と戻り5ます。

順序が重要です:

2 3 -> 1
3 2 -> 6

プログラムは無効な入力値を扱う必要はありません。

明白なアプローチ(すべての組み合わせでテーブルを使用)を思いとどまらせるために、組み込みのテキストエンコーディングまたは圧縮解除ルーチン、ベースエンコーディング、またはサイズを縮小するようなものを使用することは許可されません。テーブルを使用することは引き続き許可されており、独自の解凍もローリングが許可されていることに注意してください。

参考のために、ここにすべての組み合わせの表を示します(つまり、すべての可能な入力と出力)。

23, 35, 42, 54 -> 1
14, 31, 46, 63 -> 2
12, 26, 51, 65 -> 3
15, 21, 56, 62 -> 4
13, 36, 41, 64 -> 5
24, 32, 45, 53 -> 6

最短のコードが優先され、標準の抜け穴が適用されます。


すべての組み合わせでテーブルを使用できます-1 ^^?
-dwana

はい、テーブルを使用できます。ただし、組み込みの圧縮ルーチンを使用してサイズを小さくすることはできません。
ユーザー694733

回答:


59

Python、30

lambda a,b:a^b^7*(2<a*a*b%7<5)

ルックアップなし、ちょっとバッシング。

反対の面は、互いに3ビットの補数であるペアになります。つまり、XORが7になります。

1,6
2,5
3,4

1つのセットから2つの面が与えられた場合、もう1つのセットから面を取得します。ために(1,2,3)、我々は(XORでこれを行うことができます^)。そう、^つまり、3ビットの補数に正しい答えを断念x^7。条件付きで補完できますx^7*_

補数(7とのXOR)を取るかどうかを決定するために、トリプレットが右手の規則に違反しているかどうかを確認します。つまり、a,b次の逆循環順で

1,6
2,5
3,4

各行を3つのカテゴリの1つとして扱います。各行の要素はmods 7で負なので、を実行することでそれらを「ハッシュ」できますx*x%7

1,6 -> 1
2,5 -> 4
3,4 -> 2

各行は、7を法とする4を乗算することにより周期的に前から取得されるため、この関係が成立(b,a)するかどうかを確認して、補完するかどうかを決定できますa*a%7==b*b*4%7

これは、モジュロ7がa**2 * b**(-2)等しいかどうかをチェックすることと同等です4。6を法b**61するため、これはと同等a**2 * b**4です。他の可能な値は(ケースをチェックすることにより)2なので、3と比較することで4かどうかをチェックできます。


CJam-26-– ri:Ari:B^7A7A-e<B7B-e<)=*^
オプティマイザー

私はのオフに文字を保存することができますmin(a,7-a)実行してa^7*(a>3)、まだ短い道があるはずような気がします。何か案は?
xnor

ああ、ありa/4*7^aます
...-xnor

11
私はサイコロの顔のビットがこの特性を持っていることに気づきませんでした。良いですね!
ユーザー694733

1
@ user694733 6は2のべき乗よりも2少ないことが非常に偶然にわかります。
-xnor

64

2つの側面abが与えられた場合、3番目の側面に対して7を法とする素敵な多項式表現があります。

3(a3bab3)mod7

または因数分解

3ab(a2b2)mod7

モジュロ7は、{0,1,2,3,4,5,6}の剰余にマッピングされます。

このMath SEの答えでなぜそれが機能するのかを説明しますが、私はおそらく私が見逃しているよりクリーンな議論があると思います。動作する唯一の他の2項多項式は

(3a5b5a3b)mod7

私はもともと、ビットバッシングを算術演算に変換し、この形式の多項式でブルートフォース検索を実行して、より良いものを見つけました。

このポートをお気に入りの言語に自由に追加してください。これはCW投稿です。

J、9 by Synthetica

7|3***+*-

私の投稿を見る

Dyalog APL、9 by ngn(タイプミスはAdámにより修正)

7|3×××+×-

上記のJ回答から露骨に盗まれました。

TI-Basic、Timtechによる14

7fPart((A³B-AB³)/21

Pyth、16 by FryAmTheEggman

M%*3-*H^G3*^H3G7

g2つの値の関数を定義します。

Golfscript、18 by Peter Taylor(旧多項式)

~1$*.5?3*@.*@*- 7%

CJam、18 by MartinBüttner(ピーターのGolfScriptから移植)(古い多項式)

l~1$*_5#3*@_*@*m7%

Mathematica、20 by MartinBüttner

Mod[+##(#-#2)3##,7]&

はい、それは単項プラスであり、いいえ、単項プラスを使用しない短い方法はありません。

dc、21 by Toby Speight

sb7+d3^lb*rlb3^*-3*7%

7を追加しaて、差が常に正であることを確認する必要があります(dcには符号付き%演算子があります)。

ジュリア、MartinBüttnerによる24 23

f(a,b)=3a*b*(a^2-b^2)%7

CoffeeScript、28 26 by rink.attendant.6

x=(a,b)->3*a*b*(a*a-b*b)%7

JavaScript(ES6)、rink.attendant.6による28 26

x=(a,b)=>3*a*b*(a*a-b*b)%7

基本的にCoffeeScriptと同じです。

Python 28、xnor

lambda a,b:3*a*b*(a*a-b*b)%7

バッシュ、31

特にない:

echo $[3*($1**3*$2-$1*$2**3)%7]

または、代わりに:

echo $[3*$1*$2*($1*$1-$2*$2)%7]

別の(より長いが、おそらく興味深い)アプローチ

ニム、36によってSillesta

proc(x,y:int):int=3*x*y*(x*x-y*y)%%7

Javaの7、46 rink.attendant.6によって44

int f(int a,int b){return(a*a-b*b)*a*b*3%7;}

Javaの8、25ケビンCruijssenで23

a->b->(a*a-b*b)*a*b*3%7

PHP、49 47 by rink.attendant.6

function x($a,$b){echo($a*$a-$b*$b)*3*$a*$b%7;}

バッチ、52 unclemeat

set/aa=(3*(%1*%1*%1*%2-%1*%2*%2*%2)%%7+7)%%7
echo %a%

CMDは本来、真のモジュラスをサポートしていません(したがって、負の数を処理できません)-したがって%%7+7)%%7

LESS(パラメトリックミックスインとして)、rink.attendant.6による62 60

.x(@a,@b){@r:mod(3*@a*@b*(@a*@a-@b*@b),7);content:~"'@{r}'"}

以下の私の投稿を参照してください。

05AB1E、Emignaによる10 8(Kevin Cruijssenによる2バイト)

nÆs`3P7%

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

Haskell、汎用表示名別31 27 25

a#b=3*a*b*(a*a-b*b)`mod`7

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

Excel、27 byヴェルニッシュ

=MOD(3*(A1^3*B1-A1*B1^3),7)

Excel VBA、25 by Taylor Scott

?3*[A1^3*B1-A1*B1^3]Mod 7

Forth(gforth)41 by reffu

: f 2>r 2r@ * 2r@ + 2r> - 3 * * * 7 mod ;

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

C#、Kevin Cruijssen著23

a=>b=>(a*a-b*b)*a*b*3%7

1
FWIW、(ab)**5 % 7 == (ab)**-1 % 7 == a^b^7すべてのa場合b1..6そのようなa != bおよびa+b != 7
ピーターテイラー

@PeterTaylor実際、**57を法とする逆
変換の

2
私は、この驚くべき多項式の「理由」で眠りを失っています。おそらくmath.SEの人々が助けてくれるでしょう。 math.stackexchange.com/questions/1101870/...
デジタルトラウマ

1
math.SEの派生物を作成しました:math.stackexchange.com/a/1101984/24654
xnor

1
APLトレインをのように書き直すことができます7|3×××+×-。発音:製品の3倍、合計、差(2つの数値の間)の7剰余。
-ngn

9

CJam、43 28バイト

完全なテーブルベースのアプローチが短くなるかどうかはわかりませんが、ここにあります:

l_~^56213641532453s@S-#)g7*^

のような入力

2 3

出力:

1

これは、2つの顔とxnorのxorsのアプローチから正しい顔を決定する以前のアルゴリズムの混合です。

こちらからオンラインでお試しください


これがどのように機能するか説明できますか?ep1024と同じアイデアですか?
ユーザー694733

@ user694733まったくありません。説明を追加しました。
オプティマイザー

ええ、私は時間を見ました。彼はそれについて説明していたので、私はそれが似ているのかと思っていましたが、CJamがどのように機能するのか分かりません。
ユーザー694733

@Optimizer私もCJamを使い始めたいと思いますが、チュートリアルなどで私に指示できる一般的な方向はありますか?いくつかの例を見ることができますが、説明はほとんどありません。(
Teun Pronk

上記のリンクには、いくつかの例と、言語キーワードの説明があるメインWebサイトへのリンクがあります。それ以外は、既存の回答から学ぶためにcjamキーワードでここで検索してください。
オプティマイザー

5

LESS、62バイト

この投稿のアルゴリズムを使用します:

.x(@a,@b){@r:mod(3*@a*@b*(@a*@a+6*@b*@b),7);content:~"'@{r}'"}

整数値を使用した場合は短くなる可能性がありますが、表示するには、変数の補間を必要とするCSS contentプロパティを使用する必要がありました。

それにもかかわらず、CSSプリプロセッサ言語がコードゴルフに使用されることはあまりありません!

一部のHTMLで使用するには、次のようにします。

p::after { .x(1, 3); }
<p>Number on top: </p>

4

Pyth、30バイト

K"23542 31463 12651 "h/x+K_Kz6

入力として2桁が必要で、間にスペースはあり23ません(例:not 2 3)。

説明:

内側にある2桁のシーケンス235421、上にある2つの側面を表します。同様に31463、2など。この文字列を逆にすると、4〜のシーケンスが得られます6

このコードは、文字列のルックアップを行い"23542 31463 12651 15621 36413 24532"、インデックスを6で除算し、増分してトップサイドを決定します。

ここでオンラインでテストします。

このゴルフのヒントについては、@ FryAmTheEggmanに感謝します。


いくつかのピス関連のゴルフ:J"23542 31463 12651 "h/x+J_Jscz)6混乱するものがある場合は、pingを実行します。優先KJて値を割り当てるにhは、単項で+1s文字列のリストはですjk。(また、許可されている場合は、23入力などの文字列を使用することをお
勧めし

3

異なる検索文字列を使用して、es1024と同様のアプローチを取ります。

JavaScript(ES6)、73 72 61バイト

t=(l,r)=>-~('354233146312651215623641332453'.search([l]+r)/5)

JavaScript(ES5)、88 87 77バイト

function t(l,r){return -~('354233146312651215623641332453'.indexOf([l]+r)/5)}

CoffeeScript、71 62バイト

ただの楽しみのために、CoffeeScriptではES6としてコードが1バイト短くなっています。これは、括弧の省略が許可されているためです。

-~トリックの使用により、これはES6と同じ文字数であることが判明しました。

t=(l,r)->-~('354233146312651215623641332453'.indexOf([l]+r)/5)

1
1バイトを保存:''+l+r=>[l]+r
edc65

@ edc65ありがとう!ああ、異なるタイプを追加したときのJavaScriptの動作
-rink.attendant.6

1
はい、演算子+は奇妙です。しかし、演算子はどうですか?1+Math.floor=> -~。また、indexOfの代わりに検索します。
edc65

面白い。そして、私は知ってsearchいましたが、それはES6専用です。
rink.attendant.6

実際、String.prototype.searchECMAScript 3rd EditionからJavaScriptの一部であるため、答えを変更できます。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…–
kamoroso94

3

J(9)

この投稿のアルゴリズムを使用します。

7|3***+*-

関数のツリーグラフ(いくつかの点を明確にする可能性があります):

    f=:7|3***+*-
    f
7 | 3 * * * + * -
   5 !: 4 < 'f'
  ┌─ 7            
  ├─ |            
──┤   ┌─ 3        
  │   ├─ *        
  └───┤   ┌─ *    
      │   ├─ *    
      └───┤   ┌─ +
          └───┼─ *
              └─ -

デモンストレーション:

   3 f 5
1
   4 f 6
2
   2 f 6
3
   2 f 1
4
   1 f 2
3
   4 f 5
6

0

PHP、81バイト

私のJavaScriptソリューションと同じ:

function t($l,$r){echo(int)(1+strpos('354233146312651215623641332453',$l.$r)/5);}

0

ルア118

見つけられないバグのために、またそれを探す時間がないため、最後のバージョンを復元する必要がありました。

z=io.read;o={"","","34","5 2","2165","46 13",""," 31064","  5612","   2 5","    43"}a=z();b=z();print(o[a+b]:sub(a,a))

まだこれに取り組んでいます。


ここでこれをテストしたところ、で戻っ4てきたよう2 3です。
ユーザー694733

確かに。病気に目を向ける。
テウンプロンク

@ user694733それを修正しました:)
Teun Pronk

0

JavaScript(ES6)、79バイト

最短ではありませんが、現在の回答とは異なるアプローチを試みました。

f=(a,b)=>[a,b,7-a,7-b].reduce((p,v,i,r)=>p?p:'2312132'.indexOf([v]+r[i+1])+1,0)

0

Lua、89バイト

xnorのPythonソリューションの簡単な移植版。

x=require('bit32').bxor
function(a,b)c=a*a*b%7;return x(a,x(b,2<c and c<5 and 7 or 0))end

0

バッシュ、85

これは@xnorの魔法の多項式とゴルフの面で競合しません。しかし、これは答えを計算する別の興味深い方法だと思います:

g(){
((d[$1$2]))||{
d[$1$2]=$3
g $2 $1 $[7-$3]
g $2 $3 $1
}
}
g 1 2 3
echo ${d[$1$2]}

具体的には、サイコロについて次のことを知っています。

  • 左の面が1で、右の面が2の場合、上面は3です
  • 反対側の頂点の周りを120°回転すると、さらに3倍の面の値が得られます。例えば、{l = 2、r = 3、t = 1}が得られたら{l = 1、r = 2、t = 3}を回転させ、再び回転すると{l = 3、r = 1、t = 2}が得られます
  • 反対面の合計は常に7

上記を再帰的に組み合わせて(開始点としてハードコードされた{1,2,3}を使用して)、可能なすべての値に対して{l、r}-> tのマッピング全体を生成できます。この答えは、d [lr] = tのような完全な配列を生成する再帰関数g()を定義します。再帰関数は、最初に{1,2,3}で呼び出され、設定されていない配列要素がなくなるまでキューブ全体で再帰します。この関数は、次の2つの方法で再帰します。

  • lとrが入れ替わり、tが7から差し引かれている(反対面)
  • {l、r、t}を{r、t、l}に回転

次に、必要な値の単純な配列ルックアップを実行します。


0

Dyalog APL、9 バイト

ɐɔıʇǝɥʇuʎsのJソリューションの見事な文字置換:

7|3×××+×-

編集:私は後でこの正確な解決策が1月17日15日にngnによって提案されたことに気付きました。

  the division remainder when divided by seven of
  |        three times
  |        | the product of the arguments
  |        |   times   \┌───┐
  |        |     \  ┌───┤ × 
┌────┐   ┌────┐   ┌─┴─┐ └───┘ ┌───┐
 7| ├───┤ 3× ├───┤ ×    ┌───┤ +  - the sum of the arguments
└────┘   └────┘   └─┬─┘ ┌─┴─┐ └───┘      
                    └───┤ ×  ---- times
                        └─┬─┘ ┌───┐
                          └───┤ -  - the difference between the arguments
                              └───┘

TryAPLオンライン!


0

ジュリア、26バイト

f(a,b)=a$b$7*(2<a^2*b%7<5)

または

f(a,b)=(3*a^5*b^5-a^3*b)%7

または

f(a,b)=3*a*b*(a+b)*(a-b)%7


0

C#(Visual C#Interactive Compiler)、49バイト

x=>1+("3542331463126512156236413"+x).IndexOf(x)/5

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

@GBのおかげで-1バイト!

入力は、目に見える左右の数字を含む2文字の文字列です。

以下は、私が独自に思いついた解決策です。rink.attendant.6のJavaScriptの回答からのルックアップ文字列を活用して、5バイトを削ることができました(しかし今の回答はかなり似ています;)

C#(Visual C#Interactive Compiler)、55バイト

x=>1+"42354 31463 51265 21562 41364 24532".IndexOf(x)/6

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


1
完全な文字列の代わりに( "3542331463126512156236413" + x)を使用して49バイト
GB
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.