Gió cho tôi một con rắn số!


34

Cho một số nguyên đầu vào n, vẽ một con rắn số, nghĩa là một số đo lưới n x nbao gồm các số 1thông qua n^2đó được quấn quanh nhau theo kiểu sau:

Đầu vào n = 3:

7 8 9
6 1 2
5 4 3

Đầu vào n = 4:

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

Đầu vào 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

(Lấy cảm hứng từ vấn đề này từ Project Euler.)

Đây là , câu trả lời ngắn nhất trong byte thắng!


4
Ví dụ : 4? Hoặc bất kỳ số chẵn.
TheLethalCoder

1
Chúng ta có thể giả sử đầu vào là số lẻ?
Ông Xcoder



1
Xem thêm perlmonks.com/?node_id=487200 với nhiều giải pháp và liên kết trong trả lời.
b_jonas

Câu trả lời:



18

C #, 203 202 196 193 178 byte

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;}

Đã lưu một byte nhờ @StefanDelport.
Đã lưu 22 byte nhờ @FelipeNardiBatista.

Điều này hoạt động bằng cách quan sát sau đây về cách các hình vuông được xây dựng:

Hình ảnh của hình vuông trong đó n = 5

Như bạn có thể thấy mỗi bit được thêm vào hình vuông trước đó. Đối với các số chẵn, chúng ta đi bên phải nơi chúng ta ở, xuống cho đến khi thấp hơn một ô so với vị trí của hình vuông và sau đó rời khỏi đến cuối. Các số lẻ về cơ bản là ngược lại, chúng ta đi bên trái một, cho đến khi một trên các chiều cao hiện tại và sau đó phải đến cuối.

Phiên bản đầy đủ / được định dạng:

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;có thể trở thành n>++i, không có gì khác tôi có thể thấy, +1.
LiefdeWen

1
n%2<1?2:1để 2-x%2? Tôi chưa thử nghiệm nó trong C #, nhưng trong C và Python nó đã hoạt động.
Felipe Nardi Batista

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; ....chơi gôn một chút
Felipe Nardi Batista

@FelipeNardiBatista Tuyệt vời sẽ không bao giờ nghĩ về hai người đó! Cảm ơn.
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++;
Felipe Nardi Batista

15

APL Dyalog, 70 56 45 41 byte

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

Hãy thử trực tuyến!

Làm sao?

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

tính toán sự khác biệt giữa các chỉ số; 1¯1cho phải và trái, ¯⍵cho lên và xuống.

1,⊢,¯1,-đến 1 ⍵ ¯1 ¯⍵, +⍨⍴kéo dài mảng này theo chiều dài ⍵×2, do đó, trận chung kết 2/⍳có thể lặp lại từng mảng , với số lần lặp lại tăng lên mỗi phần tử thứ hai:

      (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

sau đó,

(⌈2÷⍨×⍨),

chuẩn bị phần tử trên cùng bên trái của hình xoắn ốc,

×⍨↑

giới hạn ⍵ 2 phần tử đầu tiên của danh sách khoảng cách này,

+\

thực hiện tổng tích lũy,

chấm điểm các chỉ số ( ⍵[i] = ⍵[⍵[i]]), để dịch ma trận gốc với các chỉ số của mọi phần tử và cuối cùng

,⍨⍴

hình dạng như một ⍵×⍵ma trận.


Đối với những người quan tâm, kỹ thuật này được thảo luận dài trong bài viết tuyệt vời này .
Giô-na

9

C, 321 307 295 284 283 282 byte

Cảm ơn cả @Zachary T và @Jonathan Frech vì đã chơi golf một byte!

#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);}

Phân bổ một mảng hai chiều của số không, sau đó bắt đầu điền nó từ một nơi nào đó ở giữa. Cuối cùng, các giá trị lớn hơn 0 nhưng nhỏ hơn hoặc bằng bình phương của đầu vào được in.

Hãy thử trực tuyến!

Định dạng:

#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
Có thể thay thế i,j,k,a,b,m;f(n){n*=n;int**l=calloc(a=m=3*n,4);bằng i,j,k,a,b,m,**l;f(n){n*=n;l=calloc(a=m=3*n,4);để tiết kiệm một byte?
Zacharý

1
Bạn có thể thay thế k<=n;bằng n>k;để lưu một byte.
Jonathan Frech

6

PHP , 192 byte

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++]);

Hãy thử trực tuyến!

Cùng một cách xây dựng một chuỗi thay vì một mảng

PHP , 217 byte

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);

Hãy thử trực tuyến!


1
[-1,1][$d&1]->$d&1?:-1
Tít

@Titus Cảm ơn bạn Tôi đã không nhìn thấy nó
Jörg Hülsermann

1
Đây là một byte nữa : for(;$k<$a;print join($o)."\n")ksort($o=&$e[+$k++]);. Và một số khác : "%$l".d. Và một điều nữa: $x*$l*$a+$y*$l-> ($x*$a+$y)*$l.
Tít

1
Và tôi nghĩ rằng trong phiên bản thứ hai, bạn có thể khởi tạo $smột dấu gạch dưới (hoặc chữ hoặc chữ số); nhân vật đó sẽ bị ghi đè.
Tít

@Titus Cảm ơn bạn và bạn có thể sử dụng .dcách tiếp cận của riêng mình để tiết kiệm 2 byte
Jörg Hülsermann

6

PHP, 185 176 174 byte

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"
";}

Chạy như ống với -nRhoặc kiểm tra nó trực tuyến .

phá vỡ

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 byte

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

Hãy thử trực tuyến!

Công dụng ⎕io←1. Bắt đầu với ma trận 0-by-1 ( ⍪⍬). 2N lần ( ⍣2⍣⍵) thêm chiều cao của ma trận ( ≢⍵) cho mỗi phần tử của nó, đặt 1 2...heightbên phải ( ,⌸) và xoay ( ⌽⍉). Khi kết thúc, điều chỉnh hướng của kết quả ( ⊖∘⌽⍣⍵⌽) và đảo ngược các số bằng cách trừ chúng khỏi N 2 +1 ( 1+×⍨-).


5

Toán học, 177 byte

(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, không tích hợp sẵn cho điều này trong Mathematica?
Ông Xcoder

5

C ++, 245 228 byte

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<<' ';}}

Hãy thử trực tuyến!

Hàm tính toán và in giá trị của từng số ma trận tùy thuộc vào vị trí x, y của nó bằng cách áp dụng logic này:

Tính toán giá trị rắn tùy theo vị trí

Phiên bản được định dạng :

#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

Python 3 , 249 247 byte

Tôi khởi tạo một mảng 2D và tìm điểm bắt đầu, là trung tâm của n lẻ hoặc offset (-1, -1) cho chẵn n, sau đó chia tỷ lệ mẫu điền / con trỏ với số 'vòng' hiện tại. Tôi cảm thấy như mình đang thiếu một mẹo để diễn giải các hướng nhưng tôi không nghĩ ra được thứ gì rẻ hơn.

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

Hãy thử trực tuyến!

-2 cảm ơn Zachary T!


Làm thế nào bạn đếm byte của bạn? các tab, dấu cách và dòng mới cũng được tính
Felipe Nardi Batista

Tôi đã thay thế mọi \ n và \ t bằng "" và lấy một len ​​(). Tôi chỉ sao chép ở trên và làm lại nó để đảm bảo rằng tôi đã không thay đổi bất cứ điều gì và quên kể lại nhưng tôi đã nhận được cùng một số. Tôi đã bỏ lỡ một cái gì đó?
nocturama

Tôi đang đếm \t\nlà 1 byte và vẫn nhận được 249 byte
Felipe Nardi Batista

e: ^^ ^ Có phương pháp nào tốt hơn / dễ dàng hơn tôi nên sử dụng không? chúng luôn xuất hiện để được sử dụng thay thế cho tôi. 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
^^ ^

các trình soạn thảo văn bản thường cho bạn biết có bao nhiêu ký tự được chọn, vì vậy CTRL + A và đọc những gì nó nói
Felipe Nardi Batista

5

Ngôn ngữ Wolfram (Mathicala) , (...) 83 byte

Byte được đo bằng UTF8, \[LeftFloor]( ) và \[RightFloor]( ) có giá 3 byte mỗi byte. Mathematica không có bất kỳ bộ ký tự byte đặc biệt nào.

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}]&

Hãy thử trực tuyến!


Sử dụng mẫu đóng cho mỗi trong 4 trường hợp, sau đó lấy tối đa cẩn thận để có được kết quả mong muốn.

Trả về một mảng 2D của số nguyên. Tôi không chắc chắn nếu điều này được cho phép, và mặc dù nó đã được hỏi trong các bình luận , OP đã không trả lời.


4

Clojure, 206 byte

(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))))

Tôi đoán đây là một khởi đầu tốt, xây dựng bảng theo trình tự thành một bản đồ băm và sau đó phân vùng nó thành n x ncác danh sách. Điều đó defmacrođã kết thúc khá dài, nhưng mã vẫn ngắn hơn so với không có. Có một cú pháp succint hơn để mô tả nó?

Hàng loạt byte tính toán điểm bắt đầu và xây dựng logic tra cứu của vận tốc tiếp theo v. Có lẽ một lồng nhau vecsẽ tốt hơn, nhưng sau đó bạn có hai chỉ số và vận tốc để theo dõi.


3

J , 41 byte

(]|.@|:@[&0](|.@|:@,.*/@$+#\)@]^:[1:)2*<:

Hãy thử trực tuyến!

Thực hiện tương tự như đệ trình APL của ngn nhưng bắt đầu với ma trận 1 trên 1 và lặp lại 2 × N 2 lần.


Bạn có thể cải thiện phương pháp thay thế của tôi (bây giờ được buộc ở tuổi 41) để đánh bại chính mình? Tôi đã cho nó chơi golf tốt nhất của tôi cho đến nay, nhưng tôi nghi ngờ ít nhất một vài byte có thể bị loại bỏ.
Giô-na

1

Con trăn 165 (hoặc 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)

Điều này tạo ra một mảng numpy, sau đó xoay nó và thêm một bên cho đến khi đạt được kích thước chính xác. Câu hỏi không chỉ định nếu cùng một điểm bắt đầu cần được sử dụng cho số chẵn và số lẻ, nếu đó không phải là trường hợp dòng if n%2==0:a=r(r(a))có thể được loại bỏ, tiết kiệm 21 byte.


1
đây không phải là Python, đó là Python + numpy
ASCII - chỉ

@ ASCII-only Có danh sách chính các tên ngôn ngữ được chấp nhận ở đâu đó không? Đây là con trăn hoàn toàn hợp lệ.
dùng2699

Nó sử dụng một thư viện, do đó bạn cũng cần bao gồm tên của thư viện ... đối với các ngôn ngữ được phép, bất kỳ ngôn ngữ nào có triển khai công khai bạn có thể chạy đều được phép
chỉ có ASCII

@ ASCII-chỉ có nơi mà viết ra? Tôi chưa thấy nó được thực hiện với hầu hết các câu trả lời trăn.
dùng2699

Có, bởi vì hầu hết trong số họ không sử dụng numpy ... và stdlib không được tính là một thư viện bên ngoài
ASCII - chỉ

0

J , 41 byte

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

định dạng chuẩn

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

Cách tiếp cận này dựa trên At Play With J Volutes (APL của Uriel sử dụng một kỹ thuật tương tự).

Nó đủ bất ngờ và thanh lịch để biện minh cho câu trả lời J thứ 2, tôi nghĩ.

Về cơ bản, chúng tôi không làm bất cứ điều gì theo thủ tục hoặc thậm chí là hình học. Thay vào đó, chúng tôi tạo ra một chuỗi đơn giản, khi quét tổng hợp và phân loại, đưa ra thứ tự chính xác của số xoắn ốc từ trái sang phải, từ trên xuống dưới. Sau đó chúng ta định hình nó thành một ma trận và được thực hiện.

Tôi sẽ thêm một lời giải thích chi tiết hơn khi thời gian cho phép, nhưng bài viết được liên kết sẽ giải thích sâu hơn.

Hãy thử trực tuyến!


0

Python 3 (Không có ngăn xếp) , 192 188 179 150 byte

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)

Hãy thử trực tuyến!

(2y+1)2-(y-x)-2yr

Đã lưu 4 byte kể từ khi xoay phasor 90 độ được thực hiện dễ dàng mà không cần số phức


0

R , 183 byte

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

Hãy thử trực tuyến!

Đầu ra là một con rắn ma trận (hoặc ma trận con rắn, bất cứ điều gì). Đây có lẽ không phải là phương pháp hiệu quả nhất, và nó có thể có khả năng chơi gôn, nhưng tôi nghĩ nó đáng để thể hiện. Tôi thực sự tự hào về điều này thực sự!

Phương thức xây dựng ma trận từ trong ra ngoài, luôn nối thêm một số nguyên bằng với số cột trong ma trận trước khi nối thêm. Mẫu theo sau là ràng buộc bởi các cột hoặc theo hàng, đồng thời đảo ngược một số giá trị để chúng được nối theo đúng thứ tự.

193 byte

Chính xác như trên, nhưng cuối cùng b

matrix(b,x)

Hãy thử trực tuyến!

cung cấp đầu ra sạch hơn một chút, nhưng tôi không thấy bất kỳ tiêu chí đặc biệt nào cho đầu ra, vì vậy câu trả lời đầu tiên sẽ hoạt động nếu tôi không nhầm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.