ヌーの道


23

反時計回りの正方形のスパイラルに番号が付けられた無限のチェス盤上の正方形で始まるヌーの位置を与えるプログラムまたは関数をゴルフし彼女はまだ訪れていないことを知ることができます。n番目 11

インスピレーション:閉じ込められた騎士OEIS A316667

編集:このシーケンスはA323763としてOEISにあります。

コードは、場所、最初の場所を生成するか、入力なしでシーケンスを生成します。n番目n

代わりに(または)最大ジャンプ後に彼女の位置を自由に指定できますが、そうする場合は、回答にこれを明記し、入力が得られることを確認してください(または適切な場合)。nn=01[1]

これはであるため、目的は、選択した言語で可能な限り少ないバイトで作業コードを生成することです。

注:ヌーは彼女の閉じ込められます(騎士が場所、正方形で、ラクダが彼の、正方形)。正方形場所。コードの振る舞いは、これよりも大きい未定義になる場合があります。(これを見つけたC ++コードの Deadcodeに感謝します!)2016年番目20843723rd708112899744968番目12851850258n

詳細

ボードは次のようになり、無期限に継続します。

101 100  99  98  97  96  95  94  93  92  91
102  65  64  63  62  61  60  59  58  57  90
103  66  37  36  35  34  33  32  31  56  89
104  67  38  17  16  15  14  13  30  55  88
105  68  39  18   5   4   3  12  29  54  87
106  69  40  19   6   1   2  11  28  53  86
107  70  41  20   7   8   9  10  27  52  85
108  71  42  21  22  23  24  25  26  51  84
109  72  43  44  45  46  47  48  49  50  83
110  73  74  75  76  77  78  79  80  81  82
111 112 113 114 115 116 117 118 119 120 121

ヌーは「GNU」である変則チェス駒の両方を移動させることができる非標準チェスの駒- ナイト12 -leaper)としてラクダ13 -leaper)。
そのため、彼女は開始位置1からこれらの位置のいずれかに移動できました。

  .   .   .   .   .   .   .   .   .   .   .
  .   .   .   .  35   .  33   .   .   .   .
  .   .   .   .  16   .  14   .   .   .   .
  .   .  39  18   .   .   .  12  29   .   .
  .   .   .   .   .  (1)  .   .   .   .   .
  .   .  41  20   .   .   .  10  27   .   .
  .   .   .   .  22   .  24   .   .   .   .
  .   .   .   .  45   .  47   .   .   .   .
  .   .   .   .   .   .   .   .   .   .   .

これらの最低は10あり、彼女はまだその正方形を訪問していないため、10はシーケンスの2番目の用語です。

次に、彼女は10から次の場所のいずれかに移動できました。

  .   .   .   .   .   .   .   .   .   .   .
  .   .   .   .   .   .  14   .  30   .   .
  .   .   .   .   .   .   3   .  29   .   .
  .   .   .   .   6   1   .   .   .  53  86
  .   .   .   .   .   .   . (10)  .   .   .
  .   .   .   .  22  23   .   .   .  51  84
  .   .   .   .   .   .  47   .  49   .   .
  .   .   .   .   .   .  78   .  80   .   .
  .   .   .   .   .   .   .   .   .   .   .

ただし、彼女はすでに正方形1訪問しているため、3番目の場所は正方形3で、彼女がまだ訪問していない最低の場所です。


ヌーの道の最初の100用語は次のとおりです。

1, 10, 3, 6, 9, 4, 7, 2, 5, 8, 11, 14, 18, 15, 12, 16, 19, 22, 41, 17, 33, 30, 34, 13, 27, 23, 20, 24, 44, 40, 21, 39, 36, 60, 31, 53, 26, 46, 25, 28, 32, 29, 51, 47, 75, 42, 45, 71, 74, 70, 38, 35, 59, 56, 86, 50, 78, 49, 52, 80, 83, 79, 115, 73, 107, 67, 64, 68, 37, 61, 93, 55, 58, 54, 84, 48, 76, 43, 69, 103, 63, 66, 62, 94, 57, 87, 125, 82, 118, 77, 113, 72, 106, 148, 65, 97, 137, 91, 129, 85

最初の11跳躍は騎士の動きなので、最初の12用語はA316667と一致します


コメントは詳細なディスカッション用ではありません。この会話はチャットに移動さました
Mego

回答:


21

JavaScript(Node.js) 191 ... 166  164バイト

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

N番目の項を返します。

n=>(g=(x,y)=>n--?g(Buffer('QPNP1O?O@242Q3C3').map(m=c=>g[i=4*((x+=c%6-2)*x>(y+=c%7-2)*y?x:y)**2,i-=(x>y||-1)*(i**.5+x+y)]|i>m||(H=x,V=y,m=i))&&H,V,g[m]=1):m+1)(1,2)

オンラインでお試しください!またはフォーマットされたバージョンを見る

どうやって?

スパイラルインデックス

座標バツyをスパイラルインデックスに変換するには、まず次のようにレイヤーLを計算します。

L=最大|バツ||y|

与えるもの:

3210+1+2+333333333232222231321112303210123+13211123+23222223+33333333

次に、以下を使用してレイヤー内の位置Pを計算します。

P={2L+バツ+yもし バツ>y2L+バツ+yもし バツy

与えるもの:

3210+1+2+330123456210123471210125803210369+143234710+254567811+36789101112

最終的なインデックスは次のとおりです。

=4L2P

NB:上記の式は、0インデックスのスパイラルを与えます。

JSコードでは、実際に4L2すぐに計算します:

i = 4 * (x * x > y * y ? x : y) ** 2

そして、Pを次のように引きます:

i -= (x > y || -1) * (i ** 0.5 + x + y)

ヌーの動き

現在の位置バツyを指定すると、ヌーの16の可能なターゲットスクエアが次の順序でテストされます。

321バツ+1+2+3391128101761213y+1541415+220+331

16組の符号付き値dバツdy適用することにより、それらを調べます。各ペアは、単一のASCII文字としてエンコードされます。

 ID | char. | ASCII code | c%6-2 | c%7-2 | cumulated
----+-------+------------+-------+-------+-----------
  0 |  'Q'  |     81     |   +1  |   +2  |  (+1,+2)
  1 |  'P'  |     80     |    0  |   +1  |  (+1,+3)
  2 |  'N'  |     78     |   -2  |   -1  |  (-1,+2)
  3 |  'P'  |     80     |    0  |   +1  |  (-1,+3)
  4 |  '1'  |     49     |   -1  |   -2  |  (-2,+1)
  5 |  'O'  |     79     |   -1  |    0  |  (-3,+1)
  6 |  '?'  |     63     |   +1  |   -2  |  (-2,-1)
  7 |  'O'  |     79     |   -1  |    0  |  (-3,-1)
  8 |  '@'  |     64     |   +2  |   -1  |  (-1,-2)
  9 |  '2'  |     50     |    0  |   -1  |  (-1,-3)
 10 |  '4'  |     52     |   +2  |   +1  |  (+1,-2)
 11 |  '2'  |     50     |    0  |   -1  |  (+1,-3)
 12 |  'Q'  |     81     |   +1  |   +2  |  (+2,-1)
 13 |  '3'  |     51     |   +1  |    0  |  (+3,-1)
 14 |  'C'  |     67     |   -1  |   +2  |  (+2,+1)
 15 |  '3'  |     51     |   +1  |    0  |  (+3,+1)

私たちはm最小の遭遇値とHV対応するセルの座標を追跡します。

最適な候補が見つかったら、オブジェクトgフラグを設定して、訪問済みとしてマークします。これは、メインの再帰関数でもあります。

バツ=1y=200


3
そんなに多くのゴルフ、すべての魔法がどのように機能するかの要約を待つことはできません!
ジョナサンアラン

Buffer各文字を強制的にシングルバイトとして解釈するために使用する必要がありましたか?
ヨナ

1
@Jonah推奨されていませんが、Bufferコンストラクターは文字列を受け入れます。ですから、はい、これはバイトのリストに変換するためのかなり安価な方法です-とは対照的[..."string"].map(c=>do_something_with(c.charCodeAt()))です。
アーナウド

1
-2バイトの座標エンコーディング:TIO
Grimmy

@Grimyよくできました!
アーナルド

8

ココナッツ337 276バイト

import math
def g((x,y))=
 A=abs(abs(x)-abs(y))+abs(x)+abs(y)
 int(A**2+math.copysign(A+x-y,.5-x-y)+1)
def f():
 p=x,y=0,0;s={p};z=[2,3,1,1]*2
 while 1:yield g(p);p=x,y=min(((a+x,b+y)for a,b in zip((1,1,2,-2,-1,-1,3,-3)*2,z+[-v for v in z])if(a+x,b+y)not in s),key=g);s.add(p)

値のジェネレーターを返します。おそらくもっとゴルフができるでしょう。(特に差分タプルのシーケンス。)このmath.seの回答から取得したスパイラルアルゴリズム。

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


1
for a,b in (-> for a,b in((タプル自体のデルタタプルもゴルフできるかもしれません)
ジョナサンアラン

1
qタプルの必要はなく、ジップも短くなります。もちろん、306バイトはもちろんゴルフ可能です
ジョナサンアラン

1
...これは284ではどうですか?編集... これは278のために
ジョナサン・アラン

1
FWIW、そのmath.seの回答には、このチャレンジの座標系に対してxyがスワップされ、両方とも負のがあります(正のxが正しく、yが上にある場合)。対称性によって違いが生じるわけではありませんが、それでも変わりません。
デッドコード

1
0.5-> .5別のバイトの保存。A**2-> A*Aもう1つ。
ジョナサンアラン

8

05AB1E77 65 58 57 52 バイト

Xˆ0UF3D(Ÿ0KãʒÄ1¢}εX+}Dε·nàDtyÆ+yO·<.±*->}D¯KßDˆkèU}¯

@Arnauldの式のポートを使用した-6バイトのおかげ。

n+1

オンラインで試してみてくださいïフッターにあるを削除する.0と出力がよりコンパクトになりますが、実際の結果を見るには自由に削除してください)。

コードの説明:

Xˆ             # Put integer 1 in the global_array (global_array is empty by default)
0U             # Set variable `X` to 0 (`X` is 1 by default)
F              # Loop the (implicit) input amount of times:
 3D          #  Push the list in the range [-3,3]: [-3,-2,-1,0,1,2,3]
     0K        #  Remove the 0: [-3,-2,-1,1,2,3]
       ã       #  Cartesian product with itself, creating each possible pair: [[3,3],[3,2],[3,1],[3,-1],[3,-2],[3,-3],[2,3],[2,2],[2,1],[2,-1],[2,-2],[2,-3],[1,3],[1,2],[1,1],[1,-1],[1,-2],[1,-3],[-1,3],[-1,2],[-1,1],[-1,-1],[-1,-2],[-1,-3],[-2,3],[-2,2],[-2,1],[-2,-1],[-2,-2],[-2,-3],[-3,3],[-3,2],[-3,1],[-3,-1],[-3,-2],[-3,-3]]
        ʒ   }  #  Filter this list of pairs by:
         Ä     #   Where the absolute values of the pair
          1¢   #   Contains exactly one 1
               #  (We now have the following pairs left: [[3,1],[3,-1],[2,1],[2,-1],[1,3],[1,2],[1,-2],[1,-3],[-1,3],[-1,2],[-1,-2],[-1,-3],[-2,1],[-2,-1],[-3,1],[-3,-1]])
 εX+}          #  Add the variable `X` (previous coordinate) to each item in the list
 D             #  Duplicate this list of coordinates
  ε            #  Map each `x,y`-coordinate to:
   ·           #   Double both the `x` and `y` in the coordinate
    n          #   Then take the square of each
     à         #   And then pop and push the maximum of the two
   Dt          #   Duplicate this maximum, and take its square-root
     yÆ        #   Calculate `x-y`
       +       #   And add it to the square-root
   yO          #   Calculate `x+y`
     ·         #   Double it
      <        #   Decrease it by 1
             #   And pop and push its signum (-1 if < 0; 0 if 0; 1 if > 0)
   *           #   Multiply these two together
    -          #   And subtract it from the duplicated maximum
   >           #   And finally increase it by 1 to make it 1-based instead of 0-based
  }D           #  After the map: Duplicate that list with values
    ¯K         #  Remove all values that are already present in the global_array
      ß        #  Pop the list of (remaining) values and push the minimum
       Dˆ      #  Duplicate this minimum, and pop and add the copy to the global_array
         k     #  Then get its index in the complete list of values
          è    #  And use that index to get the corresponding coordinate
           U   #  Pop and store this coordinate in variable `X` for the next iteration
             # After the outer loop: push the global_array (which is output implicitly)

一般的な説明:

global_array[1]
バツyX[0,0]

バツy

[[x+3,y+1], [x+3,y-1], [x+2,y+1], [x+2,y-1], [x+1,y+3], [x+1,y+2], [x+1,y-2], [x+1,y-3], [x-1,y+3], [x-1,y+2], [x-1,y-2], [x-1,y-3], [x-2,y+1], [x-2,y-1], [x-3,y+1], [x-3,y-1]]

バツyX

バツyバツy

T=maバツ2バツ22y2
R=Tバツy+Tsgnあなたはmバツ+y21+1

@Arnauldが彼の答え使用しているのと同じ式です、double、square、-1、+ 1などの05AB1Eのビルトインを使用するために異なって記述されています。

(実行中のコードのこのスパイラル部分だけを見たい場合:オンラインで試してみてください。)

バツyglobal_array
global_arrayXバツy

ループinputを何度も繰り返した後、プログラムはこれglobal_arrayを結果として出力します。


1
FWIWは、ここではスパイラルインデックスに座標を変換するために私自身の公式のポートです。5バイト短くなりますが、浮動小数点数になります。(これが問題であるかどうかはわかりません。)
アーナウルド

yy

@Arnauldおかげで、さらに5バイト節約できます。:)編集:あなたはあなたの最初のコメントですでに言及した。; p
ケビンクルーッセン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.