騎士の距離


24

チェスでは、グリッド(x、y)上の騎士は(x-2、y-1)、(x-2、y + 1)、(x-1、y-2)、(x-1、 y + 2)、(x + 1、y-2)、(x + 1、y + 2)、(x + 2、y-1)、(x + 2、y + 1)を1ステップで。(0、0)に騎士だけがいる無限のチェス盤を想像してください:

Knightを(0、0)から(t x、t y)に移動するのに何ステップ必要ですか?

入力

2つの整数:t x、t y ;

-100 <t x <100、-100 <t y <100

出力

Knightを(0、0)から(t x、t y)に移動するために必要な最小限の手順。

ルール

  • コードゴルフ

テストケース

  x    y -> out
  0,   0 ->  0
  0,   1 ->  3
  0,   2 ->  2
  1,   1 ->  2
  1,   2 ->  1
  3,   3 ->  2
  4,   0 ->  2
 42,  22 -> 22
 84,  73 -> 53
 45,  66 -> 37
 99,  99 -> 66
-45, -91 -> 46
-81,   1 -> 42
 11,  -2 ->  7

document.write('<div>');[..."EFEDEDCDCBCBCBCBCBCBCBCBCBCBCBCBCBCDCDEDEFE;FEDEDCDCBCBABABABABABABABABABABABCBCDCDEDEF;EDEDCDCBCBABABABABABABABABABABABABCBCDCDEDE;DEDCDCBCBABA9A9A9A9A9A9A9A9A9A9ABABCBCDCDED;EDCDCBCBABA9A9A9A9A9A9A9A9A9A9A9ABABCBCDCDE;DCDCBCBABA9A9898989898989898989A9ABABCBCDCD;CDCBCBABA9A989898989898989898989A9ABABCBCDC;DCBCBABA9A98987878787878787878989A9ABABCBCD;CBCBABA9A9898787878787878787878989A9ABABCBC;BCBABA9A989878767676767676767878989A9ABABCB;CBABA9A98987876767676767676767878989A9ABABC;BABA9A9898787676565656565656767878989A9ABAB;CBA9A989878767656565656565656767878989A9ABC;BABA98987876765654545454545656767878989ABAB;CBA9A987876765654545454545456567678789A9ABC;BABA98987676565454343434345456567678989ABAB;CBA9A987876565454343434343454565678789A9ABC;BABA98987676545434323232343454567678989ABAB;CBA9A987876565434323232323434565678789A9ABC;BABA98987676545432341214323454567678989ABAB;CBA9A987876565434321232123434565678789A9ABC;BABA98987676545432323032323454567678989ABAB;CBA9A987876565434321232123434565678789A9ABC;BABA98987676545432341214323454567678989ABAB;CBA9A987876565434323232323434565678789A9ABC;BABA98987676545434323232343454567678989ABAB;CBA9A987876565454343434343454565678789A9ABC;BABA98987676565454343434345456567678989ABAB;CBA9A987876765654545454545456567678789A9ABC;BABA98987876765654545454545656767878989ABAB;CBA9A989878767656565656565656767878989A9ABC;BABA9A9898787676565656565656767878989A9ABAB;CBABA9A98987876767676767676767878989A9ABABC;BCBABA9A989878767676767676767878989A9ABABCB;CBCBABA9A9898787878787878787878989A9ABABCBC;DCBCBABA9A98987878787878787878989A9ABABCBCD;CDCBCBABA9A989898989898989898989A9ABABCBCDC;DCDCBCBABA9A9898989898989898989A9ABABCBCDCD;EDCDCBCBABA9A9A9A9A9A9A9A9A9A9A9ABABCBCDCDE;DEDCDCBCBABA9A9A9A9A9A9A9A9A9A9ABABCBCDCDED;EDEDCDCBCBABABABABABABABABABABABABCBCDCDEDE;FEDEDCDCBCBABABABABABABABABABABABCBCDCDEDEF;EFEDEDCDCBCBCBCBCBCBCBCBCBCBCBCBCBCDCDEDEFE"].forEach(c=>document.write(c==';'?'<br>':`<span class="d-${c}">${c}</span>`));
document.write('<style>body{line-height:16px;color:rgba(255,255,255,0.2);}span{display:inline-block;width:16px;font-size:16px;text-align:center;}div{white-space:pre;}');[...'0123456789ABCDEF'].map((c,i)=>document.write(`.d-${c}{background:hsl(${60-4*i},80%,${65-2*i}%)}`));

関連OEIS

詳細については、OEISをご覧ください

  • A018837:ナイトが無限チェスボードで(n、0)に到達するまでのステップ数。
  • A018838:無限のチェス盤で騎士が到達するステップ数(n、n)。
  • A065775:対角線で読み取られた配列T:T(i、j)=(0,0)から(i、j)に移動するために必要なチェス盤上の騎士の移動の最小数(すべての方向に無限)。
  • A183041:無限チェス盤でのナイトの移動の最小数(0,0)から(n、1)。

あなたは、で与えられた式のリファレンスかかる場合がありますoeis.org/A065775
TSH

2
入力を複素数として受け取ることはできますx+yiか?
リン

1
@lynn私はそれが受け入れられると思います。
tsh

@ user202729は、コードスニペットを更新して結果を表示しました。
tsh

非常に細かい地図。
ウィルテック

回答:


11

Wolfram言語(Mathematica)、64バイト

組み込みのを使用しKnightTourGraphます。

Mathe172のおかげで2バイト節約されました

GraphDistance[KnightTourGraph@@({x,y}=Abs@{##}+4),y+2,(x-2)y-2]&

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

ArrayPlot@Array[GraphDistance[KnightTourGraph@@({x,y}=Abs@{##}+5),2y+3,(x-2)y-2]&,{65,65},-32]


14
Mathematicaの組み込み関数が再び攻撃
-qwr

1
少し短く:GraphDistance[KnightTourGraph@@({x,y}=Abs@{##}+5),2y+3,(x-2)y-2]&
ルーカスラング

この言語には何がありますか?なぜこれらすべてのビルトインがプリロードされていますか?タブでフレーズを完成させようとすると、時間がかかりますか?
OganM

@OganM Mathematicaはコマンドラインインターフェースで自動補完をサポートしていません。ノートブックインターフェースの自動補完は次のようになります
アレフアルファ

1
@OganM開発者は、Trie(データ構造)、またはソートされたビルトインのリストでのバイナリ検索を使用する可能性があります。はい、なぜ線形検索ですか?| Mathematicaは非フリーのクローズドソース言語であるため、予測子が実際にどのように機能するかは誰にもわかりません。| 本物のプログラマはオートコンプリートを必要としません。:P
user202729

7

JavaScript(ES6)、90 75 72バイト

A065775に与えられた式に触発されました。(そうではないが)長距離では地獄のように遅い。

f=(x,y,z=x|y)=>z<0?f(-y,x):z>1?1+Math.min(f(x-1,y-2),f(x-2,y-1)):z*3^x&y

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

どうやって?

zをビット単位のORとして定義します xyの

ステップ1

最初に、xyの両方を非負にすることにより、特定の象限に位置するようにします。z <0xまたはyが負であることを意味します)である限り、再帰呼び出しf(-y、x)を処理します。

(+1, -2) --> (+2, +1)
(-1, +2) --> (-2, -1) --> (+1, -2) --> (+2, +1)
(-1, -2) --> (+2, -1) --> (+1, +2)

ステップ2

我々は持っているが、Z> 1(いずれかのことを意味し、XまたはYがより大きくなる1)、我々は再帰的に近い私達をもたらすに、2つの移動を試みる(0、0) F(X-1、Y-2) fは( x-2、y-1)。最終的には最短パスを維持します。

ステップ#3

場合zは以下でである1、我々はで処理される3つの可能性が残っているz*3^x&y(我々が使用できるz*3-x*y代わりに)。

  • x&y == 1はxを意味します| y == 1であり、x = y = 1を意味します。(0、0)に到達するには、さらに2つの移動が必要です。

    2 moves

  • x&y == 0およびx | y == 1は、x = 1 / y = 0またはx = 0 / y = 1のいずれかがあることを意味します。(0、0)に到達するには、さらに3つの移動が必要です。

    3 moves

  • x&y == 0およびx | y == 0は、x = y = 0がすでにあることを意味します

chess.comから借りたグラフィックス


5

Python 3、90バイト

-11バイトをありがとうtsh!

def f(x,y):x=abs(x);y=abs(y);s=x+y;return(.9+max(x/4,y/4,s/6)-s/2+(s==1or x==y==2))//1*2+s

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

(読者がスクロールするのを避けるためのインラインコードフォーマット。申し訳ありませんが、私のプログラムをゴルフしなければなりません)

非常に効率的です。


どうやってこれを思いつくことができます!?

1.パリティ

ボード全体がチェッカーボードパターンで色付けされていると仮定します(つまり、x+y奇数と偶数のセルはx+y異なる色で色付けされています)。

各ステップは、2つの異なる色のセル間をジャンプする必要があることに注意してください。したがって:

  • ステップ数のパリティは、のパリティと等しくなければなりませんx+y

2.近似

ナイトが座標から始まり、ステップ(0,0)を移動しn、現在にいると仮定し(x,y)ます。
簡単にするために、と仮定x ≥ 0y ≥ 0ます。
私たちは結論づけることができます:

  • 各ステップxは最大2で増加するので、x ≤ 2×n。同様に、y ≤ 2×n
  • 各ステップx+yは最大3で増加するので、x+y ≤ 3×n

したがって、n ≥ l(x,y)どこでl(x,y) = max(max(x,y)/2, (x+y)/3。(私たちは含める必要はないことに注意してください-xまたはx-y仮定により式であるため、x ≥ 0 and y ≥ 0、そうx+y ≥ max(x-y,y-x,-x-y)x ≥ -xy ≥ -y

それa(x,y) = round(0.4 + l(x,y))はの良い近似であることが判明しましたn

  • a(x,y)誤差が未満の近似であると仮定すると、1正しい値は

    f(x,y) = round((a(x,y) - (x+y)) / 2) * 2 + (x+y)

    (減算x+yと2による除算の下で丸め)

3.式に失敗する特殊なケース

と仮定x ≥ 0y ≥ 0ます。アルゴリズムが失敗する2つの特別なケースがあります。

  • x == 1 and y == 0またはx == 0 and y == 11正しい答えがである間、アルゴリズムは誤って戻ります3
  • x == y == 22正しい答えがである間、アルゴリズムは誤って戻ります4

だから、それらを特別なケースにしましょう。および2の値がそれらのいずれかである場合、結果を追加します。xy


1
@tshしかし、それもそうですx==y==0
user202729

なんでmax(x+y,x-y,y-x)
tsh

@tsh:いいえ、参照:x = -5、y =5。x+ y = 0、abs(xy)= 10、したがってx + y <abs(xy)
Nova

@Nova「想定x ≥ 0してy ≥ 0」。
user202729


4

TI-Basic、86 54バイト

@ user202729の古いソリューションに基づく

Input :abs(X->C:abs(Y->D:C+Ans
Ans+2int(.9+(S=1 or C=2 and D=2)-.5Ans+max({C/4,D/4,Ans/6


2

Haskell、79 72バイト

p l|elem(0,0)l=0|r<-[-2..2]=1+p[(x+i,y+j)|(x,y)<-l,i<-r,j<-r,(i*j)^2==4]

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

入力をシングルトンリストとして取得しますを数値のペアのます。

単純な総当たり。結果に多くの時間とメモリが必要です。8。座標の単一要素リスト(入力)から開始し、(0,0)このリストになるまですべての要素に到達できるすべての位置を繰り返し追加します。再帰レベルを追跡し、結果として返します。

編集:@Lynnのおかげで-7バイト。



1

JavaScript(ES6)、 90 78バイト

f=(x,y)=>y<0?f(x,-y):x<y?f(y,x):x+y<3?4-x-y&3:x-3|y-1?x-4|y-3?f(x-2,y-1)+1:3:2

編集:保存された12が、その指摘@supercatのおかげバイトx<0のいずれかの意味y<0たりしますx<y。説明:これは再帰的な解決策です。最初の2つの条件は、他の条件の正しい象限を保証するだけです。3番目の条件は、原点に近い座標の答えを生成しますが、最後の2つの条件は他の2つの特殊なケース(両方の動きをテストするよりも1バイト短い)を扱います。

0
32
2++
+2++
+++3+
++++++
(etc.)

マークされたすべての正方形は+、原点に向かって直接移動してから再帰的に決定できます。


x<0テストが必要ですか?たとえば-3,6が与えられると、x<yテストはそれを6、-3にy<0変え、テストは6,3にx<y変わり、テストは3,6に変わります。
-supercat

@supercat確かに、Pythonが言うように、x>=y>=0...
ニール

1

Kotlin148の 146 140バイト

fun s(x:Int,y:Int):Int=if(y<0)s(x,-y)else
if(x<y)s(y,x)else if(x+y<3)4-x-y and 3
else if(x!=3||y!=1)if(x!=4||y!=3)s(x-2,y-1)+1
else 3 else 2

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


:Int戻り値の型を指定する必要はありません。
therealfarfetched

コンパイラーは型を判別するのに十分なほどスマートではないため、再帰関数には戻り型が必要です。
ジョンウェルズ

1
ああ、再帰呼び出しを逃しました。おっと
therealfarfetchd

1

ゼリー27 26 25 23バイト

1,-pḤµ;UÆị
¢ṗS€;0i
0ç1#

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

非常に遅い; 6を超える出力のTIOでタイムアウトします。複素数を入力として受け取ります。

説明

コードは、中間ステップで短くなり、はるかに高速に見えるため、複素数を使用します。削除してペアを使用することもできますÆi2行目の0をして置換で0,0

1,-pḤµ;UÆị    Helper link. No arguments.
1,-             Get the pair [1,-1].
    Ḥ           Double each to get [2,-2].
   p            Cartesian product: get [[1,2],[1,-2],[-1,2],[-1,-2]].
     µ          Start a new chain with the list of pairs as argument.
       U        Reverse each pair.
      ;         Append the reversed pairs to the list.
        Æi      Convert each pair [real,imag] to a complex number.

¢ṗS€;0i    Helper link. Arguments: iterations, target
¢            Call the previous link to get knight moves as complex numbers.
 ṗ           Get the iterations-th Cartesian power of the list. This will
             yield 8^n tuples containing move sequences.
  S€         Sum each move sequence to get the resulting square.
    ;0       Add the starting square, since the zeroth iteration results
             in no move sequences.
      i      Find the target squares (1-based) index in the results, or 0.

0ç1#    Main link. Argument: target
0         Starting from 0,
   #      find the
  1       first number of iterations where
 ç        calling the previous link results in a nonzero result.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.