番号付きキューブに面を出力する


19

キューブの8つの頂点に0〜7の番号を自由に割り当てます。各頂点に正確に1つの番号を割り当てる必要があります。

たとえば、頂点は次のように割り当てられます。

  3-----1
 /|    /|
4-----2 |
| |   | |
| 5---|-0
|/    |/
6-----7

0から5までの整数を取り込むプログラムを作成します。これらの6つの数値のそれぞれは、好きな方法でキューブの1つの面に正確に関連付けられます。これらの番号のいずれかが入力されると、関連付けられた面の4つの頂点番号が2×2の数字で標準出力に印刷されなければなりません。顔は立方体の外側から真っ直ぐに見えるようになっています。4つの顔の回転はすべて有効です。

たとえば、上の例の立方体の前面に0が関連付けられている場合、これはinputの有効な出力になります0

42
67

顔は90度の回転で表示される可能性があるため、これらも有効です。

27
46
76
24
64
72

この出力(およびその回転)は、顔の間違った側から見られるため無効です

24
76

同じ考えが他のすべての面に適用されます。たとえば、1が背面に関連付けられている場合、入力1は出力を生成する可能性があります13[newline]05(そして31[newline]50無効になります)。

したがって、実際の課題は、入力を4つの頂点番号に変換するのが簡単で短いように、頂点番号と回転を選択することです。

バイト単位の最短コードが優先されます。Tiebreakerは以前の投稿です。便利なバイトカウンター。

ノート

  • プログラムの代わりに関数を書くこともできます。0〜5の整数を取り、2×2桁のグリッド文字列を出力または返す必要があります。
  • stdin、コマンドライン、または関数argから入力を取得します。入力が有効であると想定できます。
  • 出力には、オプションで末尾の改行が含まれる場合があります。
  • 選択した頂点と面の番号を必ず教えてください。

回答:


17

CJam、23 16バイト

この問題には、おそらくエレガントな数学的な解決策があります。しかし、私はそれを見つける方法がわからないので、超圧縮されたハードコーディングです!

見つけた!まあ、それはビットごとの演算を使用するため、古典的にエレガントな数学的な解決策ではありませんが、完全に定式化されています。

li_o1^_p_6|o3+6%

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

キューブレイアウト

  4-----7          4-----7          3-----2
 /|    /|         /  0  /|         /  3  /|
1-----0 |        1-----0 |        6-----5 |
| |   | |        |     |2|        |     |4|
| 5---|-2        |  1  | 2        |  5  | 7
|/    |/         |     |/         |     |/ 
6-----3          6-----3          1-----4  

説明

私の古い答えでは、立方体はすでに配置されているので、最初の(左上の)頂点番号が顔番号と等しくなるように各面を記述できます。しかし、フェース番号を使用してより多くの頂点番号を計算できるようにしたかったのです。ある時点で、2番目(左上)の頂点番号を顔番号XOR 1として計算するために、ドアに足を踏み入れるというアイデアを思いつきました。上記のレイアウトと以下の数式を使用して、面のすべての頂点番号をn非常に簡潔に計算できます。

  • 左上: n
  • 右上: n^1
  • 左下の: (n^1)|6
  • 右下: ((n^1)+3)%6

参考のために、ここで目的のレイアウトで各面の出力を再現します。

Face:      0     1     2     3     4     5

Vertices:  01    10    23    32    45    54
           74    63    70    65    72    61

したがって、プログラムの全体は、頂点ごとにわずかに異なる印刷ロジックではありますが、入力面番号を読み取り、これらの値を順番に生成するだけです。最初の頂点以降のすべての頂点はのベースで始まるためn^1、一度計算するだけで済み、ロジックがさらに圧縮されることに注意してください。


後世のために、そしてそれはまだかなり良いアプローチだったと思うので、ここに私の古い答えがあります。

CJam、23バイト

この問題には、おそらくエレガントな数学的な解決策があります。しかし、私はそれを見つける方法がわからないので、超圧縮されたハードコーディングです!

"pÜ×ñè¨"487b8b3/ri_o=~p

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

キューブレイアウト

  0-----7          0-----7          3-----6
 /|    /|         /  0  /|         /  3  /|
1-----2 |        1-----2 |        4-----5 |
| |   | |        |     |2|        |     |5|
| 5---|-6        |  1  | 6        |  4  | 7
|/    |/         |     |/         |     |/ 
4-----3          4-----3          1-----0  

説明

採用される基本的なアプローチは、各面の頂点をできるだけ少ないスペースでハードコーディングすることです。オプティマイザーの基本変換ソリューションと同様に、これは頂点リストをASCII文字データとしてパックされた8進数として扱います。しかし、それは類似性がさらなる最適化のための道を作るために終わるところです!

「単純な」ソリューションに対して行った3つの重要な最適化を以下に示します。

  • 各面がその面番号を最初の頂点番号として記述できるように、立方体をレイアウトします。上記のキューブレイアウトを見ると、各面の左上の頂点番号が面番号に等しいことがわかります。これにより、入力を印刷し直す必要がありますが、6個の頂点をエンコードできるようになり、バイトを節約できます。
  • 各「文字」の最大値が256を超える文字列に頂点データをパックします。この最大値が256を超えると、文字列の長さが徐々に減少しますが、いずれかの「文字」が256を超え、したがって、1バイトASCII文字セットの一部ではなくなりました。そこで、256から1000までのすべてのベースで頂点データをエンコードしようとするプログラムを作成しました。これにより、ベース256に比べて1バイトの文字データを保存する約10のベースが見つかりました。結果の文字列は、すべて印刷可能なASCIIで構成されます。
  • 最初の最適化と混合して、非対称的に出力を生成します。CJamの通常のアプローチは、頂点データを2要素リストの2要素リストとしてフォーマットし、中央に改行を挿入し、出力を暗黙的に印刷することです。しかし、代わりに、改行を追加しない演算子で最初の頂点(入力面番号に等しい)を印刷し、他の頂点の3要素リストを取得し、次の頂点を取得して、追加する演算子で印刷します改行、および他の2つの頂点を暗黙的に印刷します。これにより、バイトが節約されます。

2
順列をエレガントな数学的アプローチとして試してみましたが、最適化なしでハードコーディングするよりも冗長です。
ピーターテイラー

あなたの最新の答えは素晴らしいです。それは完全に異なるアプローチであり、別の賛成に値するので、別の回答として投稿すべきだったと思います。基本的に、あなたは私のCの答えと同じ立方体を持っていますが、最初の3つの偶数の角が1か所移動しました。私は逃した信じることができない6+n%2 --> 6|n(私はすでに私のRubyの答えの中にあることを取り入れてきました。)注変換を行うことにより、というn --> n^1顔で、あなたの数式を簡素化することができ、あなたは捨てるように私は推測しているもののn付きでキャリーn^1、それは勝ちましたあなたのスコアを助けません。
レベルリバーセント

@steveverrill賞賛をありがとう!これをまったく新しい回答として投稿するかどうかをチャットで尋ねましたが、コンセンサスがなかったので、投稿しませんでした。立方体の周りのを慎重に順序付けてnn^1別の頂点をで計算できることに気付いたとき、私は間違いなく自分自身に満足していました|6。そして、私はそのn --> n^1変換を見ませんでした、それは間違いなく理にかなっています。しかし、あなたはそれが実際に私のスコアに影響しないと正しく推測したので、おそらくそのままにしておきます。
Runer112

先に進み、XORのアイデアをRubyの回答に組み込みました。10の節約が得られます(の2に加えて6+n%2 --> 6|n)気にしないでください。n --> n^1フェイスでトランスフォームを使用したので、私の最新のリビジョンはあなたと同じ出力を提供しますが、入力は異なります。ところで、私はビット操作が洗練されているとは思わない、それはあなたがそれらをどのように使うかに依存する!
レベルリバーセント

1
GolfScriptで1文字短縮:~.1^..n@6|@3+6%
ピーターテイラー

14

C、69

f(c){int d=c++%2*2-1;printf("%d%d\n%d%d",(c-d)%6,c%6,c%2+6,(c+d)%6);}

テストプログラムでゴルフをしていません

f(c){
 int d=c++%2*2-1;
 printf("%d%d\n%d%d",(c-d)%6,c%6,c%2+6,(c+d)%6);
}

int n;
main(){
  scanf("%d",&n);
  f(n);
}

説明

キューブの番号付けを展開すると、次のようになります。

0---7
|   |
| 0 |
|   |
1---2---7 
|   |   |
| 1 | 2 |
|   |   |
6---3---4---7
    |   |   |
    | 3 | 4 |
    |   |   |
    6---5---0
        |   |
        | 5 |
        |   |
        6---1

左上隅には、顔と同じ番号が付いています。

右下隅に番号があります (n+2)%6

奇数の場合n、右上隅が(n+1)%6あり、左下隅があります6

n右上隅も7左下も(n+1)%6

プログラムは、示されているように奇数を表示し、偶数が180度回転します。これは、右上隅が常に(n+1)%6あり、左下が常にあることを意味し(n+1)%2+6ます。反転n及びn+2容易である(これは設定することによって行われc=n+1且つ使用d加算または減算するために1、または-1必要に応じて)。

出力

$ ./a
0
21
70

$ ./a
1
12
63

$ ./a
2
43
72

$ ./a
3
34
65

$ ./a
4
05
74

$ ./a
5
50
61

5
+1これは、私が想像していたような優雅な数学的解決策です。残念ながら、Cで実装されています...
Runer112

1
@ Runer112ありがとう。残念ながら、Cは私が最もよく知っている言語です。私はRubyを学んでいますが、まだ初心者です。Rubyはこのスコアを打ち破ることができるはずですが、おそらくCjamと競合することはないでしょう。後でRubyに投稿するか、Cの答えにわずかな改善を見つけるかもしれません(たとえば、顔を最初に来るように変更c%6c%=6て回転させることで、いくつかのモジュラス計算を排除することができるはずです)顔のラベリングを1か所シフトするので、n-1,n,n+1代わりにを取得しますn,n+1,n+2
レベルリバーセント

@steveverrillあなたはすでにnグローバルを宣言しているので、それをより高く宣言して数バイトを節約し、署名をf()?に変更することができます または、fここで関数だけを見ていますか?
dwcanillas

@dwcanillas "You may write a function instead of a program"なので、関数のみをカウントしています。いずれにせよ、これは私が最もよく知っている言語の概念実証にすぎません。私はRubyの答えを短くすることにもっと興味があります。これは最初からこれよりもずっと短いものでした。
レベルリバーセント

8

エレメント、18

_4:2%6+``2+6%`-5+`

多くの高度なゴルフ言語とは異なり、Elementには圧縮演算子がないため、ソリューションの簡潔さは、使用されている正確な番号付けスキームにかなり密接に関係しています。いくつかの実験の後、単純な算術演算のみを使用して頂点を計算できる新しい番号付けスキームを作成しました。

  1-----0          1-----0          2-----5
 /|    /|         /  4  /|         /  3  /|
4-----6 |        4-----6 |        3-----7 |
| |   | |        |     |0|        |     |5|
| 7---|-5        |  2  | 5        |  1  | 0
|/    |/         |     |/         |     |/ 
3-----2          3-----2          4-----1  

左上隅は、偶数の場合は6、奇数の場合は7です。右上隅は顔番号そのものです。左下はフェース番号に2、mod 6を加えたものです。右下は5からフェース番号を引いたものです。

コードの説明は次のとおりです。

_4:2%6+``2+6%`-5+`
_4:                    take input and make several copies of it
   2%6+`               take face #, mod 2, add 6, and output
        `              output input, which already has the newline attached
         2+6%`         take face #, add 2, mod 6, and output
              -5+`     negate face #, add 5, and output

各面の出力は次のとおりです。

0
60
25

1
71
34

2
62
43

3
73
52

4
64
01

5
75
10

+1:あなたのコードは判読できないと思いますが、これがゴルフ言語でどのように得点されるかを見るのは素晴らしいことです。現在、2位のCJamの回答に続いて、共同3位にいるようです。PeterTaylorとRuner112。
Level River St

今では2番目の堅実な場所にありますが、私はそれがCJamに勝つことを予見していません。
PhiNotPi

6

オクターブ、108の 100 68 50バイト

もちろん、これは以前のアプローチである単純なハードコーディングよりもエレガントな方法です。OctaveがMatlab =よりcodegolfに適している方法に驚いています=)

f=@(n)['040201375767';'261345154623'](:,2*n+(1:2))

レイアウト:

(すみません、これを追加するのを忘れました。)

キューブレイアウト

  1-----5          1-----5          6-----7
 /|    /|         /  2  /|         /  5  /|
0-----4 |        0-----4 |        2-----3 |
| |   | |        |     |4|        |     |3|
| 3---|-7        |  0  | 7        |  1  | 5
|/    |/         |     |/         |     |/ 
2-----6          2-----6          0-----1  

古いバージョン:

f=@(n)[0 4 0 2 0 1 3 7 5 7 6 7;2 6 1 3 4 5 1 5 4 6 2 3](:,2*n+(1:2))

さらに古いバージョン:

これは本当に2x2x2の配列を作成し、「スライス」を選択するつもりです。3D行列の並べ替えを行い、毎回上スライスまたは下スライスを選択します。(これは、マトリックスではなく式のインデックス付けのため、matlabでは機能しません)より短い方法でより直接的な方法があるはずです。

f=@(n)squeeze(permute(reshape(0:7,2,2,2),circshift((1:3)',n))(n=fix(n/3)+1,circshift((1:2)',n-1),:))

f=@(n)squeeze(permute(reshape(0:7,2,2,2),circshift((1:3)',n))(floor(n/3)+1,circshift((1:2)',floor(n/3)),:))

5

CJam、31 28(または26)バイト

8,2/W%_1m<]z[D75K46]2/+ri=N*

また、ベース変換を使用して26バイトバージョンに圧縮することもできます

キューブは次のようになっていると仮定します。

  7-----1
 /|    /|
5-----3 |
| |   | |
| 6---|-0
|/    |/
4-----2

のような顔で

  7-----1      .-----.      .-----.      .-----.
 /  4  /|     /  4  /|     /  4  /|     /  0  /|
5-----3 |    .-----. |    .-----. |    .-----. |
|     |2|    |     |1|    |     |0|    |     |5|
|  1  | 0    |  0  | .    |  3  | .    |  3  | .
|     |/     |     |/     |     |/     |     |/ 
4-----2      .-----.      .-----.      .-----.    

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


4

CJam(25バイト)

"ñRXµ  roM~"(ib65b2/q~=N*

これには、印刷不可能な文字とタブ(StackExchangeソフトウェアによってマングルされます)が含まれているため、xxd形式です。

0000000: 22f1 5258 1fb5 0972 6f4d 7e22 2869 6236  ".RX...roM~"(ib6
0000010: 3562 322f 717e 3d4e 2a                   5b2/q~=N*

オンラインデモ

キューブ:

  1-----0        Faces:
 /|    /|        10 46
4-----6 |        14 37
| |   | |        20 31
| 3---|-2        23 57
|/    |/         56 20
7-----5          57 64

これは、基本圧縮率を最大化するために立方体の頂点が選択された、純粋なハードコーディングです。私は2桁の数字にデコードするので、それらのいずれも0で始めることはできません。7で始まることも望まないのです。したがって、0と7は長い対角線上になければなりません。エンコードする値を減らすために、最初に10エッジを使用する必要があります。それ以外は、バイトカウントを変更せずにかなりの柔軟性があります。

魔法の文字列から最初の文字を取り出したので、それをベース変換のベースとして使用する前にintにキャストする必要があることに少し失望しています。CJamの将来のバージョンがそのバイトを節約することを願っていますが、ここでそれを悪用するには遅すぎます。


4

JavaScript(ES6)、53 62

編集テンプレート文字列thx @NinjaBearMonkeyを使用して8バイトを保存します。注意してください、引用符内の改行は重要であり、折りたたむことはできません。

Javascriptで賢くすることはできません。冗長すぎます。

f=n=>`01
23
45
67
01
31
5702
64`.substr(n-4?n*3:20,5)

出力 for(i=0;i<6;i++)console.log(f(i),i)

01
23
0

23
45
1

45
67
2

67
01
3

02
64
4

31
57
5

(番号の関連付けをveifyするスニペットを参照してください。その楽しかったです)


1
ES6 テンプレート文字列を使用する場合\n、8バイトを節約する必要があるの代わりに、実際の改行文字を使用できます。
-NinjaBearMonkey

テンプレート文字列には、引用符の代わりに目盛り `を使用する必要があります。
NinjaBearMonkey

そうです、実際にそれをテストしました。
edc65

4

ルビー改訂1、40 36

->(c){print(c^1,c,"\n",6|c,(c+3)%6)}

4バイトを節約するためにラムダを使用することを提案してくれた@rcrmnに感謝します。私はそれを匿名のままにすることについて確信がありませんでしたが、それはここでメタ議論されたようで、これは大丈夫だと決めました。

ここでは、40バイト関数として、Rev 0のRubyの回答と比較するために、以下にも示します(元のCの回答は別の投稿にあります)。

def f(c)print(c^1,c,"\n",6|c,(c+3)%6)end

Runer112からのさらなるインスピレーション:これは、彼の最新の(16バイト!)回答で使用されている番号付けスキームの変更に依存しています。PhiNotPiのスキームを直接移植すると、同じスコアが得られます。

番号をRev 0から1ステップずつシフトし、すべてXOR 1を取得すると、次のキューブが得られます。

4---7
|   |
| 1 |
|   |
1---0---7
|   |   |
| 0 | 3 |
|   |   |
6---3---2---7
    |   |   |
    | 2 | 5 |
    |   |   |
    6---5---4
        |   |
        | 4 |
        |   |
        6---1

出力

0
10
63

1
01
74

2
32
65

3
23
70

4
54
61

5
45
72

Ruby Rev 0、56 52 50

()%6から不要なものを削除しc-d、別の2(runer112に触発された)を削除して4バイトを節約しました6+c%2 --> 6|c

スコアは関数の値であり、最初の行にすぎません。私はRubyを初めて使用し、ユーザー入力番号をnに入力するために12文字(11プラス改行)より短い方法を見つけることができないことに驚いています。その結果、プログラムの代わりに関数を実行すると、1バイト節約されます。

def f(c)d=c%2*2-1;print((c+d)%6,c,"\n",c|6,c-d)end

n=gets.to_i
f(n)

これは私のCの回答の移植版です。Cでは、%演算子は負の数の負の値を返します。Rubyでは常に正の値を返すため、に1を追加する必要はありませんc。その結果、次のように面の番号付けを1ずつシフトすると有利です。

0---7
|   |
| 1 |
|   |
1---2---7 
|   |   |
| 2 | 3 |
|   |   |
6---3---4---7
    |   |   |
    | 4 | 5 |
    |   |   |
    6---5---0
        |   |
        | 0 |
        |   |
        6---1

新しい顔の番号付けでは、プログラムは上記のように偶数を印刷し、オッズは180度回転します。

1
21
70

2
12
63

3
43
72

4
34
65

5
05
74

0
50
61

ラムダを使用することで関数を短縮できると思います。->(x){...code...}これにより、関数定義が4文字短くなります。次に、それを変数に割り当てて使用し、#callで呼び出す必要があります
-rorlork

@rcrmnありがとう、あなたは正しい、f=->(c){print(c^1,c,"\n",6|c,(c+3)%6)}実行し、2文字短くなります(を省略すると4文字短くなりますf=)。省略するのf=が正しいかどうかはわかりませんが、この関数は匿名にできないとは言いません。私は奇妙な見つけることは、この構文は、中括弧内の渡されたパラメータを持っている初心者に示されている構文、全く異なるということである:f=lambda{|c|print(c^1,c,"\n",6|c,(c+3)%6)}
レベル川セント

これは、ラムダリテラルと呼ばれるものです。確かに、構文を覚える必要がある場合、参照を見つけるのは常に難しいと思います
...-rorlork

3

Pyth、30

@ Jakube、2バイトありがとう。

Jc2jkfx>Q2!.&T^2%Q3U8jb?_J%Q2J

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

ピスの専門家からのゴルフのアドバイスは丁寧に受け入れられます。特に、出力セクションにはいくつかの改善点があると思います。

次のpythonのポート:...

Python、109

Q=input()
s=''.join(map(str,filter(lambda v:(Q<3)^(v&(1<<Q%3)>0),range(8))))
print s[1-Q%2::2],'\n',s[Q%2::2]

...のポートです

ピュアバッシュ、130

説明のために:

for v in {0..7};{
if(($1/3));then((v&(1<<$1%3)))&&a+=$v
else((v&(1<<$1%3)))||a+=$v
fi
}
i=$[$1%2*2]
echo "${a:i:2+i}
${a:2-i:4-i}"

立方体の頂点には次のように番号が付けられます。

  4-----5
 /|    /|
0-----1 |
| |   | |
| 6---|-7
|/    |/
2-----3

そして、顔にはこのように番号が付けられます:

Face  Vertices  Swap
   0  0,2,4,6
   1  0,1,4,5   x
   2  0,1,2,3
   3  1,3,5,7   x
   4  2,3,6,7
   5  4,5,6,7   x

Swapカラムは、頂点の順序が出力に切り替えなければならない示します。

アルゴリズムは、すべての頂点{0..7}から始まります。頂点は、頂点番号に設定されたビットに従って削除されます。

  • 面0、1、2では、ビット1、2、または3がそれぞれクリアされた頂点が保持されます
  • 面3,4および5では、ビット1、2または3がそれぞれ設定された頂点が保持されます。

「保持された」頂点は文字列に追加されます。文字列は、スワップフラグ(フェイス番号mod 2)が設定されているかどうかに応じて、0、1、2、3のいずれかで出力されます。


1

J-26バイト

引数として面番号を取り、数字のグリッドを返す関数。

0{.@":"0@{0&(|:|.)&(i.3#2)

次のキューブを使用しています。

  4-----5    Face numbers:
 /|    /|     0 - front
0-----1 |     1 - top
| |   | |     2 - left
| 6---|-7     3 - back
|/    |/      4 - bottom
2-----3       5 - right

例(tryj.tkで試してみてください):

   0{.@":"0@{0&(|:|.)&(i.3#2) 3         NB. inline
76
54
   f =: 0{.@":"0@{0&(|:|.)&(i.3#2)      NB. named
   f each 0 1 2 3 4 5                   NB. all results
+--+--+--+--+--+--+
|01|40|64|76|37|13|
|23|51|20|54|26|57|
+--+--+--+--+--+--+

パンとバターは0&(|:|.)。これは、繰り返し適用されたときにすべての面を訪問するようにキューブを反転および回転させる動詞です。これは、入力引数を使用して行うことです。立方体の頂点はによって生成されるi.3#2ため、開始点としてそれを使用し、0...{完了したら前面を取ります。

数字を文字列として印刷するには8文字かかります。{.@":"0@単純に配列を返すことが許可された場合、8文字全体を節約できます。[握りこぶしと握りしめられない握り始める]


1、4、および5の結果は逆転しているようです
デジタル外傷

0

> <>(魚)、38バイト

'/ =/2= 28"H5'a@i-!
noan~\;
~>:?!^1-@~

すべての出力は2つの2桁の行として保存されます。行は文字列に文字コードとして保存されます'/ =/2= 28"H'10文字列の後にとして追加される行を除くa)。最初の文字(/ = 47)は、2番目の対話でプログラムフローをリダイレクトするために使用されます。

上部の2*(53-n)要素は破棄され(nは入力番号の文字コード)、次の2つのコードは改行を挟んで印刷されます。

レイアウト:

  3-----2
 /|    /|
4-----7 |
| |   | |
| 5---|-0
|/    |/
6-----1      0 1 2 3 4 5 sides are top front bottom back left right respectively.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.