縁の騎士は厳しい


48

前書き

Aron Nimzowitschは、主要なチェスマスターであり、影響力のあるチェスライターでした。

彼の著書「My System」の最初の章では、センターの重要性と、なぜそれを支配する必要があるのか​​について説明しています。単純な理由は、あなたの駒が中心にいるとき、あなたの駒がより直接的な次の動きを持つ可能性があり、それが再びプレーヤーにより多くの力を与えるということです。

これは、空のボードで騎士のさまざまな位置とその潜在的な次の動き(ピンク色で表示)を見ると非常に明確になります。

ここに画像の説明を入力してください

目的

空のボード上の騎士の位置に基づいて、騎士の潜在的な直接的な次の動きの数を評価します。

入力仕様

騎士の位置。

最初にx(列)、次にy(行)。0 0左下隅です。

簡単にするために、チェス盤のラベルを数字のみに変更しました。例とテストケースでは、0ベースのインデックスを使用していますが、1ベースのインデックスを自由に使用できます。

任意のタイプの可能な入力形式、配列、関数引数などを使用できます。

出力仕様

空のボード上の騎士の潜在的な直接の次の動きの数。

テストケース

3 4 => 8
4 6 => 6
7 7 => 2
1 0 => 3

テストケースでは、0ベースのインデックスを使用しています。値の完全なグリッドは次のとおりです。

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

9
素敵な最初の挑戦!:-)
ルイスメンドー

14
「リムの騎士は厳しいです」

2
@staceyあなたのコメントはこのパズルの素晴らしいタイトルだっただろう:)
スターコーダー

6
さて、本当に難しい質問です。上の画像の赤い騎士はすべて同じ色ですか?
mbomb007

回答:


25

Python 2、35バイト

lambda x,y:50/(8+x*x/7-x+y*y/7-y)-4

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


Python 2、39バイト

lambda x,y:50/(8-x*(7-x)/5-y*(7-y)/5)-4

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

入力に0のインデックスを付けます。

x*(7-x)/5は座標値0..7を取ります

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

min(x,7-x,2)同じことをしますが、より長くなります。)これを合計するxy、正しいパターンが得られますが、数字が間違っています

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

ニールのソリューションを参照これが正しいパターンを与える理由に関するより良い推論を。)

最後に、a -> 50/(8-a)-4フロア分割によるマッピングは正しい値を提供します

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

インデックスが1の入力を使用する同等の長さの代替ソリューション:

lambda x,y:(x*(9-x)/6+y*(9-y)/6)**2/6+2

(7-a)*a/5は、よりも3バイト短くなっていmin(a,7-a,2)ます。
ニール

1
*l実際にlambda a,b:"23468"[(7-a)*a/5+(7-b)*b/5]は全体で1バイトかかりますが、わずか41バイトです。
ニール

@Neilで、同じことをx*(9-x)/61インデックス付きで見つけました。
xnor

1
<strike>みんなと同じようにゴルフの進歩を見せてみませんか?
非常識な

4
@Insane見た目が悪く、実際には役に立たないと思います。コードは重要なものであり、その進化を見たい人はまだ編集履歴を調べる必要があります。私の古いコードが表示する価値があるほど異なる場合、ここにあるようなバージョンを表示します。しかし、この質問では、同じ戦略に対するすべてのマイナーな改善であるため、さまざまな可能性に言及するだけで、よりわかりやすくなりました。
-xnor

17

MATL17 14 13 12バイト

@Neilに1バイトオフをありがとう!

8:HZ^ZP5X^=s

入力は1ベースです。

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

説明

これにより、入力からチェス盤の64の位置のそれぞれまでのユークリッド距離が計算され、それらの値が5の平方根に等しいかどうかがわかります。

座標は整数値であるため、5の平方根(座標から計算されたものと直接計算されたもの)を表す2つの浮動小数点値が実際に同じであることを確認できます。

8:      % Push array [1 2 ... 8]
H       % Push 2
Z^      % Cartesian power. Gives 2D array [1 1; 1 2; ... 1 8; 2 1; ... 8 8]     
ZP      % Implicit input. Compute Euclidean distances, considering each row as a point
5X^     % Square root of 5
=s      % Compute how many squared distances equal sqrt(5). Implicit display

1
印象的で説明に感謝
スターコーダー

1
5から5の平方根の平方の比較が丸め誤差のために失敗した場合、少なくとも5の平方根を5の平方根と比較することはできませんか?
ニール

@Neilアイデアをありがとう!はい、計算は整数で行われるため、2つの「5の根」が同じdouble数であると確信できます。Antがバイトを節約します
ルイスメンドー

15

Mathematica 63 43バイト

Martin Enderの提案のおかげで20バイト節約されました!

EdgeCount[8~KnightTourGraph~8,#+1+8#2/<->_]&

上記は、完全な騎士ツアーグラフ上の特定のセルから1ホップ離れた正方形の数を見つけます。


g=KnightTourGraph[8,8,VertexLabels->"Name",Axes->True]

頂点名と座標を含む完全な騎士のツアーグラフを表示します。Mathematicaはデフォルトで座標に1ベースのインデックスを付けることに注意してください。

グラフ


#+1+8#2&[r,f]Convertsは、ゼロベースの値を入力として使用して、ランク(行)r、およびファイル(列)の正方形に対応する頂点を返しますf

たとえば、#+1+8#2&[2,1]11を返します。


EdgeCount 近傍グラフのエッジの数を与えます。


ランク2、ファイル1(正方形11)のエッジ:

IncidenceList[8~KnightTourGraph~8, 8 #2 + # + 1] &[2, 1]

(*{1 <-> 11, 5 <-> 11, 11 <-> 17, 11 <-> 21, 11 <-> 26, 11 <-> 28}*)

ハイライトされたエッジ:

HighlightGraph[g, {1, 5, 11, 17, 21, 26, 28, Style[1 <-> 11, Thick, Blue], Style[5 <-> 11, Thick, Blue], Style[11 <-> 17, Thick, Blue], Style[11 <-> 21, Thick, Blue], Style[11 <-> 26, Thick, Blue], Style[11 <-> 28, Thick, Blue]},GraphHighlightStyle -> "DehighlightFade", PlotRangePadding -> .5]

ハイライト


方法2:ユークリッド距離

70バイト

この方法はより長くなりますが、興味がある場合があります。アプローチは、チェス盤の中心と対象のセルの間のユークリッド距離をチェックすることです。

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&

例示する

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{0, 0}
Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{3, 3}

2

8


チェス盤の中心からの距離が値を割り当てるのに十分であることを視覚化するため。

values={{2,3,4,4,4,4,3,2},{3,4,6,6,6,6,4,3},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{3,4,6,6,6,6,4,3},{2,3,4,4,4,4,3,2}};
f[x_]:=Text[x,#]&/@Position[values,x]r_~w~p_:=RegionMember[{3.5`,3.5`}~Disk~r,p]
h@y_:=Which[2.2~w~y,8,3~w~y,6,4~w~y,4,4.6~w~y,3,2<3,2]

Graphics[{Circle[{4.5, 4.5}, 2.3], Circle[{4.5, 4.5}, 3], 

円[{4.5、4.5}、4]、

Circle [{4.5、4.5}、4.6]、Flatten [f / @ {2、3、4、6、8}、1]}、Axes-> True、AxesOrigin-> {-1、-1}]


数字2.2、3、4、および4.6は、円の半径です。

画像


1
素晴らしいツアーグラフ
スターコーダー

20
KnightTourGraphMathematicaとその組み込み... :
ルイスメンドー

#ソースコードの最後(の直前])に迷いがあると思います。ただし、IncidenceList代わりに使用できるはずEdgeList@NeighborhoodGraphです。(あるいは、もありEdgeCountますが、それはより長くなると思います。)
マーティンエンダー

1
ああ待って、実際はもっと短い:EdgeCount[8~KnightTourGraph~8,#+1+8#2<->_]&
マーティン・エンダー

EdgeCountとてもクールです!
DavidC

12

JavaScript(ES6)、38バイト

(x,y)=>+"23468"[((7-x)*x+(7-y)*y)/5|0]

0インデックス付きの入力を受け取ります。説明:中心までの距離の二乗を見てください:

24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5

到達可能な正方形の数は5つのバンドに分類されます。

8    0-5
6    5-10
4   10-15
3   15-20
2   20-25

私は実際に24.5-(3.5-x)** 2-(3.5-y)** 2 =(7-x)* x +(7-y)* yを計算しますが、短い計算ですが、すべて逆ですバンドの順序。


非常に簡潔で非常に素晴らしいアプローチなので、私はもう自分のJSソリューションを開始する必要はありません:)
starcorder

半径の平方について式が同等であることの良い点。私はx*(7-x)下向きの弧を描くように見え0..7、たまたま曲線にフィットする単なる操作と考えていましたが、これは、とを合計したときにこのような素晴らしいパターンを生成する理由を説明しxていyます。
-xnor

11

ゼリー、10バイト

8ṗ2_³²S€ċ5

1インデックス付き。形式の単一の引数を取ります[x,y]ここで試してみてください。

8ṗ2          Cartesian square [[1,1],[1,2]…[8,8]]
   _³        Subtract the input
     ²S€     Compute the norm of each vector
        ċ5   Count fives

デニスはバイトを節約しました!


わずか11バイト、すごい!
スターコーダー

この質問は午前中に見ましたが、これは時間があるときにJellyに実装すると思った正確なアルゴリズムです。:P
PurkkaKoodari

8

Mathematica、44 40バイト

現在、同じバイトカウントの3つのソリューションがあります。

2[3,4,6,8][[Tr@⌊3.2-.8Abs[#-4.5]⌋]]&
Tr@⌈.85(4-Abs[#-4.5])⌉/.{5->6,6->8}&
⌊Tr@⌈.85(4-Abs[#-4.5])⌉^1.1608⌋&

これらはすべて、{3, 4}1 から始まるのような座標のペアを取る名前のない関数です。

やや明示的な式を考えてみました。ボード全体の一般的なパターンは次のようになります。

ここに画像の説明を入力してください

これらの色の実際の値(最も明るいものから最も暗いものまで)は2, 3, 4, 6, 8です。あれは:

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

まず、原点を中心に移動し、絶対値を取得してから結果を減算することにより、対称性を利用し4ます。これは私たちに座標を与えます0.53.5、各コーナーから増加するがます。中心座標にマッピングするために同じ我々の必要性を作るために0.51.5異なる値とする2.53.5同じ値に設定します。これは、0.8(乗算{0.4, 1.2, 2., 2.8})を掛けて結果をフローリングすることで簡単に実行できます。だから今、私たちは{0, 1, 2, 2}中心からの距離として持っています。各セルの座標を合計すると、次の表が取得されます。

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

これには、考えられるさまざまな結果すべてに対して一意の値があるため、単にのインデックスとして使用し2[3,4,6,8]ます。

2番目のバージョンでは、床の代わりに天井を使用します。この方法では、23および4すでに正しいですが、我々が得る56の代わりに68ため、置換ルールを使用して手動で修正します。

最後に、3番目のバージョンでは、拡張5して6上方に68別のフロア操作続いべき乗の手段によって。


ボードの一般的なパターンを使用したアプローチがとても気に入っています。
スターコーダー

6

APL、21文字

{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}

英語で:

  • (⍳8 8):すべてのセルの座標を含む8x8ランク2配列。
  • +/¨×⍨(⍳8 8)-⊂⍵:ボード上のすべてのセルに対する特定のセルのユークリッド距離の2乗。
  • 5=:0/1の行列。1は5に等しい距離で表示されます。
  • +/,:平坦化された行列の合計

テスト(起点1):

    f←{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}
    f¨1+(3 4)(4 6)(7 7)(1 0)
8 6 2 3

この形式では:

f←{+/,5=+/¨×⍨(⍳⍺)-⊂⍵}

左の引数は、ボードの寸法を指定できます。したがって8 8 f、標準の正方形のチェス盤で動作します。しかし、大きくて長方形のボードでは、テストケースの結果は異なります。たとえば、12x10ボードの場合:

    g←(10 12)∘f
    g¨1+(3 4)(4 6)(7 7)(1 0)
8 8 8 3

APLの専門用語では、マトリックスはランク2の配列であり、セルの内容については何も言及されていません。この用語を何年も(ab)使用していたため、私はそのことに無関心になりました。もっと伝統的な傾向のある読者向けに説明を更新します。ありがとうございました。
-lstefano

「次元の数」として「ランク」の使用は、同じ悩みを:-Pに苦しむように見えること@Istefano
ルイスMendo

私は…あなたは正しいです!線形代数を取得してからしばらく経ったことがわかります。私はあきらめます:-)
lstefano

1
完全なプログラム、27:≢⍸5=+/¨×⍨-∘⎕¨⍳8 8 オンラインでお試しください!
アダム

@Adámの意味は17
ngn

6

Java- 160150バイト

int m(int r,int c){int m=0,i,j;for(i=0;i<3;i+=2)for(j=0;j<3;j+=2){m+=r+i>0&r+i<9&c+2*j>1&c+2*j<11?1:0;m+=r+2*i>1&r+2*i<11&c+j>0&c+j<9?1:0;}return m;}

ゴルフをしていない:

public static int m(int r, int c) {
    int m=0;
    for(int i=-1;i<2;i+=2)
        for(int j=-1;j<2;j+=2){
            m += r+i>-1 && r+i<8 && c+2*j>0 && c+2*j<8 ? 1:0;
            m += r+2*i>0 && r+2*i<8 && c+j>1 && c+j<8 ? 1:0;
        }
    return m;
}

使用されていないコードは、forループの境界を変更して4バイトを節約することを除いて同一です。可能な各移動を繰り返し、境界チェック(> 0および<8)を実行することにより機能します。オフセットが(1、2)、(2、1)、(-1、2)、(-2、1)などであるという事実を使用し、iおよびjの各値に対して2つの動きをチェックできることを使用します。

編集:Leaky Nunとu902383による提案のおかげで10バイトが節約されました。


これも速かったです!
スターコーダー

そこにエラーがあった場合、修正されました。
-ejaszewski

1
int m=0,i=-1,j;いくつかのバイトを保存するには
リーキー修道女

1
論理ANDをビットANDに変更すると、さらに6文字を削除できるようになります
-user902383

6

C、44バイト

f(x,y){return "23468"[((7-x)*x+(7-y)*y)/5];}

しかし、これは優れています:

f(x,y){return "2344443234666643468888644688886446888864468888643466664323444432"[x*8+y];}

1
行方不明;。コンパイルしません。
ウゴレン


1
これはスニペットではなく、関数であり、禁止されている投稿関数ではありません。行方不明のセミコロンでごめんなさい。一定。
ジャコモガラベッロ

5

Haskell、49 48バイト

w=[0..7]
x%y=sum[1|a<-w,b<-w,(a-x)^2+(b-y)^2==5]

1
[0..7]1バイトの変数に保存できます。
xnor

5

Java、81文字(113バイト)

int r(int a,int b){return "⍄䐲㑦晃䚈衤䚈衤䚈衤䚈衤㑦晃⍄䐲".codePointAt(a*2+b/4)>>(3-b%4)*4&15;}

結果テーブル全体をUnicodeテーブルとしてエンコードし、ビット単位の操作を実行して適切なバイトを取得します。

ここでオンラインで見ることができます:https : //ideone.com/K9BojC






1

実際には、18バイト

`;7-2km`MΣ8-:50\¬¬

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

これは、他の多くの回答が使用しているのと同じ式を実装しています50/(8-x*(7-x)//5+y*(7-y))//5)-4。入力はリストとして取得されます:([x,y]またはPythonの反復可能なリテラル、(x,y)またはのようなx,y)。

説明:

`;7-2km`MΣ8-:50\¬¬
`;7-2km`M           for each value in input:
 ;7-                  make a copy, subtract from 7
    2                 push 2
     km               minimum of the three values (x, 7-x, 2)
         Σ          sum
          8-        subtract from 8
            :50\    integer divide 50 by the value
                ¬¬  subtract 2 twice

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