(x, y)에 4 방향으로 인접한 모든 유효한 점의 반복 가능한 객체를 반환하는 함수를 작성하십시오.


17

알고리즘 클래스와 컴퓨터 과학에서 일반적으로 필요한 것은 그리드 나 매트릭스 (예 : BFS 또는 DFS)에서 4 방향으로 반복하는 것입니다. 이것은 종종 루프 내에서 많은 산술과 비교를 통해 많은 어수선하고 장황한 코드를 생성하는 것으로 보입니다. 나는 이것에 대한 많은 다른 접근법을 보았지만, 이것을하는 더 간결한 방법이 있다는 느낌을 흔들 수 없습니다.

문제는 n, mpoint (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)]

그리고 여기 조건을 만족시키는 함수의 예 (파이썬에서는이 예제)가 있습니다 :

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) 쌍의 이터 러블 (선택한 언어가 정의하는) 형식을 가져야합니다.

추가 설명 :

iterable의 소비자가 액세스 할 수 x있고 y자신의 위치 만 아는 정수 라면 복소수 (및 기타 표현 / 직렬화)는 괜찮 습니다.

0이 아닌 인덱스는 허용되지만 선택한 언어가 0이 아닌 인덱스 언어 인 경우에만 허용됩니다. 언어에서 여러 번호 매기기 시스템을 사용하는 경우 기본적으로 행렬을 나타내는 데 가장 일반적으로 사용되는 데이터 구조의 번호 매기기 시스템이 사용됩니다. 이것이 주어진 언어로 여전히 모든 외국 개념이라면 시작 색인이 허용됩니다.


6
사이트에 오신 것을 환영합니다! 이 도전은 우리의 표준으로는 꽤 좋지만, 여기에 우리 스타일에 맞지 않는 몇 가지가 있습니다. 우리는 가능한 한 단일 언어로 제한되지 않는 도전을 선호합니다. 모두가 경쟁 할 수있을 때 훨씬 더 재미 있습니다. 우리는 또한 일반적으로 문자와 달리 바이트 단위 로 코드 골프 점수 를 매 깁니다. 대부분의 경우 동일하지만 문자 점수가 매겨지면 할 수있는 몇 가지 치열한 일이 있습니다. 당신이 여기 재미를 바랍니다!
Post Rock Garf Hunter

우리는 그 (x,y)자체가 사각형 안에 있다고 보장합니다 .
xnor

4
기본적으로 CGCC는 전체 프로그램뿐만 아니라 제출 기능도 허용합니다. 이를 통해 기능 개념이 반드시 필요하지 않은 언어도 경쟁 할 수 있습니다.
Jo King

3
코드 오브젝트가 아닌 STDOUT으로 출력됩니다. 이것은 일반적으로 명확한 구분 기호가있는 출력 일 수 있으므로 모호하지 않으며 기본 표준 출력 형식을
Jo King

2
정수 튜플이 아닌 복소수로 좌표를 나타낼 수 있습니까?
Joel

답변:


12

파이썬 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]

온라인으로 사용해보십시오!

네 이웃을 나열한 다음 목록 슬라이싱을 사용하여 범위를 벗어난 이웃을 제거합니다.


파이썬 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]

온라인으로 사용해보십시오!

네 이웃 중 어느 쪽이 인바운드인지 확인하는 대신, 우리는 이웃 인, 즉 유클리드 거리가 정확히 1 인 모든 인바운드 점을 확인하는 느린 방법을 사용 (x,y)합니다. 또한 클래식 div-mod 트릭을 사용하여 그리드를 반복하여 와 같이 두 개의 루프를 작성할 필요가 없습니다 for i in range(m)for j in range(n).

거리 조건을 작성하기 위해 복잡한 산술을 시도했지만 작성하는 데 시간이 더 오래 걸렸습니다 abs((k/n-x)*1j+k%n-y)==1.


파이썬 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 축하합니다!
Arnauld

4

옥타브 , 90 바이트

이것은 기하학적 접근법을 사용합니다. 먼저 원하는 크기의 0으로 구성된 행렬을 만들고 1원하는 위치로 a 를 설정합니다 . 그런 다음 커널과

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

원래 점의 4 개 이웃에있는 것과 동일한 크기의 새로운 행렬을 생성합니다. 그런 다음 find()이 새 행렬의 0이 아닌 항목의 인덱스입니다.

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

자바 스크립트 (ES6), 74 바이트

지루한 접근법.

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

온라인으로 사용해보십시오!


자바 스크립트 (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]]:[])

온라인으로 사용해보십시오!


자바 스크립트 (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ƬẎ+⁸%ƑƇ

왼쪽에있는 두 개의 (0- 인덱스 화 된) 정수 목록과 [row, column]오른쪽에있는 두 개의 정수 목록을 허용하는 이진법 링크 .[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ƬẎreturns [[0, 1], [1, 0], [0, -1], [-1, 0]], while 2Ṭ€NƬẎreturns [[1], [0, 1], [-1], [0, -1]], 그리고 싱글 톤이 랩핑 되었기 때문에, 그것들 +위한 첫 번째 요소로만 벡터화 하므로, 두 번째 요소가 0(가산 성 ID) 인 것처럼 작동 합니다. 결과적으로 출력 순서 만 변경 될 수 있습니다.
Outgolfer Erik

2

펄 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

J , 30 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

하스켈, 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.