(x、y)に4方向に隣接するすべての有効なポイントの反復可能なオブジェクトを返す関数を作成します


17

一般的なアルゴリズムクラスとコンピューターサイエンスの非常に一般的な必要性は、グリッドまたはマトリックス(BFSまたはDFSなど)で4方向に反復することです。これは、多くの場合、ループ内で多くの算術演算と比較を行う、多くの不格好で冗長なコードをもたらすようです。これに対して多くの異なるアプローチを見てきましたが、これを行うためのより簡潔な方法があるという感覚を揺るがすことはできません。

課題はn, m、point (0,0)から始まる有限平面の幅と高さ、および(x,y)その平面内の任意の有効な点を表すことができる座標が与えられ、4方向の平面内のすべての点の反復可能なオブジェクトを返す純粋な関数を書くことですに隣接(x,y)

目標は、できるだけ少ないバイトでその関数を定義することです。

有効な入力/出力を説明するのに役立つ例:

n = 5 (y-axis), m = 3 (x-axis) (zero-based)

matrix = [
    [A, B, C],
    [D, E, F],
    [G, H, I],
    [J, K, L],
    [M, N, O],
]

(x, y) => [valid iterable points]

E: (1, 1) => [(1, 0), (2, 1), (1, 2), (0, 1)]
A: (0, 0) => [(1, 0), (0, 1)]
L: (2, 3) => [(2, 2), (2, 4), (1, 3)]
N: (1, 4) => [(1, 3), (2, 4), (0, 4)]
n = 1 (y-axis), m = 1 (x-axis) (zero-based)

matrix = [
    [A],
]

(x, y) => [valid iterable points]

A: (0, 0) => []
n = 2 (y-axis), m = 1 (x-axis) (zero-based)

matrix = [
    [A],
    [B],
]

(x, y) => [valid iterable points]

A: (0, 0) => [(0, 1)]
B: (0, 1) => [(0, 0)]

そして、条件を満たしている関数の例(Pythonのこれ)です:

def four_directions(x, y, n, m):
    valid_coordinates = []
    for xd, yd in [(1, 0), (0, 1), (-1, 0), (0, -1)]:
        nx, ny = x + xd, y + yd
        if 0 <= nx < m and 0 <= ny < n:
            valid_coordinates.append((nx, ny))
    return valid_coordinates

上記の例では名前付き関数を定義していますが、匿名関数も使用できます。

入力n, m, x, yはすべて、次の範囲内の符号なし32ビット整数です。

n > 0
m > 0
0 <= x < m
0 <= y < n

出力は(x、y)ペアの反復可能な形式(ただし、選択した言語で定義されている場合)でなければなりません。

追加の説明:

複素数(および他の表現/シリアル化)は、反復可能オブジェクトのコンシューマがアクセスできる限り、xおよびy位置のみを知っている整数としては問題ありません。

非ゼロベースのインデックスは許容されますが、選択する言語が非ゼロインデックスの言語である場合のみです。言語で番号付けシステムが混在している場合は、マトリックスを表すために最も一般的に使用されるデータ構造の番号付けシステムがデフォルトになります。これらがまだ特定の言語のすべての外国の概念である場合、任意の開始インデックスが受け入れられます。


6
サイトへようこそ!この挑戦は私たちの基準ではかなり良いものですが、私たちのスタイルに反するものがいくつかあります。1つは、可能であれば単一の言語に制限されない課題を好む。誰もが競争できるときは、はるかに楽しいです。また、通常、キャラクターとは対照的に、バイト単位でコードゴルフを採点します。ほとんどの目的で同じですが、回答がキャラクターで採点された場合にできるいくつかの不正なことがあります。ここで楽しんでください!
ウィートウィザード

(x,y)長方形の中にあることが保証されていますよね?
xnor

4
デフォルトでは、CGCCは完全なプログラムと送信としての機能を許可します。これは必ずしも機能の概念を持っていない言語が同様に競争できるようにすることができます
ジョー・キング

3
出力は、コードオブジェクトではなく、STDOUTになります。通常、これは明確な区切り文字を持つ任意の出力であるため、明確であり、デフォルトの標準出力形式
Jo King

2
整数のタプルではなく複素数として座標を表すことは許可されていますか?
ジョエル

回答:


12

Python 2、66バイト

lambda m,n,x,y:[(x-1,y),(x+1,y)][~x:m-x]+[(x,y-1),(x,y+1)][~y:n-y]

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

4つのネイバーをリストし、リストスライシングを使用して、範囲外のものを削除します。


Python 2、71バイト

lambda m,n,x,y:[(k/n,k%n)for k in range(m*n)if(k/n-x)**2+(k%n-y)**2==1]

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

4つの近傍のうちのどれがインバウンドであるかをチェックする代わりに、ネイバーであるすべてのインバウンドポイントをチェックするより遅い方法、つまりユークリッド距離が正確に1から(x,y)です。また、従来のdiv-modトリックを使用してグリッドを反復処理することにより、のような2つのループを記述する必要がなくなりますfor i in range(m)for j in range(n)

複雑な算術を使用して距離条件を記述しようとしましたが、を書くのに時間がかかりましたabs((k/n-x)*1j+k%n-y)==1


Python 2、70バイト

lambda m,n,x,y:[(x+t/3,y+t%3-1)for t in-2,0,2,4if m>x+t/3>=0<y+t%3<=n]

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


11
100kおめでとうございます!
アーナルド

4

オクターブ、90バイト

これは幾何学的アプローチを使用します。最初に、目的のサイズのゼロの行列を作成1し、目的の位置にa を設定します。次に、カーネルと畳み込みます

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

これにより、元のポイントの4近傍にある同じサイズの新しい行列が生成されます。次にfind()、この新しい行列の非ゼロエントリのインデックスを作成します。

function [i,j]=f(s,a,b);z=zeros(s);z(a,b)=1;[i,j]=find(conv2(z,(v=[1;-1;1])*v'<0,'same'));

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

畳み込みは成功の鍵です。


4
確かに、どんなに小さなフォントであっても
Luis Mendo


3

JavaScript(ES6)、74バイト

退屈なアプローチ。

(h,w,x,y)=>[x&&[x-1,y],~x+w&&[x+1,y],y&&[x,y-1],++y-h&&[x,y]].filter(_=>_)

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


JavaScript(Node.js)、74バイト

退屈ではないが、同じくらい長い。入力をとして受け取ります([h,w,x,y])

a=>a.flatMap((_,d,[h,w,x,y])=>~(x+=--d%2)*~(y+=--d%2)&&x<w&y<h?[[x,y]]:[])

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


JavaScript(V8)、67バイト

すべての標準出力方法が許可されている場合、有効な座標を次のように出力できます。

(h,w,x,y)=>{for(;h--;)for(X=w;X--;)(x-X)**2+(y-h)**2^1||print(X,h)}

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


2

ゼリー 13  12 バイト

2ḶṚƬNƬẎ+⁸%ƑƇ

左側の2つの(0インデックス付き)整数のリストと[row, column]、右側の2つの整数のリストを受け入れるダイアディックリンク[height, width]。これにより、整数のリストのリストが生成されます[[adjacent_row_1, adjacent_column_1], ...]

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

どうやって?

2ḶṚƬNƬẎ+⁸%ƑƇ - Link: [row, column]; [height, width]   e.g. [3,2]; [5,3] (the "L" example)
2            - literal 2                                   2
 Ḷ           - lowered range                               [0,1]
   Ƭ         - collect up while distinct, applying:
  Ṛ          -   reverse                                   [[0,1],[1,0]]
     Ƭ       - collect up while distinct, applying:
    N        -   negate                                    [[[0,1],[1,0]],[[0,-1],[-1,0]]]
      Ẏ      - tighten                                     [[0,1],[1,0],[0,-1],[-1,0]]
        ⁸    - chain's left argument ([row, column])       [3,2]
       +     - add (vectorises)                            [[3,3],[4,2],[3,1],[2,2]]
           Ƈ - filter keep if:
          Ƒ  -   is invariant under:
         %   -     modulo ([height, width]) (vectorises)    [3,0] [4,2] [3,1] [2,2]
             - (...and [3,0] is not equal to [3,3] so ->)  [[4,2],[3,1],[2,2]]

あなたは置き換えることができḶṚƬṬ€2ḶṚƬNƬẎ戻り値[[0, 1], [1, 0], [0, -1], [-1, 0]]、一方、2Ṭ€NƬẎ戻り値[[1], [0, 1], [-1], [0, -1]]、およびシングルトンはラップさ+れているため、それらの最初の要素でのみベクトル化されるため、2番目の要素は0(付加的なアイデンティティ)のように動作します。その結果、出力の順序のみが変更される場合があります。
エリック・ザ・アウトゴルファー

2

Perl 6の56の 49バイト

nwellnhofのおかげで-7バイト!

{grep 1>(*.reals Z/@^b).all>=0,($^a X+1,-1,i,-i)}

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

配列の境界で除算されたときに0から1の間であるかどうかをチェックすることにより、境界外の要素を削除します。実数部がx座標で虚数がである複素数を介して入出力を取りますy。関数.im.re関数を使用してこれらを抽出できます。



@nwellnhofとても素敵!私のような何かをするためにそれの上に構築したいこれを、しかしdivために動作するようには思えないNum
ジョー・キング

(*.reals>>.Int Zdiv@^b).noneまたは(*.reals Z/@^b)>>.Int.none動作しますが、Int-castのコストが高すぎるようです。
nwellnhof

1

J30 29 28バイト

(([+.@#~&,1=|@-)j./)~j./&i./

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

どうやって:

  • 右手mx nargを複素数のグリッドに変えますj./&i./
  • 左引数にも同じ(私たちのポイント) j./
  • ポイントとグリッド間の距離が正確に1である場所を示すマスクを作成します 1=|@-
  • 両方を平坦化した後、それを使用してグリッドをフィルタリングします #~&,
  • 結果を実際のポイントに戻す +.@


0

、29バイト

Jθη#FIζFIε«Jικ¿№KV#⊞υ⟦ικ⟧»⎚Iυ

オンラインでお試しください!リンクは、コードの詳細バージョンです。入力をx、y、幅、高さの順に受け取ります。説明:

Jθη#

指定#された位置にa を印刷します。

FIζFIε«

指定された長方形をループします。

Jικ

現在の位置にジャンプします。

¿№KV#⊞υ⟦ικ⟧

隣接している場合#は、位置を保存します。

»⎚Iυ

ループの終わりに検出された位置を出力します。

退屈な答え:

FIζFIε¿⁼¹⁺↔⁻ιIθ↔⁻κIηI⟦ικ

オンラインでお試しください!リンクは、コードの詳細バージョンです。数学的に隣接する位置を見つけることによって機能します。


0

Haskell、62バイト

を使用して サークル方程式

f m n a b = [(x,y)|x<-[0..m-1],y<-[0..n-1],(x-a)^2+(y-b)^2==1]

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

退屈なアプローチ:81バイト

f m n x y=filter (\(x,y)->x>=0&&y>=0&&x<m&&y<n) [(x-1,y),(x+1,y),(x,y-1),(x,y+1)]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.