4x4チャレンジ


6

EnumerateTakuzuを基に作成)と呼ばれる脳ゲームが存在します。あなたの課題は、このゲームをプレイすることです。


仕事

4x4 Enumerate / Takuzuのゲームを解きます。

  • STDINまたはコマンドラインを介して開始グリッドを受け取ります。
  • STDOUTまたはファイルへの書き込みを介して解決済みグリッドを出力します。

ルール

ゲームの特徴は、赤と紫のセルで構成される4x4のボードです。

  • 各行と列に同じ数の赤と紫のセルが必要です(それぞれ2つの赤と2つの紫)。

  • 同一の行または列があってはなりません。


入力

開始グリッドは16文字/バイトのみからなる文字列として与えられます012。次に例を示します。

0001100002001200

1赤色のセルと2紫色のセルを表します。すべての入力ボードは解決可能です。


注:言語が文字列リテラル入力をサポートしていない場合は、整数の配列として入力を受け取ることができます。これが事実であることを回答で述べてください。したがって、混乱はありません。これは、配列が次のようになるはずです。

[0, 0, 0, 1, 1, 0, 0, 0, 0, 2, 0, 0, 1, 2, 0, 0]

ネストされた配列は許可されていません。


出力

解決されたボードは上記と同じ形式で出力されます。1およびのみで構成される16文字/バイトの文字列2。上記の入力に対する解決策は次のとおりです。

2121112222111212

ここでも、1赤色のセルと2紫色のセルを表します。


ボーナス

-25バイトのボーナスは ASCIIグリッドとして解くボードを出力任意の答えのために提供されます。これは、前述のボードの例です。

2|1|2|1
-+-+-+-
1|1|2|2
-+-+-+-
2|2|1|1
-+-+-+-
1|2|1|2

ボーナスバイト-50はカラーで解決ボードを出力任意の答えのために提供されます。これは、画像または色付きのテキストとして出力できます。

色付きのテキストが選択されている場合、出力は次のようになります。

2121
1122
2211
1212

ただし、画像が選択された出力方法である場合、結果のファイルは20x20ピクセルである必要があり、各セルは色付きの5x5ピクセルブロックです。次に例を示します。

ここに色分けがあります:

Red      -   #a73cba   OR   (167,  60, 186)
Purple   -   #f94a32   OR   (249,  74,  50)

サンプル

In:  0020010100000100
Out: 1221212112122112

In:  0010000200121000
Out: 2211112221121221

In:  1000100102000000
Out: 1122122122112112

1
ちなみにこのパズルはタクズと呼ばれています。
ドアノブ

ありがとう!正式な名前があることを知りませんでした。これをイントロに追加しました:) @Doorknob
Zach Gates

我々は、の配列として入力を取ることができ012?2次元配列はどうですか?
リルトシアスト2016年

言語が文字列リテラル入力をサポートしていない場合のみ(存在する場合)。それを質問に追加します。@ThomasKwa
ザック・ゲイツ

1
単一のソリューションを生成するのに十分なセルが各入力に提供されると想定できます。@ edc65
Zach Gates、

回答:


9

CJam(スコア13)

色付きテキストボーナス付き、印刷可能な文字のみ:64文字-50 = 14

l:~:L,Eb2*e!4m*_:z&{_M*L1$.e|.=1-!*_&,4=},~{27c'[@_4*27+'m@}f%N*

これは、非印刷可能な文字を使用して1つの文字によって改善することができる。27c'[@なる"^["\場合^13. XXDバージョンのスコアを与え、文字27を表します。

0000000: 6c3a 7e3a 4c2c 4562 322a 6521 346d 2a5f  l:~:L,Eb2*e!4m*_
0000010: 3a7a 267b 5f4d 2a4c 3124 2e65 7c2e 3d31  :z&{_M*L1$.e|.=1
0000020: 2d21 2a5f 262c 343d 7d2c 7e7b 221b 5b22  -!*_&,4=},~{".["
0000030: 5c5f 342a 3237 2b27 6d40 7d66 254e 2a    \_4*27+'m@}f%N* 

ボーナスなしのストレートソリューション:42文字

l:~:L,Eb2*e!4m*_:z&{_M*L1$.e|.=1-!*_&,4=},

オンラインデモ


グリッドボーナスあり:59文字-25 = 34

l:~:L,Eb2*e!4m*_:z&{_M*L1$.e|.=1-!*_&,4=},~'|f*2N*'-4*'+***

オンラインデモ


画像出力の場合、83文字-50 =33。出力はnetpbm形式です。

'P3NKSKS255Nl:~:L,Eb2*e!4m*_:z&{_M*L1$.e|.=1-!*_&,4=},~4f*M*:("§<ºùJ2":i3/f=4f*M*S*

オンラインデモ


14点じゃないですか?
2016

@Cyoce、印刷できない文字のスコア13でのみ印刷可能な文字のスコア14とバージョンが、バージョン
ピーター・テイラー

はい。見なかった。
Cyoce

6

CJam、74-50 = 24バイト(カラー出力)

l:~:L;5ZbGm*{_L.-L.*:|!\[4/_z]_:::+e_6-!\__.&=**},s4/{"["\_~4*27+'m@}f%N*

これはあまりよくできているとは思いませんが、うまくいきます!ここで試してください。警告:遅い

l:~:L;入力行をに読み込みますL。その後、5Zbある[1 2]、と私たちは16取る番目のデカルトパワー(Gm*すべての可能な解決策を得るために、このリストで)[[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2] ...]。フィルター{ },にはタクズロジックが含まれています。

ANSIコードカラー出力ボーナスを追加しました。

カラー出力

もちろん、これはウェブサイトでは機能しません。ESC文字列に印刷できないバイトがあります"["


+1のみ5Zb
Peter Taylor

1

Ruby、196バイト

->g{[o=?1,p=?2].repeated_permutation(16).find{|x|a=x.each_slice(4).to_a
t=a.transpose
a.uniq.size==4&&t.uniq.size==4&&(a+t).all?{|y|y.count(o)==2}&&x.zip(g.chars).none?{|y|y==[o,p]||y==[p,o]}}*''}

repeated_permutation、なぜあなたの名前はそんなに長くなければならないのですか?-_-

これは、それらの1つが入力パターンに一致するまで、考えられるすべてのソリューションを単に通過します。


1

C(関数)(gccビルトインあり)、283

これはCで取り組むのに興味深い課題のように思われました。かなりゴルフできると確信していますが、ここからが始まりです。

#define m(a,b)for(j=0;j<4;j++){l[j]=i&a<<j*b;if(__builtin_popcount(l[j])-2)goto l;for(k=0;k<j;k++)if(l[j]==l[k])goto l;}
i,j,k,l[4];f(char*s){for(i=0;i<65536;i++){m(15,4)m(4369,1)for(j=0;j<16;j++)if((!(i&1<<j)==s[j]-49)&&(s[j]!=48))goto l;for(j=0;j<16;j++)putchar(50-!(i&1<<j));l:;}}

文字列として関数に渡される入力f()。STDOUTへの出力。

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


1

JavaScript(ES6)、263 300

g=>{[...g].map(c=>(t+=t+(c>1),u+=u+(c&1)),u=t=0);for(m=15,n=4369,i=0;i++<6e4;){for(x=y=i,s=new Set;x;x>>=4,y>>=1)[3,5,6,9,10,12,17,257,272,4097,4112,4352].map(v=>(x&m)==v|(y&n)==v&&s.add(v));if(s.size>7&!(i&u)&!(~i&t))return g.replace(/./g,c=>1+(i>>--p&1),p=16)}}

制約を考えると、可能な解決策の数は驚くほど少ないようです:72

ボード全体を16ビットの数値として見ることができます。
行に許可される値(マスキング1111):0011、0101、0110および反転された値1100、1010、1001

異なるマスキングと混合ビット(マスキング1000100010001)を使用するだけで、列にも同じ:0 ... 0 ... 1 ... 1、0 ... 1 ... 0 ... 1、0 ... 1 ... 1 ... 0と反転値

行と列のビット配置が異なることに注意してください。そのため、uiniquenessを確認するには、行と列の両方をセットに追加し、セットのサイズが== 8であることを確認します。

グリッドで可能なすべてのソリューションを列挙するコード4x4

for(m=0xf,n=0x1111,t=i=0;i<0x10000;i++)
{
  // loop condition: row != 0, as valid values have 2 bits set in each row
  for(x=y=i,s=new Set; x; x>>=4, y>>=1) 
    [3,5,6,9,10,12,17,257,272,4097,4112,4352].map(v=>((x&m)==v||(y&n)==v)&&s.add(v))
  if (s.size==8)
    console.log(++t,i.toString(2))
}

テスト

F=g=>{ // input as a string
  [...g].map(c=>(t+=t+(c>1),u+=u+(c&1)),u=t=0);
  for(m=15,n=4369,i=0;i++<6e4;) // max valid is 51862
  { 
    for(x=y=i,s=new Set;x;x>>=4,y>>=1)
      [3,5,6,9,10,12,17,257,272,4097,4112,4352].map(v=>(x&m)==v|(y&n)==v&&s.add(v));
    if(s.size>7&!(i&u)&!(~i&t))
      return g.replace(/./g,c=>1+(i>>--p&1),p=16) 
  }
}  

// Basic test

console.log=x=>O.textContent+=x+'\n'

;[
['0020010100000100','1221212112122112'],
['0010000200121000','2211112221121221'],
['1000100102000000','1122122122112112']
].forEach(t=>{
  var i = t[0], x=t[1], r=F(i);
  console.log(i+' -> '+r+(r==x?' OK':' Fail (Expected '+x+')'))
})
<pre id=O></pre>


0x10000と置き換えることができます65536
LegionMammal978

私にとって、最初のテストのみが機能します。
user48538

私にとっては、Firefoxで動作します。@ zyabin101
edc65

@ edc65私もFirefoxを使っています。
user48538

??? 説明できません... @ zyabin101
edc65

1

C、スコア278 257

328 307バイト-カラー出力の場合は50バイト、またはカラーボーナスなしの291バイト)

t,b,c,u,r,p;v(g){for(b=0,u=59799;b<16;b+=4)u&(c=1<<(g>>b&15))?b=u:0,u|=c;return b>16;}main(i,a)char**a;{for(char*A=a[1];*A;p=p*2|*A++>49)r=r*2|*A==49;for(;++i<6e4;t=0){for(b=16;b--;)t|=(i>>b&1)<<b%4*4+b/4;if(!(p&i^p|r&~i^r|v(i)|v(t))){for(b=16;b--;)printf("\x1b[3%s%s",i&1<<b?"5m2":"1m1",b&3?"":"\n");break;}}}

これは、最初に一致したグリッドを出力するブルートフォースメソッドです。180度回転したグリッドで実際に動作して、いくつかのループを簡略化し、ルックアップテーブル(59799)を使用して、有効な行を特定します。内部的には、すべてのグリッドは16ビットの数値です。引数から単一の文字列入力を受け取ります。

カラーリングに使用されるエスケープコードのため、これを実行した後、端末のスタイルをリセットすることができます(実行printf "\x1b[0m"

壊す:

// Globals initialise to 0
t, // Transpose of current guess
b, // Bit counter for loops
c, // Current row value when validating
u, // Invalid row mask when validating
r, // Red squares mask (1s in input)
p; // Purple squares mask (2s in input)

// Validation function for rows (returns 0 if valid, shell-style)
v(g){
    for(b=0,u=59799;b<16;b+=4) // "magic" value 59799 is a map of invalid rows
        // For each row:
        u&(c=1<<(g>>b&15))?b=u:0,  // Check if row is valid
        u|=c;                      // Add row to mask (rows cannot be duplicates)
    return b>16; // b = <some massive number> + 4 if a check failed
}

main(i,a)char**a;{ // K&R style function declaration to save 2 bytes
    // Read input (in reverse to save some bytes when reading & printing)
    for(char*A=a[1];*A;
        p=p*2|*A++>49) // Find 2s (input is strictly 012) and go to next
        r=r*2|*A==49;  // Find 1s
    for(;++i<6e4;t=0){ // Brute-force grids (<3 and >=60000 are invalid anyway)
        for(b=16;b--;)t|=(i>>b&1)<<b%4*4+b/4; // Calculate transpose
        if(!(                           // Check...
            p&i^p|                      //  Matches input purples
            r&~i^r|                     //  Matches input reds
            v(i)|                       //  Rows are valid
            v(t)                        //  Columns are valid
        )){
            // Display grid (use ANSI escape codes for colour)
            for(;b--;) // b starts at 16 from last v() call
//              printf(b&3?"%c":"%c\n",(i>>b&1)+49); // no colour variant
                printf("\x1b[3%s%s",i&1<<b?"5m2":"1m1",b&3?"":"\n");
            break; // Stop search
        }
    }
}

では、59799とは何でしょうか。

各行/列には16の状態しかありません(4ビットの2進数です)。これらのうち、有効なオプションは次のとおりです。

0011 =  3 (decimal)
0101 =  5
0110 =  6
1001 =  9
1010 = 10
1100 = 12

これらの値をビットインデックスとして使用して、マスクを作成できます。

0001011001101000 = 5736 (dec)

しかし、ここでは無効な行を知りたいです。

1110100110010111 = 59799 (dec)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.