숫자 뱀을 날려줘!


34

입력 정수 주어 n, 표시하는 숫자 뱀 그릴 측정 그리드 n x n숫자의 구성 1n^2다음과 같은 방식으로 서로에 감겨 그 :

입력 n = 3:

7 8 9
6 1 2
5 4 3

입력 n = 4:

 7  8  9 10
 6  1  2 11
 5  4  3 12
16 15 14 13

입력 n = 5:

21 22 23 24 25
20  7  8  9 10
19  6  1  2 11
18  5  4  3 12
17 16 15 14 13

( Project Euler 의이 문제 에서 영감을 얻었습니다 .)

이것은 이며 바이트 단위로 가장 짧은 답변입니다!


4
예 : 4? 또는 짝수입니다.
TheLethalCoder

1
입력이 홀수라고 가정 할 수 있습니까?
Mr. Xcoder



1
회신에 많은 솔루션과 링크가있는 perlmonks.com/?node_id=487200 도 참조하십시오 .
b_jonas

답변:



18

C #을 203 202 196 193 178 바이트

n=>{var r=new int[n,n];for(int o=n-2+n%2>>1,i=r[o,o]=1,c=2,w=o,h=o,b=1-2*(i%2),j;n>i++;){r[h,w+=b]=c++;for(j=0;j<i-1;++j)r[h+=b,w]=c++;for(j=0;j<i-1;++j)r[h,w-=b]=c++;}return r;}

@StefanDelport 덕분에 바이트를 저장했습니다.
@FelipeNardiBatista 덕분에 22 바이트를 절약했습니다.

이것은 사각형이 어떻게 구성되는지에 대한 다음 관찰에 의해 작동합니다.

n = 5 인 정사각형 이미지

보시다시피 각 비트는 이전 사각형에 추가됩니다. 짝수의 경우 우리는 우리가 있던 곳으로 이동합니다. 아래로 내려갈 때까지 광장이 있던 곳보다 1이 낮아지고 끝까지 남았습니다. 홀수는 본질적으로 반대입니다. 우리는 왼쪽으로갑니다. 현재 높이보다 높고 끝까지 올 때까지 올라갑니다.

풀 / 포맷 버전 :

using System;
using System.Linq;

class P
{
    static void Main()
    {
        Func<int, int[,]> f = n =>
        {
            var r = new int[n, n];
            for (int o = n - 2 + n % 2 >> 1, i = r[o, o] = 1, c = 2, w = o, h = o, b = 1 - 2 * (i % 2), j; n > i++;)
            {
                r[h, w += b] = c++;

                for (j = 0; j < i - 1; ++j)
                    r[h += b, w] = c++;

                for (j = 0; j < i - 1; ++j)
                    r[h, w -= b] = c++;
            }

            return r;
        };

        Console.WriteLine(String.Join("\n", f(3).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
        Console.WriteLine(String.Join("\n", f(4).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");
        Console.WriteLine(String.Join("\n", f(5).ToJagged().Select(line => String.Join(" ", line.Select(l => (l + "").PadLeft(2))))) + "\n");

        Console.ReadLine();
    }
}

public static class ArrayExtensions
{
    public static T[][] ToJagged<T>(this T[,] value)
    {
        T[][] result = new T[value.GetLength(0)][];

        for (int i = 0; i < value.GetLength(0); ++i)
            result[i] = new T[value.GetLength(1)];

        for (int i = 0; i < value.GetLength(0); ++i)
            for (int j = 0; j < value.GetLength(1); ++j)
                result[i][j] = value[i, j];

        return result;
    }
}

1
++i<=n;될 수있는 n>++i것도 다른 내가 +1, 볼 수 있습니다.
LiefdeWen

1
n%2<1?2:12-x%2? C #에서는 테스트하지 않았지만 C 및 Python에서는 작동했습니다.
펠리페 나르디 바티스타

1
for(int o=n-2+n%2>>1,i=r[o,o]=1,c=2,w=o,h=o,j;n>i++;){var b=i%2<1; ....조금 골프
펠리페 나르디 바티스타

@FelipeNardiBatista 멋진 두 사람을 생각하지 않았을 것입니다! 감사.
TheLethalCoder

1
var b=1-2*(i%2);r[h,w+=b]=c++;for(j=0;j<i-1;++j)r[h+=b,w]=c++;for(j=0;j<i-1;++j)r[h,w-=b]=c++;
펠리페 나르디 바티스타

15

디아 로그 APL, 70 56 45 41 바이트

,⍨⍴∘(⍋+\)×⍨↑(⌈2÷⍨×⍨),(+⍨⍴1,⊢,¯1,-)(/⍨)2/⍳

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

어떻게?

(+⍨⍴1,⊢,¯1,-)(/⍨)2/⍳

지수 간의 차이를 계산합니다. 1그리고 ¯1좌우를위한 ¯⍵그리고 위아래로합니다.

1,⊢,¯1,-오는 등 1 ⍵ ¯1 ¯⍵,+⍨⍴ 길이 배열이 뻗어 ⍵×2최종 그래서, 2/⍳이들 각각을 반복 할 수 매초 요소 증가, 반복 카운트 :

      (1,⊢,¯1,-) 4
1 4 ¯1 ¯4
      (+⍨⍴1,⊢,¯1,-) 4
1 4 ¯1 ¯4 1 4 ¯1 ¯4
      (2/⍳) 4
1 1 2 2 3 3 4 4
      ((+⍨⍴1,⊢,¯1,-)(/⍨)2/⍳) 4
1 4 ¯1 ¯1 ¯4 ¯4 1 1 1 4 4 4 ¯1 ¯1 ¯1 ¯1 ¯4 ¯4 ¯4 ¯4

그때,

(⌈2÷⍨×⍨),

나선의 왼쪽 상단 요소 앞에

×⍨↑

처음 limit 2를 제한이 거리 목록 요소를

+\

누적 합계를 수행하고

지수를 등급 화 (⍵[i] = ⍵[⍵[i]] )를 하여 원래 행렬을 모든 요소의 인덱스로 변환하고 마지막으로

,⍨⍴

⍵×⍵행렬 로 모양 .


관심있는 사람들을 위해이 기술은 이 훌륭한 기사에서 길게 논의됩니다 .
요나

9

C, 321 307 295 284 283 282 바이트

바이트를 골프로 한 @Zachary T와 @Jonathan Frech에게 감사드립니다!

#define F for(b=a;b--;)l
i,j,k,a,b,m;**l;f(n){n*=n;l=calloc(a=m=3*n,4);F[b]=calloc(m,4);for(l[i=j=n][j]=a=k=1;n>k;++a){F[i][++j]=++k;F[++i][j]=++k;++a;F[i][--j]=++k;F[--i][j]=++k;}for(i=0;i<m;++i,k&&puts(""))for(j=k=0;j<m;)(a=l[i][j++])>0&&a<=n&&printf("%*d ",(int)log10(n)+1,k=a);}

2 차원 배열로 0을 할당 한 다음 가운데 어딘가에서 채우기 시작합니다. 마지막으로 0보다 크지 만 입력의 제곱보다 작거나 같은 값이 인쇄됩니다.

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

형식화 :

#define F for(b=a; b--;)l
i, j, k, a, b, m; **l;
f(n)
{
    n *= n;
    l = calloc(a=m=3*n, 4);

    F[b] = calloc(m, 4);

    for(l[i=j=n][j]=a=k=1; n>k; ++a)
    {
        F[i][++j] = ++k;
        F[++i][j] = ++k;
        ++a;

        F[i][--j] = ++k;
        F[--i][j] = ++k;
    }

    for(i=0; i<m; ++i, k&&puts(""))
        for(j=k=0; j<m;)
            (a=l[i][j++])>0 && a<=n && printf("%*d ", (int)log10(n)+1, k=a);
}

1
그것은 교체 할 수 i,j,k,a,b,m;f(n){n*=n;int**l=calloc(a=m=3*n,4);i,j,k,a,b,m,**l;f(n){n*=n;l=calloc(a=m=3*n,4);바이트를 저장할?
Zacharý

1
당신은 대체 할 수 있습니다 k<=n;n>k;바이트 저장합니다.
Jonathan Frech

6

PHP , 192 바이트

for($l=strlen($q=($a=$argn)**2)+$d=1,$x=$y=$a/2^$w=0;$i++<$q;${yx[$w%2]}+=$d&1?:-1,$i%$d?:$d+=$w++&1)$e[$x-!($a&1)][$y]=sprintf("%$l".d,$i);for(;$k<$a;print join($o)."\n")ksort($o=&$e[+$k++]);

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

같은 방법으로 배열 대신 문자열을 작성

PHP , 217 바이트

for($l=strlen($q=($a=$argn)**2)+$d=1,$x=$y=($a/2^$w=0)-!($a&1),$s=str_pad(_,$q*$l);$i++<$q;${yx[$w%2]}+=$d&1?:-1,$i%$d?:$d+=$w++&1)$s=substr_replace($s,sprintf("%$l".d,$i),($x*$a+$y)*$l,$l);echo chunk_split($s,$a*$l);

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


1
[-1,1][$d&1]->$d&1?:-1
Titus

@Titus 내가 그것을보고하지 않은 감사합니다
요 르그 Hülsermann

1
바이트가 하나 더 있습니다 : for(;$k<$a;print join($o)."\n")ksort($o=&$e[+$k++]);. 그리고 다른 하나 : "%$l".d. 그리고 하나 더 : $x*$l*$a+$y*$l-> ($x*$a+$y)*$l.
Titus

1
그리고 두 번째 버전 $s에서는 채워진 밑줄 (또는 문자 또는 숫자)로 초기화 할 수 있다고 생각합니다 . 해당 문자를 덮어 씁니다.
Titus

@Titus 감사합니다 그리고 당신은 .d2 바이트를 절약하기 위해 자신의 접근 방식을 사용할 수 있습니다
Jörg Hülsermann

6

PHP, 185176174 바이트

for(;$n++<$argn**2;${xy[$m&1]}+=$m&2?-1:1,$k++<$p?:$p+=$m++%2+$k=0)$r[+$y][+$x]=$n;ksort($r);foreach($r as$o){ksort($o);foreach($o as$i)printf(" %".strlen($n).d,$i);echo"
";}

파이프로 실행 -nR하거나 온라인으로 테스트하십시오 .

고장

for(;$n++<$argn**2;     # loop $n from 1 to N squared
    ${xy[$m&1]}+=$m&2?-1:1, # 2. move cursor
    $k++<$p?:               # 3. if $p+1 numbers have been printed in that direction:
        $p+=$m++%2+             # increment direction $m, every two directions increment $p
        $k=0                    # reset $k
)$r[+$y][+$x]=$n;           # 1. paint current number at current coordinates

ksort($r);              # sort grid by indexes
foreach($r as$o){       # and loop through it
    ksort($o);              # sort row by indexes
    foreach($o as$i)        # and loop through it
        printf(" %".strlen($n).d,$i);   # print formatted number
    echo"\n";               # print newline
}

6

APL (Dyalog Classic) , 32 29 바이트

1+×⍨-{⊖∘⌽⍣⍵⌽{⌽⍉,⌸⍵+≢⍵}⍣2⍣⍵⍪⍬}

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

사용합니다 ⎕io←1. 0x1 행렬 ( ⍪⍬)로 시작합니다 . 2N 배 ( ⍣2⍣⍵)는 행렬의 높이 ( ≢⍵)를 각 요소에 더하고 1 2...height오른쪽에 놓고 ( ,⌸) 회전합니다 ( ⌽⍉). 완료되면 결과의 방향 ( ⊖∘⌽⍣⍵⌽)을 수정하고 N 2 +1 ( 1+×⍨-) 에서 숫자를 빼서 숫자를 반전시킵니다 .


5

Mathematica, 177 바이트

(n=#;i=j=Floor[(n+1)/2];c=1;d=0;v={{1,0},{0,-1},{-1,0},{0,1}};a=Table[j+n(i-1),{i,n},{j,n}];Do[Do[Do[a[[j,i]]=c++;{i,j}+=v[[d+1]], {k,l}];d=Mod[d+1,4],{p,0,1}],{l,n-1}];Grid@a)&

8
Waaait, Mathematica에 내장되어 있지 않습니까?
Mr. Xcoder 2016 년

5

C ++, 245228 바이트

void f(){for(int i=0,j=-1,v,x,y,a,b;i<n;i++,j=-1,cout<<endl)while(++j<n){x=(a=n%2)?j:n-j-1;y=a?i:n-i-1;v=(b=y<n-x)?n-1-2*(x<y?x:y):2*(x>y?x:y)-n;v=v*v+(b?n-y-(y>x?x:y*2-x):y+1-n+(x>y?x:2*y-x));cout<<setw(log10(n*n)+1)<<v<<' ';}}

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

이 논리를 적용 하여 x, y 위치에 따라 행렬의 각 숫자 값을 계산하고 인쇄합니다 .

위치에 따른 뱀 값 계산

형식화 된 버전 :

#include <iostream>
#include <iomanip>
#include <math.h>

using namespace std;

void f(int n)
{
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            int value = 0;

            // Invert x and y when n is even
            int x = n % 2 == 0 ? n - j - 1 : j;
            int y = n % 2 == 0 ? n - i - 1 : i;
            if (y < (n - x))
            {
                // Left-top part of the matrix
                int padding = x < y ? x : y;
                value = n - 1 - padding * 2;
                value *= value;
                value += y >= x ? n - x - y : n + x - y - (y * 2);
            }
            else
            {
                // Right-bottom part of the matrix
                int padding = x > y ? n - x : n - y;
                value = n - padding * 2;
                value *= value;
                value += x > y ? y - padding + 1 : n + y - x - (padding * 2) + 1;
            }

            cout << setw(log10(n * n) + 1);
            cout << value << ' ';
        }

        cout << endl;
    }
}

int main()
{
    int n;
    while (cin >> n && n > 0)
    {
        f(n);
        cout << endl;
    }
}

5

파이썬 3 , 249 247 바이트

2D 배열을 초기화하고 홀수 n의 중심 또는 짝수 n의 오프셋 (-1, -1)의 시작점을 찾은 다음 현재 '링'번호로 채우기 / 커서 패턴의 크기를 조정합니다. 방향을 해석하기위한 트릭을 놓친 것처럼 느껴지지만 더 저렴한 것을 찾지 못했습니다.

def f(n):
 M=[n*[0]for a in range(n)]
 x=y=n//2-1+n%2
 M[x][y]=i=s=1
 while 1:
  t=s*2
  for d in'R'+'D'*(t-1)+'L'*t+'U'*t+'R'*t:
   if i==n*n:print(*M,sep='\n');return
   v=[1,-1][d in'LU']
   if d in'UD':x+=v
   else:y+=v
   M[x][y]=i=i+1
  s+=1

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

Zachary T에게 -2 감사합니다!


바이트 수는 어떻게 계산 했습니까? 탭, 공백 및 줄 바꿈도 중요합니다
Felipe Nardi Batista

모든 \ n 및 \ t를 ""로 바꾸고 len ()을 사용했습니다. 방금 위의 내용을 복사하고 변경하여 아무것도 변경하지 않았고 다시 계산하는 것을 잊었지만 동일한 번호를 얻었습니다. 내가 뭘 놓 쳤니?
nocturama 2016 년

나는 믿는다 \t\n1 바이트로 여전히 249 바이트 점점
펠리페 나르디 바티스타를

e : ^^^ 사용해야하는 더 좋고 쉬운 방법이 있습니까? . 그들은 항상 나에게 의미로 사용되는 것처럼 ^^^ 이상한을, 이것은 내가 IDLE에서 무엇을 얻을 수 있습니다 :len("def f(n): M=[n*[0]for a in range(n)] x=y=n//2-(n%2<1) M[x][y]=i=s=1 while 1: t=s*2 for d in'R'+'D'*(t-1)+'L'*t+'U'*t+'R'*t: if i==n*n:print(*M,sep='\n');return v=[1,-1][d in'LU'] if d in'UD':x+=v else:y+=v M[x][y]=i=i+1 s+=1") 223
nocturama

일반적으로 텍스트 편집기는 선택된 문자 수를 알려주므로 CTRL + A를 사용하여 그 내용을 읽습니다.
Felipe Nardi Batista

5

Wolfram Language (Mathematica) , (...) 83 바이트

UTF8로 측정 된 바이트, \[LeftFloor]( ) 및 \[RightFloor]( )는 각각 3 바이트입니다. Mathematica에는 특수 바이트 문자 세트가 없습니다.

Table[Max[4x^2-Max[x+y,3x-y],4y
y-{x+y,3y-x}]+1,{y,b+1-#,b=⌊#/2⌋},{x,b+1-#,b}]&

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


4 가지 경우 각각에 대해 닫힌 양식을 사용한 다음 원하는 결과를 얻기 위해 최대한주의를 기울입니다.

정수의 2D 배열을 반환합니다. 이것이 허용되는지 확실 하지 않으며 의견에 요청 되었지만 OP가 응답하지 않았습니다.


4

클로저, 206 바이트

(defmacro F[s]`(if(~'r(+ ~'p ~'v ~s))~'v ~s))
#(loop[i 1 p(*(quot(dec %)2)(inc %))v 1 r{}](if(<(* % %)i)(partition %(map r(range i)))(recur(inc i)(+ p v)({1(F %)-1(F(- %))%(F -1)(- %)(F 1)}v)(assoc r p i))))

나는 이것이 괜찮은 시작이라고 생각하고 보드를 해시 맵에 순서대로 빌드 한 다음 n x n목록으로 분할 합니다. 그defmacro 꽤 긴 었죠하지만, 코드가없는 것보다 그것으로 여전히 짧다. 그것을 설명하는 더 간결한 구문이 있습니까?

대량의 바이트는 시작점을 계산하고 다음 속도의 조회 논리를 작성합니다 v. 아마도 중첩 vec이 더 나을지 모르지만 추적 할 두 개의 인덱스와 속도가 있습니다.



1

파이썬 165 (또는 144)

from pylab import *
def S(n):
 a=r_[[[1]]];r=rot90;i=2
 while any(array(a.shape)<n):
  q=a.shape[0];a=vstack([range(i,i+q),r(a)]);i+=q
 if n%2==0:a=r(r(a))
 print(a)

이렇게하면 numpy 배열이 생성되고 회전하여 올바른 크기에 도달 할 때까지 측면을 추가합니다. 이 질문은 짝수와 홀수에 동일한 시작점을 사용해야하는지 여부를 지정하지 않았습니다. 그렇지 않은 경우 줄 if n%2==0:a=r(r(a))을 제거하여 21 바이트를 절약 할 수 있습니다.


1
이것은 파이썬이 아니라 파이썬 + numpy입니다
ASCII 전용

@ ASCII-only 어딘가에 허용되는 언어 이름의 마스터 목록이 있습니까? 이것은 완벽하게 유효한 파이썬입니다.
user2699

라이브러리를 사용하므로 라이브러리의 이름도 포함해야합니다. 허용 된 언어의 경우 공개적으로 구현할 수있는 모든 언어가 허용됩니다.
ASCII 전용

@ASCII 전용으로 작성된 곳은 어디입니까? 나는 대부분의 파이썬 답변으로 그것을 보지 못했습니다.
user2699

예, 대부분은 numpy를 사용하지 않기 때문에 stdlib는 외부 라이브러리로 계산되지 않습니다
ASCII 전용

0

J , 41 바이트

,~$[:/:[:+/\_1|.1&,(]##@]$[,-@[)2}:@#1+i.

표준 형식

,~ $ [: /: [: +/\ _1 |. 1&, (] # #@] $ [ , -@[) 2 }:@# 1 + i.

이 접근법은 At Play With J Volutes (Uriel의 APL은 비슷한 기술을 사용합니다)를 기반으로합니다.

제 2 J 답변을 정당화 할만 큼 예상치 못한 우아합니다.

기본적으로 절차 적이거나 기하학적 인 작업은 수행하지 않습니다. 대신, 우리는 스캔이 합산되고 등급이 매겨 질 때 왼쪽에서 오른쪽으로, 위에서 아래로 올바른 숫자의 순서를 제공하는 간단한 시퀀스를 산술적으로 만듭니다. 그런 다음 행렬로 형상화하고 완료합니다.

시간이 지나면 더 자세한 설명을 추가하지만 링크 된 기사에서 자세히 설명합니다.

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


0

파이썬 3 (스택리스) , 192 (188) 179 150 바이트

lambda n:[list(map(v,list(range(t-n,t)),[y]*n))for t in[1+n//2]for y in range(n-t,-t,-1)]
v=lambda x,y,r=0:y>=abs(x)and(3-2*r+4*y)*y+x+1or v(y,-x,r+1)

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

(2y+1)2(yx)2yr

복잡한 숫자없이 90도 페이저 회전을 쉽게 수행하므로 4 바이트 절약


0

R , 183 바이트

x=scan()
b=t(d<-1)
while(2*x-1-d){m=max(b)
y=(m+1):(m+sum(1:dim(b)[2]|1))
z=d%%4
if(z==1)b=cbind(b,y)
if(z==2)b=rbind(b,rev(y))
if(z==3)b=cbind(rev(y),b)
if(z==0)b=rbind(y,b)
d=d+1}
b

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

출력은 행렬 뱀 (또는 뱀 행렬)입니다. 아마도 가장 효율적인 방법은 아니며 골프를 타는 것일 수도 있지만 보여줄 가치가 있다고 생각했습니다. 나는 이것을 실제로 자랑스럽게 생각합니다!

이 메서드는 행렬을 안쪽에서 바깥쪽으로 작성하며, 추가하기 전에 항상 행렬의 열 수와 동일한 정수를 추가합니다. 뒤 따르는 패턴은 열 또는 행에 의한 바인딩이며 올바른 순서로 추가되도록 일부 값을 반대로합니다.

193 바이트

위와 동일하지만 최종 내용 b

matrix(b,x)

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

약간 더 깨끗한 출력을 제공하지만 출력에 대한 특별한 기준을 보지 못했기 때문에 실수하지 않으면 첫 번째 답변이 작동합니다.

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