나선형 이웃


19

자연수를 취해 시계 반대 방향으로 나선형으로 올리면 다음과 같은 무한한 나선형으로 끝납니다.

                  ....--57--56
                             |
36--35--34--33--32--31--30  55
 |                       |   |
37  16--15--14--13--12  29  54
 |   |               |   |   |
38  17   4---3---2  11  28  53
 |   |   |       |   |   |   |
39  18   5   0---1  10  27  52
 |   |   |           |   |   |
40  19   6---7---8---9  26  51
 |   |                   |   |
41  20--21--22--23--24--25  50
 |                           |
42--43--44--45--46--47--48--49

그 나선형의 숫자가 주어지면 당신의 임무는 이웃을 결정하는 것입니다. 위, 왼쪽, 오른쪽 및 아래 요소를 의미합니다.

살펴보면 27다음과 같은 이웃이 있음 을 알 수 있습니다.

  • 위 : 28
  • 왼쪽: 10
  • 권리: 52
  • 이하: 26

따라서 출력은 다음과 같습니다. [28,10,52,26]

규칙

  • 입력 수있을 것입니다 하나에 기본 I / O 형식n0
  • 출력은 임의의 (일관된!) 순서로 해당 숫자 4 개 이웃의 목록 / 행렬 / ..입니다.
  • 0 대신 1로 시작하는 나선으로 작업 할 수 있지만 답에 지정해야합니다.

출력 형식 [above,left,right,below]이며 0 기반 나선형을 사용합니다.

0  ->  [3,5,1,7]
1  ->  [2,0,10,8]
2  ->  [13,3,11,1]
3  ->  [14,4,2,0]
6  ->  [5,19,7,21]
16  ->  [35,37,15,17]
25  ->  [26,24,50,48]
27  ->  [28,10,52,26]
73  ->  [42,72,74,112]
101  ->  [100,146,64,102]
2000  ->  [1825,1999,2001,2183]
1000000  ->  [1004003,1004005,999999,1000001]

답변:


6

R , 156 바이트

function(n){g=function(h)c(0,cumsum(h((4*(0:(n+2)^2)+1)^.5%%4%/%1/2)))
x=g(sinpi)
y=g(cospi)
a=x[n]
b=y[n]
which(x==a&(y==b+1|y==b-1)|y==b&(x==a+1|x==a-1))}

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

  • @ngn과 약간 다른 접근 방식이므로 다른 R 답변을 게시했습니다.
  • 1- 색인
  • 이웃은 항상 오름차순으로 정렬됩니다.
  • 절반 숫자 ( , 등의 경우) 보다 정확한 6 바이트를 제거 round하고 사용cospi(x)/sinpi(x)cos(x*pi)/sin(x*pi)0.51.5
  • 결과가 동일하기 때문에 y 좌표에서 마이너스를 제거하여 다른 바이트를 저장했습니다 (위 / 아래 이웃 만 반전 됨)

설명 :

0배치 된 첫 번째 값을 고려하여 값의 행렬 좌표를 보면 다음 x=0, y=0과 같습니다.

x = [0,  1,  1,  0, -1, -1, -1,  0,  1,  2,  2,  2,  2,  1,  0, ...] 
y = [0,  0,  1,  1,  1,  0, -1, -1, -1, -1,  0,  1,  2,  2,  2, ...]

x좌표는 다음과 A174344 OEIS 시퀀스 재귀 식을 :

a(1) = 0, a(n) = a(n-1) + sin(mod(floor(sqrt(4*(n-2)+1)),4)*pi/2)

y행렬 좌표에 대해 동일한 수식이 있지만 cos대신 sin및 부정을 사용합니다.

a(1) = 0, a(n) = a(n-1) - cos(mod(floor(sqrt(4*(n-2)+1)),4)*pi/2)

그래서 R에서 우리는 공식을 sinpi/cospi매개 변수 로 사용 하여이 함수로 변환 할 수 있습니다 :

g=function(h)c(0,cumsum(h((4*(0:(n+2)^2)+1)^.5%%4%/%1/2)))

그리고 우리는 두 개의 좌표 벡터를 생성합니다 (위 / 아래 이웃이 반전 된 것과 동일한 결과를 얻을 수 있기 때문에 y 좌표를 부정하지 않습니다).

x=g(sinpi)
y=g(cospi)

우리는 (n+2)^2좌표를 생성했습니다. 좌표 n는 이웃과 이웃 을 모두 포함하는 최소 필수 좌표보다 큽니다 (긴밀한 경계는 (floor(sqrt(n))+2)^2불행히도 "골피"가 아닙니다).

따라서 모든 좌표가 생겼으므로 먼저 다음에 a,b해당 하는 좌표를 검색합니다 n.

a=x[n]
b=y[n]

마지막으로 우리는 이웃의 위치를 ​​선택합니다.

  • 상하 이웃 where x == a and y == b+1 or b-1
  • 오른쪽 / 왼쪽 이웃 where y == b and x == a+1 or a-1

사용하여 :

which(x==a&(y==b+1|y==b-1)|y==b&(x==a+1|x==a-1))

"약간 다른":)
ngm

@ngm : eheh ... 사용하는 로제타 코드가 나에게는 "모호한"것이기 때문에 어떻게 든 OEIS 시퀀스와는 다르지만 비슷한 방식으로 매트릭스의 위치 인덱스를 생성한다고 가정합니다. : D
digEmAll

4

펄 6 , 94 83 바이트

{my \ s = 0, | [+] flat ((1, i ... ) Zxx flat (1..Inf Z 1..Inf)); map {first : k, s [$ _] + $ ^ d, s}, i, -1,1, -i}

{my \s=0,|[\+] flat((1,*i...*)Zxx(1,1.5...*));map {first :k,s[$_]+$^d,s},i,-1,1,-i}

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

s복소수로 표시되는 게으르고 무한한 나선형 좌표 목록입니다. 다른 두 개의 무한 목록으로 구성 1, *i ... *됩니다 1, i, -1, -i .... 1, 1.5 ... *목록을 만듭니다 1, 1.5, 2, 2.5, 3, 3.5 .... 이 두 목록을 목록 복제와 함께 압축하면 각 나선형 좌표에서 다음 나선형 단계까지의 단계 목록이 생성 1, i, -1, -1, -i, -i, 1, 1, 1, i, i, i ...됩니다. (리스트 복제 연산자에 대한 오른쪽 인수의 소수 부분은 버려집니다.) [\+]이 목록에서 삼각 가감 소 ( )를 수행하고 앞에 0을 붙여 넣으면 나선형 좌표 목록이 생성됩니다.

마지막으로, 복잡한 숫자부터 시작 s[$_]( $_함수의 유일한 인수 인), 우리는 인덱스를 (조회 first :k하여 해당 번호로부터의 오프셋 (offset)하는 복소수의 나선형) i, -1, 1,와 -i.


4

Brain-Flak , 238 바이트

((){[()]<((({}[((()))]<>)<<>{((([{}]({}))([{}]{})())[()]){({}[()])<>}{}}>)<<>({}<(((({}{})()){}<>({}))()())<>>)<>>()())<>{{}((()()()[({})]){}<>({}<{}>))(<>)}>}{}){<>((((())()())()())()())(<>)}{}{({}[()]<<>({}<>)<>({}<({}<({}<>)>)>)<>>)}<>

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

출력은 왼쪽, 위, 오른쪽, 아래의 순서로 이루어집니다.

설명

# If n is nonzero:
((){[()]<

  ((

    # Push 1 twice, and push n-1 onto other stack.
    ({}[((()))]<>)

    # Determine how many times spiral turns up to n, and whether we are on a corner.
    # This is like the standard modulus algorithm, but the "modulus" used
    # increases as 1, 1, 2, 2, 3, 3, ...
    <<>{((([{}]({}))([{}]{})())[()]){({}[()])<>}{}}>

  # Push n-1: this is the number behind n in the spiral.
  )<

    # While maintaining the "modulus" part of the result:
    <>({}<

      # Push n+2k+1 and n+2k+3 on top of n-1, where k is 3 more than the number of turns.
      # n+2k+1 is always the number to the right in the direction travelled.
      # If we are on a corner, n+2k+3 is the number straight ahead.
      (((({}{})()){}<>({}))()())<>

    >)<>

  # Push n+1.  If we are on a corner, we now have left, front, right, and back
  # on the stack (from top to bottom)
  >()())

  # If not on a corner:
  <>{{}

    # Remove n+2k+3 from the stack entirely, and push 6-2k+(n+1) on top of the stack.
    ((()()()[({})]){}<>({}<{}>))

  (<>)}

>}{})

# If n was zero instead:
{

  # Push 1, 3, 5, 7 on right stack, and implicitly use 1 (from if/else code) as k.
  <>((((())()())()())()())

(<>)}{}

# Roll stack k times to move to an absolute reference frame
# (switching which stack we're on each time for convenience)
{({}[()]<<>({}<>)<>({}<({}<({}<>)>)>)<>>)}<>

매우 인상적! 다른 사람들처럼 전체 나선형을 생성하지 않는 것 같습니까?
ბიმო

3

MATL , 15 바이트

2+1YLtG=1Y6Z+g)

입력 및 출력은 1 기반입니다.

출력은 왼쪽, 아래쪽, 위쪽 및 오른쪽 이웃을 순서대로 제공합니다.

온라인으로 사용해보십시오! 또는 마지막 두 개 (TIO에서 시간 초과)를 제외한 모든 테스트 사례를 확인하십시오 .

2+      % Implicit input: n. Add 2. This is needed so that
        % the spiral is big enough
1YL     % Spiral with side n+2. Gives a square matrix
t       % Duplicate
G=      % Compare with n, element-wise. Gives 1 for entry containing n
1Y6     % Push 3×3 mask with 4-neighbourhood
Z+      % 2D convolution, keeping size. Gives 1 for neighbours of the
        % entry that contained n
g       % Convert to logical, to be used as an index
)       % Index into copy of the spiral. Implicit display

2
1YLMATLAB에 spiral기능이 있습니까? MATLAB은 언제 Mathematica로 바뀌 었습니까?!
sundar-복 직원 모니카

예, 1YL의 의미를 확인한 후 오리 덕킹을했고, 이 Rosetta 코드 항목 은 MATLAB 기능뿐 아니라 MATLAB 기능이라는 것을 확인할 수있는 유일한 곳이었습니다. 그 항목을 볼 때까지 골프를 위해 MATL에 추가 한 것으로 생각하기 시작했습니다.
sundar-복원 모니카

더 이상 문서화되지 않은 @sundar Weird
Luis Mendo


2

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

로 색인을 인쇄합니다 alert().

f=(n,x=w=y=n+2)=>y+w&&[0,-1,0,1].map((d,i)=>(g=(x,y,A=Math.abs)=>(k=A(A(x)-A(y))+A(x)+A(y))*k+(k+x+y)*(y>=x||-1))(x+d,y+~-i%2)-n||alert(g(x,y)))|f(n,x+w?x-1:(y--,w))

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

어떻게?

x,yZIx,y

Ax,y=||x||y||+|x|+|y|
Sx,y={1,if yx1,if y<x
Ix,y=Ax,y2+(Ax,y+x+y)×Sx,y

( math.stackexchange 의이 답변 에서 수정되었습니다)


이것은 작은 숫자로 잘 작동하는 것 같지만 2000과 같이 큰 숫자로 이것을 테스트 할 때 오류가 발생합니다. tio.run의 오류 : RangeError: Maximum call stack size exceeded브라우저 콘솔의 오류 : InternalError: too much recursion. 내가 뭔가 잘못하고 있습니까?
Night2

1
4n2


1

PHP (> = 5.4), 208 바이트

<?$n=$argv[1];for(;$i++<($c=ceil(sqrt($n))+($c%2?2:3))**2;$i!=$n?:$x=-$v,$i!=$n?:$y=+$h,${hv[$m&1]}+=$m&2?-1:1,$k++<$p?:$p+=$m++%2+$k=0)$r[-$v][+$h]=$i;foreach([0,1,0,-1]as$k=>$i)echo$r[$x+$i][$y+~-$k%2].' ';

그것을 실행하려면 :

php -n -d error_reporting=0 <filename> <n>

예:

php -n -d error_reporting=0 spiral_neighbourhoods.php 2001

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

노트:

  • -d error_reporting=0옵션은 통지 / 경고를 출력하지 않는 데 사용됩니다.
  • 이 나선은 1로 시작합니다.

어떻게?

2 차원 배열 에서이 답변 의 수정 된 버전으로 나선형을 생성하고 있습니다.

나는 n항상 나선형으로 여분의 숫자를 얻기 위해 수식을 사용한 입력 을 기반으로 나선형의 크기를 결정합니다 (위 / 아래 / 왼쪽 / 오른쪽의 존재에 대한 보증). 여분의 숫자 라운드 는 2 차원 배열의 +2높이와 +2너비를 의미 합니다.

따라서 n최대 크기의 3*3나선에 위치하면 생성 된 나선이됩니다 5*5.

나선형 크기는 c*c어디 c = ceil(sqrt(n)) + k경우 ceil(sqrt(n))홀수, 다음 k2이고 만약 ceil(sqrt(n))짝수 후 k3이다.

예를 들어 위의 수식은 다음과 같습니다.

  • 경우 n = 1다음 c = 3과 나선형 크기가 될 것입니다3*3
  • 경우 n <= 9다음 c = 5과 나선형 크기가 될 것입니다5*5
  • 경우 n <= 25다음 c = 7과 나선형 크기가 될 것입니다7*7
  • 경우 n <= 49다음 c = 9과 나선형 크기가 될 것입니다9*9
  • 등등 ...

나선형을 생성하는 동안, I 상점 xyn과 생성 한 후, 출력 I / 위의 요소들은 아래 / 오른쪽 그것을 / 좌.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.