숫자는 길이 = (N ^ 2의 자릿수) 인 필드에서 앞에 0을 인쇄해야합니다.
입력 (N) :
4
산출:
01 12 11 10
02 13 16 09
03 14 15 08
04 05 06 07
알고리즘과 구현의 청결에 관심이 있습니다. 따라서 공백은 계산되지 않으며 N의 상한은 42입니다.
L = floor(log10(N^2)) + 1
맞습니까?
숫자는 길이 = (N ^ 2의 자릿수) 인 필드에서 앞에 0을 인쇄해야합니다.
입력 (N) :
4
산출:
01 12 11 10
02 13 16 09
03 14 15 08
04 05 06 07
알고리즘과 구현의 청결에 관심이 있습니다. 따라서 공백은 계산되지 않으며 N의 상한은 42입니다.
L = floor(log10(N^2)) + 1
맞습니까?
답변:
n=input()
matrix=[[j+1]*n for j in range(n)]
x=y=0
for i in range(n)[::-2]:
x+=i*4;y+=1
for j in range(i):
matrix[j+y-1][y]=x+j
matrix[y-1][y:y+i]=range(x,x-i,-1)
R=matrix[n-y][y-1]+1
matrix[n-y][y:n-y+1]=range(R,R+i)
for j in range(y,y+i-1):
matrix[j][n-y]=matrix[j-1][n-y]-1
for row in matrix:
print ' '.join(`r`.zfill(len(`n*n`)) for r in row)
$ echo 9 | python codegolf-769-me.py
01 32 31 30 29 28 27 26 25
02 33 56 55 54 53 52 51 24
03 34 57 72 71 70 69 50 23
04 35 58 73 80 79 68 49 22
05 36 59 74 81 78 67 48 21
06 37 60 75 76 77 66 47 20
07 38 61 62 63 64 65 46 19
08 39 40 41 42 43 44 45 18
09 10 11 12 13 14 15 16 17
다른 테스트
$ echo 2 | python codegolf-769-me.py
1 4
2 3
$ echo 5 | python codegolf-769-me.py
01 16 15 14 13
02 17 24 23 12
03 18 25 22 11
04 19 20 21 10
05 06 07 08 09
$ echo 10 | python codegolf-769-me.py
001 036 035 034 033 032 031 030 029 028
002 037 064 063 062 061 060 059 058 027
003 038 065 084 083 082 081 080 057 026
004 039 066 085 096 095 094 079 056 025
005 040 067 086 097 100 093 078 055 024
006 041 068 087 098 099 092 077 054 023
007 042 069 088 089 090 091 076 053 022
008 043 070 071 072 073 074 075 052 021
009 044 045 046 047 048 049 050 051 020
010 011 012 013 014 015 016 017 018 019
루비에서 :
N=gets.to_i
index = -N
width = N
result = []
n = 0
dir=-1
while n < N*N
dir = (dir + 1) % 4
dir_x, dir_y = [[0,1],[1,0],[0,-1],[-1,0]][dir]
width -= 1 if [1,3].include?(dir)
1.upto(width) { |m|
n += 1
index += dir_y * N + dir_x
result[index] = n
}
end
width = (N*N).to_s.size
result.each_slice(N) { |l|
print l.map {|n| "%0#{width}d" % n }.join(" "), "\n"
}
테스트:
$ ruby1.9 769.rb <<< 9
01 32 31 30 29 28 27 26 25
02 33 56 55 54 53 52 51 24
03 34 57 72 71 70 69 50 23
04 35 58 73 80 79 68 49 22
05 36 59 74 81 78 67 48 21
06 37 60 75 76 77 66 47 20
07 38 61 62 63 64 65 46 19
08 39 40 41 42 43 44 45 18
09 10 11 12 13 14 15 16 17
여기 에서 계산을 사용하는 다른 솔루션 :
N=gets.to_i
r=[]
tr=->x,y{ x+(N-1)/2 + (y+(N-1)/2+(N-1)%2)*N }
r[tr[0,0]] = N*N
1.upto(N*N-1) { |n|
shell = ((Math.sqrt(n)+1)/2).to_i
leg = (n-(2*shell-1)**2)/(2*shell)
element = (n-(2*shell-1)**2)-2*shell*leg-shell+1
x,y = [[element,-shell],[shell,element],[-element,shell],[-shell,-element]][leg]
r[tr[x,y]] = N*N-n
}
r.each_slice(N) {|l|
puts l.map { |n|
"%0#{(N*N).to_s.size}d" % (n or 0)
}.join(" ")
}
테스트:
$ ruby1.9 769-2.rb <<< 5
01 16 15 14 13
02 17 24 23 12
03 18 25 22 11
04 19 20 21 10
05 06 07 08 09
Python3에서 :
n=int(input())
results = {}
val = 1
location = (0,0)
direction = (0,1)
def nxt():
return (location[0]+direction[0], location[1]+direction[1])
while val<=n*n:
if set([-1,n]).intersection(nxt()) or nxt() in results:
direction = (direction[1],direction[0]*-1)
results[location], location, val = str(val), nxt(), val+1
slen = len(str(n*n))
for y in range(n):
print( *[results[(x,y)].rjust(slen,'0') for x in range(n)] )
7의 샘플 출력
01 24 23 22 21 20 19
02 25 40 39 38 37 18
03 26 41 48 47 36 17
04 27 42 49 46 35 16
05 28 43 44 45 34 15
06 29 30 31 32 33 14
07 08 09 10 11 12 13
편집 : 재귀 솔루션-263 바이트
def a(m,s):
b,r,t=m-s*s+1,s-1,range
return[[[]],[[m]]][s]if s<2 else[[b]+list(t(b+4*r-1,b+3*r-1,-1))]+[[b+y+1]+a(m,s-2)[y]+[b+3*r-y-1]for y in t(s-2)]+[list(t(b+r,b+2*r+1))]
n=int(input())
for r in a(n*n,n):
print(*[str(x).zfill(len(str(n*n)))for x in r])
자바 솔루션
public static void main(String[] args) {
int INPUT = 5;
String[][] grid = new String[INPUT][INPUT];
int xDirection = 0;
int yDirection = 0;
int flag = 1;
for (int i = 0; i < INPUT * INPUT; i++) {
String temp = "";
for (int k = 0; k < (""+INPUT*INPUT).length() - ("" + (i + 1)).length(); k++) {
temp += "" + 0;
}
temp += (i + 1);
if (xDirection > INPUT-1)
{flag=2; yDirection++; xDirection--; i--; continue;}
else if (yDirection > INPUT -1)
{flag=3; yDirection--; xDirection--; i--; continue;}
else if (xDirection < 0)
{flag=4; xDirection++; yDirection--; i--; continue;}
if ( grid[xDirection][yDirection]==null ){
grid[xDirection][yDirection] = ""+temp;
}
else{
if (flag ==1 ) {
flag=2;
xDirection--;
}
else if (flag ==2){
flag=3;
yDirection--;
}
else if (flag==3){
flag=4;
xDirection++;
}
else{
flag=1;
yDirection++;
}
i--;
}
switch(flag){
case 1: xDirection++;break;
case 2: yDirection++;break;
case 3: xDirection--;break;
case 4: yDirection--; break;
}
}
for (int i = 0; i < INPUT; i++) {
for (int k = 0; k < INPUT; k++)
System.out.print(grid[i][k] + " ");
System.out.println();
}
}
입력 10에 대한 샘플 출력
001 036 035 034 033 032 031 030 029 028
002 037 064 063 062 061 060 059 058 027
003 038 065 084 083 082 081 080 057 026
004 039 066 085 096 095 094 079 056 025
005 040 067 086 097 100 093 078 055 024
006 041 068 087 098 099 092 077 054 023
007 042 069 088 089 090 091 076 053 022
008 043 070 071 072 073 074 075 052 021
009 044 045 046 047 048 049 050 051 020
010 011 012 013 014 015 016 017 018 019
Math :: Complex를 사용하고 현재 방향을 복잡한 변수 (1 / i / -1 / .i)로 유지합니다. 로 실행 :
$ perl -MMath::Complex spiral.pl
넣 N
습니다 $l
.
# $l = shift;
$d=i;
$x=0;
until($s{$x}){
$s{$x}=++$n;
$x+=$d;
$d*=-i if
Re($x)==Im($x)+(Re($x)<$l/2)
||Re($x)==$l-1-Im($x)
}
for$y(0..$l-1){
printf'%0'.length($l**2).'d ',$s{$_+i*$y}for 0..$l-1;
print"\n"
}
씨
#include<stdio.h>
#include<math.h>
int main() {
int A[42][42],i,j,N,c=1,k;
scanf("%d",&N);
for (i = 0, j = N - 1 ; j >= 0 ; i++, j--) {
for(k = i ; k < j; k++)A[i][k]=c++;
for(k = i ; k < j; k++)A[k][j]=c++;
for(k = j ; k > i; k--)A[j][k]=c++;
for(k = j ; k > i; k--)A[k][i]=c++;
}
if (N%2)
A[N/2][N/2]=c;
for (i=0;i<N;i++) {
for (j=0;j<N;j++)
printf("%0*d ",((int)log10(N*N)+1),A[j][i]);
printf("\n");
}
}
Func 기반의 재귀 버전-의도를 더 잘 표현할수록 더 흥미 롭습니다. 너비와 높이가 다른 경우에도 작동합니다.
<?php
$n = $argv[1];
for($y = 0; $y<$n; $y++){
for($x = 0; $x<$n; $x++)
printf("%02d ", f($n, $n, $x, $y));
echo "\n";
}
function f($w, $h, $x, $y){
return ($y)
?$w + f($h - 1, $w, $y - 1, $w - $x - 1) //strip-off first row and "rotate"
:$x;
}
산출:
C:\www>php -f golfed_spiral.php 8
00 01 02 03 04 05 06 07
27 28 29 30 31 32 33 08
26 47 48 49 50 51 34 09
25 46 59 60 61 52 35 10
24 45 58 63 62 53 36 11
23 44 57 56 55 54 37 12
22 43 42 41 40 39 38 13
21 20 19 18 17 16 15 14
나는 이것이 골프 기록에 붙이기를 귀찮게하지 않았다. 그러나 나는 그것에 대해 조금 다르게 생각하고 싶었습니다. 각 줄이나 위치를 쓰지 않고 커서를 위치로 옮기고 시작 센터 번호를 쓰고 거기에서 나선형으로 움직입니다 (방향 변경 당 움직일 위치의 흥미로운 패턴을 보여줍니다) ).
콘솔 버퍼가 더 큰 값을 받아들이고 왼쪽 상단 모서리의 위치를 계산하는 데 상당한 양의 문자 공간이 낭비됩니다 (확실히 향상 될 수 있음).
어쨌든, 그것은 재미있는 운동이었습니다.
static void Main(string[] p)
{
int squareSize = 4;
Console.BufferHeight = 300;
Console.BufferWidth = 300;
int maxTravel = 0;
int currentTravel = 0;
int travelCounter = 0;
var a = squareSize % 2 == 0;
int direction = a ? 2 : 0;
int pad = squareSize * squareSize;
int padLength = (pad + "").Length;
int y = a ? (squareSize / 2) - 1 : (squareSize - 1) / 2;
int x = a ? y + 1 : y;
x = x + (x * padLength);
for (int i = pad; i > 0; i--)
{
Console.SetCursorPosition(x, y);
Console.Write((i + "").PadLeft(padLength, '0') + " ");
switch (direction)
{
case 0:
y--;
break;
case 1:
x += padLength + 1;
break;
case 2:
y++;
break;
case 3:
x -= padLength + 1;
break;
}
if (++currentTravel > maxTravel)
{
currentTravel = 0;
direction = ++direction % 4;
if (++travelCounter == 2)
{
travelCounter = 0;
maxTravel++;
}
}
}
}
이것은 골프를 치는 좋은 솔루션은 아니지만 알고리즘에 관심이있을 수 있습니다.
나는 항상 비슷한 문제 , 즉 NxM 행렬을 통해 시계 방향 나선형 경로를 찾는 것에 매료되었습니다 . 이 문제를 해결하는 정말 직관적 인 방법 중 하나는 매트릭스를 시계 반대 방향으로 계속 돌리고 주황색처럼 껍질을 벗기는 것입니다. 나는 우아하지는 않지만 비슷한 방법을 사용하여 그 반대를 수행합니다.
def spiral_matrix(n)
matrix = Array.new(n) { Array.new(n) }
path = [*1..n*n]
padding = (n*n).to_s.size
layer = 0
until path.empty?
matrix[layer].map! { |l| l || path.shift }
matrix = matrix.transpose.reverse
layer += 1 unless matrix[layer].include?(nil)
end
matrix = matrix.transpose.reverse until matrix[0][0] == 1
matrix.transpose.each do |row|
row.each do |l|
print "%0#{padding}d" % l, ' '
end
puts
end
end
0에 가까운 메모리를 사용하는 솔루션으로 시도하고 싶었습니다. 배열도없고 아무것도 없습니다. 언제 어디서나 값을 생성 할 수 있습니다. 우리는 어떤 크기의 나선을 요청할 수 있습니다 (출력 스트림을 수신하는 것이 처리 할 수 있다면). 누군가가 거대한 나선을 필요로하기를 바랍니다.
코드는 다음과 같습니다
; number of chars required to write x in base 10
; defined for x > 0
(define log10
(λ (x)
(inexact->exact
(+ 1 (floor (/ (log x) (log 10)))))))
; tells the square number
; works for squares of both even and odd sizes
; outer square # = 0
(define square#
(λ (x y size) ; x and y begin at 0
(min x y
(- size 1 x)
(- size 1 y))))
; tells the number of values in a square
(define square-val-qty
(λ (sqr# size) ; size is the whole spiral size
(let ((res (* 4 (- size (* 2 sqr#) 1))))
(cond
((zero? res) 1)
(else res)))))
; at which value a square starts
; works for odd/even spirals
(define square-1st-val
(λ (sqr# size)
(+ (* 4 sqr# (- size sqr#)) 1)))
; square size from spiral size
(define square-side
(λ (sqr# size)
(- size (* 2 sqr#))))
(define 1+
(λ (n)
(+ n 1)))
(define 1-
(λ (n)
(- n 1)))
; calculates the position on the square (from 0)
(define position-on-square
(λ (x y size)
(let* ((sqr# (square# x y size))
(sqr-x (- x sqr#))
(sqr-y (- y sqr#))
(sqr-side (square-side sqr# size)))
(cond
((and (zero? sqr-x) (< sqr-y (1- sqr-side))) ; left part
sqr-y)
((and (eq? sqr-y (1- sqr-side)) (< sqr-x (1- sqr-side))) ; bottom
(+ (1- sqr-side) sqr-x))
((and (not (eq? sqr-y 0)) (eq? sqr-x (1- sqr-side))) ; right
(+ (* 2 (1- sqr-side)) (- sqr-side sqr-y 1)))
(else ; top
(+ (* 3 (1- sqr-side)) (- sqr-side sqr-x 1)))))))
; returns the spiral value at the given position
(define spiral-value
(λ (x y size)
(+ (square-1st-val (square# x y size) size)
(position-on-square x y size))))
; pads a string with char
(define left-pad
(λ (str char width)
(cond
((< (string-length str) width)
(left-pad (string-append (string char) str) char width))
(else
str))))
; draws a spiral!
(define draw-spiral
(λ (size)
(let ((x 0)
(y 0)
(width (log10 (* size size))))
(letrec ((draw
(λ ()
(printf "~a " (left-pad (number->string (spiral-value x y size)) #\0 width))
(cond
((and (eq? x (1- size)) (eq? y (1- size)))
(printf "~n~n"))
((eq? x (1- size))
(set! x 0)
(set! y (1+ y))
(printf "~n")
(draw))
(else
(set! x (1+ x))
(draw))))))
(draw)))))
이것으로 테스트
(draw-spiral 1)
(draw-spiral 2)
(draw-spiral 3)
(draw-spiral 4)
(draw-spiral 5)
(draw-spiral 15)
(draw-spiral 16)
출력 결과
1
1 4
2 3
1 8 7
2 9 6
3 4 5
01 12 11 10
02 13 16 09
03 14 15 08
04 05 06 07
01 16 15 14 13
02 17 24 23 12
03 18 25 22 11
04 19 20 21 10
05 06 07 08 09
001 056 055 054 053 052 051 050 049 048 047 046 045 044 043
002 057 104 103 102 101 100 099 098 097 096 095 094 093 042
003 058 105 144 143 142 141 140 139 138 137 136 135 092 041
004 059 106 145 176 175 174 173 172 171 170 169 134 091 040
005 060 107 146 177 200 199 198 197 196 195 168 133 090 039
006 061 108 147 178 201 216 215 214 213 194 167 132 089 038
007 062 109 148 179 202 217 224 223 212 193 166 131 088 037
008 063 110 149 180 203 218 225 222 211 192 165 130 087 036
009 064 111 150 181 204 219 220 221 210 191 164 129 086 035
010 065 112 151 182 205 206 207 208 209 190 163 128 085 034
011 066 113 152 183 184 185 186 187 188 189 162 127 084 033
012 067 114 153 154 155 156 157 158 159 160 161 126 083 032
013 068 115 116 117 118 119 120 121 122 123 124 125 082 031
014 069 070 071 072 073 074 075 076 077 078 079 080 081 030
015 016 017 018 019 020 021 022 023 024 025 026 027 028 029
001 060 059 058 057 056 055 054 053 052 051 050 049 048 047 046
002 061 112 111 110 109 108 107 106 105 104 103 102 101 100 045
003 062 113 156 155 154 153 152 151 150 149 148 147 146 099 044
004 063 114 157 192 191 190 189 188 187 186 185 184 145 098 043
005 064 115 158 193 220 219 218 217 216 215 214 183 144 097 042
006 065 116 159 194 221 240 239 238 237 236 213 182 143 096 041
007 066 117 160 195 222 241 252 251 250 235 212 181 142 095 040
008 067 118 161 196 223 242 253 256 249 234 211 180 141 094 039
009 068 119 162 197 224 243 254 255 248 233 210 179 140 093 038
010 069 120 163 198 225 244 245 246 247 232 209 178 139 092 037
011 070 121 164 199 226 227 228 229 230 231 208 177 138 091 036
012 071 122 165 200 201 202 203 204 205 206 207 176 137 090 035
013 072 123 166 167 168 169 170 171 172 173 174 175 136 089 034
014 073 124 125 126 127 128 129 130 131 132 133 134 135 088 033
015 074 075 076 077 078 079 080 081 082 083 084 085 086 087 032
016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031
전체 나선형이 필요한 경우 사전 계산 된 행렬에 비해 CPU 사용량이 많지만 유용 할 수 있습니다. 누가 알아! 예 :
(spiral-value 1234567 7654321 234567890) -> 1152262488724319
골프를 치지 않았어요 ... 외관에도 불구하고 아주 작습니다. 나는 긴 이름과 의견을 사용했다.
from collections import namedtuple
Crd = namedtuple('Crd',['row','col','val'])
C1 = Crd(1,1,1)
def add(c1, c2):
return Crd(c1.row + c2.row, c1.col + c2.col, c1.val + c2.val)
def deltas(l):
for i in xrange(1,l): yield Crd(0,1,1)
for i in xrange(1,l): yield Crd(1,0,1)
for i in xrange(1,l): yield Crd(0,-1,1)
for i in xrange(1,l-1): yield Crd(-1,0,1)
def ring(c, l):
yield c
for d in deltas(l):
c = add(c, d)
yield c
def spiral(n):
cur = C1
while n > 0:
for c in ring(cur, n):
yield c
cur = c
cur = add(cur, Crd(0,1,1))
n -= 2
n = input()
fmt = '%' + str(len(str(long(n*n)))) + 'd'
crds = sorted(list(spiral(n)))
for r in xrange(1,n+1):
print ' '.join([fmt % c.val for c in crds if c.row == r])
몇 년 전 제 친구가 인터뷰에서이 질문을 받았습니다. 그들은 우리 가족의 추수 감사절 저녁 식사 에 대해 그것에 대해 이야기 했으므로 나는 이것을 "감사하는 문제"라고 생각합니다.
나선을 통해 인덱스를 걷는 배열을 만듭니다. 그런 다음 결과를 인쇄합니다.
// 1) input squared -> 2) string length -> 3) $e = length of maximum number
for($e=strlen($argn**2);
// 4) decrement input (line length) every second iteration; 5) loop while input>0
$argn-=$i%2;
// 24) post-increment iteration counter $i
$i++)
// 6,7,8) loop through current line
for($p=$argn;$p--;)$r
// 9) $i=$i modulo 4; 10,11) (1-$i)%2 == [1,0,-1,0][$i] -> 12) increment/decrement $y coordinate3
[$y+=(1-$i%=4)%2]
// 13,14) (2-$i)%2 == [0,1,0,-1][$i] -> 15) increment/decrement $x coordinate
[$x+=(2-$i)%2]
// 16) print formatted to string; 17) assign to field [$y,$x] in $r
=sprintf("%0{$e}d ",++$n);
// 18) pre-increment row counter $z; 19) loop while row exists
for(;$r[++$z];
// 21) join row; 22) append newline; 23) print
print join($r[$z])."\n")
// 20) sort row by indexes
ksort($r[$z]);
파이프로 실행 -nR
하거나 온라인으로 사용해보십시오 .
5 바이트를 절약하기 위해 하나의 할당을 추가합니다 : 최종 루프를
for(;$s=$r[++$z];print join($s)."\n")ksort($s);
샘플 코드 : 4x5에서는 작동하지만 3x5에서는 실패
while (k <m && l <n) {/ * 나머지 행에서 첫 번째 행을 인쇄 * / for (i = l; i <n; ++ i) {printf ( "% d", a [k] [ 나는]); } k ++;
/* Print the last column from the remaining columns */
for (i = k; i < m; ++i)
{
printf("%d ", a[i][n-1]);
}
n--;
/* Print the last row from the remaining rows */
if ( k < m)
{
for (i = n-1; i >= l; --i)
{
printf("%d ", a[m-1][i]);
}
m--;
}
/* Print the first column from the remaining columns */
if (l < n)
{
for (i = m-1; i >= k; --i)
{
printf("%d ", a[i][l]);
}
l++;
}
}