문제는 다음과 같다:
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
391개의 풀이가 있습니다.
X,Y = map(int,raw_input().split(' '))
lis = [[-1 for i in xrange(Y)] for j in xrange(X)]
x,y = 0,0
dx,dy = 0,1
count = 0
while lis[x][y] == -1:
lis[x][y] = count
count+=1
x,y = x+dx,y+dy
if x in [-1,X] or y in [-1,Y] or lis[x][y] != -1:
x,y = x-dx,y-dy
dx,dy = dy,-dx
x,y = x+dx,y+dy
for L in lis:
for val in L:
print '%3d'%val,
print
되도록이면 if문이나 좌표값을 쓰지 않도록 노력했습니다.
from itertools import cycle
def spiral(m, n):
"""나선형 매트릭스를 일차원 배열형태로 반환
>>>spiral(3, 3) #3x3
[0, 1, 2, 7, 8, 3, 6, 5, 4]
#[0, 1, 2,
# 7, 8, 3,
# 6, 5, 4]
"""
size = m * n
matrix = [''] * size #['', '', '', ... '']
matrix[:m] = list(range(m)) #m=3인경우 [0, 1, 2, '', '', ... ]
idx = m - 1; s = idx; p = idx
pattern = [m, -1, -m, 1] #아래, 왼쪽, 위, 오른쪽
for pat in cycle(pattern): #패턴을 반복
while True:
p += pat; s += 1
if p < size and matrix[p] == '': #size를 넘지않고, 값이 비어있는경우
matrix[p] = s
else:
p -= pat; s -= 1 #복원
break #다음 패턴으로
if '' not in matrix: #모두 숫자로 채워지면
return matrix
def main(m, n):
for i, a in enumerate(spiral(m, n), 1):
print('{:2d}'.format(a), end=' ')
if i % m == 0:
print()
main(6, 6)
# 0 1 2 3 4 5
#19 20 21 22 23 6
#18 31 32 33 24 7
#17 30 35 34 25 8
#16 29 28 27 26 9
#15 14 13 12 11 10
'''
3x3의 나선형 매트릭스 모양은,
0 1 2
7 8 3
6 5 4
위와 같다. 이것을 2차원 리스트로 표현하면,
[ [0, 1, 2],
[7, 8, 3],
[6, 5, 4] ]
위와 같다. 반면 일차원 리스트로 펼쳐보면,
인덱스: 0 1 2 3 4 5 6 7 8
리스트: [0, 1, 2, 7, 8, 3, 6, 5, 4]
위와 같다. 리스트의 값 순서대로 인덱스를 정렬해보면,
인덱스: 0 1 2 5 8 7 6 3 4
리스트: [0, 1, 2, 3, 4, 5, 6, 7, 8] 이다.
0, 1, 2를 제외한 나머지의 인덱스 패턴을 보면,
(나선형 매트릭스는 오른쪽, 아래, 왼쪽, 위, 오른쪽, ... 주기가 있다)
2 5 (+3) 아래
5 8 (+3) 아래
8 7 (-1) 왼쪽
7 6 (-1) 왼쪽
6 3 (-3) 위
3 4 (+1) 오른쪽
위를 토대로 spiral(3, 3)이 그리는 상황을 따라가보면,
['', '', '', '', '', '', '', '', ''] #matrix = [''] * size
[0, 1, 2, '', '' ,'', '', '', ''] #matrix[:m] = list(range(m))
[0, 1, 2, '', '', 3, '', '', ''] #pattern +3
[0, 1, 2, '', '', 3, '', '', 4] #pattern +3
[0, 1, 2, '', '', 3, '', 5, 4] #pattern -1
[0, 1, 2, '', '', 3, 6, 5, 4] #pattern -1
[0, 1, 2, 7, '', 3, 6, 5, 4] #pattern -3
[0, 1, 2, 7, 8, 3, 6, 5, 4] #pattern +1
'''
w, h = map(int,input().split())
t = eval(repr([[0]*h]*w))
ds = [[1,0],[0,1],[-1,0],[0,-1]]
e=x=y=d=0
for i in range(w*h):
t[x][y] = i
if x+ds[d][0] in [e-1-(1 if d==3 else 0),w-e] or y+ds[d][1] in [e-1,h-e]:
d = (d+1)%4
e += d//3
x, y = map(sum,zip(ds[d],[x,y]))
for i in range(w*h):
print(("%%%dd" % (len(str(w*h-1))+1)) % t[i%w][i//w], end=('\n' if i%w==w-1 else ''))
22 47 입력시
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 22
132 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 154 23
131 258 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 278 155 24
130 257 376 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 394 279 156 25
129 256 375 486 589 590 591 592 593 594 595 596 597 598 599 600 601 502 395 280 157 26
128 255 374 485 588 683 684 685 686 687 688 689 690 691 692 693 602 503 396 281 158 27
127 254 373 484 587 682 769 770 771 772 773 774 775 776 777 694 603 504 397 282 159 28
126 253 372 483 586 681 768 847 848 849 850 851 852 853 778 695 604 505 398 283 160 29
125 252 371 482 585 680 767 846 917 918 919 920 921 854 779 696 605 506 399 284 161 30
124 251 370 481 584 679 766 845 916 979 980 981 922 855 780 697 606 507 400 285 162 31
123 250 369 480 583 678 765 844 915 978 1033 982 923 856 781 698 607 508 401 286 163 32
122 249 368 479 582 677 764 843 914 977 1032 983 924 857 782 699 608 509 402 287 164 33
121 248 367 478 581 676 763 842 913 976 1031 984 925 858 783 700 609 510 403 288 165 34
120 247 366 477 580 675 762 841 912 975 1030 985 926 859 784 701 610 511 404 289 166 35
119 246 365 476 579 674 761 840 911 974 1029 986 927 860 785 702 611 512 405 290 167 36
118 245 364 475 578 673 760 839 910 973 1028 987 928 861 786 703 612 513 406 291 168 37
117 244 363 474 577 672 759 838 909 972 1027 988 929 862 787 704 613 514 407 292 169 38
116 243 362 473 576 671 758 837 908 971 1026 989 930 863 788 705 614 515 408 293 170 39
115 242 361 472 575 670 757 836 907 970 1025 990 931 864 789 706 615 516 409 294 171 40
114 241 360 471 574 669 756 835 906 969 1024 991 932 865 790 707 616 517 410 295 172 41
113 240 359 470 573 668 755 834 905 968 1023 992 933 866 791 708 617 518 411 296 173 42
112 239 358 469 572 667 754 833 904 967 1022 993 934 867 792 709 618 519 412 297 174 43
111 238 357 468 571 666 753 832 903 966 1021 994 935 868 793 710 619 520 413 298 175 44
110 237 356 467 570 665 752 831 902 965 1020 995 936 869 794 711 620 521 414 299 176 45
109 236 355 466 569 664 751 830 901 964 1019 996 937 870 795 712 621 522 415 300 177 46
108 235 354 465 568 663 750 829 900 963 1018 997 938 871 796 713 622 523 416 301 178 47
107 234 353 464 567 662 749 828 899 962 1017 998 939 872 797 714 623 524 417 302 179 48
106 233 352 463 566 661 748 827 898 961 1016 999 940 873 798 715 624 525 418 303 180 49
105 232 351 462 565 660 747 826 897 960 1015 1000 941 874 799 716 625 526 419 304 181 50
104 231 350 461 564 659 746 825 896 959 1014 1001 942 875 800 717 626 527 420 305 182 51
103 230 349 460 563 658 745 824 895 958 1013 1002 943 876 801 718 627 528 421 306 183 52
102 229 348 459 562 657 744 823 894 957 1012 1003 944 877 802 719 628 529 422 307 184 53
101 228 347 458 561 656 743 822 893 956 1011 1004 945 878 803 720 629 530 423 308 185 54
100 227 346 457 560 655 742 821 892 955 1010 1005 946 879 804 721 630 531 424 309 186 55
99 226 345 456 559 654 741 820 891 954 1009 1006 947 880 805 722 631 532 425 310 187 56
98 225 344 455 558 653 740 819 890 953 1008 1007 948 881 806 723 632 533 426 311 188 57
97 224 343 454 557 652 739 818 889 952 951 950 949 882 807 724 633 534 427 312 189 58
96 223 342 453 556 651 738 817 888 887 886 885 884 883 808 725 634 535 428 313 190 59
95 222 341 452 555 650 737 816 815 814 813 812 811 810 809 726 635 536 429 314 191 60
94 221 340 451 554 649 736 735 734 733 732 731 730 729 728 727 636 537 430 315 192 61
93 220 339 450 553 648 647 646 645 644 643 642 641 640 639 638 637 538 431 316 193 62
92 219 338 449 552 551 550 549 548 547 546 545 544 543 542 541 540 539 432 317 194 63
91 218 337 448 447 446 445 444 443 442 441 440 439 438 437 436 435 434 433 318 195 64
90 217 336 335 334 333 332 331 330 329 328 327 326 325 324 323 322 321 320 319 196 65
89 216 215 214 213 212 211 210 209 208 207 206 205 204 203 202 201 200 199 198 197 66
88 87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67
JAVA
공부 열심히 해야겠습니다.
import java.util.Scanner;
public class go {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
System.out.print("숫자를 입력하세요 ex) 6 6 : ");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
spiralArray(num1, num2);
}
public static void spiralArray(int x, int y) {
int[][] copy = new int[x][y];
int count = 0; // 0 ~ x*y-1 값
int flag = 0; // 진행방향
int i = 0, j = 0;
while (true) {
switch (flag) { // 진행방향 ->
case 0: // 방에 값을 넣고 1 증가 시킴
copy[i][j++] = count++; // 다음 방향으로 한칸 이동
if (j == y || copy[i][j] != 0) { // 이동한 방에 값이 있거나 방이 없으면
j--; // 이전 방으로 돌아온다
i++; // 다음 진행할 방향으로 한칸이동
flag = 1; // 진행방향 설정
}
break;
case 1: // 진행방향 ↓
copy[i++][j] = count++;
if (i == x || copy[i][j] != 0) {
i--;
j--;
flag = 2;
}
break;
case 2: // 진행방향 <-
copy[i][j--] = count++;
if (j == -1 || copy[i][j] != 0) {
i--;
j++;
flag = 3;
}
break;
case 3: // 진행방향 ↑
copy[i--][j] = count++;
if (i == 0 || copy[i][j] != 0) {
i++;
j++;
flag = 0;
}
break;
}
if (count == x * y) // 모든방에 값이 들어가면 나가기
break;
}
for (i = 0; i < x; i++) {
for (j = 0; j < y; j++) {
System.out.print(copy[i][j] + "\t");
}
System.out.println();
}
}
}
결과 값
숫자를 입력하세요 ex) 6 6 : 6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
Python 3.7.4 Best Practice 참고
X, Y = map(int, input("행열 숫자를 입력하세요: ").split(','))
table = [[-1 for _ in range(Y)] for _ in range(X)]
x, y = 0, 0
dx, dy = 0, 1
count = 0
while table[x][y] == -1:
table[x][y] = count
count += 1
x, y = x+dx, y+dy
if x == X or y == Y or table[x][y] !=-1:
x, y = x-dx, y-dy
dx, dy = dy, -dx
x, y = x+dx, y+dy
for i in table:
for j in i:
print (f'{j:3d}', end=' ')
print ()
public enum Direction { // 방향을 나타내는 enum입니다~
RIGHT(1), BOTTOM(2), LEFT(3), TOP(4);
private int value;
private Direction(int value) {
this.value = value;
}
}
public class Sprial {
public void sprialArray(int row, int col) {
int[][] arr = new int[row][col];
// -1로 초기화
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
arr[i][j] = -1;
}
}
int num = 0; // 시작 숫자
int rIdx = 0, cIdx = 0; // row, col에 대한 index
Direction direction = Direction.RIGHT;
while( num < row * col ) {
arr[rIdx][cIdx] = num++;
switch ( direction ) {
case RIGHT:
if( cIdx+1<col && arr[rIdx][cIdx+1] == -1 ){
cIdx++;
}else {
direction = Direction.BOTTOM;
rIdx++;
}
break;
case BOTTOM:
if( rIdx+1<row && arr[rIdx+1][cIdx] == -1 ){
rIdx++;
}else {
direction = Direction.LEFT;
cIdx--;
}
break;
case LEFT:
if( cIdx-1>=0 && arr[rIdx][cIdx-1] == -1 ){
cIdx--;
}else {
direction = Direction.TOP;
rIdx--;
}
break;
case TOP:
if( rIdx-1>=0 && arr[rIdx-1][cIdx] == -1 ){
rIdx--;
}else {
direction = Direction.RIGHT;
cIdx++;
}
break;
default:
break;
}
}
}
}
~_~ 전 이 문제 푸는데 되게 오래 걸렸어요.. 내공이 많이 부족함을 느낍니다 ㅠㅠ 분명 예~전에 처음 플그래밍 배울때 봤던 문제였떤 것 같은데, 그때 어렵다고 패스했던 것을 다시 공부하지 않은 탓인것 같네요..ㅜ
python
class Cursor:
D = {
"right":(0,1),
"left":(0,-1),
"up":(-1,0),
"down":(1,0),
}
def __init__(self, row, col, direction):
self.row = row
self.col = col
self.direction = direction
def next(self):
adder = self.D[self.direction]
nr = self.row + adder[0]
nc = self.col + adder[1]
return Cursor(nr, nc, self.direction)
def rotate(self):
r = {
"right":"down",
"down":"left",
"left":"up",
"up":"right",
}
self.direction = r[self.direction]
class Map:
def __init__(self, row_count, col_count):
self.row_count = row_count
self.col_count = col_count
self.m = [[None for c in range(self.col_count)]
for r in range(self.row_count)]
cursor = Cursor(0,0, "right")
self.mark(cursor, 0)
for i in range(1, self.row_count * self.col_count):
next_cursor = cursor.next()
if self.edge(next_cursor):
cursor.rotate()
cursor = cursor.next()
else:
cursor = next_cursor
self.mark(cursor, i)
def mark(self, cursor, v):
self.m[cursor.row][cursor.col] = v
def edge(self, pos):
if pos.col < 0: return True
if pos.row < 0: return True
if pos.col >= self.col_count: return True
if pos.row >= self.row_count: return True
isMark = self.m[pos.row][pos.col] != None
if isMark: return True
return False
m = Map(6, 6)
for row in m.m: print row
4일이나 걸렸어요... 매일 2시간씩 해서 했는데
이 코드는 아무래도 if문이 너무 많아서 반복문내에서 매 번 if문을 하나하나 다 검사한다는게
썩 좋진 않아보이네요. 실행속도가 현저히 느릴거 같아요... 그래도 완성해서 매우 기쁩니다!
/*
입력: 6 6
출력:
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6 이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/
import java.util.Arrays;
import java.util.Scanner;
public class Spiral_Array
{
public static void main(String[] args)
{
// 출력될 숫자
int output_Number=0;
// 값을 두 개 입력받습니다.
Scanner in = new Scanner(System.in);
int n1 = in.nextInt();
int n2 = in.nextInt();
// 숫자가 들어갈 매트릭스를 생성합니다.
int[][] Matrix = new int[n1][n2];
// 배열 값들을 다 -1로 초기화 (2D)
for (int[] row: Matrix)
Arrays.fill(row, -1);
//위치 선택용 변수
int col=0, row=0, t_col=0, t_row=1, angle = 0;
// row가 늘고 col가 늘고 row가 줄고 col가 줄고 row가 늘고 col가 늘고 ... 계속 반복함
for(int i=0; i<(n1*n2); i++)
{
Matrix[col][row]=output_Number;
output_Number++;
row = row + t_row;
col = col + t_col;
if(row==n2){ // 1번째 코너
row--;
col++;
t_col = t_row;
t_row = 0;
}
if(col==n1){ // 2번째 코너
col--;
row--;
t_row = -t_col;
t_col = 0;
}
if(row<0){ // 3번째 코너
row++;
col--;
t_col = t_row;
t_row = 0;
}
if(Matrix[col][row] != -1) // 다른 수가 있다면(3번째 이후 모서리 봉착)
{
angle++;
if(angle == 1)// ┌자 구간에 진입했을때
{
row++;
col++;
t_col = 0;
t_row = 1;
}
else if(angle == 2) // ┐자 구간에 진입했을때
{
col++;
row--;
t_col = 1;
t_row = 0;
}
else if(angle == 3) // ┘자 구간에 진입했을때
{
col--;
row--;
t_col = 0;
t_row = -1;
}
else if(angle == 4) // └자 구간에 진입했을때
{
col--;
row++;
t_col = -1;
t_row = 0;
angle = 0; // 다시 초기화
}
}
}
// 출력
for(int a=0; a<n1; a++){
for(int b=0; b<n2; b++){
System.out.print(Matrix[a][b] + "\t");
}
System.out.println();
}
} // main
} // class
우선탐색을 하게하여 길을 찾게 하였습니다.
Sub Main()
'// 입력
Dim input() As String = Console.ReadLine.Split(" ")
Dim x As Integer = 0, y As Integer = 0
Dim width As Integer = CInt(input(0)), height As Integer = CInt(input(1))
Dim map(width - 1, height - 1) As Integer
Dim cnt As Integer = 0, isUp As Boolean = False
Do
cnt += 1
If x + 1 < width AndAlso map(x + 1, y) = 0 And Not isUp Then map(x + 1, y) = cnt : x += 1 : isUp = False : Continue Do
If y + 1 < height AndAlso map(x, y + 1) = 0 Then map(x, y + 1) = cnt : y += 1 : isUp = False : Continue Do
If x - 1 >= 0 AndAlso map(x - 1, y) = 0 Then map(x - 1, y) = cnt : x -= 1 : isUp = False : Continue Do
If y - 1 >= 0 AndAlso map(x, y - 1) = 0 AndAlso x + y - 1 > 0 Then : map(x, y - 1) = cnt : y -= 1 : isUp = True : Continue Do : ElseIf cnt < width * height Then : isUp = False : cnt -= 1 : Continue Do : End If
Exit Do
Loop
'// 출력
For yy As Integer = 0 To width - 1
For xx As Integer = 0 To height - 1
Console.Write(map(xx, yy) & vbTab)
Next
Console.WriteLine()
Next
Console.ReadLine()
End Sub
파이선으로 변수선언 말고는 한줄코드 추가합니다.
w = 6
h = 9
Margin = lambda x, half: half - abs(half - x - 0.5) - 0.5
MinMargin = lambda x, y: min(Margin(x, w / 2.0), Margin(y, h / 2.0))
StartBase = lambda x: (w * h) - ((w - x * 2) * (h - x * 2))
Offset1 = lambda x, y, m:(x - m, y - m, w - m * 2, h - m * 2)
Offset2 = lambda x: x[0] + x[1] if x[1] == 0 or x[0] == (x[2] - 1) else (x[2] * 2 + x[3] * 2 - 4) - (x[0] + x[1])
print '\n'.join([''.join(['%4d' % m for m in [Offset2(Offset1(x, y, MinMargin(x, y))) + StartBase(MinMargin(x, y)) for y in range(h) for x in range(w)][n * w : (n + 1) * w]]) for n in range(h)])
python 2.7.6
저장하지않고 자리에 맞는 숫자를 한번에 출력합니다.
#include <algorithm>
#include <iomanip>
int _tmain(int argc, _TCHAR* argv[])
{
int iWidth = 6;
int iHeight = 9;
for (int ixPosY = 0; ixPosY < iHeight; ++ixPosY)
{
for (int ixPosX = 0; ixPosX < iWidth; ++ixPosX)
{
int iMinMargin = std::min(std::min(ixPosY, (iWidth - 1) - ixPosX), std::min((iHeight - 1) - ixPosY, ixPosX));
int iInnerBoxIndex = iWidth * iHeight - ((iWidth - iMinMargin * 2) * (iHeight - iMinMargin * 2));
int iInnerBoxWidth = iWidth - iMinMargin * 2;
int iInnerBoxHeight = iHeight - iMinMargin * 2;
int iNowNumber = 0;
if (ixPosY == iMinMargin || ixPosX == (iInnerBoxWidth - 1) + iMinMargin)
{
iNowNumber = iInnerBoxIndex + ixPosX + ixPosY - iMinMargin * 2;
}
else
{
iNowNumber = iInnerBoxIndex + iInnerBoxWidth * 2 + iInnerBoxHeight * 2 - 4 - (ixPosX + ixPosY - iMinMargin * 2);
}
std::cout << std::setw(4) << iNowNumber;
}
std::cout << std::endl;
}
system("pause");
return 0;
}
/*
문제는 다음과 같다:
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Prob266
{
class Program
{
static void Main(string[] args)
{
string[] tmp = Console.ReadLine().Split(' ');
int a = int.Parse(tmp[0]), b = int.Parse(tmp[1]);
int cnt = 0; // 숫자 카운팅
int delta = 1; // 방향
int len = a; // 반복문 돌릴때 필요한 수
int x = 0, y = -1;
int[,] map = new int[a, b];
while (true)
{
// 가로
for (int p = 0; p < len; p++)
{
y += delta;
map[x, y] = cnt;
cnt++;
}
// 횟수 줄이고
len--;
// 0 보다 작으면 종료
if (len < 0)
{
break;
}
// 세로
for (int p = 0; p < len; p++)
{
x += delta;
map[x, y] = cnt;
cnt++;
}
// 이동방향 바꾸기
delta = -delta;
}
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
Console.Write("{0}\t", map[i, j]);
}
Console.WriteLine();
}
}
}
}
#include <iostream>
using namespace std;
void getInput(int ** arr, int row, int column);
int main() {
int row=0, column=0;
cin >> row >> column;
int ** arr = new int *[row];
for(int i=0; i<row; i++) {
arr[i] = new int [column];
}
getInput(arr, row, column);
for(int i=0; i<row; i++) {
for(int j=0; j<column; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
void getInput(int ** arr, int row, int column) {
int inputValue =-1;
int start_i = 0, start_j = 0;
int last_i = row-1, last_j = column-1;
int finalValue = (row*column)-1;
while(inputValue!=finalValue){
for(int j=start_j; j<=last_j; j++) {
inputValue+=1;
arr[start_i][j] = inputValue;
}
if(inputValue==finalValue) break;
for(int i=start_i+1; i<=last_i; i++) {
inputValue+=1;
arr[i][last_j] = inputValue;
}
if(inputValue==finalValue) break;
for(int j=last_j-1; j>=start_j; j--) {
inputValue+=1;
arr[last_i][j] = inputValue;
}
if(inputValue==finalValue) break;
for(int i=last_i-1; i>=start_i+1; i--) {
inputValue+=1;
arr[i][start_j] = inputValue;
}
if(inputValue==finalValue) break;
start_i+=1; start_j+=1; last_i-=1; last_j-=1;
}
}
#include<stdio.h>
int main(){
int x=100, y=90, x_=0, y_=0;
// x, y : 사용자 입력(행,렬)
// x_,y_ 결과표시를 위한 임시저장 변수
int a=0, b=0, c=0, i=0, j=0;
// a, b : 각각 행,열 좌표조정을 위한 변수
// c : 테두리 직선의 count 수
// i, j : 반복문을 위한 임시변수
int current = 0; // 대입할 값
int **arr;
scanf("%d %d", &x, &y);
x_ = x;
y_ = y;
arr = (int**) malloc (sizeof(int*)*x);
for(i=0; i<x; i++) arr[i]=(int*)malloc(sizeof(int)*y);
// a, b의 증가또는 감소로 arr의 인덱스(좌표 a,b) 방향을 조절하고
// 하나의 라인이 끝날 때마다 x_, y_ 값을 점점 줄여나가면서
// 나선방향으로 차례대로 값을 대입한다.
for(c=1; current<x*y; c++){
int temp = (c/2)%2;
// temp : arr의 인덱스를 표시하는 a 또는 b의 증감(방향)을 판별하기위한 변수
// 행의 경우 temp의 값이 1인경우 a가 증가하는방향, 아닌경우 감소하는 방향
// 열의 경우 temp의 값이 0인경우 b가 증가하는방향, 아닌경우 감소하는 방향
// 행, 열, 행, 열 순서대로 대입하므로
// 하나의 라인을 count하는 c가 홀수인경우 열, 짝수인경우 행
if(c%2 == 1){ // 열
for(i=0; i<y_; i++){
if(i != 0){
if(temp == 0) b++;
else b--;
}
//printf("(%d, %d) = %d\n", a, b, current);
arr[a][b] = current;
current++;
}
y_--;
}
else{ // 행
for(i=0; i<x_-1; i++){
if(temp == 1) a++;
else a--;
//printf("(%d, %d) = %d\n", a, b, current);
arr[a][b] = current;
current++;
}
if(temp == 0) b++;
else b--;
x_--;
}
}
for(i=0; i<x; i++){
for(j=0; j<y; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
return 0;
}
C언어로 작성. 풀이방법은 주석참고.
X,Y = 10,6
# 초기화
go = 1
x,y = 0,0
min_x, min_y, max_x, max_y = 0 , 0, X-1, Y-1
result = [[-1 for i in range(0,X)] for j in range(0,Y)]
for i in range(0,X*Y):
result[y][x] = i
# 방향 지정
if x == max_x and go == 1 :
go = 2
elif y == max_y and go == 2 :
go = 3
elif x == min_x and go == 3:
go = 4
# 증가 범위 재설정
min_y += 1
min_x += 1
max_x -= 1
max_y -= 1
elif y == min_y and go == 4:
go = 1
# 배열위치값 증감
if go == 1:
x += 1
elif go == 2:
y += 1
elif go == 3:
x -= 1
elif go == 4:
y -= 1
# 출력
for row in result:
for chk in row:
print '%3d'%chk,
print
초기화와 출력은 다른분 소스를 참고하고 스파이럴 배열 입력부분은 각 끝자리의 위치값을 셋팅하고 한바퀴돌때마다 끝자리 위치값이 하나씩 줄어들면 가능하다고 보고 구현
a1 = int(input("a1 입력 : "))
a2 = int(input("a2 입력 : "))
b = [[0 for i in range(a1)] for j in range(a2)]
num = 0
a1count = 0
a2count = 1
turn = 0
for turn in range((a1+a2)):
for i in range(a1 - a1count):
if a1 >= a1count:
b[turn][i+turn] = num
num += 1
a1count += 1
for i in range(a2 - a2count):
if a2 >= a2count:
b[i+(turn + 1)][a1 - (turn + 1)] = num
num += 1
a2count += 1
for i in range(a1 - a1count):
if a1 >= a1count:
b[a2 - (turn + 1)][a1 - (turn + 2) - i] = num
num += 1
a1count += 1
for i in range(a2 - a2count):
if a2 >= a2count:
b[a2 - (turn + 2)-i][turn] = num
num += 1
a2count += 1
sqrts = len(str(num))
for i in range(a2):
for j in range(a1):
print(("%0" + str(len(str(num))) + "d ") % b[i][j],end = '')
if j == a1-1:
print()
b[0][0]부터 시작해서 수동으로 그려보고, 규칙성을 찾아 일반화시켰습니다.
h, w = map(int,input().split())
board = [[-1 for j in range(w)] for i in range(h)]
board[0][0] = 0
s = [0, 0]
n, dr = 1, 1
while n < h*w:
s[0] += -2*(dr//2)-(dr%2)+2*(dr//2)*(dr%2)+1
s[1] += (dr%2)-2*(dr//2)*(dr%2)
board[s[0]][s[1]] = n
n += 1
try:
if board[s[0]-2*(dr//2)-(dr%2)+2*(dr//2)*(dr%2)+1][s[1]+(dr%2)-2*(dr//2)*(dr%2)] >= 0:
dr = (dr-1)%4
except:
dr = (dr-1)%4
for i in range(h):
for j in range(w):
print(f'{board[i][j]:3}',end=' ')
print()
18 18
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 18
66 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 84 19
65 126 179 180 181 182 183 184 185 186 187 188 189 190 191 142 85 20
64 125 178 223 224 225 226 227 228 229 230 231 232 233 192 143 86 21
63 124 177 222 259 260 261 262 263 264 265 266 267 234 193 144 87 22
62 123 176 221 258 287 288 289 290 291 292 293 268 235 194 145 88 23
61 122 175 220 257 286 307 308 309 310 311 294 269 236 195 146 89 24
60 121 174 219 256 285 306 319 320 321 312 295 270 237 196 147 90 25
59 120 173 218 255 284 305 318 323 322 313 296 271 238 197 148 91 26
58 119 172 217 254 283 304 317 316 315 314 297 272 239 198 149 92 27
57 118 171 216 253 282 303 302 301 300 299 298 273 240 199 150 93 28
56 117 170 215 252 281 280 279 278 277 276 275 274 241 200 151 94 29
55 116 169 214 251 250 249 248 247 246 245 244 243 242 201 152 95 30
54 115 168 213 212 211 210 209 208 207 206 205 204 203 202 153 96 31
53 114 167 166 165 164 163 162 161 160 159 158 157 156 155 154 97 32
52 113 112 111 110 109 108 107 106 105 104 103 102 101 100 99 98 33
51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34
음.. 아이디어가 없어서 최대한 이해하기 쉽게 했는데, 저장공간이 필요해서 에러네요.
오늘 처음 온 곳인데, 깔끔하고 좋습니다. 많이 활성화 되었으면 좋겠습니다.
using namespace std;
int main(int argc, char *argv[])
{
int w = 0;
int h = 6;
cout << "width: ";
cin >> w;
cout << "height: ";
cin >> h;
int **arr = new int *[w];
for(int i = 0; i < w; i++)
{
arr[i] = new int[h];
}
for(int round = 0, i = 0; i < w * h; round++)
{
// top
for(int x = round; x < w - round && i < w * h; x++)
{
arr[x][round] = i;
i++;
}
// right
for(int y = round + 1; y < h - round && i < w * h; y++)
{
arr[w - round - 1][y] = i;
i++;
}
// bottom
for(int x = w - round - 2; x >= round && i < w * h; x--)
{
arr[x][h - round - 1] = i;
i++;
}
// left
for(int y = h - round - 2; y > round && i < w * h; y--)
{
arr[round][y] = i;
i++;
}
}
for(int y = 0; y < h; y++)
{
for(int x = 0; x < w; x++)
{
printf("%3d ", arr[x][y]);
}
cout << endl;
}
for(int i = 0; i < w; i++)
delete[] arr[i];
delete[] arr;
return 0;
}
안녕하세요. C로 짰는데 언어선택에 C가 없어서 C++로 선택했습니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Given a 2-dimensional array, make it a spiral array.
* Spiral array is like below.
* 0 1 2 3 4 5
* 19 20 21 22 23 6
* 18 31 32 33 24 7
* 17 30 35 34 25 8
* 16 29 28 27 26 9
* 15 14 13 12 11 10
*
* array: pointer of 2-dimensional array
* row: the number of rows
* col: the number of columns
* start: the start value which is the leftmost-top value of array
*/
void spiral_array(int **array, int row, int col, int start)
{
int i;
int idx = 0;
int val = start;
while (row > 0 && col > 0) {
// left-top to right-top
for (i = idx; i < idx + col; i++) {
array[idx][i] = val++;
}
// right-top to right-bottom
for (i = idx + 1; i < idx + row; i++) {
array[i][idx + col - 1] = val++;
}
// right-bottom to left-bottom
if (row > 1) {
for (i = idx + col - 2; i >= idx; i--) {
array[idx + row - 1][i] = val++;
}
}
// left-bottom to left-top
if (col > 1) {
for (i = idx + row - 2; i > idx; i--) {
array[i][idx] = val++;
}
}
idx++;
row -= 2;
col -= 2;
}
}
/* print matrix(2-dimensional array)
* matrix: pointer of matrix
* row: the number of rows
* col: the number of columns
* space: the minimum number of characters for a value to be printed */
void print_matrix(int **matrix, int row, int col, int space)
{
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%*d ", space, matrix[i][j]);
}
printf("\n");
}
}
int **malloc_2d(int row, int col)
{
int i;
int **p = (int **)malloc(sizeof (int *) * row);
if (p == NULL) return NULL;
for (i = 0; i < row; i++) {
p[i] = (int *)malloc(sizeof (int) * col);
if (p[i] == NULL) {
int j;
for (j = 0; j < i; j++)
free(p[j]);
free(p);
return NULL;
}
}
return p;
}
void free_2d(int **p, int row)
{
int i;
for (i = 0; i < row; i++)
free(p[i]);
free(p);
}
int main(int argc, char *argv[])
{
int row, col;
printf("row: ");
scanf("%d", &row);
printf("col: ");
scanf("%d", &col);
int **mat = malloc_2d(row, col);
spiral_array(mat, row, col, 0);
print_matrix(mat, row, col, 2);
free_2d(mat, row);
return 0;
}
Clojure 로 작성하였습니다.
accumulator 형태의 재귀함수입니다.
(defn spiral
[x y]
(let [vs (range (* x y))
walk {:right [1 0]
:down [0 1]
:left [-1 0]
:up [0 -1]}
turn {:right :down
:down :left
:left :up
:up :right}
vertical? #{:up :down}
table (into
{}
(loop [v (first vs)
vs (rest vs)
loc [0 0]
way :right
to-go (dec x)
cols (dec x)
rows (- y 2)
acc []]
(cond (empty? vs) (conj acc [loc v])
(zero? to-go) (recur (first vs)
(rest vs)
(map + loc (walk (turn way)))
(turn way)
(if (vertical? way) cols rows)
(if (vertical? way) cols (dec cols))
(if (vertical? way) (dec rows) rows)
(conj acc {loc v}))
true (recur (first vs)
(rest vs)
(map + loc (walk way))
way
(dec to-go)
cols
rows
(conj acc [loc v])))))]
(doseq [y (range y)]
(doseq [x (range x)]
(print (format "%4d" (table [x y]))))
(println))))
안녕하세요^^ Java를 배우고 있는 학생입니다. 초보이지만 한번 짜봤어요^^ 좋은 크리틱 해주시면 감사하게 듣겠습니다^^
package h10_spiral_array;
import java.util.Scanner;
public class SpriralArray {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int r1, r2, n, i, j, direction;
r1=in.nextInt(); r2=in.nextInt(); //값 두개 입력받기
int total=r1*r2;
int[][] arr=new int[r1][r2];
boolean[][] check=new boolean[r1][r2];
for(i=0;i<r1;i++) for(j=0;j<r2;j++) check[i][j]=false; //check배열 초기화
n=0; i=0; j=0; direction=0; //direction 방향 0:east, 1:south, 2:west, 3:north
while(n<total){
if(i>=0&&i<r1&&j>=0&&j<r2&& check[i][j]==false){ //값 차례대로 넣기
arr[i][j]=n; check[i][j]=true; n++;
if(direction==0) j++;
else if(direction==1) i++;
else if(direction==2) j--;
else if(direction==3) i--;
}
else{ //한 방향으로 끝까지 갔을 경우 방향 바꾸기
if(direction==0){ direction=1; j--; i++; }
else if(direction==1){ direction=2; i--; j--; }
else if(direction==2){ direction=3; j++; i--; }
else if(direction==3){ direction=0; i++; j++; }
}
}
for(i=0;i<r1;i++){ //값 출력하기. 일단 total이 100미만인 경우만 생각했어요^^
for(j=0;j<r2;j++){
if(arr[i][j]<10) System.out.print(" ");
System.out.print(arr[i][j]+" ");
} System.out.println();
}
}
}
private void test() {
int size = 6;
int[][] arr = new int[size][size];
for(int i=0; i<6; i++) {
for(int k=0; k<6; k++) {
arr[i][k] = -1;
}
}
int m = 1;
int x = 0;
int y = 0;
int n = 0;
while(n<size*size) {
if(x>-1 && x<arr[0].length && y>-1 && y<arr.length && (arr[y][x]== -1)) {
arr[y][x] = n;
n++;
if(1 == m) {//오른쪽
x++;
} else if(2 == m) {//아래
y++;
} else if(3 == m) {//왼쪽
x--;
} else if(4 == m) {//위
y--;
}
} else {
if(1 == m) {
m = 2; x--; y++;
} else if(2 == m) {
m = 3; x--; y--;
} else if(3 == m) {
m = 4; x++; y--;
} else if(4 == m) {
m = 1; x++; y++;
}
}
}
for(int i=0; i<6; ++i) {
String a = "";
for(int k=0; k<6; ++k) {
if(10 > arr[i][k]) {
a += " "+arr[i][k];
} else {
a += " "+arr[i][k];
}
}
LOG.v(" "+a);
}
}
Swift로 문제 풀어봤습니다.
let x = 6
let y = 6
var i:Int = 0
// Row는 사실상 Y, Column은 사실상 X의 역할을 합니다.
var minRow:Int = 0, minColumn:Int = 0
var maxRow:Int = x-1, maxColumn:Int = y-1
var indexRow:Int = 0, indexColumn:Int = 0
// 표시될 방향
var direction = "Right"
// Spiral 배열
var spiralArray = Array<Array<Int>>()
// 배열을 초기화 하는 함수
func initSpiralArray() -> Void
{
for i in 0..x {
var array = Array<Int>()
for j in 0..y {
array.append(0)
}
spiralArray.append(array)
}
}
func nextDirection() -> Void
{
switch direction {
// 방향이 오른쪽일 경우 indexColumn이 증가, 끝일 경우 방향을 아래로 변경하고 indexRow를 증가, minRow도 증가시킵니다.
case "Right":
if indexColumn == maxColumn {
direction = "Down"
indexRow++
minRow++
} else {
indexColumn++
}
// 방향이 왼쪽인 경우 indexColumn을 감소, 끝일 경우 방향을 위로 변경하고 indexRow를 감소, maxRow도 감소시킵니다.
case "Left":
if indexColumn == minColumn {
direction = "Up"
indexRow--
maxRow--
} else {
indexColumn--
}
// 방향이 위쪽인 경우 indexRow를 감소, 끝인 경우 방향을 오른쪽으로 변경하고 indexColumn을 증가, minColumn도 증가시킵니다.
case "Up":
if indexRow == minRow {
direction = "Right"
indexColumn++
minColumn++
} else {
indexRow--
}
// 방향이 아래인 경우 indexRow를 증가, 끝인 경우 방향을 왼쪽으로 변경하고 indexColumn을 감소, maxColumn도 감소시킵니다.
case "Down":
if indexRow == maxRow {
direction = "Left"
indexColumn--
maxColumn--
} else {
indexRow++
}
default:
print()
}
}
func printArray() -> Void
{
for j in spiralArray {
println(j)
}
}
initSpiralArray()
while i != x * y {
spiralArray[indexRow][indexColumn] = ++i
// 다음 방향을 미리 지정합니다.
nextDirection()
}
printArray()
// 처음에 고민했는데 낮잠자다가 생각나서 풀었네요ㅎㅎ Java입니다ㅎㅎ
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args) {
System.out.println("생성할 Spiral Array의 크기를 입력해주세요(예> 6 6)");
Scanner sc = new Scanner(System.in);
int a,b = 0;
// Validation Check
a = sc.nextInt();
b = sc.nextInt();
int[][] arr = new int[a][b];
for(int k=0; k<a; k++){
for(int l=0; l<b; l++){
arr[k][l] = a*b;
}
}
int count=0, i=0, j=0;
// type 1 _ j++ (->)
// type 2 _ i++ (밑)
// type 3 _ j-- (<-)
// type 4 _ i-- (위)
int type = 1;
// while 4번
while(count < (a * b)){
if(type == 1){
arr[i][j++] = count++;
if(j==b || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
j--;
i++;
type++;
}
}else if(type == 2){
arr[i++][j] = count++;
if(i==a || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
i--;
j--;
type++;
}
}else if(type == 3){
arr[i][j--] = count++;
if(j==-1 || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
j++;
i--;
type++;
}
}else{ // type == 4
arr[i--][j] = count++;
if(i==-1 || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
i++;
j++;
type = 1;
}
}
}
// Spiral Array 확인
for(int k=0; k<a; k++){
for(int l=0; l<b; l++){
System.out.print(arr[k][l] + " ");
}
System.out.println();
}
}
}
r,c = map(int,raw_input().split(' '))
lst = list()
array = [[0 for x in range(c)] for x in range(r)]
row,col = r,c # 나중에 array를 출력할때를 위해 r,c 백업
cnt = 0 # 현재 출력할 수
curr_point = (0,0) # 현재 수를 출력할 좌표
curr_direct = 'RIGHT' # 현재 방향
move = { # 방향을 넣으면 움직여야할 좌표를 반환하는 dict
'UP' : (-1,0),
'DOWN' : (1,0),
'LEFT' : (0,-1),
'RIGHT' : (0,1)
}
next_direct = { # 현재 방향을 넣으면 다음방향을 반환하는 dict
'UP' : 'RIGHT',
'RIGHT' : 'DOWN',
'DOWN' : 'LEFT',
'LEFT' : 'UP'
}
for i in range(r+c-1): # 방향이 바뀔때 마다 움직여야할 거리를 순서대로 list에 담음
if i % 2 is 0:
lst.append(c)
r = r - 1
else:
lst.append(r)
c = c - 1
for i in lst: # array에 차례로 숫자를 씀
for j in range(i):
array[curr_point[0]][curr_point[1]] = cnt
cnt = cnt + 1
if j is i-1:
curr_direct = next_direct[curr_direct]
curr_point = tuple(map(sum,zip(curr_point, move[curr_direct])))
for i in range(row): # array 출력
for j in range(col):
print '%3d'%array[i][j],
print ''
맨 바깥쪽 한바퀴 채우는걸 따로 함수로 만들고 한칸씩 안쪽으로 들어가는 식으로 구현했습니다.
def spiralone(l, n, a, b, c, d):
hlen = d-b
vlen = c-a
if vlen < 1 or hlen < 1: return -1
for i in range(0, hlen):
l[a][b+i] = n
n += 1
if vlen > 1:
for i in range(1, vlen):
l[a+i][d-1] = n
n += 1
if hlen > 1:
for i in range(1, hlen):
l[c-1][d-1-i] = n
n += 1
if vlen > 2:
for i in range(1, vlen-1):
l[c-1-i][b] = n
n += 1
return n
def emptyarray(m, n):
array = []
for i in range(m):
array.append([0 for y in range(n)])
return array
def printarray(l, m, n):
for i in range(m):
for j in range(n):
print("%3d" % l[i][j], end=" ")
print("")
m, n = 16, 13
l = emptyarray(m, n)
value = 0
a, b, c, d = 0, 0, m, n
while value != -1:
value = spiralone(l, value, a, b, c, d)
a, b, c, d = a+1, b+1, c-1, d-1
printarray(l, m, n)
이제 2번째 문제네요!! 프로그래밍을 배우고있는 고등학교 2학년입니다! 게임만들듯이 짜봤어요 ㅋㅋ 조금 노가다네요
//
// main.cpp
// CodingDojang_2
//
// Created by 최세현 on 2014. 9. 2..
// Copyright (c) 2014년 worldbright. All rights reserved.
//
#include <iostream>
using namespace std;
int startx, starty, endx, endy;
int width, height;
int x, y;
int direction;
int **spiralArray;
void input()
{
cout<<"넓이 : "; cin>>width;
cout<<"높이 : "; cin>>height;
endx = width;
endy = height;
}
void init()
{
spiralArray = new int*[height];
for(int i = 0; i < width; i++) {
spiralArray[i] = new int[width];
}
startx = 0; starty = 1;
x = y = direction = 0;
}
void update()
{
for(int i = 1; i <= width*height; i++) {
spiralArray[y][x] = i;
switch (direction%4) {
case 0:
x++;
if(x == endx-1) {
direction++;
endx--;
}
break;
case 1:
y++;
if(y == endy-1) {
direction++;
endy--;
}
break;
case 2:
x--;
if(x == startx) {
startx++;
direction++;
}
break;
case 3:
y--;
if(y == starty) {
starty++;
direction++;
}
break;
}
}
}
void result()
{
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
cout<<spiralArray[i][j]<<"\t";
}
cout<<endl;
}
}
int main(int argc, const char * argv[])
{
input();
init();
update();
result();
return 0;
}
결과
넓이 : 6
높이 : 5
1 2 3 4 5 6
18 19 20 21 22 7
17 28 29 30 23 8
16 27 26 25 24 9
15 14 13 12 11 10
Program ended with exit code: 0
나중에 알고리즘 능력이 뛰어나지면 다시한번 조금 더 간결한 코드로 풀어봐야겠네요
def spiral(a, b)
direction = "right"
spiral_array = []
spiral_x,spiral_y,spiral_value = 0, 0 ,0
a.times do |i|
spiral_sub_array = []
b.times do |j|
spiral_sub_array.push(-1)
end
spiral_array.push(spiral_sub_array)
end
time_loop = a*b
time_loop.times do
spiral_array[spiral_x][spiral_y] = spiral_value
spiral_value = spiral_value + 1
case direction
when "right"
if spiral_array[spiral_x][spiral_y+1] == -1
spiral_y = spiral_y + 1
elsif spiral_array[spiral_x+1][spiral_y] == -1
spiral_x = spiral_x + 1
direction = "down"
end
when "down"
if spiral_array[spiral_x+1] != nil && spiral_array[spiral_x+1][spiral_y] == -1
spiral_x = spiral_x + 1
elsif spiral_array[spiral_x][spiral_y-1] == -1
spiral_y = spiral_y - 1
direction = "left"
end
when "left"
if spiral_array[spiral_x][spiral_y-1] == -1
spiral_y = spiral_y - 1
elsif spiral_array[spiral_x-1][spiral_y] == -1
spiral_x = spiral_x - 1
direction = "up"
end
when "up"
if spiral_array[spiral_x-1] != nil && spiral_array[spiral_x-1][spiral_y] == -1
spiral_x = spiral_x - 1
elsif spiral_array[spiral_x][spiral_y+1] == -1
spiral_y = spiral_y + 1
direction = "right"
end
end
end
a.times do |i|
b.times do |j|
print spiral_array[i][j].to_s + " "
end
puts ''
end
end
spiral(6,6)
에효.. 일단 돌리긴 했는데 이제 다른 분들꺼 보고 많이 배워야 겠네요. ㅠ
import java.util.Arrays;
public class SpiralArray {
int data[][];
int row;
int col;
public static final int UP=0, RIGHT=1, DOWN=2, LEFT=3;
String msg;
public SpiralArray(int row, int col) {
super();
this.row = row;
this.col = col;
this.data= new int[row][col];
for(int i=0;i<row;i++){
for(int j=0;j<col;j++)
data[i][j]=-1;
}
msg=null;
}
public void fill(){
int x=0, y=0, way=RIGHT;
if(data==null) {
System.out.println("Cannot fill SpiralArray!");
return;
}
for(int i=0;i<row*col;i++){
data[y][x]=i;
switch(way){
case UP:
if(y==0 || data[y-1][x]!=-1){
way=RIGHT;
x+=1;
}else{
y-=1;
}
break;
case DOWN:
if(y==row-1 || data[y+1][x]!=-1){
way=LEFT;
x-=1;
}else{
y+=1;
}
break;
case RIGHT:
if(x==col-1 || data[y][x+1]!=-1){
way=DOWN;
y+=1;
}else{
x+=1;
}
break;
case LEFT:
if(x==0 || data[y][x-1]!=-1){
way=UP;
y-=1;
}else{
x-=1;
}
break;
}
}
}
public void show(){
if(data==null || msg!=null) {
System.out.println("Cannot print SpiralArray!");
return;
}
msg="";
for(int i=0;i<row;i++){
for(int j=0;j<col;j++)
msg+=String.format(" %4d", data[i][j]);
msg+="\n";
}
System.out.println(msg);
msg=null;
}
public static void main(String[] args) {
int row, col;
SpiralArray spiralArray = new SpiralArray(6, 6);
spiralArray.fill();
spiralArray.show();
}
}
파이썬 3.4 입니다. 앞에 분들에 비하면 부족하지만, 올려 봅니다.
def spiral_array(x_max,y_max):
matrix = [[0 for i in range(x_max)] for j in range(y_max)]
x,y = 0,0
num=0
for i in range(x_max-1):
x += 1
num += 1
matrix[y][x] = num
while x_max > 0 and y_max > 0:
for i in range(y_max-1):
y += 1
num += 1
matrix[y][x] = num
y_max -= 1
for i in range(x_max-1):
x -= 1
num += 1
matrix[y][x] = num
x_max -= 1
for i in range(y_max-1):
y -=1
num += 1
matrix[y][x] = num
y_max -= 1
for i in range(x_max-1):
x += 1
num += 1
matrix[y][x] = num
x_max -= 1
return matrix
x_max, y_max = map(int,input().split())
result = spiral_array(x_max,y_max)
for y in range(y_max):
for x in range(x_max):
print ('%3d'%result[y][x], end=" ")
print('')
//C++이 아니라 C로 짰어요.
#include <stdio.h>
#include <stdlib.h>
void spiral(int **param, int m, int n);
int main()
{
int rows, cols;
int num = 0;
scanf("%d %d", &rows, &cols);
int **arr = (int**)malloc(sizeof(int*)*rows); //2차원배열 동적할당
for (int i = 0; i < rows; i++){
arr[i] = (int*)malloc(sizeof(int)*cols);
}
printf("arr에 값 할당------------\n\n");
spiral(arr, rows, cols);
for (int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
printf("%4d", arr[i][j]);
}
printf("\n");
}
printf("\n----------------------------------\n");
for (int i = 0; i < rows; i++){ //2차원배열 메모리 해제
free(arr[i]);
}
free(arr);
return 0;
}
void spiral(int **param, int m, int n)
{
int rLimit = m-1, cLimit = n-1;
int rUnderline = 0, cUnderline = 0;
int num, i, j;
for (num = 0, i = 0, j = 0; num < m*n; num++){
if (j < cLimit && i == rUnderline){
param[i][j++] = num;
}
else if (j == cLimit && i < rLimit){
param[i++][j] = num;
}
else if (j > cUnderline && i == rLimit ){
param[i][j--] = num;
}
else if (j == cUnderline && i > rUnderline){
param[i--][j] = num;
if (i == rUnderline + 1)
rLimit--, cLimit--, rUnderline++, cUnderline++;
}
}
if (m % 2){ //2n-1 * 2n-1경우 또는 2n-1 * 2n-2(앞 홀수보다 1작은수)일 경우 가운데 하나가 비는 것을 방지
if (n % 2) param[m/2][n/2] = m*n-1;
else param[m / 2][n/2-1] = m*n-1;
}
}
from operator import add
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
n, m = map(int, raw_input().split(" "))
mat = [[-1 for x in xrange(0, m)] for y in xrange(0, n)]
count = 0
cur_dir = 0
cur_pos = (0, 0)
while count < n * m - 1:
mat[cur_pos[0]][cur_pos[1]] = count
next_pos = tuple(map(add, cur_pos, directions[cur_dir]))
while next_pos[0] < 0 or next_pos[0] >= n or next_pos[1] < 0 or next_pos[1] >= m or mat[next_pos[0]][next_pos[1]] != -1:
cur_dir = (cur_dir + 1) % len(directions)
next_pos = tuple(map(add, cur_pos, directions[cur_dir]))
count += 1
cur_pos = next_pos
mat[cur_pos[0]][cur_pos[1]] = count
for i in xrange(len(mat)):
print mat[i]
C#으로 작성했습니다. 문제가 어렵다고 느끼지는 못했는데 풀면서 제 머리가 꼬이는 듯한 느낌을 받았습니다. 로직은 간단합니다. input row와 column에 따라 2-Dimensional array를 만들면 들어갈 숫자가 0에서 row*column-1 입니다. 이건, #column + #row-1 + #column-1 + ... 과 같습니다. 사각형이기 때문에 매 각이 변할 때마다 i와 j로 방향을 전환해 줍니다. 시간상의 문제로 출력 부분은 coding하지 못했는데, 후에 넣겠습니다.
public int[,] GetSpiralArray(int m, int n)
{
var count = 0;
var i = 0;
var j = 0;
var shiftX = m - 1;
var shiftY = n;
var temp = n;
var outputs = new int[m, n];
var value = 0;
while (temp <= outputs.Length)
{
outputs [i, j] = value;
value++;
if (temp == value)
{
count++;
if (count%2 == 1)
{
shiftY--;
if (shiftX == 0) break;
temp += shiftX;
}
else
{
shiftX--;
if (shiftY == 0) break;
temp += shiftY;
}
}
if (count % 4 == 0) j++;
else if (count % 4 == 1) i++;
else if (count % 4 == 2) j--;
else if (count % 4 == 3) i--;
}
return outputs;
}
package Test2;
import java.util.Scanner;
//나선형 행렬
public class Test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int i = 0;
int j = 0;
int end_row,end_col; //행,열 상한 값
int start_row = 0; //행 하한 값
int start_col = 0; //열 하한 값
int count1 = 0; //한바퀴(우,하,좌,상) 횟수
int count2 = 0; //입력할 정수
int row,col; // 행열의 크기
int exit = 1; // 다 돌았을 경우 종료
Scanner scan = new Scanner(System.in);
//행, 열 입력 받기
System.out.println("행 수를 입력하세요.");
row = scan.nextInt();
System.out.println("열 수를 입력하세요.");
col = scan.nextInt();
end_row = row;
end_col = col;
//매트릭스 배열 선언
int[][] list = new int[row][col];
//반복문 횟수
count1 = (row+1)/2;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
list[i][j] = -1;
}
}
i=0;
j=0;
while(count1 > 0)
{
//우
for(j=start_col; j<end_col; j++)
{
if(list[i][j] == -1)
{
list[i][j] = count2++;
}
else
{
exit = 0;
break;
}
}
start_row++;
j--;
//하
for(i=start_row; i<end_row; i++)
{
if(list[i][j] == -1)
{
list[i][j] = count2++;
}
else
{
exit = 0;
break;
}
}
i--;
end_col--;
//좌
for(j=end_col-1; j>=start_col; j--)
{
if(list[i][j] == -1)
{
list[i][j] = count2++;
}
else
{
exit = 0;
break;
}
}
j++;
end_row--;
//상
for(i=end_row-1; i>=start_row; i--)
{
if(list[i][j] == -1)
{
list[i][j] = count2++;
}
else
{
exit = 0;
break;
}
}
if(exit == 0)
break;
else
{
start_col++;
i++;
count1--;
}
}
//행렬 출력
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
System.out.printf("%3d\t", list[i][j]);
}
System.out.println();
}
}
}
후 오래걸렸네요... 더 개선할 수 있으면 지적 좀 해주세요!!
Scala로 풀었습니다. 생각보다 시간이 많이 걸렸네요.
def spiral(row: Int, column: Int): Array[Array[Int]] = {
def fn(n: Int, m: Int, dir: Int, count: Int, result: Array[Array[Int]]): Array[Array[Int]] = {
def next(n: Int, m: Int, dir: Int, count: Int, result: Array[Array[Int]]) = {
if(dir % 4 == 0) {
fn(n, m + 1, dir, count, result)
} else if(dir % 4 == 1) {
fn(n + 1, m, dir, count, result)
} else if(dir % 4 == 2) {
fn(n, m - 1, dir, count, result)
} else {
fn(n - 1, m, dir, count, result)
}
}
val isFail: Boolean = {
n < 0 || m < 0 || n >= row || m >= column || result(n)(m) != -1
}
if(count >= row * column) {
result
} else if (isFail) {
if(dir % 4 == 0) {
next(n, m - 1, dir + 1, count, result)
} else if(dir % 4 == 1) {
next(n - 1, m, dir + 1, count, result)
} else if(dir % 4 == 2) {
next(n, m + 1, dir + 1, count, result)
} else {
next(n + 1, m, dir + 1, count, result)
}
} else {
result(n)(m) = count
next(n, m, dir, count + 1, result)
}
}
fn(0, 0, 0, 0, Array.fill[Int](row, column)(-1))
}
println(
spiral(6,6).map(_.mkString("\t")).mkString("\n")
)
raw = '6 6'
width, height = map(int, raw.split(' '))
matrix = [0]*(width*height)
deltas = [1, width, -1, -width]
direction = 0
go_x = width
go_y = height-1
count, index = 0, -1
while go_x >= 0 and go_y >= 0:
delta = deltas[direction]
if direction%2 == 0:
go = go_x
go_x -= 1
else:
go = go_y
go_y -= 1
if go > 0:
for i in range(0, go):
index += delta
matrix[index] = count
count += 1
direction = (direction + 1) % 4
maxnum = width*height-1
digits = len(str(maxnum))
for y in range(0, height):
padded = [str(x).rjust(digits) for x in matrix[y*width:(y+1)*width]]
print(' '.join(padded))
빈 배열을 만들고 달팽이처럼 돌아가면서 채웠습니다.
매 루프마다 인덱스를 1, width, -1, -width, ... 만큼 더해주면서..
다른 코드들을 보니 출력하는 부분도 깔끔하고 그렇더군요.. 공부를 더 해야겠습니다.
한시간 정도 걸렸는데 일부러 더 다듬지 않고 걍 올립니다.
input_str = raw_input()
input_str = input_str.split()
m = int(input_str[0])
n = int(input_str[1])
finish = min(m,n) - 1
ord_list = []
def min(m,n):
if m >= n:
return n
else:
return m
for i in range(n):
ord_list.append(i)
order = n-1
for i in range(finish):
if i % 2 == 0:
delta1 = n
delta2 = -1
else:
delta1 = -n
delta2 = 1
for j in range(m-i-1):
order += delta1
ord_list.append(order)
for j in range(n-i-1):
order += delta2
ord_list.append(order)
spiral = []
for i in range(len(ord_list)):
spiral.append(0)
max_digits = len(str(m*n-1))
for i in range(len(ord_list)):
num = str(i)
for j in range(max_digits):
if len(num) == j+1:
num = ' '*(max_digits-j-1) + num
break
spiral[ord_list[i]] = str(i)
for i in range(m*n-1):
at = 2*i + 1
if i % n == n-1:
spiral.insert(at, '\n')
continue
spiral.insert(at, '\t')
print ''.join(spiral)
C++로 최대한 간단하게 만들어봤습니다 :) 임시 저장 공간 없이 만드는 건 도저히 못 할 것 같네요. Left, right, top, bottom 변수를 둬서 해결했습니다. 코드 짧게 만드는데 약간의 삽질이 필요했습니다.
#include <iostream>
#include <iomanip>
void printSpiralMatrix(size_t row, size_t col) {
using namespace std;
int *A = new int[row * col];
for (int val = 0, l = 0, r = col - 1, t = 0, b = row - 1;
l <= r && t <= b; ++l, --r, ++t, --b) {
for (int i = l; i <= r; ++i)
A[t * row + i] = val++;
for (int i = t + 1; i <= b - 1; ++i)
A[i * row + r] = val++;
for (int i = r; t < b && i >= l; --i)
A[b * row + i] = val++;
for (int i = b - 1; l < r && i >= t + 1; --i)
A[i * row + l] = val++;
}
for (size_t r = 0; r < row; ++r) {
for (size_t c = 0; c < col; ++c) {
cout << setw(3) << A[r * row + c];
}
cout << endl;
}
delete[] A;
}
int main() {
printSpiralMatrix(6, 6);
}
import itertools
class SpiralArray:
DIRECTION = itertools.cycle(((0, 1), (1, 0), (0, -1), (-1, 0)))
def __init__(self, size):
self.xsize, self.ysize = int(size[0]), int(size[1])
self.board = [[None for x in range(self.xsize)] for y in range(self.ysize)]
self.dir = next(self.DIRECTION)
self.xpos = self.ypos = 0
def __str__(self):
ans = ''
for row in self.board:
rowformat = [str('{0:4d}'.format(x)) for x in row]
ans += ' '.join(rowformat) + '\n'
return ans
def run(self):
for value in range(self.xsize * self.ysize):
self.board[self.ypos][self.xpos] = value
if not self.checkbound(self.ypos, self.xpos):
self.dir = next(self.DIRECTION)
self.move()
def move(self):
self.ypos += self.dir[0]
self.xpos += self.dir[1]
def checkbound(self, ypos, xpos):
ypos += self.dir[0]
xpos += self.dir[1]
return -1 < xpos < self.xsize and -1 < ypos < self.ysize and self.board[ypos][xpos] is None
if __name__ == '__main__':
a = SpiralArray(input('? ').split(' '))
a.run()
print(a)
Scala로 풀었습니다.
object Direction extends Enumeration {
type Direction = Value
val RIGHT, DOWN, LEFT, UP = Value
}
import Direction._
class SpiralArray(x: Int, y: Int) {
val array = Array.fill[Int](x, y)(-1) // 2차원 배열, 초기값은 -1
var direction = RIGHT
init()
def init() = {
val lastNumber = x * y - 1 // 배열에 넣을 마지막 숫자
var pos = (0, 0) // 시작 위치
for (num <- (0 to lastNumber)) {
array(pos._1).update(pos._2, num)
if (num != lastNumber) pos = nextPosition(pos._1, pos._2)
}
}
/**
* 현재 위치가 (i,j) 일때 다음 위치 알아내기
*/
def nextPosition(i: Int, j: Int): (Int, Int) = {
// 방향에 따라 다음 위치 선정
val position = direction match {
case RIGHT => (i, j + 1)
case DOWN => (i + 1, j)
case LEFT => (i, j - 1)
case UP => (i - 1, j)
}
if (position._1 != -1 && position._1 != x && position._2 != -1 && position._2 != y
&& array(position._1)(position._2) == -1) {
position // 다음 위치가 끝이 아니고 다음 위치의 숫자가 바뀌지 않은 경우 다음 위치 리턴
}
else {
changeDirection() // 방향을 바꾸고, 다음 위치 다시 확인
nextPosition(i, j)
}
}
/**
* right => down => left => up
*/
def changeDirection() = {
direction = direction match {
case RIGHT => DOWN
case DOWN => LEFT
case LEFT => UP
case UP => RIGHT
}
}
}
object Boot extends App {
val sa = new SpiralArray(6, 6)
for (row <- sa.array) println(row.mkString("\t"))
}
def spiral_array(row, col):
a = [[-1 for i in range(col+2)] for j in range(row+2)]
for j in range(col+2):
a[0][j] = -2
a[row+1][j] = -2
for i in range(row+2):
a[i][0] = -2
a[i][col+1] = -2
direct = 0
i, j = 1, 1
a[i][j] = 0
tot = row*column
cnt = 1
while cnt != tot:
i0, j0 = i, j
if direct == 0:
if a[i][j+1] == -1:
j = j + 1
elif direct == 1:
if a[i+1][j] == -1:
i = i + 1
elif direct == 2:
if a[i][j-1] == -1:
j = j - 1
elif direct == 3:
if a[i-1][j] == -1:
i = i - 1
if i0 == i and j0 == j:
if direct == 3:
direct = 0
else:
direct = direct + 1
else:
a[i][j] = cnt
cnt = cnt + 1
return a
row = 6
column = 6
a = spiral_array(row, column)
for i in range(1,row+1):
for j in range(1,column+1):
print "%3d" %a[i][j],
print '\n'
print '\n'
for i in range(0,row+2):
for j in range(0,column+2):
print "%3d" %a[i][j],
print '\n'
6*6에 대한 예시입니다. 미리 배열선언하고 테두리에 boundary로 -2를 두른 후에 초기값 -1을 기준으로 spiral_array를 작성했습니다. 아래 출력문은 테두리 있는 것과 없는 것입니다. 확실히 코드가 지저분하네요ㅠ.ㅠ 다음에는 코드 줄 수를 줄일 수 있는 방법으로 한 번 생각해보겠습니다.
object Main extends App {
object Direction extends Enumeration {
type Direction = Value
val UP, DOWN, RIGHT, LEFT= Value
}
import Direction._
class SpiralArray(width: Int, height: Int) {
val array = Array.fill[Int](width, height)(-1)
var direction = Direction.RIGHT
def process(): Array[Array[Int]] = {
processRun(0, 0, 0)
}
def processRun(x: Int, y: Int, num: Int): Array[Array[Int]] = {
array(x).update(y, num)
if (width * height -1 == num) array
else {
val nextPos = nextPosition(x, y, num)
processRun(nextPos._1, nextPos._2, nextPos._3)
}
}
def nextPosition(x: Int, y: Int, num: Int): (Int, Int, Int) = {
val position = direction match {
case RIGHT => (x, y+1, num+1)
case DOWN => (x+1, y, num+1)
case LEFT => (x, y-1, num+1)
case UP => (x-1, y, num+1)
}
if (position._1 != -1 &&
position._1 != width &&
position._2 != -1 &&
position._2 != height &&
array(position._1)(position._2) == -1) {
position
} else {
changeDirection()
nextPosition(x, y, num)
}
}
def changeDirection() = {
direction = direction match {
case RIGHT => DOWN
case DOWN => LEFT
case LEFT => UP
case UP => RIGHT
}
}
}
def printArray(args: Array[Array[Int]]) {
for (row <- args) println(row.mkString("\t"))
}
val array = new SpiralArray(6, 6);
val resultArray = array.process()
printArray(resultArray)
}
Python 3.4.2로 풀어보았습니다.
N, M = input("NxM (e.g. 3 5): ").split()
N = int(N)
M = int(M)
k = -1 # while 들어가서 0부터 시작하므로 -1로 setting
cnt = 1 # 카운트 변수 초기화
switch = 1 # 홀수:1, 짝수:-1
b = [] # 행렬값을 저장할 공간
for x in range(M): # 행렬 초기화
b.append([0] * N)
x = 0 # 행렬 자릿값(x, y) 초기화
y = -1
while k <= N*M : # k값이 마지막일때까지 반복
if switch == 1 : # p값 설정은
p = N - int(cnt/2) # 1. N에서 하나씩 줄여감
elif switch == -1 :
p = M - int(cnt/2) # 2. M에서 하나씩 줄여감
if p == 0 : # 더 이상 배열에 저장할 필요가 없으면 종료!
break
for i in range(p) : # p만큼 반복
k += 1
if switch == 1 :
if int((cnt+1)/2)%2 == 1 : # cnt=1,2,5,6,...일 때 y++
y += 1
else : # cnt=3,4,7,8,...일 때 y--
y -= 1
elif switch == -1 :
if int((cnt+1)/2)%2 == 1 : # cnt=1,2,5,6,...일 때 x++
x += 1
else : # cnt=3,4,7,8,...일 때 y--
x -= 1
b[x][y] = k # 배열에 해당 값 저장
cnt += 1 # n번째 카운트
switch *= -1 # 홀짝 토글
# 결과 행렬 출력
for i in range(M) :
for j in range(N) :
print("%3d" % b[i][j], end=" ")
print()
;; 좌측 상단이 0,0 인 좌표를 사용하였음.
(defn snail-coordinates [width height]
(let [start-point [-1 0]
directions (cycle [[1 0] [0 1] [-1 0] [0 -1]]) ;; 달팽이 모양의 방향
repeats (interleave (iterate dec width) (iterate dec (dec height))) ;; 반복횟수
;; 소용돌이 모양의 움직임 리스트
moves (mapcat #(repeat %1 %2) repeats directions)]
;; 움직임을 합산해가면서 나가면 좌표가 나온다.
(->> (reductions #(map + %1 %2) start-point moves)
(drop 1) ;; 시작점 위치 제외
(take (* width height)))))>
(defn snail-numbers [width height]
;; '달팽이-좌표'에 '숫자'를 매핑한다.
(let [coord-num-map (zipmap (snail-coordinates width height) (range))]
;; 리스트 만든다.
(for [y (range height)]
(for [x (range width)]
(coord-num-map [x y])))))
(clojure.pprint/pprint (snail-numbers 7 5))
;;결과
;;=> ((0 1 2 3 4 5 6)
;; (19 20 21 22 23 24 7)
;; (18 31 32 33 34 25 8)
;; (17 30 29 28 27 26 9)
;; (16 15 14 13 12 11 10))
class SpiralArray
{
private int row, col;
public SpiralArray(int row, int col)
{
this.row = row;
this.col = col;
}
public void calc()
{
int row = this.row-1;
int col = this.col-1;
int arr[][] = new int[row+1][col+1];
int count = 0;
int temp = 0;
int last = 0;
while(temp <= row / 2)
{
for(int j=temp; j<=col - temp; j++)
{
arr[temp][j] = last + count++;
}
count = 0;
for(int i=temp; i<=row-temp; i++)
{
arr[i][col-temp] = arr[temp][col-temp] + count++;
}
count = 0;
for(int j=col-temp; j>=temp; j--)
{
arr[row-temp][j] = arr[row-temp][col-temp] + count++;
}
count = 0;
for(int i=row-temp; i>temp; i--)
{
arr[i][temp] = arr[row-temp][temp] + count++;
}
last = arr[temp+1][temp]+1;
count = 0;
temp++;
}
print(arr);
}
public void print(int[][] arr)
{
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
System.out.printf("%4d", arr[i][j]);
}
System.out.println();
}
}
}
swift로 작성했습니다
let x = Process.arguments[1].toInt()!
let y = Process.arguments[2].toInt()!
//let x = 6
//let y = 6
let endNumber = x * y
enum DIRECTION{
case LEFT, RIGHT, TOP, BOTTOM
}
var max_width = x - 1
var max_height = y - 1
var count = 0
var direction = DIRECTION.RIGHT
var row = 0, column = 0
var resultArray = Array(count: y, repeatedValue: Array(count: x, repeatedValue: 0))
for num in 0..<endNumber{
resultArray[row][column] = num
switch(direction)
{
case DIRECTION.RIGHT:
if(count == max_width)
{
direction = DIRECTION.BOTTOM
max_height--
count = 0
row++
}
else{
column++
count++
}
break
case DIRECTION.BOTTOM:
if(count == max_height)
{
direction = DIRECTION.LEFT
max_width--
count = 0
column--
}
else{
row++
count++
}
break
case DIRECTION.LEFT:
if(count == max_width)
{
direction = DIRECTION.TOP
max_height--
count = 0
row--
}
else{
column--
count++
}
break
case DIRECTION.TOP:
if(count == max_height)
{
direction = DIRECTION.RIGHT
max_width--
count = 0
column++
}
else{
row--
count++
}
break
}
}
// print
for newY in 0..<y{
for newX in 0..<x{
print(String(resultArray[newY][newX])+"\t")
}
println()
}
package rootcucu.codefight;
import java.util.*;
import java.awt.Point;
public class Spiral {
int width;
int height;
int arr[];
Spiral(int width, int height){
this.width = width;
this.height = height;
}
public void write(){
for (int y = 0; y < height; y++){
for (int x = 0; x < width; x++){
System.out.format("%3d ", arr[y*width + x]);
}
System.out.print("\n\n");
}
}
void make(){
arr = new int[width * height];
Arrays.fill(arr, -1);
Point p = new Point(0, 0);
int dX = 1, dY = 0; // prefix d means delta.
for (int number = 0; number < width*height; number++){
setValue(p, number);
Point pNext = getNext(p, dX, dY);
if (!isWritableLocation(pNext)){
pNext = findNextLocation(p);
if (pNext != null){
dX = pNext.x - p.x;
dY = pNext.y - p.y;
}
}
p = pNext;
}
}
private Point getNext(Point p, int dX, int dY){
return new Point(p.x + dX, p.y + dY);
}
private void setValue(Point p, int number){
arr[getPos(p)] = number;
}
private boolean isWritableLocation(Point p){
int x = p.x;
int y = p.y;
if ((x < 0) || (x >= width) || (y < 0) || (y >= height))
return false;
return arr[getPos(p)] == -1;
}
// findWritableLocationAdjacentTo 가 더 적절해 보임.
private Point findNextLocation(Point p){
int[][] directions = new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
for (int[] direction:directions){
Point pNext = new Point(p.x + direction[0], p.y + direction[1]);
if (isWritableLocation(pNext)){
return pNext;
}
}
return null;
}
private int getPos(Point p){
return p.y*width + p.x;
}
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("input width, height (-1 to finish)");
int width = scanner.nextInt();
if (width < 0)
return;
int height = scanner.nextInt();
Spiral obj = new Spiral(width, height);
obj.make();
obj.write();
}
}
}
실행 결과
input width, height (-1 to finish)
3 4
0 1 2
9 10 3
8 11 4
7 6 5
input width, height (-1 to finish)
8 5
0 1 2 3 4 5 6 7
21 22 23 24 25 26 27 8
20 35 36 37 38 39 28 9
19 34 33 32 31 30 29 10
18 17 16 15 14 13 12 11
input width, height (-1 to finish)
-1
#266.py
def side(p,q,l,result,m=0,n=0):
#filling the side
for i in range(p):
result[n][m+i]=l+i
result[n+q-1][m+p-1-i]=l+p+q-2+i
for j in range(q-1):
result[n+j][m+p-1]=l+p-1+j
result[n+q-1-j][m]=l+2*p+q-3+j
def change(x,y,result):
#do the side work to the end
count=0
start=0
while(x>0 and y>0):
side(x,y,start,result,count,count)
count+=1
start+=2*(x+y-2)
x-=2
y-=2
def print_answer(result):
#print the result easy to read.
for x in range(len(result)):
for y in range(len(result[0])):
print "%3d" %result[x][y],
print
#x,y=map(int,raw_input().split())
x,y=6,6
result=[[0 for p in range(x)] for q in range(y)]
change(x,y,result)
print_answer(result)
오른쪽, 왼쪽, 아래쪽, 위쪽 구현하는 반복문들을 따로 만들어서 처리했습니다. c언어로 작성했습니다.
int row, col;
int i, j, dir=1; //dir 1 = 오른쪽, 2 = 아래쪽, 3 = 왼쪽, 4=위쪽
int num = 0;
bool finish = true;
int cnt=1;
scanf("%d%d",&row,&col);
int ** arr= (int**)malloc(sizeof(int) * row); //┐
for(i = 0; i < row; i++) //2차원배열 동적할당
arr[i]=(int *)malloc(sizeof(int)*col); //┘
for(i = 0; i < col; i++) //초기화
{
for(j = 0; j < row; j++)
arr[j][i] = 0;
}
i = 0, j = 0;
while(finish)
{
if(dir == 1) //오른쪽
{
for(;j < row; j++)
{
if(arr[j][i] == 0)
{
arr[j][i] = num;
num++;
}
else
{
break;
}
}
dir++;
j--;
i++;
}
if(dir == 2) //아래쪽
{
for(;i < col; i++)
{
if(arr[j][i] == 0)
{
arr[j][i] = num;
num++;
}
else
{
break;
}
}
dir++;
i--;
j--;
}
if(dir == 3) //왼쪽
{
for(;j >= 0; j--)
{
if(arr[j][i] == 0)
{
arr[j][i] = num;
num++;
}
else
{
break;
}
}
dir++;
j++;
i--;
}
if(i*j == num)
{
finish = true;
}
if(dir == 4) //왼쪽
{
for(;i > 0; i--)
{
if(arr[j][i] == 0)
{
arr[j][i] = num;
num++;
}
else
{
break;
}
}
dir=1;
i++;
j++;
}
if(num==row*col)
{
finish = false;
}
}
for(i = 0; i < col; i++) //출력
{
for(j = 0; j < row; j++)
{
printf("%4d",arr[j][i]);
}
printf("\n");
}
for(i=0; i<row; i++) //동적해제
free(arr[i]);
free(arr);
system("pause");
return 0;
w, h = 8, 8
mat = [ [0]*h for x in range(w) ]
th = h
num=0
inc=1
xpos=0
ypos=0
for x in range(w*2-1):
for y in range(th):
# 증가, 감소를 결정
y = y * inc
# 열증가 및 감소
if x%2 == 0:
mat[xpos][ypos+y] = num
else: # 행증가 및 감소
mat[xpos+y][ypos] = num
# 값
num = num + 1
# 루프횟수가 처음시작할때 빼고 2번에 한번씩 감소한다.
if x%2 == 0:
th = th -1
# 행증가
if x%2 == 1:
inc = inc*-1
if y<0:
xpos = xpos + y
ypos = ypos + 1
else:
xpos = ypos
ypos = ypos - 1
# 열증가
elif x==0 or x%2 == 0:
if y<0:
xpos = xpos - 1
ypos = ypos + y
else:
xpos = xpos + 1
ypos = ypos + y
for x in range(w):
w1 = x
for y in range(h):
s = "{0:>2}".format(mat[x][y])
print(s, end=' ')
print("\n")
package test;
public class SpiralArray {
public static boolean goRight(int[][] map, int x, int y){
if( x+1 >= 6 ){
return false;
}
if( map[y][x + 1] == -1){
return true;
}else{
return false;
}
}
public static boolean goDown(int[][] map, int x, int y){
if( y+1 >= 6 ){
return false;
}
if( map[y + 1][x] == -1){
return true;
}else{
return false;
}
}
public static boolean goLeft(int[][] map, int x, int y){
if( x-1 < 0 ){
return false;
}
if( map[y][x - 1] == -1){
return true;
}else{
return false;
}
}
public static boolean goUp(int[][] map, int x, int y){
if( y-1 < 0 ){
return false;
}
if( map[y-1][x] == -1){
return true;
}else{
return false;
}
}
public static void setValue(int [][] map, int x, int y, int value ){
map[y][x] = value;
}
public static void main(String[] args){
int[][] map = new int[6][6];
for( int x = 0; x < 6; x++){
for( int y = 0; y < 6; y++){
map[x][y] = -1;
}
}
int naviX = 0;
int naviY = 0;
int block = 0;
int index = 0;
while( true ){
while(goRight(map, naviX, naviY)){
setValue(map, naviX, naviY, index);
index++;
naviX++;
block = 0;
}
block++;
while(goDown(map, naviX, naviY)){
setValue(map, naviX, naviY, index);
naviY++;
index++;
block = 0;
}
block++;
while(goLeft(map, naviX, naviY)){
setValue(map, naviX, naviY, index);
naviX--;
index++;
block = 0;
}
block++;
while(goUp(map, naviX, naviY)){
setValue(map, naviX, naviY, index);
naviY--;
index++;
block = 0;
}
block++;
if( block >= 4){
setValue(map, naviX, naviY, index);
break;
}
}
for( int y = 0; y < 6; y++){
for( int x = 0; x < 6; x++){
System.out.format("%4d", map[y][x]);
if( x == 5 ){
System.out.print("\n");
}
}
}
}
}
대충 짜긴 했는데 맘에는 안드네요,
import java.util.Scanner;
/**입력에 맞는 2차원 배열을 생성하고. 내용은 -1로 초기화.
* 4가지 진행방향 별 method 이용, 1. 오른쪽 2. 아래쪽 3. 왼쪽 4. 위쪽
* 처리 후, 방향을 전환한다.
*
* @author Yongmin Kim
*
*/
public class Spiral_Array {
// 저장할 2차원배열
private int[][] array;
// 행열 입력 값
private int row, col;
// 포인터의 위치
private int indexOfRow, indexOfCol;
// 방향지시
private int direction;
// 카운터
private int counter;
public Spiral_Array() {
// 변수초기화
init();
// 카운터가 max치일 때까지 반복
while (counter < (row * col)) {
switch (direction) {
case 1:// 방향이 오른쪽으로 향하는 경우
right_down();
break;
case 2:// 방향이 아래쪽으로 향하는 경우
down_left();
break;
case 3:// 방향이 왼쪽으로 향하는 경우
left_up();
break;
case 4:// 방향이 위쪽으로 향하는 경우
up_right();
break;
default:// 오류
direction = 5;
break;
}// end switch
// error handling
if (direction == 5) {
System.out.println("Direction error");
break;
}
}// end while
display();
}
/**
* initialize
*/
private void init() {
// 행열 입력값 받음
Scanner input = new Scanner(System.in);
row = input.nextInt();
col = input.nextInt();
// 2차원 배열 동적할당
array = new int[row][];
for (int i = 0; i < row; i++)
array[i] = new int[col];
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
array[i][j] = -1;
}
}
indexOfRow = 0;
indexOfCol = 0;
direction = 1;
counter = 0;
}
/**
* 1. 오른쪽->아래
*/
private void right_down() {
// 우측으로 이동하며 값을 바꿈
for (; indexOfCol < col; indexOfCol++, counter++) {
if (array[indexOfRow][indexOfCol] != -1) {
indexOfCol--;
indexOfRow++;
direction = 2;
return;
}
array[indexOfRow][indexOfCol] = counter;
}
// 방향을 아래로 바꿈
indexOfCol--;
indexOfRow++;
direction = 2;
return;
}
/**
* 2. 아래->왼쪽
*/
private void down_left() {
// 아래측으로 이동하며 값을 바꿈
for (; indexOfRow < row; indexOfRow++, counter++) {
if (array[indexOfRow][indexOfCol] != -1) {
indexOfRow--;
indexOfCol--;
direction = 3;
return;
}
array[indexOfRow][indexOfCol] = counter;
}
// 방향을 왼쪽으로 바꿈
indexOfRow--;
indexOfCol--;
direction = 3;
return;
}
/**
* 3. 왼쪽->위쪽
*/
private void left_up() {
// 왼쪽으로 이동하며 값을 바꿈
for (; indexOfCol >= 0; indexOfCol--, counter++) {
if (array[indexOfRow][indexOfCol] != -1) {
indexOfCol++;
indexOfRow--;
direction = 4;
return;
}
array[indexOfRow][indexOfCol] = counter;
}
// 방향을 위로 바꿈
indexOfCol++;
indexOfRow--;
direction = 4;
return;
}
/**
* 4. 위쪽->오른쪽
*/
private void up_right() {
// 위쪽으로 이동하며 값을 바꿈
for (; indexOfRow >= 0; indexOfRow--, counter++) {
if (array[indexOfRow][indexOfCol] != -1) {
indexOfRow++;
indexOfCol++;
direction = 1;
return;
}
array[indexOfRow][indexOfCol] = counter;
}
// 방향을 오른쪽으로 바꿈
indexOfRow++;
indexOfCol++;
direction = 1;
return;
}
/**
* display
*/
public void display(){
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
System.out.print(array[i][j]+"\t");
}
System.out.println();
}
}
}
/*
문제는 다음과 같다:
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
row가 n이면
n-1개씩 숫자를 묶으면 4개씩 끊긴다..
그 다음은 n-2개씩 묶이고...
(정사각형만 적용됨)
*/
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int row=0;
int col=0;
int ** arr;
int i=0;
int j=0;
int cnt=0;
int forcnt=0;
int loop=0;
int set=0;
printf("row와 col 입력: ");
scanf("%d %d",&row,&col);
arr = (int**)malloc(sizeof(int*)*row);
for(i=0;i<row;i+=1)
{
arr[i] = (int*)malloc(col*sizeof(int));
}
set = row-1;
while(set>0)
{
for(j=loop;j<col-1-loop;j+=1)
{
arr[loop][j] = cnt;
cnt+=1;
}
// j==4 status
//forcnt+=1;
for(i=loop;i<row-1-loop;i+=1)
{
arr[i][j] = cnt;
cnt+=1;
}//forcnt+=1;
// i==4 , j==4 status
for(j=row-1-loop;j>loop;j-=1)
{
arr[i][j] = cnt;
cnt+=1;
}//forcnt+=1;
// i==4 j==0 stat
for(i=row-1-loop;i>loop;i-=1)
{
arr[i][j] = cnt;
cnt+=1;
}//forcnt+=1;
//i==0 j==0 stat
loop+=1;
set -= 2;
}
if(row % 2 == 1)
{
arr[row/2][col/2] = row*col-1;
}
for(i=0;i<row;i+=1)
{
for(j=0;j<col;j+=1)
{
printf("%3d",arr[i][j]);
}
printf("\n");
}
}
Common Lisp 입니다. 배열 다루는 것도 어렵네요 ㅜ 포맷팅 출력 아직 몰라서 REPL에서 보여주는 배열 값으로 확인을 했습니다;
(defun array-slice (arr row)
"http://stackoverflow.com/a/12327524"
(make-array (array-dimension arr 1)
:displaced-to arr
:displaced-index-offset (* row (array-dimension arr 1))))
(defun spiral-array (N)
(let ((data (make-array `(,N ,N) :initial-element 0))
(x 0)
(y 0)
(counter 0))
(labels ((move-horizontal (step amount)
(loop for i from 1 to amount
do
(setf x (+ x step))
(setf counter (1+ counter))
(setf (aref data y x) counter)))
(move-vertical (step amount)
(loop for i from 1 to amount
do
(setf y (+ y step))
(setf counter (1+ counter))
(setf (aref data y x) counter)))
(left (amount)
(move-horizontal -1 amount))
(right (amount)
(move-horizontal +1 amount))
(up (amount)
(move-vertical -1 amount))
(down (amount)
(move-vertical +1 amount))
(ready-next-turn ()
(setf x (1+ x))
(setf counter (1+ counter))
(setf (aref data y x) counter)))
;; start spinning
(loop for n from (1- N) downto 1 by 2
do
(right n)
(down n)
(left n)
(when (> n 1)
(up (1- n))
(ready-next-turn))))
;; print array
(loop for row from 0 to (1- (array-dimension data 1)) do
(print (array-slice data row)))))
public class SpiralArray {
final static int INVALIDATED = -1;
public static void main(String[] args) {
int[][] arr = new int[6][6];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = INVALIDATED;
}
}
new SpiralArray().spiral(arr, 0, 0, 0, 0);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.printf("%2d ", arr[j][i]);
}
System.out.println();
}
}
private void spiral(int[][] arr, int x, int y, int dir, int num) {
arr[x][y] = num;
switch(dir) {
case 0:
if (x < arr.length - 1 && arr[x + 1][y] == INVALIDATED) {
x++;
break;
}
dir = (++dir) % 4;
case 1:
if (y < arr[x].length - 1 && arr[x][y + 1] == INVALIDATED) {
y++;
break;
}
dir = (++dir) % 4;
case 2:
if (0 < x && arr[x - 1][y] == INVALIDATED) {
x--;
break;
}
dir = (++dir) % 4;
case 3:
if (0 < y && arr[x][y - 1] == INVALIDATED) {
y--;
break;
}
dir = (++dir) % 4;
default:
if (x < arr.length - 1 && arr[x + 1][y] == INVALIDATED) {
x++;
break;
}
return;
}
spiral(arr, x, y, dir, num + 1);
}
}
void exce2()
{
int x, y;
int posX = -1, posY = 0;
int **mat;
const int left = 1, right = 2, up = 3, down = 4;
int direc = right;
printf("input x : ");
scanf_s("%d", &x);
printf("input y : ");
scanf_s("%d", &y);
mat = (int **)malloc(sizeof(int) * y);
for (int i = 0; i < y; i++)
{
mat[i] = (int *)malloc(sizeof(int) * x);
for (int j = 0; j < x; j++)
mat[i][j] = -1;
}
for (int i = 0; i < (x*y); i++)
{
switch (direc)
{
case right:
posX++;
if (posX == x - 1 || mat[posY][posX + 1] != -1)
direc = down;
break;
case down:
posY++;
if (posY == y - 1 || mat[posY+1][posX] != -1)
direc = left;
break;
case left:
posX--;
if (posX == 0 || mat[posY][posX - 1] != -1)
direc = up;
break;
case up:
posY--;
if (posY == 0 || mat[posY-1][posX] != -1)
direc = right;
break;
}
mat[posY][posX] = i;
}
for (int i = 0; i < y; i++)
{
for (int j = 0; j < x; j++)
{
printf("%3d ", mat[i][j]);
}
printf("\n");
}
}
매트릭스에 미리 나선형으로 넣어두고 출력하는 방식을 사용하였습니다.
#include "stdafx.h"
#include <cassert>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int x = 5;
int y = 6;
int** pMap = new int*[x];
for (int i = 0; i < x; ++i)
pMap[i] = new int[y];
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
pMap[i][j] = 0;
}
/////////////////////////////////////
int nPos_i = 0;
int nPos_j = 0;
int nNum = 1;
int nCount = 0;
while (nNum != x * y + 1 )
{
int nRemain = nCount%4;
nCount++;
switch (nRemain)
{
case 0:
for (int i = 0; i < x;)
{
if (pMap[nPos_i][nPos_j] == 0)
{
pMap[nPos_i][nPos_j] = nNum++;
if (nPos_i + 1 == x)
break;
if (pMap[nPos_i + 1][nPos_j] == 0)
nPos_i++;
else
break;
}
else
nPos_i++;
}
break;
case 1:
for (int i = 0; i < y;)
{
if (pMap[nPos_i][nPos_j] == 0)
{
pMap[nPos_i][nPos_j] = nNum++;
if (nPos_j + 1 == y)
break;
if (pMap[nPos_i][nPos_j + 1] == 0)
nPos_j++;
else
break;
}
else
nPos_j++;
}
break;
case 2:
for (int i = 0; i < x;)
{
if (pMap[nPos_i][nPos_j] == 0)
{
pMap[nPos_i][nPos_j] = nNum++;
if (nPos_i == 0)
break;
if (pMap[nPos_i - 1][nPos_j] == 0)
nPos_i--;
else
break;
}
else
nPos_i--;
}
break;
case 3:
for (int i = 0; i < y;)
{
if (pMap[nPos_i][nPos_j] == 0)
{
pMap[nPos_i][nPos_j] = nNum++;
if (nPos_j == 0)
break;
if (pMap[nPos_i][nPos_j - 1] == 0)
nPos_j--;
else
break;
}
else
nPos_j--;
}
break;
default:
assert(0);
break;
}
}
for (int i = 0; i < y; ++i)
{
for (int j = 0; j < x; ++j)
printf("%3d", pMap[j][i]);
printf("\n");
}
/////////////////////////////////////
for (int i = 0; i < x; ++i)
delete [] pMap[i];
delete [] pMap;
return 0;
}
package test;
import java.util.Scanner;
public class SpiralArray {
public enum Direction {
RIGHT, LEFT, DOWN, UP
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int width = scan.nextInt();
int height = scan.nextInt();
int x = 0, y = 0;
int[][] map = new int[width][height];
for(int i = 0;i<width;i++){
for(int j = 0;j<height;j++){
map[i][j] = -1;
}
}
Direction direc = Direction.RIGHT;
for(int num=0;num<(width*height);num++){
map[x][y] = num;
switch(direc){
case RIGHT:
if(y+1 < width && map[x][y+1] == -1 )
y++;
else{
direc = Direction.DOWN;
x++;
}break;
case DOWN :
if(x+1 < height && map[x+1][y] == -1)
x++;
else{
direc = Direction.LEFT;
y--;
}break;
case LEFT :
if(y-1>=0 && map[x][y-1] == -1)
y--;
else{
direc = Direction.UP;
x--;
}break;
case UP :
if(x-1>=0 && map[x-1][y] == -1)
x--;
else {
direc = Direction.RIGHT;
y++;
}break;
}
}
for(int h = 0;h<width;h++){
for(int k = 0;k<height;k++){
System.out.printf("%3d", map[h][k]);
}
System.out.print("\n");
}
}
}
Python 2.7.8 입니다. spiral 하게 array를 채울경우 네개의 변을 한 바퀴 도는 것을 한턴으로 보고, 진행 방향을 우,하,좌,상으로 각각 for문을 돌렸습니다. 한 턴의 각 진행방향 당 채워야 할 숫자가 0,-1,-1,-2 이렇게 줄어드는 것을 이용했습니다.
xy = map(int, raw_input("input(X Y):").split())
matrix = [[0 for col in range(xy[0])] for row in range(xy[1])]
count = 0
for i in range((xy[1] + 1) / 2):
for x in range(xy[0] - (2 * i)):
dx = x + i
matrix[i][dx] = count
count += 1
for y in range((xy[1]- 2 * i) - 1):
dy = y+i+1
matrix[dy][dx] = count
count += 1
for x in range((xy[0]- 2 * i) - 1):
dx -= 1
matrix[dy][dx] = count
count += 1
for y in range(xy[1]- 2 * (i + 1)):
dy -= 1
matrix[dy][dx] = count
count += 1
for i in range(xy[1]):
print "\n"
for j in range(xy[0]):
print "%3d" % matrix[i][j],
코드 더러워영..
def snail(_width,_height):
Matrix = [[0 for x in range(_width)] for x in range(_height)]
width = _width
height = _height
x = 0
y = 0
xstep = 0
ystep = 0
left = 0
right = 1
up = 2
down = 3
direction = right
for index in range(1,_width*_height+1):
Matrix[y][x] = index
if direction == right or direction == left:
if xstep >= width-1:
if direction == right:
direction = down
y+=1
else:
direction = up
y-=1
width -= 1
xstep = 0
continue
if direction == up or direction == down:
if ystep >= height-2:
if direction == down:
direction = left
x-=1
else:
direction = right
x+=1
height -= 1
ystep = 0
continue
if direction == right:
x += 1
xstep += 1
elif direction == left:
x -= 1
xstep += 1
elif direction == up:
y -= 1
ystep += 1
elif direction == down:
y += 1
ystep += 1
print(*Matrix)
snail(10,10)
JAVA 초보입니다.
class SpiralArray{
private int[][] arr = null;
private int n1 = 0, n2 = 0;
SpiralArray(){
this.run();
}
public void run(){
Scanner sc = new Scanner(System.in);
n1 = sc.nextInt();
n2 = sc.nextInt();
arr = new int[n1][n2];
int rowMax=n1, colMax=n2, row=0, col=-1, num=0;
while(rowMax > 0 && colMax > 0 && num != (n1*n2)){
//오른쪽
for(int i=0; i<colMax; i++){
if(num == (n1*n2)){ break; }
else{ arr[row][++col] = num++; }
}
//아래쪽
rowMax--;
for(int i=0; i<rowMax; i++){
if(num == (n1*n2)){ break; }
else{ arr[++row][col] = num++; }
}
colMax--;
//왼쪽
for(int i=0; i<colMax; i++){
if(num == (n1*n2)){ break; }
else{ arr[row][--col] = num++; }
}
//위쪽
rowMax--;
for(int i=0; i<rowMax; i++){
if(num == (n1*n2)){ break; }
else{ arr[--row][col] = num++; }
}
colMax--;
}
for(int i=0; i<n1; i++){
for(int j=0; j<n2; j++){
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
sc.close();
}
}
public class CodeDoZang {
public static void main(String[] args) {
new SpiralArray();
}
}
/*
5 7
0 1 2 3 4 5 6
19 20 21 22 23 24 7
18 31 32 33 34 25 8
17 30 29 28 27 26 9
16 15 14 13 12 11 10
*/
Swift로 작성하였습니다.
enum Direction {
case Right, Down, Left, Up
}
func nextSpiralF(var spiralMap: Array<Array<Int>>)(var direct: Direction) -> ((x: Int, y: Int), Int) -> ((Direction, (x: Int, y: Int), Array<Array<Int>>)) {
return {
spiralMap[$0.y][$0.x] = $1
switch direct {
case .Right where $0.x + 1 >= spiralMap[0].count || spiralMap[$0.y][$0.x + 1] != -1 : direct = .Down
case .Down where $0.y + 1 >= spiralMap.count || spiralMap[$0.y + 1][$0.x] != -1 : direct = .Left
case .Left where $0.x - 1 < 0 || spiralMap[$0.y][$0.x - 1] != -1 : direct = .Up
case .Up where $0.y - 1 < 0 || spiralMap[$0.y - 1][$0.x] != -1 : direct = .Right
default: break
}
return (direct, $0, spiralMap)
}
}
func printSpiralMap(spiralMap: Array<Array<Int>>) {
spiralMap.forEach {
$0.forEach { print(String(format: "%3d", $0), separator: "", terminator: " ") }
print("")
}
}
func main(x x: Int, y: Int) {
let nextSpiral = nextSpiralF(Array<Array<Int>>(count: y, repeatedValue: Array(count: x, repeatedValue: -1)))(direct: Direction.Right)
let result = (0..<x * y).reduce( (direct: Direction.Right, point: (x: -1, y: 0), spiralMap: Array<Array<Int>>()) ) {
switch $0.0.direct {
case .Right: return nextSpiral(($0.0.point.x + 1, $0.0.point.y), $0.1)
case .Down: return nextSpiral(($0.0.point.x, $0.0.point.y + 1), $0.1)
case .Left: return nextSpiral(($0.0.point.x - 1, $0.0.point.y), $0.1)
case .Up: return nextSpiral(($0.0.point.x, $0.0.point.y - 1), $0.1)
}
}
printSpiralMap(result.spiralMap)
}
main(x: 6, y: 10)
/*
Output
0 1 2 3 4 5
27 28 29 30 31 6
26 47 48 49 32 7
25 46 59 50 33 8
24 45 58 51 34 9
23 44 57 52 35 10
22 43 56 53 36 11
21 42 55 54 37 12
20 41 40 39 38 13
19 18 17 16 15 14
*/
Java로 작성하였습니다.
다른분들 처럼 enum을 사용하긴 했지만, 반복문 안에 case로 붙는게 맘에 안들어서 enum안에 메소드를 만들었습니다.
public class SpiralArray {
enum Direction {
RIGHT(1,0), DOWN(0,1), LEFT(-1,0), UP(0,-1);
private int dx, dy;
private Direction(int dx, int dy){
this.dx = dx;
this.dy = dy;
}
public Direction turn(){
switch(this){
case RIGHT : return DOWN;
case DOWN : return LEFT;
case LEFT : return UP;
case UP : return RIGHT;
default : return RIGHT;
}
}
}
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int rowCount = in.nextInt();
int colCount = in.nextInt();
int[][] array = new int[rowCount][colCount];
initArray(array);
fillSprial(array);
printArray(array);
}
private static void initArray(int[][] array) {
for(int i=0; i<array.length; i++){
for(int j=0; j<array[i].length; j++)
array[i][j] = -1;
}
}
private static void fillSprial(int[][] array) {
int rowCount = array.length;
int colCount = array[0].length;
int count = rowCount * colCount;
Direction direction = Direction.RIGHT;
int row = 0, col = 0;
for(int i=0; i<count; i++){
array[row][col] = i;
int nextRow = row + direction.dy;
int nextCol = col + direction.dx;
if(0 > nextRow || nextRow >= rowCount ||
0 > nextCol || nextCol >= colCount ||
array[nextRow][nextCol] != -1)
direction = direction.turn();
row += direction.dy;
col += direction.dx;
}
}
public static void printArray(int[][] array){
for(int i=0; i<array.length; i++){
for(int j=0; j<array[i].length; j++)
System.out.print(array[i][j] + "\t");
System.out.println();
}
}
}
이렇게 짤 수도 있네요. Python입니다.
h, w = map(int, input().split(' '))
lst = [[-1 for x in range(0, w)] + [0] for x in range(0, h)] + [[0 for x in range(0, w + 1)]]
x = y = cnt = 0
grow = (0, 1, 0, -1)
dx = 0
dy = 1
while (lst[x][y] < 0):
lst[x][y] = cnt
cnt = cnt + 1
if (lst[x + grow[dx]][y + grow[dy]] > -1):
dx = (dx + 1) % 4
dy = (dy + 1) % 4
x += grow[dx]
y += grow[dy]
for x in range(0, h):
for y in range (0, w):
print ("%3d " % lst[x][y], end="")
print()
[ 파이썬 3.5 ]
def makeBox(vX, vY) :
box=[]
for i in range(vY) :
box.append([None]*vX)
return box
def pNumber(point, vX, vY, box, iNumber) :
for i in range(vX) :
p = box[point][i]
if p == None :
box[point][i] = iNumber
iNumber += 1
for i in range(vY) :
p = box[i][vX-1-point]
if p == None :
box[i][vX-1-point] = iNumber
iNumber += 1
for i in range(vX) :
p = box[vY-1-point][vX-1-i]
if p == None :
box[vY-1-point][vX-1-i] = iNumber
iNumber += 1
for i in range(vY) :
p = box[vY-1-i][point]
if p == None :
box[vY-1-i][point] = iNumber
iNumber += 1
return iNumber
def numberBox(vX, vY) :
box=makeBox(vX, vY)
point=0
iNumber=0
for i in range(int(vY/2)+int(vY%2)) :
iNumber=pNumber(point, vX, vY, box, iNumber)
point += 1
return box
size=str(input('Input two number : ')).split(' ')
if not len(size) == 2 or not str.isdecimal(size[0]) or not str.isdecimal(size[1]): exit(1)
vX=int(size[0])
vY=int(size[1])
result = numberBox(vX,vY)
max=str(len(str(vX*vY)))
for i in range(len(result)) :
print()
for j in range(len(result[i])) :
eval('print ("%'+max+'d" % result[i][j],end=" ")')
n = input("배열 값 입력 : ")
matrix = [[-1 for i in range(int(n))] for row in range(int(n))]
# 현재 위치, 이동할 값,
where = [0, 0]
move = [[0, 1], [1, 0], [0, -1], [-1, 0]]
count = int(n)
count_f = 1
flag = 0
value = 0
while count > 0:
for i in range(count):
matrix[where[0]][where[1]] = value
value += 1
if i == count - 1:
break;
where[0] += move[flag % 4][0]
where[1] += move[flag % 4][1]
flag += 1
count_f += 1
where[0] += move[flag % 4][0]
where[1] += move[flag % 4][1]
if count_f % 2 == 0:
count -= 1
for i in range(len(matrix)):
print (matrix[i], end = "\n")
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int width = 1, height = 1;
// 맵 초기화
cin >> width >> height;
std::vector<std::vector<int>> map;
for (int x = 0; x < width; ++x)
{
map.emplace_back();
for (int y = 0; y < height; ++y)
{
map[x].push_back(0);
}
}
// 숫자 삽입
int num = 0;
int endNum = width*height;
int currX = 0, currY = 0;
int currWidth = width, currHeight = height;
while (num < endNum)
{
map[currX][currY] = num;
while (num < endNum - 1 && currX < currWidth - 1)
{
++currX;
++num;
map[currX][currY] = num;
}
while (num < endNum - 1 && currY < currHeight - 1)
{
++currY;
++num;
map[currX][currY] = num;
}
while (num < endNum - 1 && currX > width - currWidth)
{
--currX;
++num;
map[currX][currY] = num;
}
--currHeight;
while (num < endNum - 1 && currY > height - currHeight)
{
--currY;
++num;
map[currX][currY] = num;
}
++currX;
--currWidth;
++num;
}
// 출력
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
cout.width(4);
cout << map[x][y];
}
cout << endl << endl;
}
return 0;
}
개판...ㅠ
def const_array(n):
array = []
for x in range(n+2):
array.append([0]*(n+2))
array[x][0] = 1
array[x][-1] = 1
array[0] = [1]*(n+2)
array[-1] = [1]*(n+2)
return array
def remove_board(array):
array.pop(0)
array.pop(-1)
for x in range(len(array)):
array[x].pop(0)
array[x].pop(-1)
def fill_array(array, start_po, start_num, direction):
# (0,1): up (0,-1): down
# (1,0): right (-1,0): left
if array[start_po[0]][start_po[1]] != 0:
return 0, None
if direction == (1,0):
while array[start_po[0]][start_po[1]] == 0:
array[start_po[0]][start_po[1]] = start_num
start_num += 1
start_po[1] += 1
start_po[0] += 1
start_po[1] -= 1
return start_num, (0,-1)
if direction == (-1,0):
while array[start_po[0]][start_po[1]] == 0:
array[start_po[0]][start_po[1]] = start_num
start_num += 1
start_po[1] -= 1
start_po[0] -= 1
start_po[1] += 1
return start_num, (0,1)
if direction == (0,1):
while array[start_po[0]][start_po[1]] == 0:
array[start_po[0]][start_po[1]] = start_num
start_num += 1
start_po[0] -= 1
start_po[0] += 1
start_po[1] += 1
return start_num, (1,0)
if direction == (0,-1):
while array[start_po[0]][start_po[1]] == 0:
array[start_po[0]][start_po[1]] = start_num
start_num += 1
start_po[0] += 1
start_po[0] -= 1
start_po[1] -= 1
return start_num, (-1,0)
def print_array(array):
for x in array:
for y in x:
print('%2d ' % y,end='')
print('\n',end='')
if __name__ == '__main__':
dim = input("Enter the size of spiral array: ")
sprial_array = const_array(int(dim))
direction = (1,0)
start_po = [1,1]
next_num = 1
while True:
next_num, direction = fill_array(sprial_array, start_po, next_num, direction)
if not next_num:
break
remove_board(sprial_array)
print_array(sprial_array)
haeng = input("haeng:")
yeol = input("yeol:")
field = []
def create_field(h, y):
for i in range(h):
field.append([])
for i in range(h):
for k in range(y):
field[i].append(0)
create_field(haeng, yeol)
field[0][0] = "Start"
def print_field():
for i in range(haeng):
print field[i]
class Traveller(object):
def __init__(self, location_h, location_y, step):
self.location_h = location_h
self.location_y = location_y
self.step = step
def scout_right(self):
if self.location_y +1 > yeol-1:
return False
else:
if field[self.location_h][self.location_y + 1 ] == 0:
return True
else:
return False
def move_right(self):
self.location_y += 1
field[self.location_h][self.location_y] = self.step
self.step += 1
def scout_down(self):
if self.location_h +1 > haeng-1:
return False
else:
if field[self.location_h +1][self.location_y] == 0:
return True
else:
return False
def move_down(self):
self.location_h += 1
field[self.location_h][self.location_y] = self.step
self.step += 1
def scout_left(self):
if self.location_y -1 < 0:
return False
else:
if field[self.location_h][self.location_y -1] == 0:
return True
else:
return False
def move_left(self):
self.location_y -= 1
field[self.location_h][self.location_y] = self.step
self.step += 1
def scout_up(self):
if self.location_h -1 < 0:
return False
else:
if field[self.location_h -1][self.location_y] == 0:
return True
else:
return False
def move_up(self):
self.location_h -= 1
field[self.location_h][self.location_y] = self.step
self.step += 1
traveller = Traveller(0, 0, 1)
def master_right():
if traveller.scout_right() == False:
print_field()
else:
while traveller.scout_right()==True:
traveller.move_right()
else:
master_down()
def master_down():
if traveller.scout_down()==False:
print_field()
else:
while traveller.scout_down()==True:
traveller.move_down()
else:
master_left()
def master_left():
if traveller.scout_left()==False:
print_field()
else:
while traveller.scout_left() == True:
traveller.move_left()
else:
master_up()
def master_up():
if traveller.scout_up()==False:
print_field()
else:
while traveller.scout_up() == True:
traveller.move_up()
else:
master_right()
master_right()
여행자가 이동하면서 부딪히면 길을 돌아가는 방식입니다. 행/열 수는 입력할 수 있습니다.
python 3.4
args = input().split(' ')
max_x, max_y = int(args[0]), int(args[1])
x = y = 0
val = 0
way = 'RIGHT'
matrix = [[-1 for col in range(max_x)] for row in range(max_y)]
for val in range(max_x * max_y):
matrix[x][y] = val
if way == 'RIGHT':
if y + 1 == max_x or matrix[x][y+1] > -1:
way = 'DOWN'
x = x + 1
else:
way = 'RIGHT'
y = y + 1
elif way == 'DOWN':
if x + 1 == max_y or matrix[x+1][y] > -1:
way = 'LEFT'
y = y - 1
else:
way = 'DOWN'
x = x + 1
elif way == 'LEFT':
if y - 1 < 0 or matrix[x][y-1] > -1:
way = 'UP'
x = x - 1
else:
way = 'LEFT'
y = y - 1
else: # UP
if x - 1 < 0 or matrix[x-1][y] > -1:
way = 'RIGHT'
y = y + 1
else:
way = 'UP'
x = x - 1
for row in matrix:
for var in row:
print("%3d" % var, end=' ')
print()
#include <stdio.h>
#include <stdlib.h>
#define RIGHT 0
#define DOWN 1
#define LEFT 2
#define UP 3
int main() {
int x, y;
int max_x, max_y, min_x, min_y, pos_x, pos_y;
int ** matrix;
int i, j;
int way;
scanf("%d %d", &x, &y);
printf("변수 초기화...\n");
matrix = (int **) malloc(sizeof(int *) * x);
for (i = 0; i < x; i++) {
matrix[i] = (int *) malloc(sizeof(int) * y);
}
max_x = x - 1;
max_y = y - 1;
min_x = 0;
min_y = 0;
pos_x = 0;
pos_y = 0;
way = RIGHT;
printf("matrix 값 셋팅...\n");
for (i = 0; i < (x * y); i++) {
printf ("%d %d %d %d\n", i, way, pos_x, pos_y);
matrix[pos_y][pos_x] = i;
switch (way) {
case RIGHT:
pos_x ++;
if (pos_x == max_x) {
way = DOWN;
max_x --;
}
break;
case DOWN:
pos_y ++;
if (pos_y == max_y) {
way = LEFT;
min_y ++;
}
break;
case LEFT:
pos_x --;
if (pos_x == min_x) {
way = UP;
max_y --;
}
break;
case UP:
pos_y --;
if (pos_y == min_y) {
way = RIGHT;
min_x ++;
}
break;
}
}
printf("matrix 값 출력...\n");
for (i = 0; i < y; i++) {
for (j = 0; j < x; j++) {
printf("%02d ", matrix[i][j]);
}
printf("\n");
}
for (i = 0; i < x; i++) {
free(matrix[i]);
}
free(matrix);
return 0;
}
x_size, y_size = (eval(x) for x in raw_input().split())
L=[]
for i in range(y_size):L.append([-1]*x_size)
dx,dy = 1,0
x,y = 0,0
for i in range(x_size*y_size):
L[y][x] = i
if not dx+x in range(x_size) or\
not dy+y in range(y_size) or\
L[y+dy][x+dx] != -1:
if (dx,dy) == (1,0) : (dx,dy) = (0,1)
elif (dx,dy) == (0,1) : (dx,dy) = (-1,0)
elif (dx,dy) == (-1,0) : (dx,dy) = (0,-1)
elif (dx,dy) == (0,-1) : (dx,dy) = (1,0)
x+=dx
y+=dy
for line in L:
for el in line:
print "%3d"%el,
print
python 2.7
복소수를 이용한 회전으로 구현해봤습니다. turn_points의 값만큼 이동하다가 회전하는 방식입니다.
import itertools
import sys
def spiral_array(w, h):
array = [-1]*w*h
turn_points = itertools.chain(*zip(range(w,-1,-1), range(h-1,-1,-1)))
point = turn_points.next()
v = 1+0j
x = y = 0
for i in range(w*h):
array[y*w + x] = i
point -= 1
if point < 1:
v *= 1j
point = turn_points.next()
x += int(v.real)
y += int(v.imag)
return array
w, h = int(sys.argv[1]), int(sys.argv[2])
result = spiral_array(w,h)
char_count = len(str(w*h))
f = (("%"+str(char_count+2)+"d") * w +"\n") * h
print(f % tuple(result))
결과
$ python SpiralArray.py 7 7
0 1 2 3 4 5 6
23 24 25 26 27 28 7
22 39 40 41 42 29 8
21 38 47 48 43 30 9
20 37 46 45 44 31 10
19 36 35 34 33 32 11
18 17 16 15 14 13 12
#include <stdio.h>
#include <stdlib.h>
void generate_num(int ** arr,int col,int row);
void print_num(int ** arr,int col,int row);
int main(void)
{
int col,row;
int i,j;
int ** arr = NULL;
//1.allocation_memory
scanf("%d %d",&col,&row);
arr = (int **)malloc(sizeof(int *)*row);
for(i=0;i<row;i++)
arr[i]=(int*)malloc(sizeof(int)*col);
//2.generate_number
generate_num(arr,col,row);
print_num(arr,col,row);
return 0;
}
void generate_num(int ** arr,int col,int row)
{
int num=0;
int i=0;
int col_max=col;
int row_max=row;
int col_min=0;
int row_min=0;
while(num<row*col)
{
for(i=col_min;i<col_max;i++)
{
arr[row_min][i]=num++;
}
row_min++;
for(i=row_min;i<row_max;i++)
{
arr[i][col_max-1]=num++;
}
col_max--;
for(i=col_max-1;i>=col_min;i--)
{
arr[row_max-1][i]=num++;
}
row_max--;
for(i=row_max-1;i>=row_min;i--)
{
arr[i][col_min]=num++;
}
col_min++;
}
}
void print_num(int ** arr,int col,int row)
{
int i,j;
int num=1;
for(i=0;i<row;i++)
{
for(j=0;j<col;j++)
{
printf("%2d ",arr[i][j]);
}
printf("\n");
}
return;
}
JAVA로 짜봤습니다 입력부분은 생략하고 입력값이 정사각형이라고 가정할시에 짜봤는데 횟수의 반복이 입력받은 값은 1번 그 후로는 2번씩 반복 되더군요 예를 들어 6이 입력되면 처음에는 0~5까지 6까지 1번 그리고 6~10,11~15 5씩 2번 ... 4,3,2,1 씩 2번 이렇게 반복이 됩니다. 그리고 오른쪽 아래쪽 왼쪽 위쪽 순으로 반복이 될때 오른쪽이랑 아래쪽은 각각 값의 +가 되고 왼쪽 위쪽은 각각 값의 -이 되어서 2번씩 반복할때마다 k값을 -1곱하면서 +1,-1 되게 구했습니다
import java.util.Scanner;
public class test30 {
public static void main(String[] args) {
int[][] arr;
int k = 1;
int a,b;
int cnt=1;
int ber=0;
int col=0,row=-1;
Scanner scan = new Scanner(System.in);
a = scan.nextInt();
b = scan.nextInt();
int num = a;
arr = new int[a][b];
while(ber<(a*b)){
for(int i=0; i<num; i++){
row = row+k;
arr[col][row] = ber;
ber++;
}
cnt++;
if(cnt==2){
num--;
cnt=0;
}
for(int i=0; i<num; i++){
col = col+k;
arr[col][row] = ber;
ber++;
}
cnt++;
k = k*-1;
}
for(int i=0; i<a; i++){
for(int j=0; j<a; j++){
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
}
Ruby
cube = ->x,y { (0...y).map {|e| [*0...x].product [e] } }
peel = ->cub { h,*t = cub; h ? h + peel[t.transpose.reverse] : [] }
sprl = ->x,y,c=cube[x,y],s=peel[c] { c.map {|r| r.map {|e|"%3d"%s.index(e)}*''} }
Test
expect(sprl[4,3]).to eq [" 0 1 2 3",
" 9 10 11 4",
" 8 7 6 5"]
expect(sprl[6,6]).to eq [" 0 1 2 3 4 5",
" 19 20 21 22 23 6",
" 18 31 32 33 24 7",
" 17 30 35 34 25 8",
" 16 29 28 27 26 9",
" 15 14 13 12 11 10"]
Output
#=> puts sprl[6,6]
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
python 3.5
import numpy as np
def make_spiral_array(a, b):
array = np.zeros((a, b))
i = 0
x, y = 0, 0
k, j = a, b
c, d = -1, 0
p = 0
while(i!=a*b):
array[x][y] = i
i += 1
if p == 0:
y += 1
if y == k:
p = 1
y = k - 1
x += 1
k -= 1
elif p == 1:
x += 1
if x == j:
p = 2
x = j - 1
y -= 1
j -= 1
elif p == 2:
y -= 1
if y == c:
p = 3
y = c + 1
x -= 1
c += 1
elif p == 3:
x -= 1
if x == d:
p = 0
x = d + 1
y += 1
d += 1
return array
print(make_spiral_array(6,6))
보기 어려운 코드..
class cursor:
def __init__(self, A):
self.loc, self.head, self.A, self.count = ([0,0], [0,1], A, 0)
self.x_len, self.y_len =(len(A), len(A[0]))
print("생성")
def go(self):
self.refresh()
self.count += 1
self.loc[0], self.loc[1] = (self.loc[0]+self.head[0], self.loc[1]+self.head[1])
def refresh(self):
self.A[self.loc[0]][self.loc[1]] = self.count
def turn(self):
if self.head == [0,1]: self.head = [1,0]
elif self.head == [1,0]: self.head = [0,-1]
elif self.head == [0,-1]: self.head = [-1,0]
elif self.head == [-1,0]: self.head = [0,1]
while __name__ == '__main__':
x, y = map(int, input("N N 형태로 입력:").split(" "))
mat = []
for m in range(y):
mat.append([])
for n in range(x):
mat[m].append(-1)
c = cursor(mat)
for i in range(x-1): c.go()
print(c.loc)
while 1:
c.turn()
if y>1:
for i in range(y-1):c.go()
y -= 1
c.turn()
if x>1:
for i in range(x-1):c.go()
x -= 1
print(x,y)
if x==1 or y==1:
if x==1:
c.turn()
for i in range(y-1):c.go()
c.refresh()
break
for i in range(len(c.A)):
for j in range(len(c.A[i])):
print('{0:>7}'.format(c.A[i][j]), end = "")
print()
파이썬
import java.util.Scanner;
public class Spiral_Array {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String[] inpt = scan.nextLine().split(" ");
int[] length = {0,0};
for (int i = 0; i<inpt.length; i++){
length[i] = Integer.parseInt(inpt[i]);
}
Map map = new Map(length[0], length[1]);
map.draw();
}
public static class Map {
int[][] map;
public Map(int m, int n){
map = new int[m][n];
}
public void draw(){
int m = map.length, n = map[0].length;
Cursor cursor = new Cursor(m, n, this);
map[0][0] = 1;
for (int i = 1; i < m*n; i++){
cursor.go();
map[cursor.y][cursor.x] = i;
}
map[0][0] = 0;
for (int[] j : map){
for (int i : j){
System.out.print(String.format("%3d", i));
}
System.out.println();
}
}
public boolean isFull(int y, int x){
if (map[y][x] != 0)
return true;
else
return false;
}
}
public static class Cursor {
int y = 0, x = 0;
int dy = 0, dx = 1;
int m, n;
Map map;
public Cursor(int sm, int sn, Map mp){
m = sm;
n = sn;
map = mp;
}
public void go(){
if ((0<=y+dy && y+dy<m) && (0<=x+dx && x+dx<n) && !(map.isFull(y+dy, x+dx))){
y = y+dy;
x = x+dx;
} else {
turn();
y = y+dy;
x = x+dx;
}
}
public void turn(){
if (dy == 0 && dx == 1){
dy = 1;
dx = 0;
} else if (dy == 1 && dx == 0){
dy = 0;
dx = -1;
} else if (dy == 0 && dx == -1){
dy = -1;
dx = 0;
} else if (dy == -1 && dx == 0){
dy = 0;
dx = 1;
}
}
}
}
자바
커서를 생성 후 커서를 이동하여 값을 덮어씁니다.
void makeSpiral(int row, int col) {
int[][] arr = new int[row][col];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
arr[i][j] = -1;
}
}
int num = 0;
int rIdx = 0, cIdx = 0;
Direction direction = Direction.RIGHT;
while( num < row * col ) {
arr[rIdx][cIdx] = num++;
switch ( direction ) {
case RIGHT:
if( cIdx+1<col && arr[rIdx][cIdx+1] == -1 ){
cIdx++;
}else {
direction = Direction.BOTTOM;
rIdx++;
}
break;
case BOTTOM:
if( rIdx+1<row && arr[rIdx+1][cIdx] == -1 ){
rIdx++;
}else {
direction = Direction.LEFT;
cIdx--;
}
break;
case LEFT:
if( cIdx-1>=0 && arr[rIdx][cIdx-1] == -1 ){
cIdx--;
}else {
direction = Direction.TOP;
rIdx--;
}
break;
case TOP:
if( rIdx-1>=0 && arr[rIdx-1][cIdx] == -1 ){
rIdx--;
}else {
direction = Direction.RIGHT;
cIdx++;
}
break;
default:
break;
}
}
for (int i = 0; i < row; i++) {
System.out.println();
for (int j = 0; j < col; j++) {
System.out.print(arr[i][j] + " ");
}
}
}
주석이 필요없는 가독성 높은 코드에 도전해보았습니다. python 3.5
import numpy as np # 2D Array 사용 위해
class point_2D:
def __init__(self,x,y):
self.x=x
self.y=y
def Change_Direction(direction):
if direction=='right' :
direction='down'
return direction
if direction=='left' :
direction='up'
return direction
if direction=='up' :
direction='right'
return direction
if direction=='down' :
direction='left'
return direction
def Find_Next(sa,direction,current_position,array_size):
limit=array_size
next_position=point_2D(0,0)
next_position.x=current_position.x
next_position.y=current_position.y
if direction=='right' and (current_position.y+1)<limit and sa[current_position.x,current_position.y+1]==-1:
next_position.y=current_position.y+1
return (next_position,direction)
if direction=='left' and (current_position.y-1)>-1 and sa[current_position.x,current_position.y-1]==-1:
next_position.y=current_position.y-1
return (next_position,direction)
if direction=='up' and (current_position.x-1)>-1 and sa[current_position.x-1,current_position.y]==-1 :
next_position.x=current_position.x-1
return (next_position,direction)
if direction=='down' and (current_position.x+1)<limit and sa[current_position.x+1,current_position.y]==-1 :
next_position.x=current_position.x+1
return (next_position,direction)
direction=Change_Direction(direction)
next_position=Find_Next(sa,direction,current_position,limit)
return next_position
def Write_Array(sa,next_position,i) :
sa[next_position.x,next_position.y]=i
def MakeSpiralArray(array,array_size):
sa=array
N=array_size
direction="right"
current_position=point_2D(0,0)
next_position=point_2D(0,0)
Write_Array(sa,current_position,0)
for i in range(1,N**2) :
current_position,direction=Find_Next(sa,direction,current_position,N)
Write_Array(sa,current_position,i)
def print_array(array,array_size):
ar=array
N=array_size
for i in range(N):
for j in range(N):
print("%3d" % ar[i,j],end="")
print("")
#### main ####
N=6
sa=np.full((N,N),-1,dtype=int)
MakeSpiralArray(sa,N)
print_array(sa,N)
파이썬입니다. 방향과 방향에 따른 오프셋, 테두리검사 위치 등을 튜플을 이용해서 if 문 하나로 방향을 바꾸는 동작을 작성했는데.... 여전히 부족하네요...
w, h = [int(x) for x in input().split()[:2]]
matrix = [0] * (w * h)
directions = (1, w, -1, -w)
cp, cd, n = 0, 0, 0
while n < w * h:
matrix[cp] = n
cy, cx = divmod(cp, w)
edges = ((w-1, cy), (cx, h-1), (0, cy), (cx, 1))
if (cx, cy) != (edges[cd]) and 0 <= cp + directions[cd] < w * h and\
matrix[cp + directions[cd]] == 0:
cp += directions[cd]
else:
cd = (cd + 1) % 4
cp += directions[cd]
n += 1
print('\n'.join(' '.join("{:>3d}".format(matrix[j*w+i]) for i in range(w)) for j in range(h)))
# 입력 값에서 배열 만들기
print("Spiral Array")
a = input("number number")
b = len(a)
j = 0
for i in a:
if i == " ":
break
j += 1
c = int(a[:j])
d = int(a[j:b])
mat=[[0 for col in range(c)]for row in range(d)]
# 배열에 숫자
i=0
z=c*d
c=c-1#가로 종점 좌표
d=d-1#세로 종점 좌표
x,y=0,0#가로,세로 좌표
dx,dy=1,1#방향 변환 벡터 1은 가로 세로 증가 의미 -1은 가로 세로 감소 의미
o=0#가로 시작점 좌표
p=1#세로 시작점 좌표
while i!=z:
if dx==1 and dy==1:
mat[x][y]=i
y=y+1
i=i+1
if y==c:
dx=-1
c=c+dx
if dx==-1 and dy==1:
mat[x][y]=i
x = x + 1
i=i+1
if x==d:
dy=-1
d=d+dy
if dx==-1 and dy==-1:
mat[x][y] = i
y=y-1
i=i+1
if y==o:
dx=1
o=o+dx
if dx==1 and dy==-1:
mat[x][y] = i
x=x-1
i=i+1
if x==p:
dy=1
p=p+dy
for row in mat:
print(row)
답안 풀다가, enum 부분은 이승효님것을 참고해서 변경했습니다~
JAVA 입니다.
package test1;
import java.util.Arrays;
import java.util.Scanner;
//문제는 다음과 같다:
//
//6 6
//
// 0 1 2 3 4 5
// 19 20 21 22 23 6
// 18 31 32 33 24 7
// 17 30 35 34 25 8
// 16 29 28 27 26 9
// 15 14 13 12 11 10
// 0 1
// 3 2
// 1 2
// 4 3
// 0 1 2
// 7 8 3
// 6 5 4
// 0 1 2 3
// 12 13 14 4
// 11 16 15 5
// 10 9 8 7 6
//위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
public class Spriral_array {
public enum Direction { // 방향을 나타내는 enum입니다~
RIGHT(1), DOWN(2), LEFT(3), UP(4);
private int value;
private Direction(int value) {
this.value = value;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int row = 6;// sc.nextInt();
int col = 6;// sc.nextInt();
int matrix[][] = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
matrix[i][j] = -1;
}
}
// Arrays.fill(matrix, -1);
// 계속 오른쪽으로 회전
// 오른쪽으로 이동, 아래로 이동, 왼쪽으로 이동, 위로 이동 순서로 반복
// direction % 4 == 0 오른쪽
// direction % 4 == 1 왼쪽
// 오른쪽
int direction = 0;
int temp_num = 0;
int r = 0;
int c = 0;
Direction direc_enum = Direction.RIGHT;
for (int i = 0; i < row * col; i++) {
matrix[r][c] = i;
switch (direc_enum) {
case RIGHT:
if (c + 1 < col && matrix[r][c + 1] == -1) {
c++;
} else {
direc_enum = Direction.DOWN;
r++;
}
break;
case DOWN:
if (r + 1 < row && matrix[r + 1][c] == -1) {
r++;
} else {
direc_enum = Direction.LEFT;
c--;
}
break;
case LEFT:
if (c - 1 >= 0 && matrix[r][c - 1] == -1) {
c--;
} else {
direc_enum = Direction.UP;
r--;
}
break;
case UP:
if (r - 1 >= 0 && matrix[r - 1][c] == -1) {
r--;
} else {
direc_enum = Direction.RIGHT;
c++;
}
break;
default:
break;
}
}
for (int r1 = 0; r1 < row; r1++) {
for (int c1 = 0; c1 < col; c1++) {
System.out.print(matrix[r1][c1]);
System.out.printf("\t");
}
System.out.println();
}
}
}
import java.util.Scanner;
public class No2_SpiralArray {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
String line = scan.nextLine();
String[] strArray = line.split(" ");
int yRange = Integer.parseInt(strArray[0]);
int xRange = Integer.parseInt(strArray[1]);
int[][] spiralArray = genSpiralArray(xRange, yRange);
printArray(spiralArray);
}
public static int[][] genSpiralArray(int xRange, int yRange){
int[][] spiralArray = new int[yRange][xRange];
int x = 0, y = 0;
int num = 0;
boolean xIncFlag = true;
boolean yIncFlag = true;
int xLeftBound = 0;
int xRightBound = xRange - 1;
int yTopBound = 1;
int yBottomBound = yRange - 1;
boolean xyToggleFlag = true; //true is x, false is y
while(true){
spiralArray[y][x] = num;
if(xyToggleFlag){
if(xIncFlag) x++;
else x--;
} else {
if(yIncFlag) y++;
else y--;
}
if(xIncFlag && x == xRightBound) {
xIncFlag = false;
xRightBound--;
xyToggleFlag = false;
} else if(!xIncFlag && x == xLeftBound) {
xIncFlag = true;
xLeftBound++;
xyToggleFlag = false;
}
if(yIncFlag && y == yBottomBound) {
yIncFlag = false;
yBottomBound--;
xyToggleFlag = true;
} else if(!yIncFlag && y == yTopBound) {
yIncFlag = true;
yTopBound++;
xyToggleFlag = true;
}
if(num == (xRange * yRange - 1))
break;
num++;
}
return spiralArray;
}
public static void printArray(int[][] array){
for(int y = 0; y<array.length; y++){
for(int x = 0; x<array[0].length; x++){
System.out.print(String.format("%3d ", array[y][x]));
}
System.out.println();
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int nRow =1, nColmn=1;
cin >> nRow >> nColmn;
int **matrix = new int*[nRow];
for (int nrow = 0; nrow < nRow; ++nrow)
{
matrix[nrow] = new int[nColmn];
}
int nMax =0;
int nflag = 0;
int x = 0;
int y = 0;
int nXWall_P =1, nYWall_P =1;
int nXWall_N =1, nYWall_N =1;
while (true)
{
matrix[x][y] = nMax;
if(nMax == nRow*nColmn -1 )
break;
if(nflag == 0)
{
if(y < nColmn - nYWall_P)
y += 1;
else
{
nYWall_P++;
nflag++;
}
}
if(nflag == 1)
{
if(x < nRow - nXWall_P)
x += 1;
else
{
nXWall_P++;
nflag++;
}
}
if(nflag == 2)
{
if(y >= nYWall_N)
y -= 1;
else
{
nYWall_N++;
nflag++;
}
}
if(nflag == 3)
{
if (x > nXWall_N)
x -= 1;
else
{
nXWall_N++;
nflag = 0;
continue;
}
}
if(++nMax == nRow*nColmn)
break;
}
for (int i =0; i< nRow; i++)
{
for (int j=0; j < nColmn; j++)
{
cout <<matrix[i][j] << " ";
}
cout <<"\r\n";
}
return 0;
}
파이썬 3.5로 작성되었습니다.
num = []
def matrix(m, n):
for i in range(m):
for j in range(n):
num.append(0)
count = 0
order = 0
for i in range(m):
num[i] = count
count += 1
order = m - 1
mc = m
nc = n
while 1:
nc -= 1
for i in range(nc):
num[order+m] = count
order += m
count += 1
if count >= m*n: break
mc -= 1
for i in range(mc):
num[order-1] = count
order -= 1
count += 1
if count >= m*n: break
nc -= 1
for i in range(nc):
num[order-m] = count
order -= m
count += 1
if count >= m*n: break
mc -= 1
for i in range(mc):
num[order+1] = count
order += 1
count += 1
if count >= m*n: break
s = 0
while s < m*n:
if num[s] < 10:
print("", end=" ")
print(num[s], end=" ")
s += 1
if s % m == 0:
print("")
ib = input().split(' ')
matrix(int(ib[0]), int(ib[1]))
[결과화면]
4 3
0 1 2 3
9 10 11 4
8 7 6 5
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
결과화면을 그림을 첨부할 줄 몰라서 일일히 타이핑했습니다...
파이썬 배운지 얼마되지 않아서 5시간 걸렸습니다 ㅠㅠ
맨 아래 두 줄의 두 개의 입력 받는 부분은
2016/01/07 01:27 카카달려
님이 쓰신 코드 부분을 참고하였습니다.
감사합니다.
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; // 행렬 가로:6,세로:6으로 가정. int a[7][7]; // 1-based indexing 사용! int main(){ int val = 0; int idx = 1; while (idx <= 3){ for (int i = idx; i <= 6-idx+1; i++) a[idx][i] = val++; for (int i = idx+1; i <= 6-idx+1; i++) a[i][6-idx+1] = val++; for (int i = 6-idx; i >= idx; i--) a[6-idx+1][i] = val++; for (int i = 6-idx; i >= idx+1; i--) a[i][idx] = val++; idx++; } // 이 시점에서 배열은 이미 다 완성됨 // 이제 formatting 작업 for (int i = 1; i <= 6; i++){ for (int j = 1; j <= 6; j++){ if (a[i][j] < 10) printf(" %d ",a[i][j]); else printf("%d ",a[i][j]); } printf("\n"); } return 0; }
C++ 입니다. 단순 구현문제네요...약간만 수정하면 임의의 nxm 행렬에 대해서도 가능합니다.
#include <stdio.h>
#include <stdlib.h>
#define RIGHT 1
#define DOWN 2
#define LEFT 3
#define UP 4
int main(void)
{
int height, width, i, j, number, direc, wall;
int **arr;
wall = 0;
direc = RIGHT;
printf("Size(x * x): ");
scanf_s("%d %d", &height, &width);
arr = (int**)malloc(sizeof(int*) * height); //2차원 동적 배열 선언//
for (i = 0; i < height; i++) {
arr[i] = (int*)malloc(sizeof(int) * width);
}
i = 0;
j = -1;
for (number = 0; number < height * width; number++) { //동적 배열에 숫자 입력//
if (direc == RIGHT) {
if (j == width - 1 - wall) {
i++;
direc = DOWN;
}
else
j++;
}
else if (direc == DOWN) {
if (i == height -1 - wall) {
j--;
direc = LEFT;
}
else
i++;
}
else if (direc == LEFT) {
if (j == wall) {
i--;
direc = UP;
wall++;
}
else
j--;
}
else if (direc == UP) {
if (i == wall) {
j++;
direc = RIGHT;
}
else
i--;
}
arr[i][j] = number;
}
for (i = 0; i < height; i++) { //모든 숫자 출력//
for (j = 0; j < width; j++) {
printf("%2d ", arr[i][j]);
}
printf("\n");
}
for (i = 0; i < height; i++) { //2차원 동적배열 해제//
free(arr[i]);
}
free(arr);
return 0;
}
package main
import (
"fmt"
"os"
)
type Dir int
const INVALID_INDEX = -1
const (
RIGHT Dir = iota
DOWN
LEFT
UP
)
type Board struct {
width, height int
data [][]int
}
func NewBoard(width, height int) *Board {
b := Board{}
b.width = width
b.height = height
b.data = make([][]int, height)
for i := 0; i < height; i++ {
b.data[i] = make([]int, width)
}
for j := 0; j < height; j++ {
for i := 0; i < width; i++ {
b.data[j][i] = INVALID_INDEX
}
}
return &b
}
func (b *Board) Valid(x, y int) bool {
if x < 0 || x >= b.width || y < 0 || y >= b.height {
return false
}
if (b.data[y][x] != INVALID_INDEX) {
return false
}
return true
}
func (b *Board) Show() {
for j := 0; j < b.height; j++ {
for i := 0; i < b.width; i++ {
fmt.Printf("%3d ", b.data[j][i])
}
fmt.Println()
}
}
type Object struct {
x, y int
dir Dir
index int
board *Board
}
func NewObject(b *Board) *Object {
o := Object{}
o.board = b
return &o
}
func (o *Object) Put() {
o.board.data[o.y][o.x] = o.index
o.index++
}
func (o *Object) Turn() {
o.dir++
o.dir %= 4
}
func (o *Object) Advance() bool {
tx := o.x
ty := o.y
switch o.dir {
case UP: ty--
case DOWN: ty++
case LEFT: tx--
case RIGHT: tx++
}
if (o.board.Valid(tx, ty)) {
o.x = tx
o.y = ty
return true
} else {
return false
}
}
func main() {
width := 0
height := 0
fmt.Printf("Input board width: ")
fmt.Fscanf(os.Stdin, "%d", &width)
fmt.Printf("Input board height: ")
fmt.Fscanf(os.Stdin, "%d", &height)
board := NewBoard(width, height)
obj := NewObject(board)
for {
obj.Put()
if (obj.Advance() == false) {
obj.Turn()
if (obj.Advance() == false) {
break;
}
}
}
board.Show()
}
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
void ShowData( int** data, int row, int col );
void main()
{
int width = 0;
int height = 0;
scanf_s( "%d %d", &width, &height );
int **array = new int *[height];
for( int i = 0; i < height; i++ )
{
array[i] = new int[width];
memset( array[i], 0, sizeof( int ) * width );
}
int colPos = 0;
int rowPos = -1;
int endNum = height * width;
int num = 0;
int directon = 1;
int rowloopSize = width;
int colloopSize = height;
while( num < endNum )
{
for( int i = 0; i < rowloopSize; ++i )
{
rowPos += directon;
array[colPos][rowPos] = num++;
ShowData( array, width, height );
}
colloopSize--;
for( int i = 0; i < colloopSize; ++i )
{
colPos += directon;
array[colPos][rowPos] = num++;
ShowData( array, width, height );
}
rowloopSize--;
directon *= -1;
}
}
// 배열에 입력된 값 출력
void ShowData( int** data, int row, int col )
{
int y, x;
//Sleep( 20 );
for(int i = 0; i < 5000000; ++i )
;
system( "cls" );
for( y = 0; y < col; y++ )
{
for( x = 0; x < row; x++ )
{
if( data[y][x] == 0 && (x != 0 || y != 0))
{
printf( " " );
}
else
printf( "%4d", data[y][x] );
}
printf( "\n\n" ); // 행이 끝났을때 마다 줄 바꿔줌
}
return;
}
'''
입력: 6 6
출력:
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6 이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
'''
y = 6
x = 6
matrix = [[0 for i in range(y)] for j in range(x)]
count = 0
start_y = 0
start_x = 0
end_x = x
end_y = y
task = 0
reserv = False
while count < x*y :
if reserv == False :
for n_x in range(start_x, end_x ) :
matrix[start_y][n_x] = count
count +=1
end_x -=1
for n_y in range(start_y + 1, end_y ) :
matrix[n_y][end_x] = count
count +=1
end_y -=1
else :
for n_x in reversed(range(start_x, end_x )) :
matrix[end_y][n_x] = count
count +=1
start_y +=1
for n_y in reversed(range(start_y, end_y )) :
matrix[n_y][start_x] = count
count +=1
start_x +=1
reserv = not reserv
for elem in matrix :
print (elem)
C언어로 구현하였고 정사각행렬됩니당 N 값은 1이상부터 가능합니다! 알고리즘 접근방법은 첫줄을 N만큼 이동시키면서 value++하여 대입하였고 그다음줄은 아래로 N-1만큼 이동시키면서 value++, 그다음줄도 왼쪽으로 N-1만큼 이동시키면서 value++, 그다음줄은 위로 N-2만큼, 오른쪽으로 N-2만큼, N-3, N-3, N-4, N-4 만큼 되어서 0이되면 반복을 중지합니다. if문이 너무 복잡해져서 전역변수로 방향에따른 x,y의 변화를 배열로 선언했고 방향값은 direct%4 해서 정해주었습니다.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int y[] = { 1, 1, -1, -1 };
int x[] = { 1, -1, -1, 1 };
int main()
{
int n = 0;
scanf(" %d", &n);
int length = n;
int** Mtrx = (int**)malloc(sizeof(int*) * length);
for (int i = 0; i < length; i++)
Mtrx[i] = (int*)malloc(sizeof(int) * length);
int count = 1;
int direct = 0;
int value = 0;
int i = 0, j = 0, c = 0;
while (length)
{
for (int c = 0; c < length; c++)
{
Mtrx[j][i] = value++;
direct % 2 == 0 ?
(c != length - 1 ? i += x[direct % 4] : j += y[direct % 4])
:(c != length - 1 ? j += y[direct % 4] : i += x[direct % 4]);
}
if ((direct) % 2 == 0)
length--;
direct++;
}
for (int w = 0; w < n; w++)
{
for (int m = 0; m < n; m++)
printf("%d ", Mtrx[w][m]);
printf("\n");
}
for (int q = 0; q < n; q++)
free(Mtrx[q]);
free(Mtrx);
}
Delphi 2010
procedure fnSpiralArray(A, B: Integer; Memo1: TMemo); // AxB Matrix
var
Box: array of array of Integer;
i, j, f: Integer;
s: string;
procedure fnRignt(var f: Integer; nStep: Integer);
var
i, k: Integer;
begin
k := B - nStep - 1;
for i := nStep to B - nStep - 2 do
begin
f := f + 1;
Box[nStep, i] := f;
end;
end;
procedure fnDown(var f: Integer; nStep: Integer);
var
i, k: Integer;
begin
k := B - nStep - 1;
for i := nStep to A - nStep - 2 do
begin
f := f + 1;
Box[i, k] := f;
end;
end;
procedure fnLeft(var f: Integer; nStep: Integer);
var
i, k: Integer;
begin
k := A - nStep - 1;
for i := nStep to B - nStep - 2 do
begin
f := f + 1;
Box[k, B - i - 1] := f;
end;
end;
procedure fnUp(var f: Integer; nStep: Integer);
var
i, k: Integer;
begin
for i := nStep to A - nStep - 2 do
begin
f := f + 1;
Box[A - i - 1, nStep] := f;
end;
end;
begin
f := 0;
SetLength(Box, A, B);
for i := 0 to (A - 1) div 2 do
begin
fnRignt(f, i);
fnDown(f, i);
fnLeft(f, i);
fnUp(f, i);
end;
Memo1.Lines.BeginUpdate;
Memo1.Lines.Clear;
for i := 0 to A - 1 do
begin
s := '';
for j := 0 to B - 1 do
s := s + format('%3d', [Box[i, j]]);
Memo1.Lines.Add(s);
end;
Memo1.Lines.EndUpdate;
SetLength(Box, 1);
end;
procedure TForm4.Button3Click(Sender: TObject);
begin
fnSpiralArray(6, 7, Memo1);
end;
올려 놓은 풀이 중 심플한 것(양지훈 님)이 마음에 들었습니다. 그대로 올립니다. 이이상 줄이기는 힘들 듯합니다. 보다 보니 실력이 많이 부족한 것을 느낍니다. 실행 가능하게 아주 조금 변경을 하였네요.
X, Y = map(int, input('Please input Row & Column : ').split(' '))
lis = [[-1 for i in range(0, Y)] for j in range(0, X)]
x, y = 0, 0
dx, dy = 0, 1
count = 0
while lis[x][y] == -1:
lis[x][y] = count
count += 1
x, y = x + dx, y + dy
if x in [-1, X] or y in [-1, Y] or lis[x][y] != -1:
x, y = x - dx, y - dy
dx, dy = dy, -dx
x, y = x + dx, y + dy
for row in lis:
print(row)
# 사용자 입력 (width, height)
WIDTH, HEIGHT = map(int, raw_input('x y (ex. 10 10) : ').split(' '))
DIR_RIGHT, DIR_DOWN, DIR_LEFT, DIR_UP = 0, 1, 2, 3
# x, y축 사용 가능 영역
x1, y1 = 0, 0
x2, y2 = WIDTH, HEIGHT
# 현재 위치
pos_x, pos_y = 0, 0
num = 0
# 진행 방향
dir = DIR_RIGHT
# init matrix
mat = [0] * WIDTH
for k in range(WIDTH):
mat[k] = [0] * HEIGHT
# set value
while num < (WIDTH*HEIGHT):
mat[pos_y][pos_x] = num
if dir==DIR_RIGHT:
if (pos_x+1)>=x2:
dir = DIR_DOWN
x2 -= 1
pos_y += 1
else:
pos_x += 1
elif dir==DIR_DOWN:
if (pos_y+1)>=y2:
dir = DIR_LEFT
y2 -= 1
pos_x -= 1
else:
pos_y += 1
elif dir==DIR_LEFT:
if (pos_x)<=x1:
dir = DIR_UP
x1 += 1
pos_y -= 1
else:
pos_x -= 1
elif dir==DIR_UP:
if (pos_y-1)<=y1:
dir = DIR_RIGHT
y1 += 1
pos_x += 1
else:
pos_y -= 1
num += 1
# print
for val in mat:
print (''.join('%3d' % n for n in val))
재귀적으로 풀었습니다.
class SpiralArrayPrinter {
public:
/*
문제는 다음과 같다:
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/
static void Run() {
const int rsiz = 6;
const int csiz = 6;
std::vector<std::vector<int>> matrix;
for (int i = 0; i < rsiz; ++i) {
matrix.push_back(std::vector<int>(csiz, 0));
}
MatrixWrapper wrap(matrix, 0, 0, rsiz - 1, csiz - 1);
wrap.Fill(0);
for (int r = 0; r < rsiz; ++r) {
for (int c = 0; c < csiz; ++c) {
int val = wrap.Get(r, c);
std::cout << val << ",\t";
}
std::cout << std::endl;
}
}
class MatrixWrapper {
public:
MatrixWrapper(std::vector<std::vector<int>>& raw_matrix,
int top, int left, int bottom, int right)
: raw_matrix_(raw_matrix), top_(top), left_(left), bottom_(bottom), right_(right)
{}
int Get(int r, int c) {
return raw_matrix_[left_ + r][top_ + c];
}
void Set(int r, int c, int val) {
raw_matrix_[left_ + r][top_ + c] = val;
}
void Fill(int add) {
int n = add;
for (int i = 0; i < c_siz(); ++i) {
Set(0, i, n++);
}
for (int i = 1; i < r_siz(); ++i) {
Set(i, c_siz() - 1, n++);
}
for (int i = c_siz() - 2; i >= 0; --i) {
Set(r_siz() - 1, i, n++);
}
for (int i = r_siz() - 2; i >= 1; --i) {
Set(i, 0, n++);
}
auto smaller = CreateSmaller();
if (smaller){
smaller->Fill(n);
}
}
private:
std::shared_ptr<MatrixWrapper> CreateSmaller() {
if (bottom_ - top_ - 2 > 0 && right_ - left_ - 2 > 0)
return std::make_shared<MatrixWrapper>(raw_matrix_, top_ + 1, left_ + 1, bottom_ - 1, right_ - 1);
else
return nullptr;
}
int c_siz() const {
return right_ - left_ + 1;
}
int r_siz() const {
return bottom_ - top_ + 1;
}
std::vector<std::vector<int>>& raw_matrix_;
const int top_;
const int left_;
const int bottom_;
const int right_;
};
};
자바 스크립트 입니다.
var input = prompt("좌표를 띄어쓰기 구분으로 입력(1 1)", "6 6").split(" ");
var rowStart = 0;
var colStart = 0;
var rowLen = parseInt(input[0]);
var colLen = parseInt(input[1]);
var totalLen = rowLen * colLen;
var arr2 = new Array(rowLen);
for(var i = 0; i < arr2.length; i++){
arr2[i] = new Array(colLen);
}
var moveRow = 0;
var moveCol = 1;
var row = 0, col = -1;
var firstLoopEnd = false;
for(var i = 0; i < totalLen; i++){
row += moveRow;
col += moveCol;
arr2[row][col] = i;
if((col == (colLen - 1) && moveCol == 1)){
moveRow = 1;
moveCol = 0;
if(firstLoopEnd) rowLen--;
} else if(((col == colStart) && moveCol == -1)){
moveRow = -1;
moveCol = 0;
rowStart++;
firstLoopEnd = true;
} else if((row == (rowLen - 1) && moveRow == 1)){
moveRow = 0;
moveCol = -1;
if(firstLoopEnd) colStart++;
} else if(((row == rowStart) && moveRow == -1)){
moveRow = 0;
moveCol = 1;
colLen--;
}
}
for(var i = 0; i < arr2.length; i++){
for(var j = 0; j < arr2[0].length; j++){
document.write(arr2[i][j] + ",");
}
document.write("<br>");
}
단순 회전이라고만 생각했는데 내부로 들어갈 때 마다 한칸씩 처리해주는 게 또 변수인 것 같아요.
R = int(input("insert Raw : "))
C = int(input("insert Cal : "))
def spiral_array(R,C):
array = [['X' for i in range(R) ] for j in range(C)]
count = 0
raw, col = 0, 0
raw_dr, col_dr = 0, 1
while(count < R*C):
array[raw][col] = count
raw += raw_dr
col += col_dr
if(raw in [-1,R] or col in [-1,C] or array[raw][col] != 'X'):
raw -= raw_dr
col -= col_dr
raw_dr , col_dr = col_dr, -raw_dr
raw += raw_dr
col += col_dr
count += 1
for i in range(R):
for j in range(C):
print (array[i][j], end=" ")
print ("\n")
spiral_array(R,C)
python 3.5
def Spiral_Array(m,n):
list=[[-1 for j in range(0,n)] for i in range(0,m)]
dx,dy=0,0
di=0
count=0
while(count!=m*n):
if(list[dx][dy]==-1):
list[dx][dy]=count
count+=1
if(di==0):
if(dy+1<n and list[dx][dy+1]==-1):
dy=dy+1
else:
di=1
if(di==1):
if(dx+1<m and list[dx+1][dy]==-1):
dx=dx+1
else:
di=2
if(di==2):
if(dy-1>=0 and list[dx][dy-1]==-1):
dy=dy-1
else:
di=3
if(di==3):
if(dx-1>=0 and list[dx-1][dy]==-1):
dx=dx-1
else:
di=0
for i in range(0,m):
print list[i]
n = int(raw_input())
m = int(raw_input())
Spiral_Array(m,n)
허접한 풀이
void main(void) {
int height = 0;
int width = 1;
while(height != width) {
scanf("%d", &height);
scanf("%d", &width);
}
int** spiral = (int**) malloc (sizeof(int*) * width);
for(int i = 0 ; i< width; i++)
spiral[i] = (int*) malloc (sizeof(int) * width);
for(int i = 0 ; i< width; i++)
for(int j = 0 ; j< width; j++)
spiral[i][j] = 0;
int value = 0;
int i = 0;
int j = 0;
int s_x = 0;
int s_y = 0;
int e_x = width-1;
int e_y = height-1;
for(int n = 0 ; n< (width*width); n++) {
if(j == s_y && i < e_x) {
spiral[i][j] = value;
i++;
if(e_x == i)
s_y++;
}
else if(i == e_x && j < e_y ) {
spiral[i][j] = value;
j++;
if(e_y == j)
e_x--;
}
else if(j == e_y && i >= 0 && i!=s_x) {
spiral[i][j] = value;
if(i > 0 )
i--;
if(s_x == i)
e_y--;
}
else {
spiral[i][j] = value;
j--;
if(s_y == j)
s_x++;
}
value++;
}
for(int i = 0 ; i< width; i++) {
for(int j = 0 ; j< width; j++) {
printf("%d\t",spiral[j][i]);
}
printf("\n");
}
}
using System;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
int xsize = 10;
int ysize = 10;
int[,] a = new int[xsize, ysize];
for(int i = 0; i < xsize; i++)
{
for (int j = 0; j < ysize; j++)
{
a[i, j] = -1;
}
}
direction d = direction.right;
int x = 0;
int y = 0;
for (int i = 0; i < xsize * ysize; i++)
{
a[x, y] = i;
switch (d)
{
case direction.left:
if(x == 0 || a[x-1, y] > -1)
{
d = direction.top;
}
break;
case direction.right:
if (x == xsize-1 || a[x+1, y] > -1)
{
d = direction.bottom;
}
break;
case direction.top:
if (y == 0 || a[x, y-1] > -1)
{
d = direction.right;
}
break;
case direction.bottom:
if (y == ysize-1 || a[x, y+1] > -1)
{
d = direction.left;
}
break;
}
switch (d)
{
case direction.left:
x--;
break;
case direction.right:
x++;
break;
case direction.top:
y--;
break;
case direction.bottom:
y++;
break;
}
print(a, xsize, ysize);
Console.ReadKey();
}
}
static void print(int[,] a, int xsize, int ysize)
{
Console.Clear();
for (int i = 0; i < ysize; i++)
{
for (int j = 0; j < xsize; j++)
{
Console.Write("{0}\t", a[j, i]);
}
Console.WriteLine();
}
}
}
enum direction
{
left, right, top, bottom
}
}
C로 작성한 부분입니다. 조금 무식하게 작성한게 아닌가 싶은데..빨리 다른분들 어떻게 하셨는지 풀이 보고 싶어서 ㅜㅜ 일단 완성 시켜보았습니다.
#include <stdio.h>
int main() {
int input_size_v = 0; //세로
int input_size_h = 0; //가로
int ver_var = 0; //Matrix 입력 시, 세로 크기 변수
int hol_var = 0; //Matrix 입력 시, 가로 크기 변수
int mat[100][100];
int i = 0; //세로 for 문 변수
int j = 0; //가로 for 문 변수
int num = 0; //전체 숫자 카운터
int total_size = 0; //입력된 숫자 사이즈
scanf_s("%d %d", &input_size_h, &input_size_v);
printf("Matrix Size : %d, %d \r\n", input_size_h, input_size_v);
total_size = input_size_h*input_size_v;
ver_var = input_size_v;
hol_var = input_size_h;
while (num < total_size) {
//왼쪽 :: 기입한 Size 까지 숫자 Input
for (; j < hol_var; j++) {
mat[i][j] = num;
num++;
}
j--; //사이즈 이상이므로 -1;
hol_var--; //mat사이즈 -1;
//아래로
for (i++; i < ver_var; i++) {
mat[i][j] = num;
num++;
}
i--; //사이즈 이상이므로 -1;
ver_var--; //mat 사이즈 -1;
//오른쪽
for (j--; j >= input_size_h - hol_var - 1; j--) {
mat[i][j] = num;
num++;
}
j++;
//위로
for (i--; i >= input_size_v - ver_var; i--) {
mat[i][j] = num;
num++;
}
j++;
i++;
}
i = 0;
j = 0;
num = 0;
while (num < total_size)
{
for (i = 0; i < input_size_v; i++) {
for (j = 0; j < input_size_h; j++)
{
printf("%02d ", mat[i][j]);
num++;
}
printf("\r\n");
}
}
system("pause");
return 0;
}
Java 풀이입니다
public class SpiralArray {
public static void main(String[] args) {
int sizeX = 6;
int sizeY = 6;
int[][] spiral = new int[sizeX][sizeY];
for(int i = 0; i < sizeX; i++){
for(int j = 0; j < sizeY; j++){
spiral[i][j] = -1;
}
}
int dx = 1, dy = 0;
int x = 0, y = 0;
for(int i = 0; i < sizeX * sizeY; i++){
spiral[x][y] = i;
if(0 > x + dx || sizeX - 1 < x + dx || spiral[x + dx][y] != -1){
if(dx == 1){
dx = 0;
dy = 1;
}else if(dx == -1){
dx = 0;
dy = -1;
}
}
if(0 > y + dy || sizeY - 1 < y + dy || spiral[x][y + dy] != -1){
if(dy == -1){
dx = 1;
dy = 0;
}else if(dy == 1){
dx = -1;
dy = 0;
}
}
x += dx;
y += dy;
}
for(int i = 0; i < sizeY; i++){
for(int j = 0; j < sizeX; j++){
System.out.print(String.format("%d\t", spiral[j][i]));
}
System.out.print("\n");
}
}
}
#include <iostream>
using namespace std;
void getInput(int ** arr, int row, int column);
int main() {
int row=0, column=0;
cin >> row >> column;
int ** arr = new int *[row];
for(int i=0; i<row; i++) {
arr[i] = new int [column];
}
getInput(arr, row, column);
for(int i=0; i<row; i++) {
for(int j=0; j<column; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
void getInput(int ** arr, int row, int column) {
int inputValue =-1;
int start_i = 0, start_j = 0;
int last_i = row-1, last_j = column-1;
int finalValue = (row*column)-1;
while(inputValue!=finalValue){
for(int j=start_j; j<=last_j; j++) {
inputValue+=1;
arr[start_i][j] = inputValue;
}
if(inputValue==finalValue) break;
for(int i=start_i+1; i<=last_i; i++) {
inputValue+=1;
arr[i][last_j] = inputValue;
}
if(inputValue==finalValue) break;
for(int j=last_j-1; j>=start_j; j--) {
inputValue+=1;
arr[last_i][j] = inputValue;
}
if(inputValue==finalValue) break;
for(int i=last_i-1; i>=start_i+1; i--) {
inputValue+=1;
arr[i][start_j] = inputValue;
}
if(inputValue==finalValue) break;
start_i+=1; start_j+=1; last_i-=1; last_j-=1;
}
}
#include <iostream>
#include <iomanip>
int main(void)
{
int **matrix = nullptr;
int row, col;
int limitX, limitY;
int x, y;
int num = 1;
int delta = 1;
std::cin >> row >> col;
limitX = col;
limitY = row;
y = 0, x = -1;
///////////////////////////////////////////////
matrix = new int* [row];
*matrix = new int[row * col];
for (int i = 1; i < row; i++)
matrix[i] = matrix[i - 1] + col;
///////////////////////////////////////////////
while (limitX >= 0 && limitY >= 0)
{
for (int index = 0; index < limitX; index++)
{
x += delta;
matrix[y][x] = num++;
}
limitY--;
for (int index = 0; index < limitY; index++)
{
y += delta;
matrix[y][x] = num++;
}
limitX--;
delta = -delta;
}
///////////////////////////////////////////////
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
std::cout << std::setw(3) << matrix[i][j] << " ";
}
std::cout << std::endl;
}
///////////////////////////////////////////////
delete[] * matrix;
delete[] matrix;
///////////////////////////////////////////////
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <string>
using namespace std;
void spiral(int**,int,int);
void output(int**,int,int);
int main(void) {
int height, width;
cin >> height >> width;
int** sp = new int*[height];
for (int i = 0; i < height; i++) {
sp[i] = new int[width];
}
spiral(sp, height, width);
output(sp, height, width);
for (int i = 0; i < height; i++) {
delete sp[i];
}
delete[] sp;
system("pause");
return 0;
}
void spiral(int** msp, int mh, int mw) {
int num = 0, i=0;
while (num != mh*mw) {
//Top
//(0, 0) ~ (0, w-1)
//(1, 1) ~ (1, w-2)
for (int j = i; j < mw - i; j++) {
if (num == mh*mw) break; //num이 spiral의 마지막 숫자가 되면 break;
msp[i][j] = num++;
}
//Right
//(1 ,w-1) ~ (h-1, w-1)
//(2, w-2) ~ (h-2, w-2)
for (int j = i+1; j < mh - i; j++) {
if (num == mh*mw) break;
msp[j][mw - i - 1] = num++;
}
//Bottom
//(h-1, w-2) ~ (h-1, 0)
//(h-2, w-3) ~ (h-2, 1)
for (int j = mw - 2 - i; j > i - 1; j--) {
if (num == mh*mw) break;
msp[mh - i - 1][j] = num++;
}
//Left
//(h-2, 0) ~ (1, 0)
//(h-3, 1) ~ (2, 1)
for (int j = mh - 2 - i; j > i; j--) {
if (num == mh*mw) break;
msp[j][i] = num++;
}
i++;
}
}
void output(int** msp, int mh, int mw) {
for (int i = 0; i < mh; i++) {
for (int j = 0; j < mw; j++) {
printf("%4d", msp[i][j]);
}
cout << endl;
}
}
itertools.cycle함수를 이용해 오른쪽, 아래, 왼쪽, 위를 스텝으로 사용하되,
next()함수를 이용해 필요할때만 호출했습니다.
def f(x, y):
board = [[-1] * x for _ in range(y)] # -1로만 채워진 2차원 배열
pattern = itertools.cycle([(0, 1), (1, 0), (0, -1), (-1, 0)])
a, b = next(pattern) # board[i+a][j+b]
i, j = 0, 0 # board[i][j]
n = 0 # 0, 1, 2, ...
while any(-1 in line for line in board): # 리스트에 -1이 없을때까지
# 다음 스텝 조건
if i+a >= y or j+b >= x or (i+a or j+b) < 0 or board[i+a][j+b] != -1:
a, b = next(pattern)
board[i][j] = n
i += a
j += b
n += 1
return board
f(6, 6)
#include <iostream>
using namespace std;
enum eDirection
{
eRight,
eBottom,
eLeft,
eTop,
eEnd
};
void main(void)
{
cout << "숫자 2개 입력 (가로X세로) : ";
int width = 0;
int height = 0;
scanf_s("%d %d", &width, &height);
cout << width << " X " << height << endl;
int** arr;
arr = new int*[height];
for (int i = 0; i < height; i++)
{
(arr[i]) = new int[width];
for (int j = 0; j < width; j++)
{
arr[i][j] = 0;
}
}
int num = 0;
int h = 0;
int w = 0;
int cycle = -1;
int dir = eRight;
while (true)
{
arr[h][w] = num;
switch ((eDirection)dir)
{
case eRight:
if (w >= width - cycle - 1)
{
h++;
dir++;
break;
}
w++;
break;
case eBottom:
if (h >= height - cycle - 1)
{
w--;
dir++;
break;
}
h++;
break;
case eLeft:
w--;
if (w <= cycle)
{
dir++;
cycle++;
break;
}
break;
case eTop:
if (h <= cycle + 1)
{
dir = eRight;
}
h--;
break;
}
num++;
if (num >= width*height)
break;
}
//출력
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
}
매트릭스 만들어서 채우고 출력.
int main(int argc, const char * argv[]) {
int r = 6, c = 6;
int* mat = calloc(r*c, sizeof(int));
fill(mat, r, c);
print(mat, r, c);
free(mat);
return 0;
}
출력은 간단..
void print(int* mat, int rows, int cols) {
for (int r = 0; r < rows; r++) {
for (int c =0; c< cols; c++) {
printf("%3d", mat[r * cols + c]);
}
printf("\n");
}
}
채우려면... 겹겹이 박스를 그린다.
void fill(int* mat, int rows, int cols) {
Pen pen = {mat, rows, cols, 0, 0, 0};
for (int i=0; i < cols-i && i < rows-i; i++) {
box_(&pen, i, i, rows-i-1, cols-i-1);
}
}
Pen은 현재 위치와 채울 값을 누적 기록해야 함.
typedef struct Pen {
int* mat;
int rows;
int cols;
int r;
int c;
int value;
} Pen;
박스는 top/left/bottom/right 를 입력으로 받아서 top -> left -> bottom -> right 순서로 줄을 그리자. 박스가 너무 작으면 그리지 말고.
void box_(Pen* pen, int top, int left, int bottom, int right) {
moveTo(pen, top, left);
lineTo(pen, top, right); if (top == bottom) return;
lineTo(pen, bottom, right); if (left == right) return;
lineTo(pen, bottom, left);
lineTo(pen, top+1, left);
}
moveTo는.. 위치로 점프하면서 점 찍기
void moveTo(Pen* pen, int r, int c) {
pen->r = r;
pen->c = c;
pen->mat[r * pen->cols + c] = pen->value++;
}
그럼 lineTo 는 현재 위치에서 목표 지점으로 1칸씩 이동 (moveTo이용)
void lineTo(Pen* pen, int r, int c) {
while (pen->r != r || pen->c != c) { // 목표 위치에 도달할 때까지
if (abs(pen->r - r) > abs(pen->c - c)) { // 더 차이 많이 나는 방향으로
int dr = pen->r < r ? 1 : -1; // 한칸씩
moveTo(pen, pen->r + dr, pen->c); // 이동
} else {
int dc = pen->c < c ? 1 : -1;
moveTo(pen, pen->r, pen->c + dc);
}
}
}
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
final int n = scanner.nextInt();
final int m = scanner.nextInt();
new SpiralArray().printSpiralArray(n, m);
scanner.close();
}
public void printSpiralArray(final int n, final int m) {
int[][] array = new int[n][m];
int count = 0;
Direction dic = Direction.RIGHT;
int row = 0;
int col = 0;
int rowIndex = 0;
int colIndex = 0;
while(count < n * m) {
if(dic == Direction.RIGHT) {
for( ; colIndex < m - col; colIndex++) {
array[rowIndex][colIndex] = count++;
}
colIndex--;
rowIndex++;
dic = Direction.DOWN;
} else if(dic == Direction.DOWN) {
for( ; rowIndex < n - row; rowIndex++) {
array[rowIndex][colIndex] = count++;
}
rowIndex--;
colIndex--;
dic = Direction.LEFT;
row++;
} else if(dic == Direction.LEFT) {
for( ; colIndex >= col; colIndex--) {
array[rowIndex][colIndex] = count++;
}
colIndex++;
rowIndex--;
dic = Direction.UP;
} else if(dic == Direction.UP) {
for( ; rowIndex >= row; rowIndex--) {
array[rowIndex][colIndex] = count++;
}
rowIndex++;
colIndex++;
dic = Direction.RIGHT;
col++;
}
}
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array[0].length; j++) {
System.out.printf("%2d ", array[i][j]);
}
System.out.println();
}
}
}
이거 그림 첨부 어케 하는거여? 손으로 알고리즘 설명하기에는 너무 귀찮은데 ㅡㅡ;
static void Main(string[] args)
{
int[,] arr = CreateArray(4, 4);
Show(arr);
int[] spiral = SpiralArray(arr);
foreach (var val in spiral)
Console.Write(val + " ");
Console.WriteLine();
}
static int[,] CreateArray(int n, int m)
{
int[,] arr = new int[n, m];
Random rand = new Random();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
arr[i, j] = rand.Next(100);
}
return arr;
}
static int[] GetOneDimArrayFrom(int[,] arr)
{
List<int> arrList = new List<int>();
foreach (var val in arr)
arrList.Add(val);
return arrList.ToArray();
}
static void Show(int[,] arr)
{
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
Console.Write("{0,2} ", arr[i, j]);
Console.WriteLine("\n");
}
int length = arr.GetLength(0) * arr.GetLength(1);
for (int i = 0; i < length; i++)
Console.Write("{0,2} ", i);
Console.WriteLine();
}
static int[] SpiralArray(int[,] arr)
{
int[] oneDimArr = GetOneDimArrayFrom(arr);
int len = oneDimArr.Length;
int w = arr.GetLength(1);
int h = arr.GetLength(0);
int mx = w - 1, my = h - 1, jump = w;
int px = 0, dir = 1, count = w;
List<int> spiral = new List<int>(len);
bool[] check = new bool[len];
Array.Clear(check, 0, len);
spiral.Add(oneDimArr[0]);
check[0] = true;
while (true)
{
for (int i = 0; i < mx ; i++)
{
px += (1 * dir);
if (!(px >= 0 && px <= len) || check[px])
{
px -= (1 * dir);
break;
}
spiral.Add(oneDimArr[px]);
check[px] = true;
}
for (int i = 0; i < my; i++)
{
px += (jump * dir);
if (!(px >= 0 && px <= len) || check[px])
{
px -= (jump * dir);
count--;
break;
}
spiral.Add(oneDimArr[px]);
check[px] = true;
}
dir *= -1;
if (count < 0)
break;
}
return spiral.ToArray();
}
가입 후 처음 남기는 게시물입니다. _ !!! 버그와싸우느라 주석은 없습니다.(으랏챠!) 여긴 c로푸시는 분들이 많군요 (전 c밖에 아직 익숙치가 못해서 ㅠㅠ) 히히히 즐 코 하세요 전 이만 야식먹으러 ☆뿅
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i = 0, j = 0, k = 0, z = 0;
int x = 0, y = 0;
int **ptr = NULL;
scanf_s("%d", &x);
scanf_s("%d", &y);
ptr = (int **)calloc(x , sizeof(int *));
for (int i = 0; i < x; i++)
{
ptr[i] = (int*)calloc(y, sizeof(int));
}
while ( k != x * y - 1 )
{
while (j < y - z -1 )
{
ptr[i][++j] = ++k;
}
while (i < x - z - 1)
{
ptr[++i][j] = ++k;
}
while (j > z)
{
ptr[i][--j] = ++k;
}
while (i > 1 + z)
{
ptr[--i][j] = ++k;
}
z++;
}
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
printf("%d ", ptr[i][j]);
}
printf("\n");
}
return 0;
}
안녕하세요. C++로 풀어봤습니다. 입력 배열 N의 크기만큼 동적할당해서 해봤어요
#include <iostream>
#include <iomanip>
using namespace std;
void main()
{
cout<<"Hello Stranger?"<<endl;
cout<<"N을 입력하시오."<<endl;
int N = 0;
cin>>N;
int M= N;
int** arr = NULL;
arr = new int*[N];
for(int i=0; i<N; i++)
arr[i] = new int[N];
for(int i=0; i<N; i++)
for(int j=0; j<N; j++)
arr[i][j] = 0;
////////////////////////////////////////
int cnt = 0;
int col = 0;
int row = 0;
int inc = 1;
while(true)
{
for(int i=0; i<N; i++)
{
arr[row][col] = cnt;
col += inc;
cnt++;
}
row += inc;
col -= inc;
N--;
if(N == 0)
break;
for(int j=0; j<N; j++)
{
arr[row][col] = cnt;
row += inc;
cnt++;
}
row -= inc;
col -= inc;
inc *= -1;
}
for(int i=0; i<M; i++)
{
for(int j=0; j<M; j++)
cout<<setw(2) << setfill(' ') <<arr[i][j]<<" ";
cout<<endl;
}
}
좀 다른 방식으로 풀어봄
public static int[,] GetSpiralMat(int rSize) {
int matSize = rSize * rSize;
int[,] mat = new int[rSize, rSize];
//Surface position index by Level
Func<int, int, List<Tuple<int, int>>> surfacePos = (k, lvl) => {
int suf2 = k - 1;
int suf3 = k - 2;
List<Tuple<int, int>> positions = new List<Tuple<int, int>>();
if (suf2 > 0) {
foreach (int v in Enumerable.Range(0, k))
positions.Add(new Tuple<int, int>(lvl, lvl + v));
foreach (int v in Enumerable.Range(1, suf2))
positions.Add(new Tuple<int, int>(v + lvl, suf2 + lvl));
foreach (int v in Enumerable.Range(1, suf2))
positions.Add(new Tuple<int, int>(suf2 + lvl, (suf2 + lvl) - v));
foreach (int v in Enumerable.Range(0, suf3))
positions.Add(new Tuple<int, int>((suf3 + lvl) - v, lvl));
}
else if (suf2 == 0) positions.Add(new Tuple<int, int>(lvl, lvl));
return positions;
};
//Surface position Aggregation
List<Tuple<int, int>> matPos = new List<Tuple<int, int>>();
int slvl = 0;
for (int i = rSize; i >= 0; i -= 2) {
matPos.AddRange(surfacePos(i, slvl));
slvl++;
}
//Map number sequence to position
Enumerable.Range(0, matSize).ToList().ForEach(k => mat[matPos[k].Item1, matPos[k].Item2] = k);
return mat;
}
int[,] mat = GetSpiralMat(9);
for (int r = 0; r < mat.GetLength(0); r++) {
for (int c = 0; c < mat.GetLength(1); c++) {
Console.Write($"{mat[r, c]:r3} ");
}
Console.Write('\n');
}
x,y = input().split(' ')
x = int(x)
y = int(y)
list_ = [[[] for i in range(x)] for i in range(y)] # 기본 틀 생성
count = 0 # 넣어야하는 숫자를 카운트해주는 변수
a_wall = 0
b_wall = x-1
c_wall = y-1
d_wall = 0
### 각 a,b,c,d 벽 a_wall
### ____________________
### | |
### d_wall | | b_wall
### |____________________|
### c_wall
while (a_wall <= c_wall or b_wall >= d_wall) and count != x*y:
for i in range(d_wall, b_wall):
if count == x*y: break
list_[d_wall][i] = count
count += 1
# a_wall 라인으로 가다 b_wall을 만날대까지 내려가며 숫자 채움
for i in range(a_wall, c_wall):
if count == x*y: break
list_[i][b_wall] = count
count += 1
# b_wall 라인으로 가다 c_wall을 만날대까지 내려가며 숫자 채움
for i in range(b_wall,d_wall,-1):
if count == x*y: break
list_[c_wall][i] = count
count += 1
# c_wall 라인으로 가다 d_wall을 만날대까지 내려가며 숫자 채움
for i in range(c_wall,a_wall,-1):
if count == x*y: break
list_[i][d_wall] = count
count += 1
# d_wall 라인으로 가다 a_wall을 만날대까지 내려가며 숫자 채움
if a_wall == b_wall == c_wall == d_wall:
list_[d_wall][b_wall] = count
# 이 코드는 (5 5) 형식의 배열의경우 마지막 한자리를 채우기위한 코드.
a_wall += 1
b_wall -= 1
c_wall -= 1
d_wall += 1
# 각벽을 중앙을 기준으로 한칸씩 모아줌.
space = 5
for row in range(y):
for col in range(x): #↓보기좋게 출력하고싶어서..
print(list_[row][col],' '*(space-len(str(list_[row][col]))), end='')
print()
# 출력
#### 2016.11.30 D-449 ####
좀 더 잘하고싶은데 아직 많이 미숙합니다. ㅎ
int main() { int i, j, x, y, N = 0, type = 0; printf("X : "); scanf("%d", &x); printf("Y : "); scanf("%d", &y); int arr; arr = (int)malloc(sizeof(int)y); arr[0] = (int)malloc(sizeof(int)xy); for(i = 1; i < y; i++) { arr[i] = arr[i-1] + x; } for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { arr[i][j] = -1; } } i = 0, j = 0; while (N < xy) { if ((i<0) || (i>=y) || (j<0) || (j>=x) || (arr[i][j] != -1)) { switch (type) { case 0: j--; i++; break; case 1: i--; j--; break; case 2: j++; i--; break; case 3: i++; j++; break; } type = (type+1)%4; } arr[i][j] = N++; switch (type) { case 0: j++; break; case 1: i++; break; case 2: j--; break; case 3: i--; break; } } for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { printf("%3d ", arr[i][j]); } printf("\n"); } free(arr[0]); free(arr); return 0; }
#include <iostream>
using namespace std;
const int MAX = 100;
int dx[] = { 1, 0, -1, 0 };
int dy[] = { 0, 1, 0, -1 };
int main()
{
int m, n;
int matrix[MAX][MAX];
cin >> m >> n;
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
matrix[i][j] = 0;
int count = m * n;
int dir = 0, x = 0, y = 0;
for (int i = 1; i <= count; ++i)
{
matrix[y][x] = i;
if (x + dx[dir] < 0 || x + dx[dir] >= n || y + dy[dir] < 0 || y + dy[dir] >= m
|| matrix[y + dy[dir]][x + dx[dir]] != 0) // 기존의 방향으로 배열을 못채울 경우
dir++; // 방향 변경
dir %= 4;
x += dx[dir];
y += dy[dir];
}
for (int i = 0; i < m; ++i)
{
for (int j = 0; j < n; ++j)
cout << matrix[i][j] << " ";
cout << endl;
}
return 0;
}
한 바퀴 도는 것을 한 사이클이라고 생각해서 함수로 짜서 while문을 돌렸습니다. 생각보다 푸는데 시간이 좀 걸리네요 ㅠㅠ 아직 한참 부족하다는 것을 느낍니다.
#include <iostream>
// value in the matrix element
int value = 1;
// fill the matrix
void fill(int** matrix, int s_col, int s_row, int e_col, int e_row);
// print the matrix
void printMatrix(int** matrix, int row, int col);
int main(void)
{
using std::cin;
int row, col;
// get the row and col dimension
cin >> row >> col;
// allocate matrix
int** matrix = new int* [row];
for(int i = 0; i < row; i++)
matrix[i] = new int[col];
int s_row = 0;
int s_col = 0;
int e_row = row - 1;
int e_col = col - 1;
while(e_row - s_row >= 0 && e_col - s_col >= 0)
{
fill(matrix, s_col, s_row, e_col, e_row);
s_col++;
s_row++;
e_col--;
e_row--;
}
printMatrix(matrix, row, col);
// free matrix
for(int i = 0; i < row; i++)
delete[] matrix[i];
delete[] matrix;
}
void fill(int** matrix, int s_col, int s_row, int e_col, int e_row)
{
// copy the starting point
int row = s_row;
int col = s_col;
while(col <= e_col) matrix[row][col++] = value++;
col--;
row++;
// col 방향으로 한 줄만 채우면 완성인 경우 return
if(s_row == e_row)
return;
else
{
while(row <= e_row) matrix[row++][col] = value++;
row--;
col--;
}
// row 방향으로 한 줄만 채우면 완성인 경우 return
if(s_col == e_col)
return;
else
{
while(col >= s_col) matrix[row][col--] = value++;
col++;
row--;
}
while(row > s_row) matrix[row--][col] = value++;
}
void printMatrix(int** matrix, int row, int col)
{
using std::cout;
using std::endl;
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
cout << matrix[i][j] << "\t";
cout << endl;
}
}
Scanner in = new Scanner(System.in);
int x, y;
System.out.print("행를 입력하세요 : ");
x = in.nextInt();
System.out.print("열을 입력하세요 : ");
y = in.nextInt();
int [][] Array= new int[x][y];
int number = 0;
int s = 1; // 형과 열의 증가, 감소 처리를 위한 변수
int x_ = 0, y_ = -1;
int xx = x, yy = y;
try{
while (number < xx * yy) {
for (int i = 0; i < y; i++) {
number++;
y_ += s;
Array[x_][y_] = number;
System.out.println("y_ :" + y_ + " y :" + y);
}
System.out.println(number +"열 종료");
x--;
for (int j = 0; j < x; j++) {
number++;
x_ += s;
Array[x_][y_] = number;
System.out.println("x_ :" + x_ + " x :" + x);
}
System.out.println(number +"행 종료");
y--;
s *= -1;
}
}
catch(Exception e){
System.out.println(e.getMessage());
}
for (int i = 0; i < Array.length; i++) {
for (int j = 0; j < Array[i].length; j++) {
System.out.print(Array[i][j]+ "\t");
}
System.out.println("");
}
겨우겨우 풀엇네요....ㅠ
#include <stdio.h>
int main()
{
int inPutCol, inPutRow;
int i, j;
int matrixNum;
int cnt;
int flag;
int tempRow, tempCol,outPutRow,outPutCol;
int arrMatrix[100][100];
inPutCol = 0;
inPutRow = 0;
printf("숫자를 입력하세요 : ");
scanf("%d %d", &inPutCol, &inPutRow);
outPutRow = inPutRow;
outPutCol = inPutCol;
tempRow = -1;
tempCol = 0;
matrixNum = 1;
cnt = inPutCol*inPutRow;
j = 0;
i = 0;
flag = 1;
while (cnt > 0)
{
if (flag == 1)
{
printf("flag = %d \n", flag);
for (i = 0; i < inPutRow; i++)
{
tempRow = tempRow + flag;
arrMatrix[tempCol][tempRow] = matrixNum;
printf("[%d,%d] = %d \n", j+1, tempRow+1, matrixNum);
matrixNum++;
cnt--;
}
for (j = 1; j < inPutCol; j++)
{
tempCol = tempCol + flag;
arrMatrix[tempCol][tempRow] = matrixNum;
printf("[%d,%d] = %d \n", tempCol+1, tempRow+1, matrixNum);
matrixNum++;
cnt--;
}
inPutCol--;
inPutRow--;
flag = flag*(-1);
}
else
{
printf("flag = %d \n", flag);
for (j = 0; j < inPutRow; j++)
{
tempRow--;
arrMatrix[tempCol][tempRow] = matrixNum;
printf("[%d,%d] = %d \n", tempCol+1, tempRow+1, matrixNum);
matrixNum++;
cnt--;
}
for (j = 1; j < inPutCol; j++)
{
tempCol--;
arrMatrix[tempCol][tempRow] = matrixNum;
printf("[%d,%d] = %d \n", tempCol+1, tempRow+1, matrixNum);
matrixNum++;
cnt--;
}
inPutCol--;
inPutRow--;
flag = flag*(-1);
}
}
for (i = 0; i < outPutCol; i++)
{
for (j = 0; j < outPutRow; j++)
{
printf("%d ", arrMatrix[i][j]);
}
printf("\n");
}
}
input = raw_input().split(" ")
print input
xInput = int(input[0])
yInput = int(input[1])
xStep, yStep = xInput, yInput
max = xInput * yInput
x, y = 0, -1
p = [0, 1]
matrix = [[0]*yInput for i in xrange(xInput)]
value = 0
isGoing = 1
while(isGoing):
for i in xrange(1, yStep + 1):
x += p[0]
y += p[1]
matrix[x][y] = value
value += 1
if value >= max:
isGoing = 0
break
for i in xrange(1, xStep):
x += p[1]
y += p[0]
matrix[x][y] = value
value += 1
if value >= max:
isGoing = 0
break
xStep -= 1
yStep -= 1
p[1] *= -1
for i in xrange(0, xInput):
for j in xrange(0, yInput):
print("%5d" % matrix[i][j]),
print ""
파이썬으로 작성했습니다.
package codingdojang;
import java.util.Arrays;
import java.util.Scanner;
public class Number2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String[] input = scan.nextLine().split(" ");
scan.close();
int[] step = Arrays.stream(input).mapToInt(Integer::parseInt).toArray();
int xInput = step[0];
int yInput = step[1];
int max = xInput * yInput;
int[] p = {0, 1};
int x = 0;
int y = -1;
Integer[][] matrix = new Integer[xInput][yInput];
int value = 0;
boolean isGoing = true;
while(isGoing) {
for ( int i = 0; i < step[1]; i++ ) {
x += p[0];
y += p[1];
matrix[x][y] = value;
value++;
isGoing = checkValue(value, max);
if (!isGoing)
break;
}
for ( int i = 0; i < (step[0] - 1); i++ ) {
x += p[1];
y += p[0];
matrix[x][y] = value;
value++;
isGoing = checkValue(value, max);
if (!isGoing)
break;
}
step[0]--;
step[1]--;
p[1] *= -1;
}
for ( int i = 0; i < xInput; i++ ) {
for ( int j = 0; j < yInput; j++ ) {
System.out.printf("%5d", matrix[i][j]);
}
System.out.println();
}
}
private static boolean checkValue(int value, int max) {
return value >= max ? false : true;
}
}
자바로 작성했습니다.
너무 무식하게 풀었네요 :)
package com.genius.vernum;
public class SpiralArray {
static int[][] tableA = new int[6][6];
static int[][] tableB = new int[6][6];
public static void main(String[] args) {
int k = 0;
for (int i = 0; i < 6; i++) {
tableA[0][i % 6] = k;
tableB[0][i % 6] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 5; i++) {
tableA[0][(i % 6) + 1] = k;
tableB[0][(i % 6) + 1] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 5; i++) {
tableA[0][(i % 5) + 1] = k;
tableB[0][(i % 5) + 1] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 4; i++) {
tableA[0][(i % 4) + 1] = k;
tableB[0][(i % 4) + 1] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 4; i++) {
tableA[1][(i % 4) + 1] = k;
tableB[1][(i % 4) + 1] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 3; i++) {
tableA[1][(i % 3) + 2] = k;
tableB[1][(i % 3) + 2] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 3; i++) {
tableA[1][(i % 3) + 2] = k;
tableB[1][(i % 3) + 2] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 2; i++) {
tableA[1][(i % 2) + 2] = k;
tableB[1][(i % 2) + 2] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 2; i++) {
tableA[2][(i % 2) + 2] = k;
tableB[2][(i % 2) + 2] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 1; i++) {
tableA[2][(i % 1) + 3] = k;
tableB[2][(i % 1) + 3] = k;
k++;
}
rightRotationA();
rightRotationB();
for (int i = 0; i < 1; i++) {
tableA[2][(i % 1) + 3] = k;
tableB[2][(i % 1) + 3] = k;
k++;
}
rightRotationA();
rightRotationB();
rightRotationA();
rightRotationB();
printTableA();
}
static void rightRotationA() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
tableA[i][j] = tableB[j][5 - i];
}
}
}
static void rightRotationB() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
tableB[i][j] = tableA[i][j];
}
}
}
static void printTableA() {
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 6; j++) {
System.out.print(tableA[i][j] + "\t");
}
System.out.println("");
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int height , width ;
int h_sign = 1, w_sign = 1;
int h= 0, w= 0;
int sum = 1;
int **arr;
scanf("%d %d", &width, &height);
arr = (int**)malloc(sizeof(int*) * height+1);
for (int i = 0; i < height; i++)
{
arr[i] = (int*)malloc(sizeof(int) * width);
memset(arr[i],0,sizeof(int)*width);
}
arr[height] = (int*)malloc(sizeof(int) * width);
arr[h][w] = 1;
for (int i = 0; i < height; i++)
{
while (arr[h][w+w_sign]==0)
{
sum += 1;
w += 1 * w_sign;
arr[h][w] = sum;
}
while (arr[h+h_sign][w] == 0)
{
sum += 1;
h += 1 * h_sign;
arr[h][w] = sum;
}
h_sign = h_sign*-1;
w_sign = w_sign*-1;
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
printf("%2d ",arr[i][j]-1);
}
printf("\n");
}
}
동적 메모리할당을 이용해 2차원 배열로 만들어서 해봤습니다.
#include<iostream>
using namespace std;
void dal_array(int in1, int in2)
{
int count = 0;
int x_cnt = 0;
int y_cnt = 0;
int **arr = new int*[in1];
for (int i = 0; i < in1; ++i) {
arr[i] = new int[in2];
memset(arr[i], 0, sizeof(int)*in2);
}
for(int k=0; k<in1/2;k++)
{
//->
for (int i = 0 + x_cnt; i < in2 - x_cnt; i++)
{
arr[y_cnt][i] = count++;
}
//V
for (int i = 1 + y_cnt; i < in1 - y_cnt; i++)
{
arr[i][in1 - y_cnt-1] = count++;
}
//<
for (int i = in2 - (x_cnt+2); i >= x_cnt; i--)
{
arr[in1 - y_cnt-1][i] = count++;
}
//^
for (int i = in1 - (y_cnt+2); i > y_cnt; i--)
{
arr[i][x_cnt] = count++;
}
x_cnt++;
y_cnt++;
}
for (int i = 0; i < in1; i++)
{
for (int j = 0; j < in2; j++)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
//동적할당해지
for (int i = 0; i < in1; ++i) {
delete[] arr[i];
}
delete[] arr;
}
int main()
{
int input1, input2;
cout << "숫자를 입력하세요 .";
cin >> input1 >> input2;
dal_array(input1, input2);
}
import numpy as np
def Spiral(m, n):
mat = np.zeros([m, n])
k = 0
p = 0
while p <= min(m, n)/2:
for i in range(p, n-1-p):
mat[p,i] = k
k += 1
for i in range(p, m-1-p):
mat[i, n-1-p] = k
k += 1
for i in range(n-1-p, p, -1):
mat[m-1-p, i] = k
k += 1
for i in range(m-1-p, p, -1):
mat[i, p] = k
k += 1
p += 1
if n%2 != 0:
mat[n//2, n//2] = k
return mat
/*
dev : peanuBro
date : 170218
content :
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iostream>
#include <iomanip>
using namespace std;
int main(void)
{
int currentX=0;
int currentY=0;
int findCount = 0;
int maxX;
int maxY;
int **arr;
enum class Direction{UP, DOWN, RIGHT, LEFT};
int flagCourse;
cout << "X Y 입력 : ";
cin >> maxX >> maxY;
arr = new int*[maxY];
for (int i = 0; i < maxY; i++)
{
arr[i] = new int[maxX];
for (int j = 0; j < maxX; j++)
{
arr[i][j] = -1;
}
}
arr[currentY][currentX] = findCount;
flagCourse = ((int)Direction::RIGHT);
while (true)
{
switch (flagCourse)
{
case (int)Direction::UP:
{
if (currentY == 0)
{
flagCourse = (int)Direction::RIGHT;
}
else
{
if (arr[currentY - 1][currentX] == -1)
{
arr[--currentY][currentX] = ++findCount;
}
else
{
flagCourse = (int)Direction::RIGHT;
}
}
break;
}
case (int)Direction::DOWN:
{
if (currentY == (maxY-1))
{
flagCourse = (int)Direction::LEFT;
}
else
{
if (arr[currentY+1][currentX] == -1)
{
arr[++currentY][currentX] = ++findCount;
}
else
{
flagCourse = (int)Direction::LEFT;
}
}
break;
}
case (int)Direction::RIGHT:
{
if (currentX == (maxX-1))
{
flagCourse = (int)Direction::DOWN;
}
else
{
if (arr[currentY][currentX + 1] == -1)
{
arr[currentY][++currentX] = ++findCount;
}
else
{
flagCourse = (int)Direction::DOWN;
}
}
break;
}
case (int)Direction::LEFT:
{
if (currentX == 0)
{
flagCourse = (int)Direction::UP;
}
else
{
if (arr[currentY][currentX -1] == -1)
{
arr[currentY][--currentX] = ++findCount;
}
else
{
flagCourse = (int)Direction::UP;
}
}
break;
}
default:
{
break;
}
}
if (findCount == (maxX*maxY)-1)
{
break;
}
}
for (int i = 0; i < maxY; i++)
{
for (int j = 0; j < maxX; j++)
{
cout << setw(5) << arr[i][j] ;
}
cout << endl;
}
}
# Get & validate input values
while True:
inp = input()
if len(inp) < 3:
print('Invalid input.')
continue
inps = inp.split(' ')
rows = int(inps[0])
cols = int(inps[1])
if rows <= 0 or cols <= 0:
print('Invalid input.')
continue
break
# Prepare numbers to fill
nums = list(range(rows*cols))
# filling direction
dirc = [[0, 1], [1, 0], [0, -1], [-1, 0]]
# Prepare empty spiral matrix
spmatrix = [[-1 for col in range(cols)] for row in range(rows)]
# Fill spiral matrix
i = 0
r = 0
c = 0
dmode = 0
while i < rows*cols:
spmatrix[r][c] = nums[i]
tmp_r = r + dirc[dmode][0]
tmp_c = c + dirc[dmode][1]
# Inspect conditions to change direction
if tmp_r < 0 or tmp_r >= rows or tmp_c < 0 or tmp_c >= cols or spmatrix[tmp_r][tmp_c] !=-1:
dmode +=1
dmode %= 4
r += dirc[dmode][0]
c += dirc[dmode][1]
i += 1
# Print the result
for i in range(rows):
for j in range(cols):
print("{0:>2}".format(spmatrix[i][j]), end=' ')
print();
매 루프마다 채우는 방향을 바꿔야 하는 조건을 테스트하는 방식으로 풀었습니다.
python 3.5.2
answer is
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 11], [32, 59, 60, 61, 62, 63, 64, 65, 66, 43, 12], [31, 58, 77, 78, 79, 80, 81, 82, 67, 44, 13], [30, 57, 76, 87, 86, 85, 84, 83, 68, 45, 14], [29, 56, 75, 74, 73, 72, 71, 70, 69, 46, 15], [28, 55, 54, 53, 52, 51, 50, 49, 48, 47, 16], [27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17]]
# r,c = map(int,input().split(' '))
r=8
c=11
lst = list()
array=[[0 for x in range(c)] for x in range(r)]
row,col = r,c
cnt=0
curr_point=(0,0)
curr_direct='right'
move = {
'up':(-1,0),
'down':(1,0),
'right':(0,1),
'left':(0,-1)
}
next_direct={
'up':'right',
'right':'down',
'down':'left',
'left':'up'
}
# 움직일 거리를 list 에 담는다.
for i in range(r+c-1):
if i%2 == 0 :
if i==0 :
pass
else :
c -= 1
if c == 0 :
break
else :
lst.append(c)
else :
r -= 1
if r == 0 :
break
else :
lst.append(r)
# 숫자 기입
for i in lst :
for j in range(i):
array[curr_point[0]][curr_point[1]] = cnt
cnt += 1
if (j == (i-1)) :
curr_direct = next_direct[curr_direct]
curr_point = tuple(map(sum,zip(curr_point, move[curr_direct])))
array
변수 선언이 많은 편인가요? 저한텐 이렇게 하는 게 가장 이해하기 쉽네요..
#include <iostream>
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
using namespace std;
/* http://codingdojang.com/scode/266
문제는 다음과 같다:
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/
int main() {
int **matrix;
int rowCount, colCount;
int rowIndex = 0, colIndex = 0;
int rowTopLimit = 1, rowBottomLimit;
int colLeftLimit = 0, colRightLimit;
int direction;
int element = 0;
cin >> colCount >> rowCount;
rowBottomLimit = colCount - 1;
colRightLimit = rowCount - 1;
matrix = new int *[rowCount];
for (int i = 0; i < rowCount; i++) {
matrix[i] = new int[colCount];
}
direction = RIGHT;
while (element < rowCount * colCount) {
matrix[rowIndex][colIndex] = element;
element++;
switch (direction) {
case UP:
rowIndex--;
if (rowIndex == rowTopLimit) {
direction = RIGHT;
rowTopLimit++;
}
break;
case DOWN:
rowIndex++;
if (rowIndex == rowBottomLimit) {
direction = LEFT;
rowBottomLimit--;
}
break;
case LEFT:
colIndex--;
if (colIndex == colLeftLimit) {
direction = UP;
colLeftLimit++;
}
break;
case RIGHT:
colIndex++;
if (colIndex == colRightLimit) {
direction = DOWN;
colRightLimit--;
}
break;
default:
break;
}
}
for (int i = 0; i < colCount; i++) {
for (int j = 0; j < rowCount; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
return 0;
}
public class Spiral {
static int insertX=0;
static int insertY=0;
static int x = 0;
static int y = 0;
static int xConvert = 0;
static int yConvert = 0;
static int[][] array;
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
System.out.print("x를 입력 : ");
insertX = Integer.parseInt(br.readLine());
System.out.print("y를 입력 : ");
insertY = Integer.parseInt(br.readLine());
array = new int[insertX][insertY];
System.out.println();
} catch (IOException e) {
e.printStackTrace();
}
for(int i=0; i<insertX; i++){
for(int j=0; j<insertY; j++){
array[i][j] = -1;
}
}
for(int i=0; i<insertX*insertY; i++){
if(xConvert == 0 && yConvert == 0){//가로가 오른쪽으로
array[x][y++] = i;
if(insertY == y || array[x][y] != -1){//가로 증가 세로 고정
x++;
y--;
yConvert = -1;
continue;
}
}else if(xConvert == 0 && yConvert == -1){//세로가 밑으로
array[x++][y] = i;
if(insertX == x || array[x][y] != -1){//가로 고정 세로로 증가
x--;
y--;
xConvert = -1;
yConvert = 0;
continue;
}
}else if(xConvert == -1 && yConvert == 0){//가로가 왼쪽으로
array[x][y--] = i;
if(y < 0 || array[x][y] != -1){//가로 감소 세로 고정
x--;
y++;
xConvert = -1;
yConvert = -1;
continue;
}
}else if(xConvert == -1 && yConvert == -1){//세로가 위쪽으로
array[x--][y] = i;
if(x < 0 || array[x][y] != -1){//가로 고정 세로 감소
x++;
y++;
xConvert = 0;
yConvert = 0;
continue;
}
}
}
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
System.out.print(array[i][j]+" ");
}
System.out.println("");
}
}
}
/*************************************************************
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*************************************************************/
#include<stdio.h>
#include<stdlib.h>
int** Make_2D_Arr(int column, int row);
int main(void)
{
int** arr;
int column, row, max_column, max_row,flag=0,min_column=0, min_row=1;
int i,j=0,k=0;
scanf("%d %d",&column,&row);
arr = Make_2D_Arr(column, row);
max_column = column-1;
max_row = row-1;
for(i=0;i<column*row;i++)
{
if(flag == 0)
{
arr[j][k]=i+1;
if(k==max_column)
{
max_column--;
flag++;
j++;
}
else
{
k++;
}
}
else if(flag == 1)
{
arr[j][k]=i+1;
if(j==max_row)
{
max_row--;
flag++;
k--;
}
else
{
j++;
}
}
else if(flag == 2)
{
arr[j][k]=i+1;
if(k==min_column)
{
min_column++;
flag++;
j--;
}
else
{
k--;
}
}
else if(flag == 3)
{
arr[j][k]=i+1;
if(j==min_row)
{
min_row++;
flag=0;
k++;
}
else
{
j--;
}
}
}
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf("%2d ",arr[i][j]);
}
printf("\n");
}
return 0;
}
int** Make_2D_Arr(int column, int row)
{
int i;
int** p_arr;
p_arr = (int**)malloc(row*sizeof(int*));
for(i=0;i<row;i++)
{
p_arr[i] = (int *)malloc(column*sizeof(int));
}
return p_arr;
}
뭔가 어렵게 푼거같네요...
public class SpiralArray {
public static void main(String[] args){
int num1 = 8;
int num2 = 9;
int[][] arr = new int[num1][num2];
int directionWidth =1;
int directionHeight = 0;
int move = 0;
int width =0;
int height =0;
int direction =0;
int directionNum =0;
int directionNumTemp = -1;
System.out.print(num1+" ");
System.out.println(num2);
for( int i = 0; i < num1*num2; i++){
arr[height][width] = move;
width += directionWidth;
height += directionHeight;
move++;
if( (width == num2 - 1 - direction)&& (directionHeight == 0)&&(directionWidth ==1)){
directionWidth = 0;
directionHeight = 1;
directionNum++;
}
else if( (height == num1-1 - direction)&&(directionWidth == 0)&&(directionHeight == 1) ){
directionHeight = 0;
directionWidth = -1;
directionNum++;
}
else if( (width == 0 +direction) && (directionHeight==0)&&(directionWidth == -1) ){
directionWidth = 0;
directionHeight = -1;
directionNum++;
}
else if( (height == direction) && (directionWidth== 0)&&(directionHeight == -1)){
directionHeight = 0;
directionWidth = 1;
directionNum++;
}
if (directionNum == 3){
direction = 1;
}else if( directionNum > 3 ){
if( directionNumTemp != directionNum){
if( directionNum%4 ==3){
directionNumTemp = directionNum;
direction++;
}
}
}
}
for(int k =0; k<num1; k++){
for(int l = 0; l<num2; l++){
System.out.print(arr[k][l]);
}
System.out.println("");
}
}
}
class Program
{
static void Main(string[] args)
{
int printNum = 0;
string result = Console.ReadLine();
List<int> inputNum = result.Split(' ').Select(x => Convert.ToInt32(x)).ToList();
int input1 = inputNum[0];
int input2 = inputNum[1];
int[,] arrResult = new int[input1,input2];
for(int i= 0; i<input1/2; i++)
{
int num = (input2 - 1) - (i * 2);
for (int a = 0; a < num; a++)
{
arrResult[i, a+i] = printNum;
printNum++;
}
for (int b = 0; b < num; b++)
{
arrResult[i+b, input2-i-1] = printNum;
printNum++;
}
for (int c = 0; c < num; c++)
{
arrResult[input1-i-1, input2-c-i-1] = printNum;
printNum++;
}
for (int d = 0; d < num; d++)
{
arrResult[input1-d-i-1, i] = printNum;
printNum++;
}
}
if (input1 % 2 != 0)
{
arrResult[input1 / 2, input2 / 2] = printNum;
}
for (int i = 0; i < input1; i++)
{
for (int j = 0; j < input2; j++)
{
Console.Write(arrResult[i, j] + " ");
}
Console.WriteLine();
}
Console.ReadLine();
}
}
#include <iostream>
#include <iomanip>
using namespace std;
void getResult(int ** arr, int row, int col);
void main()
{
int row = 0; //행
int col = 0; //열
int i = 0, j = 0; //for문을 위한 카운터
cin >> row >> col;
int **arr = new int *[row];
for (i = 0; i < row; i++)
{
arr[i] = new int[col];
}
getResult(arr, row, col);
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
cout << setfill(' ') << setw(2) << arr[i][j] << " ";
}
cout << endl;
}
return;
}
void getResult(int ** arr, int row, int col)
{
int row_min = 0, row_max = row - 1;
int col_min = 0, col_max = col - 1;
int max_num = row * col - 1;
int input_num = 0;
int i = 0;
while (1)
{
for (i = col_min; i <= col_max; i++)
{
arr[row_min][i] = input_num;
input_num++;
}
row_min++;
if (input_num > max_num) break;
for (i = row_min; i <= row_max; i++)
{
arr[i][col_max] = input_num;
input_num++;
}
col_max--;
if (input_num > max_num) break;
for (i = col_max; i >= col_min; i--)
{
arr[row_max][i] = input_num;
input_num++;
}
row_max--;
if (input_num > max_num) break;
for (i = row_max; i >= row_min; i--)
{
arr[i][col_min] = input_num;
input_num++;
}
col_min++;
if (input_num > max_num) break;
if (col_max < 0) break;
}
return;
}
행렬할 때마다 느끼는건데, row 랑 column 너무 햇갈려ㅠㅜ
#include <iostream>
using namespace std;
#define M 4
#define N 4
// matrix를 미리 정함
// 1 2 3 4
// 12 13 14 5
// 11 16 15 6
// 10 9 8 7
int main()
{
int A[M][N] = { {1, 2, 3, 4}, {12, 13, 14, 5}, {11, 16, 15, 6}, {10, 9, 8, 7} };
int x = 0;
int y = 0;
int dx = 0;
int dy = 1;
int min_x = 0;
int max_x = M - 1;
int min_y = 0;
int max_y = N - 1;
int i = 0;
while (i < M * N)
{
cout << A[x][y] << endl;
x += dx;
y += dy;
i++;
if (y > max_y)
{
x++;
y = max_y;
dy = 0;
dx = 1;
min_x++;
}
else if (y < min_y)
{
x--;
y = min_y;
dy = 0;
dx = -1;
max_x--;
}
else if (x > max_x)
{
y--;
x = max_x;
dx = 0;
dy = -1;
max_y--;
}
else if (x < min_x)
{
y++;
x = min_x;
dx = 0;
dy = 1;
min_y++;
}
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[] ) {
int row, column; // 행, 열
int inc=0; // 2차원 배열에 입력 방향에 따른 입력 시작/종료 위치 보정을 위한 값
int num=0; // 0~(row*colunm-1), ex) 3x4 → 0~11
row=atoi(argv[1]);
column=atoi(argv[2]);
// 2차원 배열을 동적으로 생성
int **matrix = (int **)malloc(sizeof(int *)*row);
for(int i=0; i<row; i++) matrix[i] = (int *)malloc(sizeof(int)*column);
// 각 방향(→, ↓, ←, ↑)에서 조건에 맞는 범위내에서 num을 증가시켜면서 2차원 배열에 값을 저장
// num 값이 row * column 과 같으면 반복문을 빠져나옴
// 한바퀴 돌때마다 inc 값을 증가시켜 각 for 문에서 입력의 시작/종료 시점을 보정
while(1) {
for(int i=inc; i<column-inc; i++) matrix[inc][i] = num++;
if(num==row*column) break;
for(int i=inc+1; i<row-inc; i++) matrix[i][column-inc-1] = num++;
if(num==row*column) break;
for(int i=column-1-1-inc; i>inc-1; i--) matrix[row-1-inc][i] = num++;
if(num==row*column) break;
for(int i=row-1-1-inc; i>inc-1+1; i--) matrix[i][inc] = num++;
if(num==row*column) break;
inc++;
}
// 전체 배열 출력
for(int i=0; i<row; i++) {
for(int j=0; j<column; j++) printf("%3d", matrix[i][j]);
printf("\n");
}
// 동적 할당 해제
for(int i=0; i<row; i++) free(matrix[i]);
free(matrix);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#define SPIRAL_DEBUG
#ifdef SPIRAL_DEBUG
#define MEM_SHORTAGE_MSG \
printf("[ERR] Memory shortage. %s %s %d", \
__FILE__, __func__, __LINE__)
#define MEM_NULL_MSG \
printf("[ERR] Memory points NULL status already. %s %s %d", \
__FILE__, __func__, __LINE__)
#else
#define MEM_SHORTAGE_MSG
#define MEM_NULL_MSG
#endif
static int *_create_array(size_t size);
static int _destroy_array(int **ppdel);
static int _input_data_in_spiral_array(int *parr, int col, int row,
int start_num, int end_num, int start_cordi, int max_row);
static int _print_data_in_spiral_array(const int *parr,
const int col, const int row);
///////////////////////////////////////////////////////////////////////////////
static int *_create_array(size_t size)
{
int *pnew = (int *)malloc(size);
if (pnew == NULL)
{
MEM_SHORTAGE_MSG;
goto error;
}
memset((void *)pnew, 0x00, size);
return pnew;
error :
return NULL;
}
static int _destroy_array(int **ppdel)
{
if (ppdel == NULL)
{
MEM_NULL_MSG;
goto error;
}
if (*ppdel)
{
free((void *)*ppdel);
*ppdel = NULL;
}
return 0;
error :
return -1;
}
static int _input_data_in_spiral_array(int *parr, int col, int row,
int start_num, int end_num, int start_cordi, int max_row)
{
int i;
int j;
int k;
int origin_col = col;
int origin_row = row;
j = k = start_cordi;
/* The hightest row */
for (i = 0; i < row; i++)
{
parr[j * max_row + k++] = start_num++;
if (start_num >= end_num)
return 0;
}
/* The rightest col */
j++;
k--;
col--;
for (i = 0; i < col; i++)
{
parr[j++ * max_row + k] = start_num++;
if (start_num >= end_num)
return 0;
}
/* The lowest row */
j--;
k--;
row--;
for (i = 0; i < row; i++)
{
parr[j * max_row + k--] = start_num++;
if (start_num >= end_num)
return 0;
}
/* The leftest col */
j--;
k++;
col--;
for (i = 0; i < col; i++)
{
parr[j-- * max_row + k] = start_num++;
if (start_num >= end_num)
return 0;
}
/* move start cordination */
start_cordi++;
if (start_num < end_num)
_input_data_in_spiral_array(parr, origin_col - 2, origin_row - 2,
start_num, end_num, start_cordi, max_row);
return 0;
}
static int _print_data_in_spiral_array(const int *parr,
const int col, const int row)
{
int i;
int j;
printf("\n -------- array print -------- \n\n");
for (i = 0; i < col; i++)
{
for (j = 0; j < row; j++)
printf("%3d\t", parr[i * row + j]);
printf("\n");
}
printf("\n");
return 0;
}
int main(void)
{
int row;
int col;
int *parr;
scanf("%d %d", &col, &row);
parr = _create_array(sizeof(int) * row * col);
if (parr == NULL)
goto error;
if (_input_data_in_spiral_array(parr, col, row,
0, col * row, 0, row) < 0)
goto error;
if (_print_data_in_spiral_array(parr, col, row) < 0)
goto error;
if (_destroy_array(&parr) < 0)
goto error;
return 0;
error :
return -1;
}
c로 작성 했습니다. 저장하는 방식 말고 한번에 출력하는 방법으로 접근했는데 수식을 못 뽑아 내는 바람에 ㅠㅠ 코드는 저장하는 방식으로 구현한 내용입니다. 재귀를 썼는데 제법 까다롭네요 흠흠;;
int init;
typedef struct _sheet { int endnum; int putnum; int row[2]; int coulum[2]; int arry[100][100]; }Sheet;
void fcoulum_utod(Sheet sheet); void fcoulum_btot(Sheet sheet); void frow_rtol(Sheet sheet); void frow_ltor(Sheet sheet);
//////////////////////////////////////////////////////////////////////////////////////////////////
void frow_ltor(Sheet *sheet)
{
if (ENDFLAG)
{
for (int i = RowStart; i <= RowEnd; i++, sheet->putnum++)
{
printf("\nFUNTION
////////////////////
for (int i = 0; i < init; i++)
{
for (int j = 0; j < init; j++)
{
printf("%4d", sheet->arry[i][j]);
}
printf("\n");
}
/////////////////////
fcoulum_utod(sheet);
}
}
void fcoulum_utod(Sheet *sheet)
{
if (ENDFLAG)
{
for (int i = CoulumStart; i <= CoulumEnd; i++, sheet->putnum++)
{
printf("\nFUNTION
void frow_rtol(Sheet *sheet)
{
if (ENDFLAG)
{
for (int i = RowEnd; i >= RowStart; i--, sheet->putnum++)
{
printf("\nFUNTION
void fcoulum_btot(Sheet *sheet)
{
if (ENDFLAG)
{
for (int i = CoulumEnd; i >= CoulumStart; i--, sheet->putnum++)
{
printf("\nFUNTION
//////////////////////////////////////////////////////////////////////////////////////////////////
int main() { Sheet sheet;
printf("\n만들 배열의 크기를 입력하세요: ");
scanf("%d", &init);
if (init) printf("\n입력받은 숫자: %d", init);
else printf("\nINIT ERROR");
sheet.endnum = init * init;
sheet.putnum = 0;
sheet.row[0] = 0;
sheet.row[1] = init - 1;
sheet.coulum[0] = 0;
sheet.coulum[1] = init - 1;
for (int i = 0; i < init; i++)
{
for (int j = 0; j < init; j++)
{
sheet.arry[i][j] = 0;
}
printf("\n");
}
printf("\nSUCCSED CLEAR\n");
frow_ltor(&sheet);
printf("\nSUCCSED FUNTION\n");
for (int i = 0; i < init; i++)
{
for (int j = 0; j < init; j++)
{
printf("%4d", sheet.arry[i][j]);
}
printf("\n");
}
}
# 입력
width = 6
height = 6
# 초기값
blank = -1
matrix = [[blank for w in range(0, width)] for h in range(0, height)]
# 커서
x, y = 0, 0
for idx in range(0, width * height):
matrix[y][x] = idx
# 다음위치 검색 (막힌곳과 열린곳 확인)
check_top = y == 0 or matrix[y-1][x] != blank
check_left = x == 0 or matrix[y][x-1] != blank
check_bottom = y >= height-1 or matrix[y+1][x] != blank
check_right = x >= width -1 or matrix[y][x+1] != blank
if check_left and check_top and not check_right:
x += 1
elif check_top and check_right and not check_bottom:
y += 1
elif check_right and check_bottom and not check_left:
x -= 1
elif check_bottom and check_left and not check_top:
y -= 1
for arr in matrix:
print(arr)
private static void printSpiralArray(int n){
int spiralArray[][] = new int[n][n];
for(int i=0; i<n; i++){
spiralArray[0][i] = i;
}
int num = n;
int xIndex = n-1;
int yIndex = 0;
int lotationCnt = 0;
int loatationIndex = 1;
String direction = "down";
while(n-loatationIndex > 0){
if(direction.equals("down")){
for(int i=0; i<n-loatationIndex; i++){
spiralArray[++yIndex][xIndex] = num++;
}
direction = "left";
}else if(direction.equals("left")){
for(int i=0; i<n-loatationIndex; i++){
spiralArray[yIndex][--xIndex] = num++;
}
direction = "top";
}else if(direction.equals("top")){
for(int i=0; i<n-loatationIndex; i++){
spiralArray[--yIndex][xIndex] = num++;
}
direction = "right";
}else if(direction.equals("right")){
for(int i=0; i<n-loatationIndex; i++){
spiralArray[yIndex][++xIndex] = num++;
}
direction = "down";
}
lotationCnt++;
if(lotationCnt%2==0){
loatationIndex++;
}
}
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
System.out.print(spiralArray[i][j] + " ");
}
System.out.println();
}
}
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
namespace STATE
{
typedef enum
{
LEFT ,
RIGHT ,
UP ,
DOWN
}Enum;
}
class Spiral
{
private:
int mX;
int mY;
int mValue;
STATE::Enum mState;
int** mpBuffer;
int mVertical;
int mHorizon;
public:
Spiral( int rVertical , int rHorizon )
{
mState = STATE::RIGHT;
mVertical = rVertical;
mHorizon = rHorizon;
mpBuffer = ( int** )calloc( mVertical , sizeof( int* ) );
for( int i = 0 ; i < mVertical ; ++i )
{
mpBuffer[ i ] = ( int* )malloc( mHorizon * sizeof( int ) );
for( int j = 0 ; j < mHorizon ; ++j )
{
mpBuffer[ i ][ j ] = -1;
}
}
mX = 0;
mY = 0;
mValue = 0;
mpBuffer[ 0 ][ 0 ] = 0;
}
virtual ~Spiral()
{
for( int i = 0 ; i < mVertical ; ++i )
{
free( mpBuffer[ i ] );
}
free( mpBuffer );
}
int ShiftLeft()
{
if( ( mY - 1 ) >= 0 && mpBuffer[ mX ][ mY - 1 ] == -1 )
{
mpBuffer[ mX ][ --mY ] = ++mValue;
return 0;
}
return -1;
}
int ShiftRight()
{
if( ( mY + 1 ) < mHorizon && mpBuffer[ mX ][ mY + 1 ] == -1 )
{
mpBuffer[ mX ][ ++mY ] = ++mValue;
return 0;
}
return -1;
}
int ShiftUp()
{
if( ( mX - 1 ) >= 0 && mpBuffer[ mX - 1 ][ mY ] == -1 )
{
mpBuffer[ --mX ][ mY ] = ++mValue;
return 0;
}
return -1;
}
int ShiftDown()
{
if( ( mX + 1 ) < mVertical && mpBuffer[ mX + 1 ][ mY ] == -1 )
{
mpBuffer[ ++mX ][ mY ] = ++mValue;
return 0;
}
return -1;
}
void SetState( STATE::Enum rState )
{
mState = rState;
}
STATE::Enum GetState()
{
return mState;
}
void Print()
{
for( int i = 0 ; i < mVertical ; ++i )
{
for( int j = 0 ; j < mHorizon ; ++j )
{
cout << mpBuffer[ i ][ j ] << "\t";
}
cout << endl;
}
}
};
int main( int argc , char** argv )
{
int vertical = 6;
int horizon = 6;
int ret = 0;
Spiral spiral( vertical , horizon );
//spiral.Print();
for( int i = 1 ; i < vertical * horizon ; ++i )
{
switch( spiral.GetState() )
{
case STATE::RIGHT:
ret = spiral.ShiftRight();
if( ret < 0 )
{
spiral.SetState( STATE::DOWN );
spiral.ShiftDown();
}
break;
case STATE::DOWN:
ret = spiral.ShiftDown();
if( ret < 0 )
{
spiral.SetState( STATE::LEFT );
spiral.ShiftLeft();
}
break;
case STATE::LEFT:
ret = spiral.ShiftLeft();
if( ret < 0 )
{
spiral.SetState( STATE::UP );
spiral.ShiftUp();
}
break;
case STATE::UP:
ret = spiral.ShiftUp();
if( ret < 0 )
{
spiral.SetState( STATE::RIGHT );
spiral.ShiftRight();
}
break;
}
}
spiral.Print();
}
# 코딩도장 002. Spiral Array
# Notepad++ (Windows 32bits 7.3.3)
# Python 3.5.2 (AMD64)
#
# N X M 매트릭스의 경우,
#
# 규칙 1)
# EAST direction으로 진행하고, 다음에는 SOUTH, WEST 그리고 NORTH로 진행하며
# 다시 EAST로 순환하는 구조를 가진다.
#
# 규칙 2)
# 좌상단의 첫 숫자는 1이며
# 그 다음 direction까지는 다음의 숫자만큼만 1씩 증가하면서 진행하고 direction을 바꾼다.
# N-1, M-1, N-1, M-2, N-2, ...
# 즉 처음에는 N-1번 진행을 하지만 그 다음부터는 M과 N의 숫자를 하나씩 줄여가면서 진행한다.
# 그래서 N 또는 M의 값이 0까지 진행을 하면 멈춘다.
# 6 * 5의 경우,
# 6-1, 5-1, 6-1, 5-2, 6-2, 5-3, 6-3, 5-4, 6-4, 5-5 <-- 여기서 멈추게 된다.
# 즉 5, 4, 5, 3, 4, 2, 3, 1, 2, 0 <--- 여기서 멈추게 된다.
# 이는 코드에서 spin_order로 표현되어 있다.
#
# 규칙 2를 이용하여 각각의 direction으로 몇 칸씩 가야 하는지 확인한 후 이동한다.
N = 5
M = 5
###### 규칙 2 시작
spin_order = list()
n = N
m = M
spin_order.append(N-1)
while(True):
m = m - 1
if m == 0:
break
else:
spin_order.append(m)
n = n - 1
if n == 0:
break
else:
spin_order.append(n)
###### 규칙 2 종료
# 2차원 배열을 0으로 초기화
# ddegul님 https://goo.gl/bNKCs1 참조
result = [[0 for col in range(N)] for row in range(M)]
pos_x = 0
pos_y = 0
num = 1
result[pos_x][pos_y] = num
direction = "EAST"
for i in spin_order:
for j in range(i):
num = num + 1
if direction == "EAST":
pos_x = pos_x + 1
result[pos_x][pos_y] = num
if direction == "SOUTH":
pos_y = pos_y + 1
result[pos_x][pos_y] = num
if direction == "WEST":
pos_x = pos_x - 1
result[pos_x][pos_y] = num
if direction == "NORTH":
pos_y = pos_y - 1
result[pos_x][pos_y] = num
if direction == "EAST":
direction = "SOUTH"
elif direction == "SOUTH":
direction = "WEST"
elif direction == "WEST":
direction = "NORTH"
elif direction == "NORTH":
direction = "EAST"
for i in range(len(result)):
for j in range(len(result[0])):
print("%4d" %(result[j][i]), end = " ")
print("")
import java.util.*;
class Spiral_Array {
public static void main(String[] args) {
/*
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
3 7
0 1 2 3 4 5 6
15 16 17 18 19 20 7
14 13 12 11 10 9 8
*/
Scanner robot = new Scanner(System.in);
System.out.print("입력 : ");
int x = robot.nextInt();
System.out.print("입력 : ");
int y = robot.nextInt();
int[][] arr = new int[x][y];
/*
→ ↓ ← ↑
*/
int xp = 0;
int yp = 0;
int ps = 1;
for(int i=1 ; i < x*y ; i++){
while(i < x*y){
int ps_temp = ps;
if(ps == 1 && yp+1 < y && arr[xp][yp+1] == 0 ){
arr[xp][yp+1] = i;
yp++;
}else if(ps == 2 && xp+1 < x && arr[xp+1][yp] == 0 ){
arr[xp+1][yp] = i;
xp++;
}else if(ps == 3 && yp-1 >= 0 && arr[xp][yp-1] == 0 ){
arr[xp][yp-1] = i;
yp--;
}else if(ps == 4 && xp-1 > 0 && arr[xp-1][yp] == 0 ){
arr[xp-1][yp] = i;
xp--;
if(xp == 0 && yp == 0){
xp++;
ps = 1;
}
}else{
if(ps < 4){
ps++;
}else{
ps = 1;
}
}
if(ps_temp != ps){
i--;
}
i++;
}
}
for(int i = 0; i < arr.length; i++){
for(int j = 0 ; j < arr[0].length ; j++){
String str = arr[i][j] < 10 ? " 0"+arr[i][j] : " "+arr[i][j];
System.out.print(str);
}
System.out.println();
}
}
}
어제 풀이를 한번 올렸었는데 맘에 안들어서 한번 더 했네요ㅠㅠㅠㅠㅠ이것도 완전 맘에 들지는 않지만....
import java.util.*;
enum Direction{
RIGHT, LEFT, UP, DOWN
}
class Spiral_Array_v2 {
public static void main(String[] args) {
Scanner robot = new Scanner(System.in);
System.out.print("입력 : ");
int x = robot.nextInt();
System.out.print("입력 : ");
int y = robot.nextInt();
Direction dir = Direction.RIGHT;
int[][] arr = new int[x][y];
for(int[] o : arr){
Arrays.fill(o, -1);
}
int xp = 0;
int yp = 0;
int num = 0;
/********************************************************************/
while(num < x*y){
arr[xp][yp] = num++;
if(num == x*y) break;
if( (dir == Direction.RIGHT && yp+1 < y && arr[xp][yp+1] == -1)
|| ( dir == Direction.DOWN && xp+1 < x && arr[xp+1][yp] == -1 )
|| ( dir == Direction.LEFT && yp-1 >= 0 && arr[xp][yp-1] == -1 )
|| ( dir == Direction.UP && xp-1 >= 0 && arr[xp-1][yp] == -1 )){
}else{
if( dir == Direction.RIGHT ){
dir = Direction.DOWN;
}else if(dir == Direction.DOWN){
dir = Direction.LEFT;
}else if(dir == Direction.LEFT){
dir = Direction.UP;
}else{
dir = Direction.RIGHT;
}
}
switch(dir){
case RIGHT : ++yp; break;
case DOWN : ++xp; break;
case LEFT : --yp; break;
case UP : --xp; break;
}
}
/********************************************************************/
for(int i = 0; i < arr.length; i++){
for(int j = 0 ; j < arr[0].length ; j++){
String str = arr[i][j] < 10 ? " 0"+arr[i][j] : " "+arr[i][j];
System.out.print(str);
}
System.out.println();
}
}
}
import java.util.Scanner;
public class practiceMain {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int row = s.nextInt();
int col = s.nextInt();
//시작하면 행렬 크기를 입력받는다
int[][] matrix = new int[row][col];
//숫자를 저장할 행렬 선언
int count = row*col;
//행렬에 저장될 인자가 총 몇개인지
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
matrix[i][j] = -1;
}
}//매트릭스 초기화
int matrixDirection = 0;
//방향을 나타낸다. 변환 주기는 →(0) - ↓(1) - ←(2) - ↑(3) - →(0)
int currentRow=0;
int currentCol=0;
//행렬내 좌표값 체킹 위해...
for(int i=0; i<count; i++){
switch(matrixDirection){
case 0:
if((currentCol+1) >= col){
matrixDirection++;
matrix[currentRow][currentCol]=i;
System.out.println("direction change:"+i+", direction:"+matrixDirection);
break;
}else if(matrix[currentRow][currentCol+1]!=-1){
//오른쪽으로 갈 다음 칸이 이미 차있는 칸이거나... 혹은 끝일경우
matrixDirection++;
matrix[currentRow][currentCol]=i;
System.out.println("direction change:"+i);
break;
}
matrix[currentRow][currentCol]=i;
System.out.println("row:"+currentRow+", col:"+currentCol+", i:"+i);
break;
case 1:
if((currentRow+1) >= row){
matrixDirection++;
matrix[currentRow][currentCol]=i;
break;
}else if(matrix[currentRow+1][currentCol]!=-1){
//아래로 갈 다음 칸이 이미 차있는 칸이거나... 혹은 끝일경우
matrixDirection++;
matrix[currentRow][currentCol]=i;
System.out.println("direction change:"+i);
break;
}
matrix[currentRow][currentCol]=i;
System.out.println("row:"+currentRow+", col:"+currentCol+", i:"+i);
break;
case 2:
if(currentCol <= 0){
matrixDirection++;
matrix[currentRow][currentCol]=i;
break;
}else if(matrix[currentRow][currentCol-1]!=-1){
//왼쪽으로 갈 다음 칸이 이미 차있는 칸이거나... 혹은 끝일경우
matrixDirection++;
matrix[currentRow][currentCol]=i;
System.out.println("direction change:"+i);
break;
}
matrix[currentRow][currentCol]=i;
System.out.println("row:"+currentRow+", col:"+currentCol+", i:"+i);
break;
case 3:
if(currentRow <= 0){
matrixDirection=0;
matrix[currentRow][currentCol]=i;
break;
}else if(matrix[currentRow-1][currentCol]!=-1){
//위로 갈 다음 칸이 이미 차있는 칸이거나... 혹은 끝일경우
matrixDirection=0;
matrix[currentRow][currentCol]=i;
System.out.println("direction change:"+i);
break;
}
matrix[currentRow][currentCol]=i;
System.out.println("row:"+currentRow+", col:"+currentCol+", i:"+i);
break;
}
//두번째 switch문에서는 방향값 조정
switch(matrixDirection){
case 0:
currentCol++;
break;
case 1:
currentRow++;
break;
case 2:
currentCol--;
break;
case 3:
currentRow--;
break;
}
//가로로 갈 경우와
//세로로 갈 경우를 나눠야 한당
//어떻게!?
}
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
System.out.print(matrix[i][j]+"\t");
}
System.out.println("");
}
}
}
자바로 미흡하게나마 짜봤어영
int n = 6, m = 6; String[][] str = new String[n][n];
int k = 0;
int ii = 0;
while(k < m*m) {
for(int j=ii; j<n; j++) {
str[ii][j] = String.valueOf(k++);
}
for(int i=(ii+1); i<n; i++) {
str[(i)][n-1] = String.valueOf(k++);
}
for(int j = (n-2); j >= ii; j--) {
str[n-1][j] = String.valueOf(k++);
}
for(int i = (n-2); i > ii; i-- ) {
str[i][ii] = String.valueOf(k++);
}
n--;
ii++;
}
for(int i = 0; i<m;i++)
for(int j=0; j<m; j++) {
System.out.print(str[i][j]+", ");
if (j > 0 && j % (m-1) == 0)
System.out.println(" ");
}
}
import java.util.Scanner;
public class Algorithm {
public static void main(String[] args) {
// TODO Auto-generated method stub
int right =0;
int down =1;
int left =2;
int up =3;
int direction = right;
Scanner sc = new Scanner(System.in);
int row = sc.nextInt();
int col = sc.nextInt();
int end = row*col;
int[][] result = new int[row][col];
boolean[][] data = new boolean[row][col];
int hori = -1;
int verti = 0;
for(int i=0; i<end; i++){
if(direction == right){
hori++;
if(hori>=col || data[verti][hori]){
hori--; verti++;
result[verti][hori] = i;
data[verti][hori] = true;
direction = down;
}else{
result[verti][hori] = i;
data[verti][hori] = true;
}
}else if(direction == down){
verti++;
if(verti>=row || data[verti][hori]){
verti--; hori--;
result[verti][hori] = i;
data[verti][hori] = true;
direction = left;
}else{
result[verti][hori] = i;
data[verti][hori] = true;
}
}else if(direction == left){
hori--;
if(hori<0 || data[verti][hori]){
hori++; verti--;
result[verti][hori] = i;
data[verti][hori] = true;
direction = up;
}else{
result[verti][hori] = i;
data[verti][hori] =true;
}
}
else if(direction == up){
verti--;
if(data[verti][hori]){
verti++; hori++;
result[verti][hori] = i;
data[verti][hori] = true;
direction = right;
}else{
result[verti][hori] = i;
data[verti][hori] = true;
}
}
}
for(int i=0; i<row;i++){
for(int j=0; j<col; j++){
if(result[i][j] <10){
System.out.print(" "+result[i][j]);
}else{
System.out.print(" "+result[i][j]);}
}
System.out.println("");
}
}
}
scale = N*M
count = 0 # 짝수면 반복문 전부 홀수면 절반 실행
x = 0
R = 0 # 싸이클이 끝나고 의 현재의 값 R
# k의 범위 구하기
while(scale > 0):
if N-2*x-1 == 0 or M-2*x-1 == 0 :
scale -= (M-2*x-1 + N-2*x-1 +1)
count += 1
else:
scale -= (M-2*x-1 + N-2*x-1)
count += 1
if scale != 0 :
scale -= (M-2*x-1 + N-2*x-1)
count += 1
x += 1
# 2차원 배열 만들기
matrix = [[0 for row in range(M)] for col in range(N)]
#나선형으로 진행하는 좌표
for k in range(x):
#처음만 y좌표를 0으로 놓음
#1
if M-2*k-1 != 0 :
for i1 in range(k, M-(k+2)+1):
if k ==0:
matrix[0][i1] = i1-k
R = i1-k
else:
matrix[k][i1] = u + R
R = u + R
else :
matrix[k][k] = 1 + R
R = 1 + R
#2
if N-2*k-1 != 0:
for i2 in range(k, N-(k+2)+1):
u = 0
u += 1
matrix[i2][M-k-1] = u + R
R = u + R
elif M-2*k-1 == 0 and N-2*k-1 == 0 :
pass
else :
matrix[k][M-k-1] = 1+R
R = 1 + R
print("2 %s" %R)
count -= 1
print("count= %s" %count)
if count != 0:
#3
for i3 in list(reversed(range(k+1, M-(k+1)+1))):
u = 0
u += 1
matrix[N-k-1][i3] = u+R
R = u+ R
#4
for i4 in list(reversed(range(k+1, N-(k+1)+1))):
u = 0
u += 1
matrix[i4][k] = u + R
R = u+ R
count -= 1
else:
break
# matrix 프린트
for X in range(N):
for Y in range(M):
chr1 = matrix[X][Y]
print("%3d" %chr1, end = "")
print("\n")
n=input()
n=int(n)
a = [[0 for col in range(n)] for row in range(n)]
row=0#행
col=0#열
num=0#행렬에 들어갈 숫자
if n%2==0:#n=짝수일때
cur=n-1
tmp=n
while cur>0:
while col<cur:# right move
a[row][col]=num
num+=1
col+=1
while row<cur:# down move
a[row][col]=num
num+=1
row+=1
while col>=tmp-cur:# left move
a[row][col]=num
num+=1
col-=1
while row>=tmp-cur:#up move
a[row][col]=num
num+=1
row-=1
row+=1
col+=1
cur-=1#4
else:
cur=n-1
tmp=n
while cur>1:
while col<cur:# right move
a[row][col]=num
num+=1
col+=1
while row<cur:# down move
a[row][col]=num
num+=1
row+=1
while col>=tmp-cur:# left move
a[row][col]=num
num+=1
col-=1
while row>=tmp-cur:#up move
a[row][col]=num
num+=1
row-=1
row+=1
col+=1
cur-=1
row=(int)(tmp/2)
col=row
a[row][col]=num
for i in range(n):
for j in range(n):
print(a[i][j],end=" ")
print("\n")
``````{.python}
n=input()
n=int(n)
a = [[0 for col in range(n)] for row in range(n)]
row=0#행
col=0#열
num=0#행렬에 들어갈 숫자
if n%2==0:#n=짝수일때
cur=n-1
tmp=n
while cur>0:
while col<cur:# right move
a[row][col]=num
num+=1
col+=1
while row<cur:# down move
a[row][col]=num
num+=1
row+=1
while col>=tmp-cur:# left move
a[row][col]=num
num+=1
col-=1
while row>=tmp-cur:#up move
a[row][col]=num
num+=1
row-=1
row+=1
col+=1
cur-=1#4
else:
cur=n-1
tmp=n
while cur>1:
while col<cur:# right move
a[row][col]=num
num+=1
col+=1
while row<cur:# down move
a[row][col]=num
num+=1
row+=1
while col>=tmp-cur:# left move
a[row][col]=num
num+=1
col-=1
while row>=tmp-cur:#up move
a[row][col]=num
num+=1
row-=1
row+=1
col+=1
cur-=1
row=(int)(tmp/2)
col=row
a[row][col]=num
for i in range(n):
for j in range(n):
print(a[i][j],end=" ")
print("\n")
print(row,col)
c로 풀이. 많이 조잡.
#include <stdio.h>
int main(void)
{
int a,b,c,num=0;
int i,j,k;
int s[20][20];
scanf("%d%d",&a,&b);
if (a>=b) c=a;
else c=b;
for(k=0;k<c/2;k++)
{
i=j=k;
for(i=k;i<a-k-1;i++) {s[j][i]=num++; if (num==a*b) break;}
if (num==a*b) break;
for(j=k;j<b-k-1;j++) {s[j][i]=num++; if (num==a*b) break;}
if (num==a*b) break;
for(i=a-k-1;i>k;i--) {s[j][i]=num++; if (num==a*b) break;}
if (num==a*b) break;
for(j=b-k-1;j>k;j--) {s[j][i]=num++; if (num==a*b) break;}
if (num==a*b) break;
}
for(i=0;i<b;i++)
{
for(j=0;j<a;j++) printf(" %3d",s[i][j]);
printf("\n");
}
return 0;
}
func nextIndexOfIndex(index: Int,
direction: inout Int,
counterInDirection: inout Int,
hCount: inout Int,
vCount: inout Int,
rows: Int,
columns: Int) -> Int {
var nextIndex = -1
// 기존 방향으로의 카운터가 0
// 더 이상 입력하지 못 하니 다음 방향으로 전환
if counterInDirection == 0 {
direction = (direction + 1) % 4
switch direction % 2 {
case 0:
// 수평 이동으로 변경하고 새로운 방향으로 입력할 숫자 갯수 초기화
counterInDirection = hCount
hCount = hCount - 1
case 1:
// 상하 이동으로 변경 새로운 방향으로 입력할 숫자 갯수 초기화
counterInDirection = vCount
vCount = vCount - 1
default:
return nextIndex
}
}
switch direction {
case 0:
nextIndex = index + 1
case 1:
nextIndex = index + columns
case 2:
nextIndex = index - 1
case 3:
nextIndex = index - columns
default:
return -1
}
counterInDirection = counterInDirection - 1 // 다음 인덱스를 구했으니 진행 방향 카운터 차감
return nextIndex
}
func printSpiralMatrix(rows: Int, columns: Int) {
// 행렬 입력 갯수 초기값
var hCount = columns - 1 // matrix[0] = 0 으로 초기화 하면서 1 소진
var vCount = rows - 1 // 최초 수평 이동으로 행 카운트 1 소진하고 시작
let total = rows * columns
var matrix: Array<Int> = Array(repeating: -1, count: total)
matrix[0] = 0
// 입력방향 초기값 0 for right
var d = 0 // 방향 초기화
var counterInDirection = hCount
var nextIndex = 0
// 행렬 크기 만큼 한 번의 루프로 행렬 생성
for i in 1..<total {
nextIndex = nextIndexOfIndex(index: nextIndex,
direction: &d,
counterInDirection: &counterInDirection,
hCount: &hCount,
vCount: &vCount,
rows: rows,
columns: columns)
if nextIndex < 1 || nextIndex >= total {
break
}
matrix[nextIndex] = i
}
// 출력 루프
for i in 0..<total {
print(matrix[i], terminator:"")
if (i%columns) == (columns - 1) {
print("")
} else {
print("\t", terminator:"")
}
}
}
printSpiralMatrix(rows: 6, columns: 6)
python 3.6, using numpy 2d arrays, def spiral(length) 는 spiral 로 들어가는 tuple(열, 행) 의 리스트를 넘깁니다.
import numpy as np
def spiral(m,n):
pairs = []
cnt = 0
f, s = 0, -1 # fixed_num, start_num
while True:
right = [(f, i) for i in range(s+1, s+1+n-cnt)] # right, inc
pairs += right
cnt += 1
if cnt == m:
return pairs
s, f = right[-1]
down = [(i, f) for i in range(s+1, s+1+m-cnt)] # down, inc
pairs += down
if cnt == n:
return pairs
f, s = down[-1]
left = [(f, i) for i in range(s-1, s-1-n+cnt, -1)] # left, dec
pairs += left
cnt += 1
if cnt == m:
return pairs
s, f = left[-1]
up = [(i, f) for i in range(s-1, s-1-m+cnt,-1)] # up, dec
pairs += up
if cnt == n:
return pairs
f, s = up[-1]
m, n = map(int, input("Matrix shape? ").split()) # get m number of m * n matrix
array = [i for i in range(m * n)] # make array, len(array) is m*n
matrix = np.zeros((m, n)).astype(int) # make m*n matrix based on zeros
spiral = spiral(m, n) # spiral list of (tuple)
for i in range(m * n):
x, y = spiral[i]
matrix[x][y] = array[i]
print(matrix)
>>>
Matrix shape? 6 6
[[ 0 1 2 3 4 5]
[19 20 21 22 23 6]
[18 31 32 33 24 7]
[17 30 35 34 25 8]
[16 29 28 27 26 9]
[15 14 13 12 11 10]]
javascript(ES6)
var initarray = function(rowsize = 6, colsize = 6) {
return Array.from(Array(rowsize), (v, k) => Array.from(Array(colsize), () => -1));
};
Array.prototype.getRowCol = function() {
return {row : this.length, col : this[0].length};
}
Array.prototype.printMatrix = function() {
var {row, col} = this.getRowCol();
var maxlength = ("" + (row * col)).length;
var getspace = function(len, maxlen) {
return new Array(maxlen - len + 2).join(" ");
};
var str = "";
for (line of this) {
for (value of line) {
str += getspace(("" + value).length, maxlength) + value;
}
str += "\n";
}
console.log(str);
};
Array.prototype.makeSpiral = function() {
var {row, col} = this.getRowCol();
var [x, y, dx, dy] = [0, 0, 0, 1];
for (let i = 0; i < row * col; i++) {
this[x][y] = i;
[x, y] = [x + dx, y + dy];
if (!this[x] || !this[x][y] || this[x][y] !== -1 ) {
[x, y] = [x - dx, y - dy];
[dx, dy] = [dy, -dx];
[x, y] = [x + dx, y + dy];
}
}
return this;
};
initarray(6, 6).makeSpiral().printMatrix();
public class SpiralArray {
public static void main (String[] arg) {
int matrixRange = 6;
int arrays[][] = new int[matrixRange][matrixRange];
int count=0, switchN=1, row=-1, col=0, routine=matrixRange;
while (routine > 0) {
for (int i=0; i<routine; i++) {
row += switchN;
arrays[col][row] = count;
count++;
}
routine--;
for (int j=0; j<routine; j++) {
col += switchN;
arrays[col][row] = count;
count++;
}
switchN *= -1;
}
for (int i=0; i<arrays.length; i++) {
for (int j=0; j<arrays[i].length; j++) {
System.out.print(arrays[i][j]+"\t");
}
System.out.println();
}
}
}
/*
프로그램 내용 : 문제는 다음과 같다:
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
작성한 날짜 : 2017년 6월 22일
*/
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x, y;
int m_x, m_y;
int **map;
int height = 0, width = -1;
int cnt = 0, course = 1; //출력숫자, 방향설정
scanf_s("%d %d", &x, &y);
m_x = x;
m_y = y;
map = (int**)malloc(sizeof(int)*y);
for (int i = 0; i < y; i++)
{
*(map + i) = (int*)malloc(sizeof(int)*x); //2차원 배열 생성
}
while (1)
{
for (int i = 0; i < m_x; i++)
{
width += course; //가로 증가 또는 감소
map[height][width] = cnt;
cnt++;
}
for (int j = 0; j < m_y-1; j++)
{
height += course; //높이 증가 또는 감소
map[height][width] = cnt;
cnt++;
}
m_x--;
m_y--;
course *= -1; //방향결정
if (m_x == 0 || m_y==0)
{
break; //0이면 종료
}
}
//출력
for (int i = 0; i < y; i++)
{
for (int j = 0; j < x; j++)
{
printf("%4d", map[i][j]); //나선형 회전을 한 값을 출력
}
printf("\n");
}
return 0;
}
W = 6
H = 6
map = []
direction = [(1,0), (0,1), (-1,0), (0,-1)] # 동, 남, 서, 북
for i in range(6):
map.append([-1]*6)
def get_xy(x, y, c_dir):
t_x = x+direction[c_dir][0]
t_y = y+direction[c_dir][1]
if t_x<0 or t_y<0 or t_x>=W or t_y>=H or map[t_y][t_x] != -1:
c_dir = (c_dir+1)%4
return x+direction[c_dir][0], y+direction[c_dir][1], c_dir
return t_x, t_y, c_dir
def go():
global map
x = 0
y = 0
curr_direction = 0
for i in range(W*H):
map[y][x] = str(i)
x, y, curr_direction = get_xy(x, y, curr_direction)
def output():
for i in range(6):
print(" ".join(map[i]))
go()
output()
동서남북에 대한 방향벡터를 저장하는 길이 4짜리 배열을 이용하여 6X6 배열을 한칸씩 이동하면서 숫자를 1씩 늘려나가도록 작성하였습니다. 방향이 변경되는 경우에 대한 조건문을 만들고, 해당 조건문이 참일경우 동서남북 방향벡터 배열의 index를 1늘려서 방향이 변경되도록 하였습니다.(동->남, 남->서, 서->북, 북->동)
go로 풀어봤어요~
// ysoftman
package main
import "fmt"
func main() {
var m, n int
fmt.Scanf("%d %d", &m, &n)
fmt.Println(m, n)
// 2차원 배열 생성
var matrix [][]int
matrix = make([][]int, m)
for i := 0; i < m; i++ {
matrix[i] = make([]int, n)
}
// // -1 초기화
// for i := 0; i < m; i++ {
// for j := 0; j < n; j++ {
// matrix[i][j] = -1
// }
// }
cnt := 0
left, top, right, bottom := 0, 0, n, m
x, y := 0, 0
for left < right && top < bottom {
// 오른쪽 방향으로 고고
for x < right {
matrix[y][x] = cnt
x++
cnt++
}
top++
y = top
x = right - 1
// 아래쪽 방향으로 고고
for y < bottom {
matrix[y][x] = cnt
y++
cnt++
}
right--
x = right - 1
y = bottom - 1
if m == 1 {
left = n
}
// 왼쪽 방향으로 고고
for x >= left {
matrix[y][x] = cnt
x--
cnt++
}
bottom--
y = bottom - 1
x = left
if n == 1 {
top = m
}
// 위쪽 방향으로 고고
for y >= top {
matrix[y][x] = cnt
y--
cnt++
}
left++
x = left
y = top
}
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
fmt.Printf("%2d ", matrix[i][j])
}
fmt.Println()
}
}
제가 이런 걸 그릴 때 생각하는 방식대로 코딩해 봤습니다.
import java.util.HashSet;
import java.util.Scanner;
public class Gen {
/* 진행방향 1 : 우/하 -1 : 좌/상 */
static int direction = 1;
/* 막힌 횟수 : 2가 되면 0으로 초기화 */
static int stuck = 0;
/* 어느 축을 따라가는가? */
static char axis = 'x';
/* 진행 가능 여부를 확인하는 집합 */
static HashSet axix = new HashSet<Integer>();
static HashSet axiy = new HashSet<Integer>();
/* 현재 위치 */
static int curX = 0;
static int curY = 0;
/* 가로 길이와 세로 길이를 입력받아 사각형을 만듧 */
public static int[][] setting(){
Scanner scan = new Scanner(System.in);
System.out.println("가로 길이를 입력해주세요.");
int x = scan.nextInt();
System.out.println("세로 길이를 입력해주세요.");
int y = scan.nextInt();
int[][] tetragon = new int[x][y];
/* 움직일 수 있는 범위 설정 */
axix.add(-1);
axix.add(x);
axiy.add(-1);
axiy.add(y);
/* 만들어진 사각형을 리턴 */
return tetragon;
}
/* 입력 받은 값을 현재 좌표에 기록 후 좌표 설정 */
public static int[][] go(int[][] tetragon, int number){
/* 좌표에 값 기록 */
tetragon[curX][curY] = number;
/* x축과 y축을 나누어 생각 */
if(axis == 'x'){
/* 현재 따라가는 좌표와 수직인 좌표의 값을 집합에 추가 (이동 범위 설정) */
axiy.add(curY);
/* 다음 칸이 막혔을 경우 */
if(axix.contains(curX+direction)){
stuck += 1;
axis = 'y';
/* 꼭지점에 두 번째 닿았을 경우 방향 전환 */
if(stuck == 2){
direction *= -1;
stuck = 0;
curY += direction;
}else{
curY += direction;
}
}else{
curX += direction;
}
}else{
axix.add(curX);
if(axiy.contains(curY+direction)){
stuck += 1;
axis = 'x';
if(stuck == 2){
direction *= -1;
stuck = 0;
curX += direction;
}else{
curX += direction;
}
}else{
curY += direction;
}
}
return tetragon;
}
/* 사각형 출력 */
public static void showTetragon(int[][] tetragon){
for(int y=0;y<tetragon[0].length;y++){
for(int x=0;x<tetragon.length;x++){
System.out.print("[" + tetragon[x][y] + "] ");
}
System.out.println();
}
}
/* 메인 */
public static void main(String[] args) {
int[][] tetragon = setting();
long start = System.nanoTime();
for(int i=0;i<tetragon.length * tetragon[0].length;i++)
go(tetragon, i);
showTetragon(tetragon);
long end = System.nanoTime();
System.out.println(end-start);
}
}
[Python 3.6]
def spiralarray(num1, num2):
array = []
for n1 in range(num1):
row = []
for n2 in range(num2):
row.append(None)
array.append(row)
direct = 'r'
linenum = 0
rownum = 0
array[linenum][rownum] = 0
for n in range(1, num1*num2):
if direct == "r":
if rownum == num2 - 1 or array[linenum][rownum + 1] != None:
direct = "d"
linenum += 1
else:
rownum += 1
elif direct == "d":
if linenum == num1 - 1 or array[linenum + 1][rownum] != None:
direct = "l"
rownum -= 1
else:
linenum += 1
elif direct == "l":
if rownum == 0 or array[linenum][rownum - 1] != None:
direct = "u"
linenum -= 1
else:
rownum -= 1
else:
if linenum == 0 or array[linenum - 1][rownum] != None:
direct = "r"
rownum += 1
else:
linenum -= 1
array[linenum][rownum] = n
for arrayline in array:
for num in arrayline:
print("%3s" % num, end=' ')
print()
public class Ex009 {
static int[][] arr = null;
enum Direction{RIGHT,BOTTOM,LEFT,TOP,FAIL}
public static void main(String[] args) {
// TODO Auto-generated method stub
//입력 및 초기화
init();
//작업 및 출력
footPrint(arr);
}
//발자취 남기기
static private void footPrint(int[][] arr) {
int row = 0;
int column = 0;
int count = 0;
Direction dir = Direction.RIGHT;
//다음으로 이동할 방향이 없을때까지 반복
do {
//배열에 숫자 대입
arr[row][column] = count;
count++;
//다음 위치로 이동
switch(dir) {
case RIGHT:
column++;
break;
case BOTTOM:
row++;
break;
case LEFT:
column--;
break;
case TOP:
row--;
break;
}
}while(!(dir = getDirection(arr,row,column,dir)).equals(Direction.FAIL) );
//마지막 위치에 숫자대입
arr[row][column] = count;
//출력
for(int i=0; i < arr.length; i++) {
for(int j=0; j < arr[i].length; j++)
System.out.print(arr[i][j] + "\t");
System.out.println();
}
}
/*
* 방향탐색함수. 다음 이동할 방향을 반환한다.
* 현재 이동방향이었던 상수를 대입하고 그쪽으로 계속 이동할 수 있는지 검사 후 이동할 수 없다면 다음 이동방향을 설정한 후 재귀적으로 이 함수를 또 호출하여
* 해당방향으로 이동할 수 있는지 검사.
* 재귀가 5번 호출되면 사방으로 모두 이동 불가하므로 재귀함수 호출을 종료한다.
*/
static int iterCount = 0;
static private Direction getDirection(int[][] arr,int row, int column, Direction dir) {
System.out.println("getDirection() 호출");
//재귀 5번 호출될 때, 이동할 수 있는 방향이 없으므로 Direction.FAIL 상수를 반환
if(iterCount == 5) {
iterCount = 0;
return Direction.FAIL;
}
iterCount++;
switch(dir) {
case RIGHT:
System.out.println("스위치 right");
if(column+1 < arr[row].length && arr[row][column+1] == -1) {
dir = Direction.RIGHT;
iterCount = 0;
}
else
dir = getDirection(arr,row,column,Direction.BOTTOM);
break;
case BOTTOM:
System.out.println("스위치 bottom");
if(row+1 < arr.length && arr[row+1][column] == -1) {
dir = Direction.BOTTOM;
iterCount = 0;
}
else
dir = getDirection(arr,row,column,Direction.LEFT);
break;
case LEFT:
System.out.println("스위치 left");
if(column-1 >= 0 && arr[row][column-1] == -1) {
dir = Direction.LEFT;
iterCount = 0;
}
else
dir = getDirection(arr,row,column,Direction.TOP);
break;
case TOP:
System.out.println("스위치 top");
if(row-1 >= 0 && arr[row-1][column] == -1) {
dir = Direction.TOP;
iterCount = 0;
}
else
dir = getDirection(arr,row,column,Direction.RIGHT);
break;
}
return dir;
}
//2차원 배열 초기화
static private void init() {
int row,column;
row = getInputData("row");
column = getInputData("column");
arr = new int[row][column];
for(int i=0; i < row; i++)
for(int j=0; j < column; j++)
arr[i][j] = -1;
}
//행,열 입력받기
static private int getInputData(String varName) {
Scanner scan = new Scanner(System.in);
int input;
do {
System.out.print(varName + ": ");
input = scan.nextInt();
}while(input < 2);
return input;
}
}
로직
배열의 현재 위치에 족적(숫자)를 남기고
현재 설정된 이동 방향으로 이동 가능한지 체크
3-1. 이동이 가능하다면 이동한다. 다시 1번부터 반복.
3-2. 이동이 불가능 하다면 현재 설정된 이동방향에서 시계방향으로 90도 돌게된 방향으로 이동가능한지 체크, 이것도 안된다면 그다음 90도 돈 방향으로 되는지 체크... 체크하는 도중 이동가능한 방향이 나온다면 해당 방향으로 이동. 모든 방향을 체크했는데도 이동할 방향이 없다면 로직 종료.
결과는 어떻게해서 나오긴하는데 코드가 맘에 안드네요. 지적 달게 받겠습니다.
import numpy as np
X, Y = map(int, input('X Y = ').split())
arr = np.full((X, Y), -1)
dx, dy = [0, 1, 0, -1], [1, 0, -1, 0]
x, y, d = 0, 0, 0
for i in range(X * Y):
arr[x, y] = i
xx, yy = x + dx[d], y + dy[d]
if not (0 <= xx < X and 0 <= yy < Y and arr[xx, yy] < 0):
d = (d + 1) % 4
xx, yy = x + dx[d], y + dy[d]
x, y = xx, yy
print(arr)
package java_tutorial;
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args) {
int movement = 1;
int count = 0;
int a = 0, b = -1;
Scanner sc = new Scanner(System.in);
System.out.print("가로, 세로 몇 칸짜리? : ");
int length = sc.nextInt();
int height = sc.nextInt();
int [][]spiral = new int[height][length];
int lenLimit = length;
int heiLimit = height;
while(true){
for(int i = 0; i < lenLimit; i++){
b = b + movement;
spiral[a][b]=count;
count++;
}
lenLimit--;
heiLimit--;
for(int i = 0; i < heiLimit; i++)
{
a = a + movement;
spiral[a][b] = count;
count++;
}
if(lenLimit >= heiLimit && lenLimit == 0)
{
break;
}
if(lenLimit <= heiLimit && heiLimit == 0)
{
break;
}
movement=-movement;
}
for(int i = 0; i < height; i++)
{
for(int j = 0; j < length; j++)
{
System.out.print(spiral[i][j]+"\t");
}
System.out.println();
}
}
}
Python 3으로 풀었습니다. 뭔가 깔끔해보이지 않네요.
def print_spiral_array(m, n):
array = [[-1 for _ in range(n)] for _ in range(m)]
x, y, invalid = 0, 0, -1
steps = [(0, 1), (1, 0), (0, -1), (-1, 0)]
curr = 0
for i in range(m * n):
# print(i, x, y)
array[x][y] = i
new_x, new_y = x + steps[curr][0], y + steps[curr][1]
# collision
if new_x < 0 or new_x >= m or new_y < 0 or new_y >= n or array[new_x][new_y] != invalid:
curr = (curr + 1) % len(steps)
new_x, new_y = x + steps[curr][0], y + steps[curr][1]
x, y = new_x, new_y
for row in array:
for item in row:
print('%4s' % item, end='')
print()
print()
print_spiral_array(6, 6)
파이썬입니다
#2. Spiral Array
#1. row column input
#2. build up an array by using list-in-list
#3. 방향자를 복소수로하여 부딪히면 방향전환
#4. 출력 (출력시 오른쪽정렬하는법을 일반적으로 하는 방법은 모르겠음)
#1. 잘못 입력시 에러만 남
size = input()
space = size.find(' ')
row = int(size[0:space])
col = int(size[space+1:])
#2.
Array = []
hub = []
for i in range(col):
hub.append(-1)
for i in range(row):
Array.append(hub[:])
#3.
m, n, k = 0, 0, 0
Array[m][n] = k
D = complex(1,0)
while k < row*col -1:
m = m + int(D.real)
n = n + int(D.imag)
try:
if Array[m][n]!=-1:
m = m - int(D.real)
n = n - int(D.imag)
D = D*(1j)
else:
k = k+1
Array[m][n]=k
except IndexError:
m = m - int(D.real)
n = n - int(D.imag)
D = D*(1j)
#4.
for j in range(col):
for i in range(row):
print('{:2d}'.format(Array[i][j]),end=' ')
print()
import java.util.Scanner;
enum Direction {R, D, L, T}
public class Calculate {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
Direction d = Direction.R;
System.out.println("생성하고자 하는 매트릭스 크기를 입력하세요.");
System.out.println("(6x6 생성시 6, 6 을 입력)");
System.out.print("X축 크기 : ");
int x = s.nextInt();
System.out.print("Y축 크기 : ");
int y = s.nextInt();
int[][] table = new int[x][y];
//배열을 -1로 초기화 (입력되지 않은 위치)
for(int i=0 ; i<x ; i++)
for(int j=0 ; j<y ; j++)
table[i][j] = -1;
int pX = 0;
int pY = 0;
String str = "";
for(int i=0 ; i<x*y ; i++) { //전체 매트릭스 횟수 반복
table[pY][pX] = i;
//현재 방향으로 계속 이동 가능 여부 확인
if( (d == Direction.R && pX+1<x && table[pY][pX+1] == -1) || //오른쪽 이동 가능
(d == Direction.D && pY+1<y && table[pY+1][pX] == -1) || //하단 이동 가능
(d == Direction.L && pX-1>-1 && table[pY][pX-1] == -1) || //왼쪽 이동 가능
(d == Direction.T && pY-1>-1 && table[pY-1][pX] == -1) //상단 이동 가능
){
;// 이동이 가능하면 아무것도 수행하지 않음
} else {
//현재 방향으로 계속 이동 불가능할 경우 다음 방향으로 변경
if (d == Direction.R) d = Direction.D;
else if(d == Direction.D) d = Direction.L;
else if(d == Direction.L) d = Direction.T;
else if(d == Direction.T) d = Direction.R;
}
//다음 위치로 좌표 이동
if (d == Direction.R) ++pX;
else if(d == Direction.D) ++pY;
else if(d == Direction.L) --pX;
else if(d == Direction.T) --pY;
}
for(int i=0 ; i<y ; i++){
for(int j=0 ; j<x ; j++){
str = table[i][j] < 10 ? " 0"+table[i][j] : " "+table[i][j];
System.out.print(str);
}
System.out.println();
}
}
}
public class SpiralArray {
static int gop = 0;
public static int[][] moveArray(int[][] arr, String move, int colStart, int colEnd, int rowStart, int rowEnd, int num) {
if(num == 0) {
gop = (colEnd+1) * (rowEnd+1);
}
if(num == gop) {
return arr;
}else {
if(move.equals("r")) {
// 오른쪽으로
// col 증가
for(int i=colStart; i<=colEnd; i++) {
arr[rowStart][i] = num;
num++;
}
return moveArray(arr, "d", colStart, colEnd, rowStart+1, rowEnd, num);
}else if(move.equals("d")) {
// 아래로
// row 증가
for(int i=rowStart; i<=rowEnd; i++) {
arr[i][colEnd] = num;
num++;
}
return moveArray(arr, "l", colStart, colEnd-1, rowStart, rowEnd, num);
}else if(move.equals("l")) {
// 왼쪽으로
// col 감소
for(int i=colEnd; i>=colStart; i--) {
arr[rowEnd][i] = num;
num++;
}
return moveArray(arr, "u", colStart, colEnd, rowStart, rowEnd-1, num);
}else {
// 위로
// row감소
for(int i=rowEnd; i>=rowStart; i--) {
arr[i][colStart] = num;
num++;
}
return moveArray(arr, "r", colStart+1, colEnd, rowStart, rowEnd, num);
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int arr1 = sc.nextInt();
int arr2 = sc.nextInt();
int[][] sArr = new int[arr1][arr2];
int[][] moveArray = moveArray(sArr, "r", 0, arr1-1, 0, arr2-1, 0); // index는 0부터이기 때문에 -1씩 해줌
for(int i=0; i<arr1; i++) {
for(int j=0; j<arr2; j++) {
System.out.print(moveArray[i][j] + " ");
}
System.out.println();
}
}
}
재귀함수 써서 풀어봤어요
def SpiralArray(X, Y):
result = [[0 for i in range(X)] for j in range(Y)]
x, y = (0, 0)
min_x, min_y = (0, 1)
max_x = X-1
max_y = Y-1
flag = 0
for i in range(X*Y):
print('x: ' + str(x) +' y: '+str(y) + ' = ' + str(i))
result[y][x] = i
if(flag == 0):
x+=1
if(x == max_x):
max_x-=1
flag = 1
elif(flag == 1):
y+=1
if(y == max_y):
max_y-=1
flag = 2
elif(flag == 2):
x-=1
if(x == min_x):
min_x+=1
flag = 3
elif(flag == 3):
y-=1
if(y == min_y):
min_y+=1
flag = 0
return result
def main():
if (__name__ == '__main__'):
for i in SpiralArray(6,6):
row = ''
for j in i:
row += ('%3d'%j)
print(row+'\n')
main()
일단은 try, except 써서 문제는 풀긴 했는데
except랑 finally 부분을 줄여 보려고 하면 CPU가 계속 돌더라구요;;
while 부분도 계속 돌아가길래 일단은 count 변수로 4번까지로 한정해두긴 했는데.. 이런 부분들이 해결이 안 되네요..
x, y = map(int, input().split(' '))
l=[]
for i in range(x):
l.append(["0"]*y)
def view(mat):
print("="*2*y)
for opo in range(len(l)):
print(" ".join(mat[opo]))
i = 0
j = 0
di = 0
dj = 1
for k in range(x*y):
l[i][j]=str(k+1)
view(l)
count=0
while count<4:
count+=1
try:
if l[i+di][j+dj]=="0":
i+=di
j+=dj
break
except:
pass
finally:
if l[i][j]!="0":
a=di
b=dj
di=b
dj=-a
count+=1
row=int(input('행의 수를 입력해주세요:'))
col=int(input('열의 수를 입력해주세요:'))
array=[['\n' for y in range(col)] for x in range(row)]
cnt=0
i=0
j=0
num=1
array[0][0]=0
while cnt < round(row/2):
for j in range(j+1, col):
if array[i][j]=='\n':
array[i][j]=num
num+=1
else:
j-=1
break
for i in range(i+1, row):
if array[i][j]=='\n':
array[i][j]=num
num+=1
else:
i-=1
break
for j in range(j-1, -1, -1):
if array[i][j]=='\n':
array[i][j]=num
num+=1
else:
j+=1
break
for i in range(i-1, -1, -1):
if array[i][j]=='\n':
array[i][j]=num
num+=1
else:
i+=1
break
cnt+=1
print(array)
$row = 6;
$col= 6;
$total = $row*$col;
$x_max = $row-1;
$y_max = $col-1;
$total=$row*$col;
$array = process(0,0,$x_max,0,$y_max,0,1,0,$total);
for($x=0;$x<=$x_max;$x++){
for($y=0;$y<=$y_max;$y++){
if(strlen($array[$x][$y])==1) $array[$x][$y] = "0".$array[$x][$y];
echo $array[$x][$y]." ";
}
echo "<br>";
}
// $x = x좌표값
// $y = y좌표값
// $x_max = x 변수에 세팅할 수 있는 최대값
// $y_max = y 변수에 세팅할 수 있는 최대값
// $x_min = x 변수에 세팅할 수 있는 최소값
// $y_min = y 변수에 세팅할 수 있는 최소값
// $type = 어떤 좌표의 값이 증가할지 감소할지를 결정하는 값
// $insert = 배열에 세팅되는 숫자
// $max = 배열에 세팅되는 최대값
// 1) y좌표가 증가하고(X최대값 까지)
// 2) X좌표가 증가하고(Y최대값 까지)
// ------------------------------ X최소값 증가, Y최대값 감소
// 3) Y좌표가 감소하고(Y최소값 까지)
// 4) X좌표가 감소하고(X최소값 까지)
// ------------------------------ Y최소값 증가, X최대값 감소
// 1->2->3->4->1 ....
function process($x,$y,$x_max,$x_min,$y_max,$y_min,$type,$insert,$max){
for($cnt = 0; $cnt < $max; $cnt++){
$array[$x][$y] = $insert;
if($type ==1 && $y < $y_max){
$y++;
if($y == $y_max) $type=2;
}else if($type ==2 && $x < $x_max){
$x++;
if($x == $x_max){
$type=3;
$x_min++;
$y_max--;
}
}else if($type ==3 && $y > $y_min){
$y--;
if($y == $y_min) $type=4;
}else if($type ==4 && $x > $x_min){
$x--;
if($x == $x_min){
$type=1;
$y_min++;
$x_max--;
}
}
$insert++;
}
return $array;
}
Scanner scan = new Scanner(System.in);
int a,b,i,j;
int r = 0,c = 0,num=0, l=0;
//l=0 R, 1=1 B, 1=2 L, l=3 U
a = scan.nextInt();
b = scan.nextInt();
int[][] test = new int[a][b];
for(i=0;i<a;i++)
{
for(j=0;j<b;j++)
{
test[i][j] = -1 ;
}
}
while (num < a * b)
{
test[r][c] = num++;
switch (l) {
case 0:
if(c+1<b && test[r][c+1] == -1)
c++;
else{
l=1;
r++;
}
break;
case 1:
if(r+1<a && test[r+1][c] == -1)
r++;
else{
l=2;
c--;
}
break;
case 2:
if(c-1>=0 && test[r][c-1] == -1)
c--;
else{
l=3;
r--;
}
break;
case 3:
if(r-1>=0 && test[r-1][c] == -1)
r--;
else{
l=0;
c++;
}
break;
default:
break;
}
}
for(i=0;i<a;i++)
{
for(j=0;j<b;j++)
{
System.out.print(test[i][j] + "\t");
}
System.out.println("");
}
}
}
방향을 지정하여 조건에 맞으면 입력하는 방식으로 하니 쉽게풀렸네요. 방향없이하니까 지렁이처럼 나오더군요...
def init_array(row,col):
initArr = []
for ix in range(row):
tmpArr = []
for iy in range(col):
tmpArr.append(-1)
initArr.append(tmpArr)
return initArr
def spiral_Array(row,col):
sArr = init_array(row,col)
irow = 0
icol = 0
cnt = 0
arrow = 'r'
while 1:
if sArr[irow][icol] == -1:
#현재 위치 -1확인
sArr[irow][icol] = cnt
cnt += 1
#자리 이동
if arrow == 'r':
#오른쪽 -1 확인
if (icol+1 < col) and (sArr[irow][icol+1] == -1):
icol+=1
else:
arrow='d'
elif arrow == 'd':
#아래 -1 확인
if (irow+1 < row) and (sArr[irow+1][icol] == -1):
irow+=1
else:
arrow='l'
elif arrow == 'l':
#왼쪽 -1 확인
if (icol-1 >= 0) and (sArr[irow][icol-1] == -1):
icol-=1
else:
arrow='u'
elif arrow == 'u':
if (irow-1 >= 0) and (sArr[irow-1][icol] == -1):
#위로 -1 확인
irow-=1
else:
arrow='r'
if cnt > row*col-1:
break
return sArr
print(spiral_Array(6,6))
import java.util.Arrays;
enum Direction {
TOP, RIGHT, BOTTOM, LEFT
}
public class Example2 {
public static void main(String[] args) {
int num1 = 6;
int num2 = 6;
Example2 ex = new Example2();
ex.GetSpiral(num1, num2);
}
private void GetSpiral(int n1, int n2) {
Direction direct = Direction.TOP;
int[][] sprial = new int[n1][n2];
for (int[] row : sprial) {
Arrays.fill(row, -1);
}
int num = 0;
int top = 0;
int bottom = n2 - 1;
int right = n1 - 1;
int left = 0;
while (true) {
if (num == n1 * n2) {
break;
}
switch (direct) {
case TOP:
for (int j = 0; j < n1; j++) {
if (sprial[top][j] == -1) {
sprial[top][j] = num++;
}
}
top++;
direct = Direction.RIGHT;
break;
case RIGHT:
for (int i = 0; i < n2; i++) {
if (sprial[i][right] == -1) {
sprial[i][right] = num++;
}
}
right--;
direct = Direction.BOTTOM;
break;
case BOTTOM:
for (int j = n1 - 1; j >= 0; j--) {
if (sprial[bottom][j] == -1) {
sprial[bottom][j] = num++;
}
}
bottom--;
direct = Direction.LEFT;
break;
case LEFT:
for (int j = n2 - 1; j >= 0; j--) {
if (sprial[j][left] == -1) {
sprial[j][left] = num++;
}
}
left++;
direct = Direction.TOP;
break;
}
}
// print
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
System.out.print(sprial[i][j] + " ");
}
System.out.println("");
}
}
}
풀긴 했는데 좀 비효율적인것 같네요.. 일단 저는 top, right, left, bottom 의 위치를 지정해서 풀었습니다. 그리고 값이 있으면 필터 했어요.
def f1(d, x, y):
if d == 1:
y += 1
elif d == 2:
x += 1
elif d == 3:
y -= 1
elif d == 4:
x -= 1
return x, y
def f(y1, x1):
arr1 = [[-1 for x in range(0, y1)] for x in range(0, x1)]
x,y = 0,0
d1 = 1
for i1 in range(0, x1*y1):
if y >= y1 or x >= x1 or x < 0 or y < 0 or arr1[x][y] != -1:
if d1 == 1:
d1 = 2
y -= 1
x += 1
elif d1 == 2:
d1 = 3
x -= 1
y -= 1
elif d1 == 3:
d1 = 4
y += 1
x -= 1
elif d1 == 4:
d1 = 1
x += 1
y += 1
arr1[x][y] = i1
x, y = f1(d1, x, y)
for i1 in range(len(arr1)):
print(arr1[i1])
f(6,6)
f(6,7)
# -*- coding: utf-8 -*-
# python 3.6
import itertools
inpStr = "6 6"
inpX = int(inpStr.split()[0])
inpY = int(inpStr.split()[1])
# inpX by inpY 크기의 dic{(X좌표, y좌표):None} 초기화
dic = {(x, y): None for (x, y) in [(i, j)
for i in range(inpX) for j in range(inpY)]}
# 순환 참조할 (dx, dy) : RDLURDLU...
direction = itertools.cycle([(1, 0), (0, 1), (-1, 0), (0, -1)])
x = 0
y = 0
dxdy = next(direction)
dx = dxdy[0]
dy = dxdy[1]
for i in range(inpX * inpY):
dic[(x, y)] = i
# 다음 이동 좌표가 배열을 벗어 나거나, 즉, (x, y) 키 가 존재하지 않거나
# 이미 값이 입력돼 있을 경우 방향 전환
if (x + dx, y + dy) not in dic.keys() or dic[(x + dx, y + dy)] is not None:
dxdy = next(direction)
dx = dxdy[0]
dy = dxdy[1]
x += dx
y += dy
# print matrix
for y in range(inpY):
for x in range(inpX):
print("%4d " % dic[(x, y)], end="")
print()
파이썬을 공부한지 얼마 안됬는데 2차원 리스트의 열을 다루는 법을 모르겠네요, 행렬의 열을 어떻게 다루면 좀 더 빨라질 듯한데.. 지적 감사히 받겠습니다.
#2차원리스트이지만 x,y간의 관계에 따라 커브를 도는 규칙이 존재.
#규칙은 아래와 같다, 아래에서 생성된 리스트의 각 원소는 한방향으로 채울 칸 수를 결정.
#리스트의 원소에 대응하는 인덱스는 방향을 결정 index%4: 0:right 1:down 2:left 3:up
if x==y:
step_y,step_x=list(range(1,y+1)),list(range(1,x))
elif x>y:
step_y,step_x=list(range(1,y+1)),list(range(x-y,x))
else:
step_y,step_x=list(range(y-x+1,y+1)),list(range(1,x))
lenx,leny=len(step_x),len(step_y)
for i in range(1,lenx+1):
step_y.insert(leny-i,step_x.pop())
step_y.reverse()
step=step_y
#위에서 만든 리스트 step을 통해 한칸씩 field의 수를 count로 채워나간다.
for index,temp in enumerate(step):
if index % 4==0:
for i in range(temp):
field[nowx][nowy+1]=count
count+=1
nowy+=1
elif index%4==1:
for i in range(temp):
field[nowx+1][nowy]=count
nowx+=1
count+=1
elif index%4==2:
for i in range(temp):
field[nowx][nowy-1]=count
nowy-=1
count+=1
else:
for i in range(temp):
field[nowx-1][nowy]=count
nowx-=1
count+=1
#출력
for i in range(x):
for j in range(y):
print("%4d" %field[i][j],end='')
print("")
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] array = new int[n+1][m+1];
int x = 0;
int y = 0;
int dir = 1;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
array[i][j] = -1;
for (int i = 0; i < n*m; i++) {
array[x][y] = i;
if (dir == 1){
if (y+1 >= m || array[x][y+1] != -1) { dir = 2; x++; }
else y++;
}
else if (dir == 2) {
if (x+1 >= n || array[x+1][y] != -1) { dir = 3; y--; }
else x++;
}
else if (dir == 3) {
if (y-1 < 0 || array[x][y-1] != -1) { dir = 4; x--; }
else y--;
}
else {
if (x-1 < 0 || array[x-1][y] != -1) { dir = 1; y++; }
else x--;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
System.out.printf("%3d",array[i][j]);
System.out.println("");
}
sc.close();
}
package main
import "fmt"
const (
RIGHT = 1 + iota
DOWN
LEFT
UP
)
var matrix [][]int
func main() {
var mat_x, mat_y int
fmt.Scanf("%d %d", &mat_x, &mat_y)
fmt.Println(mat_x, mat_y)
matrix = make([][]int, mat_x)
for i := 0; i < mat_x; i++ {
matrix[i] = make([]int, mat_y)
}
make_matrix(0, mat_x, mat_y - 1, 0, 0, RIGHT)
for x := 0; x < mat_x; x++ {
for y := 0; y < mat_y; y++ {
fmt.Print(fmt.Sprintf("%02d ", matrix[x][y]))
}
fmt.Println("")
}
}
func make_matrix(start_num, x_len, y_len, x_pos, y_pos, direct int) {
switch direct {
case RIGHT:
for i := start_num; i < start_num + x_len; i++ {
matrix[x_pos][y_pos] = i;
y_pos ++
}
start_num = start_num + x_len
x_len -= 1
x_pos += 1
y_pos -= 1
case DOWN:
for i := start_num; i < start_num + y_len; i++ {
matrix[x_pos][y_pos] = i
x_pos ++
}
start_num = start_num + y_len
y_len -= 1
x_pos -= 1
y_pos -= 1
case LEFT:
for i := start_num ; i < start_num + x_len ; i++ {
matrix[x_pos][y_pos] = i
y_pos --
}
start_num = start_num + x_len
x_len -= 1
y_pos += 1
x_pos -= 1
case UP:
for i := start_num; i < start_num + y_len; i++ {
matrix[x_pos][y_pos] = i
x_pos --
}
start_num = start_num + y_len
y_len -= 1
x_pos += 1
y_pos += 1
}
direct += 1
if direct > UP {
direct = RIGHT
}
if x_len <= 0 && y_len <= 0 {
return
} else {
make_matrix(start_num, x_len, y_len, x_pos, y_pos, direct)
}
return
}
#include <iostream>
#include <vector>
#include <stack>
#include <math.h>
#include <Windows.h>
using namespace std;
void gotoxy(int x, int y)
{
COORD pos = { x - 1, y - 1 };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
vector<vector<int>> spiral(int arr_size_1, int arr_size_2) {
vector<vector<int>> arr(arr_size_1, vector<int>(arr_size_2, -1));
int pos_x = 0;
int pos_y = 0;
int num = 0;
arr[0][0] = 0;
string direction = "right";
while (1) {
if (num == arr_size_1 * arr_size_2 - 1) {
break;
}
if (direction == "right") {
if (pos_x + 1 < arr_size_2) {
if (arr[pos_y][pos_x + 1] == -1)
{
arr[pos_y][++pos_x] = ++num;
}
else {
direction = "down";
}
}
else {
direction = "down";
}
}
else if (direction == "down") {
if (pos_y + 1 < arr_size_1) {
if (arr[pos_y + 1][pos_x] == -1)
{
arr[++pos_y][pos_x] = ++num;
}
else {
direction = "left";
}
}
else {
direction = "left";
}
}
else if (direction == "left") {
if (pos_x - 1 >= 0) {
if (arr[pos_y][pos_x - 1] == -1)
{
arr[pos_y][--pos_x] = ++num;
}
else {
direction = "up";
}
}
else {
direction = "up";
}
}
else if (direction == "up") {
if (pos_y - 1 >= 0) {
if (arr[pos_y - 1][pos_x] == -1)
{
arr[--pos_y][pos_x] = ++num;
}
else {
direction = "right";
}
}
else {
direction = "right";
}
}
}
return arr;
}
int main() {
vector<vector<int>> arr = spiral(10, 8);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 8; j++) {
gotoxy((j + 1) * 5, (i + 1) * 2);
cout << arr[i][j];
}
}
cout << endl;
}
#include <iostream>
#include <vector>
#include <stack>
#include <math.h>
#include <Windows.h>
using namespace std;
void gotoxy(int x, int y)
{
COORD pos = { x - 1, y - 1 };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
vector<vector<int>> spiral(int arr_size_1, int arr_size_2) {
vector<vector<int>> arr(arr_size_1, vector<int>(arr_size_2, -1));
int pos_x = 0;
int pos_y = 0;
int num = 0;
arr[0][0] = 0;
string direction = "right";
while (1) {
if (num == arr_size_1 * arr_size_2 - 1) {
break;
}
if (direction == "right") {
if (pos_x + 1 < arr_size_2) {
if (arr[pos_y][pos_x + 1] == -1)
{
arr[pos_y][++pos_x] = ++num;
}
else {
direction = "down";
}
}
else {
direction = "down";
}
}
else if (direction == "down") {
if (pos_y + 1 < arr_size_1) {
if (arr[pos_y + 1][pos_x] == -1)
{
arr[++pos_y][pos_x] = ++num;
}
else {
direction = "left";
}
}
else {
direction = "left";
}
}
else if (direction == "left") {
if (pos_x - 1 >= 0) {
if (arr[pos_y][pos_x - 1] == -1)
{
arr[pos_y][--pos_x] = ++num;
}
else {
direction = "up";
}
}
else {
direction = "up";
}
}
else if (direction == "up") {
if (pos_y - 1 >= 0) {
if (arr[pos_y - 1][pos_x] == -1)
{
arr[--pos_y][pos_x] = ++num;
}
else {
direction = "right";
}
}
else {
direction = "right";
}
}
}
return arr;
}
int main() {
vector<vector<int>> arr = spiral(10, 8);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 8; j++) {
gotoxy((j + 1) * 5, (i + 1) * 2);
cout << arr[i][j];
}
}
cout << endl;
}
m = 6; n = 6
# prepare 2D array
ans = [[-1 for i in range(n)] for j in range(m)]
# True 이면 x가 증/감, False이면 y가 증감
xTurn = True
# Dir이 +1이면 축방향 증가, -1이면 축방향 감소
dx,dy = 1, 1
#각각 x축 좌표, y축 좌표, 행렬에 들어갈 값,
x,y,v = 0,0,0
while v < m*n:
#만약에 x와 y가 행렬 밖의 범위이거나, 그 값이 이미 -1이 아닌 값으로 채워져 있다면
#(초기값은 -1이므로 이미 채워져 있으면 0보다 크거나 같다)
if x<0 or x>=n or y<0 or y>=m or ans[y][x] >= 0:
if xTurn == True: # x 차례 였다면
xTurn = False # 이제 y 차례로 바꿔야 함
x -= dx # 한 칸 더 갔으므로 반대 방향으로 한칸 이동해 둔다.
dx *= -1 # 다음 번에 x는 반대 방향으로 가야함
y += dy # y는 다음 방향으로 한칸 이동해 두어야 함
else:
xTurn = True
y -= dy
dy *= -1
x += dx
else:
ans[y][x] = v # 이전에 방문하지 않고, 행렬 범위 안이라면
v += 1 # 값을 넣고 다음 값으로 증가 시킴
if xTurn == True: # 다음 칸으로 으로 이동 (+1 or -1 방향)
x += dx
else:
y += dy
# 결과를 출력한다
for j in range(m):
for i in range(n):
val = '{0:3d}'.format(ans[j][i])
print(val, end=' ')
print()
dirseq = [[1, 0, -1, 0], [0, 1, 0, -1]]
def findnext(x, y, dir):
for i in range(4):
xnext = x + dirseq[0][(dir+i)%4]
ynext = y + dirseq[1][(dir+i)%4]
if xnext < X and ynext < Y and table[ynext][xnext] == '.':
return xnext, ynext, dir+i
return -1, -1, -1
# make and init table
X, Y = input('input size of array : ').split()
X = int(X)
Y = int(Y)
table = [['.' for x in range(X)] for y in range(Y)]
# make to spiral array table
x, y, dir = 0, 0, 0
for i in range(X*Y):
table[y][x] = i
x, y, dir = findnext(x, y, dir)
# print table
for y in range(Y):
for x in range(X):
print('%3d' %table[y][x], end=' ')
print()
```{.java} import java.util.ArrayList; import java.util.Scanner;
public class Practice {
public static void main(String[] args) {
Scanner buf = new Scanner(System.in);
int m = buf.nextInt();
int n = buf.nextInt();
int[][] arr = new int[m][n];
for(int i=0 ;i<m;i++) {
for(int j=0 ; j<n;j++) {
arr[i][j] = buf.nextInt();
}
}
for(int i=0 ;i<m;i++) {
for(int j=0 ; j<n;j++) {
int temp= arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = temp;
}
}
for(int i=0 ;i<m;i++) {
for(int j=0 ; j<n;j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println("");
}
}
}
NONE = -1
RIGHT, LEFT, DOWN, UP = 0, 1, 2, 3
NEXT_X = [0, 0, 1, -1]
NEXT_Y = [1, -1, 0, 0]
TURN = [DOWN, UP, LEFT, RIGHT]
x_size = 20
y_size = 10
d = RIGHT
no = 0
x, y = 0, -1
arr = [[NONE for j in range(y_size)] for i in range(x_size)]
while no < x_size * y_size:
next_x = x + NEXT_X[d]
next_y = y + NEXT_Y[d]
if -1 < next_x < x_size and -1 < next_y < y_size and arr[next_x][next_y] == NONE:
arr[next_x][next_y] = no
x = next_x
y = next_y
no += 1
else:
d = TURN[d]
for row in arr:
for no in row:
print('{:3}'.format(no), end=' ')
print()
마지막 숫자를 미리 구한 다음 for 구문으로 하나씩 적게 합니다. 다음에 숫자를 적을 위치를 계산한 뒤, 위치가 행렬 밖이거나, 해당 위치에 다른 숫자가 이미 있으면 방향을 틉니다. 방향 틀기는 순서가 일정하므로 함수화합니다.
import re
inp = [int(i) for i in re.findall("\d+", input("입력 = "))]
length = inp[0] * inp[1]
point = [1,1]
array = {}
d = [1, 0]
chr_len = len(str(length)) +2
def chn_dir(dir) :
if dir == [1, 0] : dir = [0, 1]
elif dir == [0, 1] : dir = [-1, 0]
elif dir == [-1, 0] : dir = [0, -1]
elif dir == [0, -1] : dir = [1, 0]
return dir
def ListAdd(lisA,lisB) :
Add = [sum(K) for K in zip(lisA,lisB)]
return Add
for n in range(length) :
j = point[0]
k = point[1]
array[j,k] = n
next = ListAdd(point,d)
if array.get(tuple(next)) != None or next[0] > inp[0] or next[1] > inp[1] or 0 in next :
d=chn_dir(d)
point = ListAdd(point,d)
else : point = ListAdd(point,d)
#print(array)
line = ""
aa = 1
bb = 1
for i in range(length) :
t1 = (aa, bb)
chr = str(array.get(t1))
line += " " * (chr_len - len(chr)) + chr
aa += 1
if aa > inp[0] :
aa = 1
bb += 1
line += "\n"
print(line)
public class SpiralArray {
public static void main(String[] args) {
int matSize = 6;
int size = matSize; //바뀐 방향으로 채워야 하는 공간
int row, col; row = col = 0;
int[][] arr = new int[matSize][matSize];
for(int num = 0; num < matSize*matSize;){
//우
if(row == col){
for (int i = 0; i < size; i++) {
arr[row][col++] = num++;
}size--;col--;row++;
}
//하
if(row <= col){
for (int i = 0; i < size; i++) {
arr[row++][col] = num++;
}row--;col--;
}
//좌
if(row - col == 1){
for (int i = 0; i < size; i++) {
arr[row][col--] = num++;
}size--;col++;row--;
}
//상
if(row >= col){
for (int i = 0; i < size; i++) {
arr[row--][col] = num++;
}row++;col++;
}
}
for (int i = 0; i<matSize; i++){
for (int j = 0; j<matSize; j++){
System.out.print("\t" + arr[i][j]);
}
}
}
}
import java.util.Scanner;
public class Main {
public static boolean inCorner(int[][] spiral, int x, int y){
return (x<0||x>spiral.length-1||y<0||y>spiral[0].length-1)||(spiral[x][y]!=0);
//return true when x,y is out of range
}
public static boolean isBlank(int[][] spiral, int x, int y){
if (x<0||x>spiral.length-1||y<0||y>spiral[0].length-1) return false;
else if(x==0&&y==0) return false;
else return spiral[x][y]==0;
}
public static boolean isTop(int[][] spiral, int x, int y){
//check whether stopped point is upper most
return inCorner(spiral,x-1,y)&&inCorner(spiral,x,y-1)&&isBlank(spiral,x,y+1);
}
public static boolean isBottom(int[][] spiral, int x, int y){
//check whether stopped point is bottom most
return inCorner(spiral,x+1,y)&&inCorner(spiral,x,y+1)&&isBlank(spiral,x,y-1);
}
public static boolean isLeft(int[][] spiral, int x, int y){
//check whether stopped point is left most
return inCorner(spiral,x+1,y)&&inCorner(spiral,x,y-1)&&isBlank(spiral,x-1,y);
}
public static boolean isRight(int[][] spiral, int x, int y){
//check whether stopped point is right most
return inCorner(spiral,x-1,y)&&inCorner(spiral,x,y+1)&&isBlank(spiral,x+1,y);
}
public static void spiral(int[][] spiral){
int num =0; int row = spiral.length; int col = spiral[0].length;
int x=0; int y=0;
while(num<row*col){
if(isTop(spiral,x,y)){
if(x==0&&y==0){
spiral[x][y] = 1;
num = num+1;
y= y+1;
}
while(isBlank(spiral,x,y+1)){
spiral[x][y] = num;
num = num+1;
y= y+1;
}
}
else if(isBottom(spiral,x,y)){
while(isBlank(spiral,x,y-1)){
spiral[x][y] = num;
num = num+1;
y= y-1;
}
}
else if(isRight(spiral,x,y)){
while(isBlank(spiral,x+1,y)){
spiral[x][y] = num;
num = num+1;
x= x+1;
}
}
else if(isLeft(spiral,x,y)){
while(isBlank(spiral,x-1,y)){
spiral[x][y] = num;
num = num+1;
x= x-1;
}
}
else if(num==row*col-1){
spiral[x][y] = num;
num = num+1;
}
}
spiral[0][0]=0;
}
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int row = sc.nextInt();
int col = sc.nextInt();
int[][] spiral = new int[row][col];
spiral(spiral);
for(int i=0; i<row; i++){
System.out.print("\r\n");
for(int j=0; j<col; j++){
System.out.print("\t"+spiral[i][j]);
}
}
sc.close();
}
}
class Spiral:
d = [(1,0), (0,1),(-1,0),(0,-1)]
def __init__(self, w, h):
self.w = w
self.h = h
self.result = [0] * (w*h)
self._calc()
def display(self):
for y in range(self.h):
for x in self.result[y*self.w:(y+1)*self.w]:
print("%3d" % x, end=' ')
print(' ')
def _next_step(self, p, d):
if not d: return
nx, ny = p[0] + d[0][0], p[1] + d[0][1]
if nx>=0 and nx<self.w and ny>=0 and ny<self.h and self.result[nx+ny*self.w] == 0:
return nx, ny
else:
d.append(d.pop(0))
return self._next_step(p, d[:len(d)-1])
def _calc(self):
c = 0
step = 0, 0
while any([v == 0 for v in self.result]) and step:
self.result[step[0]+step[1]*self.w] = c
c += 1
step = self._next_step(step, self.d)
Spiral(6,6).display()
결과를 담는 list를 생성 "[0] * (w*h)"후 _next_step 메서드로 다음 step의 존재 여부 확인하여 존재 하는 경우 계속해서 값을 채우는 방식을 사용했습니다.
_next_step은 d의 첫번째 값으로 현재 진행 중인 방향을 표시하며 진행이 불가능 한 경우 list의 다음 진행 방향으로 바꾸고 4가지 방향 모두 진행이 불가능 한 경우 None을 리턴하여 더이상 진행이 불가함을 표시 합니다.
int **malloc_2d(int row, int col)
{
int i;
int **p = (int **)malloc(sizeof(int *) * row);
if (p == NULL) return NULL;
for (i = 0; i < row; i++) {
p[i] = (int *)malloc(sizeof(int) * col);
if (p[i] == NULL) {
int j;
for (j = 0; j < i; j++)
free(p[j]);
free(p);
return NULL;
}
}
return p;
}
void free_2d(int **p, int row)
{
int i;
for (i = 0; i < row; i++)
free(p[i]);
free(p);
}
int main()
{
for (;;)
{
int i = 0;
int j = 0;
int n;
int m;
int k = 0;
int c = 0;
char a = 'c';
printf("row:");
scanf("%d", &n);
printf("col:");
scanf("%d", &m);
int** arr = malloc_2d(n, m);
while (1)
{
if (m - k - 1 >= k)
{
for (i = k, j = k; j <= m - k - 1; j++)
arr[i][j] = c++;
}
else
break;
if (n - k - 1 >= 0 && m - k - 1 >= 0 && i < n - k - 1)
{
for (i = k + 1, j = m - k - 1; i <= n - k - 1; i++)
arr[i][j] = c++;
}
else
break;
if (m - k - 2 >= k && m - k - 2 >= k)
{
for (i = n - k - 1, j = m - k - 2; j >= k; j--)
arr[i][j] = c++;
}
else
break;
if (n - k - 2 >= k && n - k - 2 >= k + 1)
{
for (i = n - k - 2, j = k; i >= k + 1; i--)
arr[i][j] = c++;
}
else
break;
k++;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
printf("%*d ", 3, arr[i][j]);
printf("\n");
}
free_2d(arr, n);
printf("quit=q key, more=another key :");
while (getchar() != '\n');
scanf("%c", &a);
if (a != 'q')
{
while (getchar() != '\n');
continue;
}
else
break;
}
getchar();
return 0;
}
const mark = (obj, idx) => {
if (!obj.isUsed) {
obj.isUsed = true;
obj.value = idx;
return true;
} else {
return false;
}
}
const makeMatrix = n => {
const arr = Array.from(new Array(n), (v, i) => Array.from(new Array(n), (v, i) => {
return {
value: 0, isUsed: false
};
}));
let row = 0;
let col = 0;
let index = 0;
const max = n * n;
while (index < max) {
for (col; col < n; col++) {
if (mark(arr[row][col], index)) {
index++;
} else {
break;
}
}
col--;
row++;
for (row; row < n; row++) {
if (mark(arr[row][col], index)) {
index++;
} else {
break;
}
}
row--;
col--;
for (col; col >= 0; col--) {
if (mark(arr[row][col], index)) {
index++;
} else {
break;
}
}
col++;
row--;
for (row; row >= 0; row--) {
if (mark(arr[row][col], index)) {
index++;
} else {
break;
}
}
row++;
col++;
}
for (let i = 0; i < n; i++) {
let result = '';
for (let j = 0; j < n; j++) {
result += arr[i][j].value + '\t';
}
console.log(result);
}
};
makeMatrix(6);
#include <stdio.h>
#include <memory.h>
enum eFillDirection
{
RIGHT = 0,
DOWN,
LEFT,
UP,
NUM_OF_DIRECTION
};
#define EMPTY_SPACE -1
class CDojo2_Spiral
{
public:
CDojo2_Spiral() {};
~CDojo2_Spiral() {};
void Solve(int row, int colum);
private:
void FillArray(int** Array, int StartNum, int rowOffset, int columOffset, int rowCount, int columCount, eFillDirection fillDirection);
};
void CDojo2_Spiral::Solve(int row, int colum)
{
int** SpiralArray = nullptr;
SpiralArray = new int*[row];
for (int i = 0; i < row; i++)
{
SpiralArray[i] = new int[colum];
memset(SpiralArray[i], EMPTY_SPACE, sizeof(int)*colum);
}
FillArray(SpiralArray, 0, 0, 0, row, colum, eFillDirection::RIGHT);
for (int i = 0; i < row; i++)
{
for (int j = 0; j < colum; j++)
{
printf("%4d ", SpiralArray[i][j]);
}
printf("\n");
}
}
void CDojo2_Spiral::FillArray(int** Array, int StartNum, int rowOffset, int columOffset, int rowCount, int columCount, eFillDirection fillDirection)
{
bool bBlocked = false;
int rowIdx = rowOffset;
int columIndex = columOffset;
int currentNum = StartNum;
while (true)
{
Array[rowIdx][columIndex] = currentNum;
int nextRowIdx = rowIdx;
int nextcolumIdx = columIndex;
switch (fillDirection)
{
case RIGHT:
nextcolumIdx++;
break;
case DOWN:
nextRowIdx++;
break;
case LEFT:
nextcolumIdx--;
break;
case UP:
nextRowIdx--;
break;
}
if (nextRowIdx < 0 || rowCount <= nextRowIdx ||
nextcolumIdx < 0 || columCount <= nextcolumIdx ||
Array[nextRowIdx][nextcolumIdx] != EMPTY_SPACE)
{
if (currentNum != StartNum)
{
int nextDirection = (fillDirection + 1) % eFillDirection::NUM_OF_DIRECTION;
FillArray(Array, currentNum, rowIdx, columIndex, rowCount, columCount, (eFillDirection)nextDirection);
}
break;
}
rowIdx = nextRowIdx;
columIndex = nextcolumIdx;
currentNum++;
}
}
int main()
{
CDojo2_Spiral exam;
exam.Solve(6, 6);
}
#include <iostream>
using namespace std;
void SpiralDown(int**Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth);
void SpiralLeft(int**Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth);
void SpiralUp(int**Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth);
void SpiralRight(int**Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth);
void main()
{
int**SpiralArray;
int howX, howY;
cin >> howX >> howY;
SpiralArray = new int*[howX];
for (int i = 0; i < howX; i++)
SpiralArray[i] = new int[howY];
SpiralRight(SpiralArray, howX, howY, 0, 0, 0, 0);
for (int j = 0; j < howY; j++)
{
for (int i = 0; i < howX; i++)
printf("%3d", SpiralArray[i][j]);
printf("\n");
}
for (int i = 0; i < howX; i++)
delete[] SpiralArray[i];
delete[] SpiralArray;
system("pause");
}
void SpiralRight(int ** Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth)
{
if (howX*howY - 1 == Counting)
{
Array[CounterX][CounterY] = Counting;
return;
}
if (CounterX < howX -1- depth)
{
Array[CounterX][CounterY] = Counting;
Counting++;
CounterX++;
SpiralRight(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
else
SpiralDown(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
void SpiralDown(int ** Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth)
{
if (howX*howY - 1 == Counting)
{
Array[CounterX][CounterY] = Counting;
return;
}
if (CounterY < howY -1- depth)
{
Array[CounterX][CounterY] = Counting;
Counting++;
CounterY++;
SpiralDown(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
else
SpiralLeft(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
void SpiralLeft(int ** Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth)
{
if (howX*howY - 1 == Counting)
{
Array[CounterX][CounterY] = Counting;
return;
}
if (CounterX > depth)
{
Array[CounterX][CounterY] = Counting;
Counting++;
CounterX--;
SpiralLeft(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
else
{
depth++;
SpiralUp(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
}
void SpiralUp(int ** Array, int howX, int howY, int CounterX, int CounterY, int Counting, int depth)
{
if (howX*howY - 1 == Counting)
{
Array[CounterX][CounterY] = Counting;
return;
}
if (CounterY > depth)
{
Array[CounterX][CounterY] = Counting;
Counting++;
CounterY--;
SpiralUp(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
else
SpiralRight(Array, howX, howY, CounterX, CounterY, Counting, depth);
}
재귀함수를 이용한 SpiralArray VisualStudio 2017
void generate_num(int arr,int col,int row); void print_num(int arr,int col,int row); int main(void) { int col,row; int i,j; int ** arr = NULL;
//1.allocation_memory
scanf("%d %d",&col,&row);
arr = (int **)malloc(sizeof(int *)*row);
for(i=0;i<row;i++)
arr[i]=(int*)malloc(sizeof(int)*col);
//2.generate_number
generate_num(arr,col,row);
print_num(arr,col,row);
return 0;
}
void generate_num(int * arr,int col,int row) { int num=0; int i=0; int col_max=col; int row_max=row; int col_min=0; int row_min=0; while(num<rowcol) { for(i=col_min;i<col_max;i++) { arr[row_min][i]=num++;
}
row_min++;
for(i=row_min;i<row_max;i++)
{
arr[i][col_max-1]=num++;
}
col_max--;
for(i=col_max-1;i>=col_min;i--)
{
arr[row_max-1][i]=num++;
}
row_max--;
for(i=row_max-1;i>=row_min;i--)
{
arr[i][col_min]=num++;
}
col_min++;
} } void print_num(int ** arr,int col,int row) { int i,j; int num=1; for(i=0;i<row;i++) { for(j=0;j<col;j++) { printf("%2d ",arr[i][j]); } printf("\n"); } return; }
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[][] result = new int[n][m];
for(int i=0; i < n; i++) {
for(int j=0; j < m; j++) {
result[i][j] = -1;
}
}
int i=0, j=0, item=0, check = 0;
while(item < n*m) {
result[i][j] = item;
if(check%4 == 0) {
if(j+1 < m && result[i][j+1] == -1) j++;
else {
check++;
i++;
}
} else if(check%4 == 1) {
if(i+1 < n && result[i+1][j] == -1) i++;
else {
check++;
j--;
}
} else if(check%4 == 2) {
if(j > 0 && result[i][j-1] == -1) j--;
else {
check++;
i--;
}
} else if(check%4 == 3) {
if(i > 0 && result[i-1][j] == -1) i--;
else {
check++;
j++;
}
}
item++;
}
for(i=0; i < n; i++) {
for(j=0; j < m; j++) {
System.out.print(result[i][j]);
if(j!=m-1) System.out.print(" ");
}
System.out.println();
}
sc.close();
}
}
package programming;
import java.util.Arrays;
import java.util.Scanner;
public class spiralArray {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int arr[][];
int ROWS, COLS; // 행,열
int count = 0; // 배열 원소의 값(점점 증가된다)
int row = 0, col = 0; // 반복 시작 좌표
int right = 1, below = 2, left = 3, top = 4; // 방향 (우->하->좌->상) 반복
int position = 1; // 방향을 우측으로 초기화
// 사용자로부터 행과 열을 입력받는다.
System.out.println("행,열을 입력하시오:");
ROWS = sc.nextInt();
COLS = sc.nextInt();
System.out.println();
// 각 모서리의 기준값(좌표의 최대,최소값)을 미리 정해둔다.
// 최대값은 안으로 들어 올수록 작아지고 최소값은 커진다.
int maxR = ROWS;
int maxC = COLS;
int minR = 0, minC = 0;
arr = new int[ROWS][COLS]; // 입력받은 값으로 2차원 배열을 초기화
while (count < ROWS * COLS) { // 배열 원소의 값이 배열의 크기보다 커질때 반복 중지
if (position == right) { // 오른쪽으로 진행
arr[row][col] = count;
col++; // 오른쪽 방향 -> 열 증가
count++;
if (col == maxC) { // 배열의 범위를 벗어나면 방향을 아래로 바꾸고 현재 if문 탈출
position = below;
row++; // 그 다음 범위를 미리 지정
col--; // col이 범위를 벗어났으니 다시 감소시킴으로서 범위조정
continue;
}
}
if (position == below) { // 아래쪽 진행
arr[row][col] = count; // right에서 벗어날때 범위를 올바르게 맞춰 줬으니까 그대로 count대입
row++; // 아래쪽 방향 -> 행 증가
count++;
if (row == maxR) { // 배열의 범위를 벗어나면 방향을 왼쪽으로 바꾸고 현재 if문 탈출
position = left;
row--; // row가 범위를 벗어났으니 다시 감소시킴으로서 범위조정
col--; // 왼쪽 방향을 진행 할때 바로 count를 삽입 할수 있도록 여기서 범위 조정
continue;
}
}
if (position == left) {
arr[row][col] = count;
col--;
count++;
if (col < minC) { // 배열의 범위를 벗어나면 방향을 위쪽으로 바꾸고 현재 if문 탈출
position = top;
col++;
row--;
continue;
}
}
if (position == top) {
arr[row][col] = count;
row--;
count++;
if (row == minR) { // 배열의 범위를 벗어나면 방향을 오른쪽으로 바꾸고 현재 if문 탈출
// position이 top일때 까지 진행되었다는 말은 1회전이 완료되었다는 뜻이다.
// max값은 감소시켜주고 min값은 증가시켜준다.그리고 2회전 시작
position = right;
row++; col++; // 다음 회전할때 바로 count를 삽입할 수 있도록 여기서 미리 배열의 범위조정
maxR--; maxC--;
minC++; minR++;
continue;
}
}
}
// 최종 출력
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
System.out.printf("%2d ", arr[i][j]);
}
System.out.println("\n");
}
}
}
파이썬으로 구상한 상당히 길고 더러운 코드입니다.. (초급 프로그래머이니만큼 이해해주시면 감사하겠습니다) 기본적인 컨셉은 input으로 넣어준 크기대로 행렬을 만들어주고, 나선 모형에 따라 값을 각 위치에 넣어주는 클래스를 만들어 변형해주는 식입니다. (movePlace, copyValue)
먼저, 숫자가 커지는 루트에서 꺾이는 지점을 수학적으로 구해놓습니다. 이후 movePlace를 통해 나선 모형을 따라 이동하고, copyValue를 통해 각 위치에 해당하는 값으로 default 값을 변화시켜줍니다.
# 변수 입력 a, b를 받는다
b, a = input().split(" ")
a = int(a);
b = int(b) # b는 행, a는 열
# 나선이 꺾이는 지점을 설정한다
base = min(a, b)
(upkey, downkey, leftkey, rightkey) = (0, 0, 0, 0) # 변수 선언
(moveDownList, moveUpList, moveLeftList, moveRightList) = ([], [], [], []) # 변수 선언
if base % 2 == 0:
downkey = int(base / 2)
upkey = int(base / 2)
leftkey = int(base / 2)
rightkey = int((base / 2) - 1)
else:
downkey = int((base + 1) / 2)
upkey = int((base - 1) / 2)
leftkey = int((base - 1) / 2)
rightkey = int((base - 1) / 2)
for i in range(downkey):
moveDownList.append((i, (a - 1) - i))
for i in range(upkey):
moveUpList.append(((b - 1) - i, i))
for i in range(leftkey):
moveLeftList.append(((b - 1) - i, (a - 1) - i))
for i in range(rightkey):
moveRightList.append((1 + i, i))
# BoxGroup의 각 요소들의 값을 정한다
BoxGroup = [[10 * i + j for j in range(a)] for i in range(b)] # bxa 행렬의 default 값을 설정한다
class Key:
def __init__(self, i, j):
self.place = (i, j)
self.value = 0
self.direction = self.moveRight # default 움직임은 오른쪽으로 이동
def copyValue(self, a, b):
BoxGroup[a][b] = self.value
self.value += 1
def movePlace(self, a, b):
if self.place in moveDownList:
self.direction = self.moveDown
elif self.place in moveUpList:
self.direction = self.moveUp
elif self.place in moveLeftList:
self.direction = self.moveLeft
elif self.place in moveRightList:
self.direction = self.moveRight
self.direction(a, b)
def moveDown(self, a, b): # 진행방향을 아래쪽으로 변화
self.place = (a + 1, b)
def moveUp(self, a, b): # 진행방향을 위쪽으로 변화
self.place = (a - 1, b)
def moveLeft(self, a, b): # 진행방향을 왼쪽으로 변화
self.place = (a, b - 1)
def moveRight(self, a, b): # 진행방향을 아래쪽으로 변화
self.place = (a, b + 1)
# 값을 변환하기
Run = Key(0, 0)
for n in range(a * b):
Run.copyValue(Run.place[0], Run.place[1])
Run.movePlace(Run.place[0], Run.place[1])
# BoxGroup의 각 요소들을 출력한다
for i in range(b):
j = 0
while j < a:
A = BoxGroup[i]
if len(str(A[j])) == 1:
A[j] = str(" ") + str(A[j])
print(A[j], end=' ')
j += 1
print("")
#include<stdio.h>
#include<stdlib.h>
int main(){
int** mat;
int n;
scanf("%d", &n);
mat=calloc(n,sizeof(int*));
for(int i=0;i<n;i++){
mat[i]=calloc(n,sizeof(int));
}
int t=0;
int num=0;
for(int i=0;i<(n/2);i++){
for(int j=0;j<n-t-1;j++){
mat[i][i+j]=num++;
}
for(int j=0;j<n-t-1;j++){
mat[i+j][n-1-i]=num++;
}
for(int j=0;j<n-t-1;j++){
mat[n-1-i][n-1-i-j]=num++;
}
for(int j=0;j<n-t-1;j++){
mat[n-1-i-j][i]=num++;
}
t+=2;
}
int z=n/2;
if(z*2!=n){
mat[z][z]=num;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%d ",mat[i][j]);
}
printf("\n");
}
return 0;
}
조금 복잡하지만 c 초보로서 나름 젤 쉽게 해결해보았습니다!
public class spiralArray {
public static void main(String[] args) {
int size=6 ;
// n*n배열
int[][] arr = new int[size][size];
int imin = 0;
int imax = size-1;
int jmin = 0;
int jmax = size-1;
for(int n=0, count=0; n<size*size; n++) {
if(count==size-1)
break;
// goRight
for(int j=jmin; j<=jmax; j++) {
arr[imin][j]=count;
count++;
}
imin++;
// goDown
for(int i=imin; i<=imax; i++) {
arr[i][jmax]=count;
count++;
}
jmax--;
// goLeft
for(int j=jmax; j>=jmin; j--) {
arr[imax][j]=count;
count++;
}
imax--;
// goUp
for(int i=imax; i>=imin; i--) {
arr[i][jmin]=count;
count++;
}
jmin++;
}
for(int index=0; index<size; index++) {
System.out.println();
for(int jndex=0; jndex<size; jndex++) {
System.out.print(arr[index][jndex]+" ");
}
}
}
}
우, 하, 좌, 상이 [x, y-1, x-1, y-2, ...] 번 반복되는 수열의 급수를 [1..]과 zip하면 됩니다.
import Data.List
import Data.List.Split
import Data.Array (Array, array)
import qualified Data.Array as Array
import Text.Printf
vecAdd (a,b) (c,d) = (a+c, b+d)
interleave :: [a] -> [a] -> [a]
interleave a b = concat $ filter ((==2).length) $ transpose [a, b]
spiral :: Int -> Int -> Array (Int, Int) Int
spiral x y
= array ((0, 0), (y-1, x-1))
$ flip zip [0..]
$ tail $ scanl vecAdd (0, -1)
$ concat $ zipWith replicate lengths directions
where
directions = cycle [(0, 1), (1, 0), (0, -1), (-1, 0)]
lengths = interleave [x, x-1 .. 0] [y-1, y-2 .. 0]
render :: Array (Int, Int) Int -> String
render arr = unlines . fmap concat . chunksOf (x+1) . fmap (printf "%3d") . Array.elems $ arr
where (_, (y, x)) = Array.bounds arr
> putStrLn $ render $ spiral 10 5
0 1 2 3 4 5 6 7 8 9
25 26 27 28 29 30 31 32 33 10
24 43 44 45 46 47 48 49 34 11
23 42 41 40 39 38 37 36 35 12
22 21 20 19 18 17 16 15 14 13
좌좌봐봐
public enum Direction {
RIGHT(1), BOTTOM(2), LEFT(3), TOP(4);
int val;
private Direction(int value) {
this.val = value;
}
}
int[][] spiralArr;
static Direction direction;
public static void main(String[] args) {
int cnt = 0;
main m = new main();
Scanner sc = new Scanner(System.in);
System.out.println("배열의 행, 열을 입력하시오.");
String str = sc.nextLine();
int x = (int) str.charAt(0) - 48;
int y = (int) str.charAt(1) - 48;
m.spiralArr = new int[x][y];
for (int i = 0; i < m.spiralArr.length; i++) {
for (int j = 0; j < m.spiralArr[i].length; j++) {
m.spiralArr[i][j] = -1;
}
}
direction = Direction.RIGHT;
m.fillArr(x, y);
for (int i = 0; i < m.spiralArr.length; i++) {
for (int j = 0; j < m.spiralArr[i].length; j++) {
// m.spiralArr[i][j] = cnt++;
System.out.print(m.spiralArr[i][j] + "\t");
}
System.out.println();
}
}
public void fillArr(int row, int col) {
int num = 0;
int rIdx = 0, cIdx = 0;
while (num < row * col) {
spiralArr[rIdx][cIdx] = num++;
switch(direction)
{
case RIGHT:
if(cIdx+1 < col && spiralArr[rIdx][cIdx+1] == -1)
{
cIdx++;
}
else
{
direction = Direction.BOTTOM;
rIdx++;
}
break;
case BOTTOM:
if(rIdx+1 < row && spiralArr[rIdx+1][cIdx] == -1)
{
rIdx++;
}
else
{
direction = Direction.LEFT;
cIdx--;
}
break;
case LEFT:
if(cIdx-1 >= 0 && spiralArr[rIdx][cIdx-1] == -1)
{
cIdx--;
}
else
{
direction = Direction.TOP;
rIdx--;
}
break;
case TOP:
if(rIdx-1 >= 0 && spiralArr[rIdx-1][cIdx] == -1)
{
rIdx--;
}
else
{
direction = Direction.RIGHT;
cIdx++;
}
break;
}
}
}
java 입니다.
import java.util.Scanner;
public class level_3_Spiral_Array {
public static void main(String[] args) {
System.out.println("배열이 가로 길이를 입력하세요.");
Scanner sc = new Scanner(System.in);
int width = sc.nextInt();
System.out.println("배열의 세로 길이를 입력하세요.");
int height = sc.nextInt();
sc.close();
int widthmin = 0, widthmax = width - 1, heightmin = 0, heightmax = height - 1, count = 0;
int[][] snail = new int[height][width];
for(int j = 0; j < height * width; j++)
{
if(count == width * height - 1)
{
break;
}
for(int i = widthmin; i <= widthmax; i++) // 오른쪽으로.
{
snail[widthmin][i] = count;
count++;
}
heightmin++;
for(int i = heightmin; i <= heightmax; i++) // 아래로.
{
snail[i][widthmax] = count;
count++;
}
widthmax--;
for(int i = widthmax; i >= widthmin; i--) // 왼쪽으로.
{
snail[heightmax][i] = count;
count++;
}
heightmax--;
for(int i = heightmax; i >= heightmin; i--) // 위로.
{
snail[i][widthmin] = count;
count++;
}
widthmin++;
}
for(int i = 0; i < height; i++)
{
System.out.println();
for(int j = 0; j < width; j++)
{
System.out.print(snail[i][j] + " ");
}
}
}
}
문제 예시처럼 6, 6 으로 사이즈 정하면 정상적으로 나오는데 (입력 한 값이 모두 짝수 일 경우는 항상 정상 출력.)
이런 경우에는 출력이 비슷하게는 나오지만 정상적으로 안나오네요. 왜이러지?
한쪽방향 끝까지 가면 방향이 바뀌는 것을 고려해서 작성하였습니다. 동작은 spiral_array() 확인하시면 되고 검증부분 추가하였습니다.
def spiral_array(rowsize, colsize):
vecoffset = [(0, 1), (1, 0), (0, -1), (-1, 0)]
arr = [[-1 for j in range(colsize)] for i in range(rowsize)]
vec = 0
val = 0
row, col = 0, 0
arr[row][col] = val
while val < rowsize * colsize - 1:
r, c = row + vecoffset[vec][0], col + vecoffset[vec][1]
if r >= 0 and r < rowsize and c >= 0 and c < colsize and arr[r][c] == -1:
val += 1
row, col = r, c
arr[row][col] = val
else:
vec = (vec + 1) % 4
return arr
evals = [{"row": 6, "col": 6,
"ret": [[0, 1, 2, 3, 4, 5],
[19, 20, 21, 22, 23, 6],
[18, 31, 32, 33, 24, 7],
[17, 30, 35, 34, 25, 8],
[16, 29, 28, 27, 26, 9],
[15, 14, 13, 12, 11, 10]]},
{"row": 3, "col": 3,
"ret": [[0, 1, 2],
[7, 8, 3],
[6, 5, 4]]},
{"row": 4, "col": 2,
"ret": [[0, 1],
[7, 2],
[6, 3],
[5, 4]]},
{"row": 4, "col": 4,
"ret": [[0, 1, 2, 3],
[11, 12, 13, 4],
[10, 15, 14, 5],
[9, 8, 7, 6]]}
]
def printArr(row, col, arr):
str = ""
for i in range(row):
for j in arr[i]:
str += "{:02d} ".format(j)
str += "\n"
return str
for eval in evals:
ret = spiral_array(eval["row"], eval["col"])
assert(ret == eval["ret"])
print(printArr(eval["row"], eval["col"], ret))
#include <iostream>
#include <iomanip>
using namespace std;
void SpiralM(int * _matrix[],int _row,int _column);
int main()
{
int ** matrix;
int row, column;
cin >> row >> column;
matrix = new int*[row];
for (int i = 0; i < row; i++)
matrix[i] = new int[column];
for (int i = 0; i < row; i++)
for (int j = 0; j < column; j++) matrix[i][j] = -1;
SpiralM(matrix, row, column);
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
cout << setw(3);
cout<< matrix[i][j] << " ";
}
cout << endl;
}
return 0;
}
void SpiralM(int * _matrix[], int _row, int _column)
{
int num = 0;
int temp = 0;
int differ = 1;
int final_num = _row * 4 - 5;
int ctemp = 0 , rtemp = 0;
int count;
if (_row % 2 == 0) count = _row / 2; // if n is even, n & n-1 rotate n/2
else count = _row / 2 + 1;
while (count != 0)
{
_matrix[rtemp][ctemp] = num;
if (count != 1) _matrix[rtemp + 1][ctemp] = final_num; // forbid initialize final final_num in odd
temp = num;
num = final_num + 1;
final_num = final_num - temp - 8 + num;
for (int i = ctemp+1; i <= _column - differ; i++) // increase column
{
_matrix[rtemp][i] = ++temp;
}
int ctemp2 = _column - differ; // column fix
for (int i = rtemp+1; i <= _row-differ; i++) // increase row
{
_matrix[i][ctemp2] = ++temp;
}
int rtemp2 = _row - differ; // row fix
for (int i = ctemp2 - 1; i >= _column - ctemp2 - 1; i--) // decrease column
{
_matrix[rtemp2][i] = ++temp;
}
int ctemp3 = _column - ctemp2 - 1; // column fix
for (int i = rtemp2 - 1; i >= _row - rtemp2; i--) // decrease row
{
_matrix[i][ctemp3] = ++temp;
}
differ += 1;
ctemp++;
rtemp++;
count--;
}
}
처음 올렸던 코드는 홀수의 경우 잘못 출력되서 수정하고 코드는 이쁘게 정리해봤습니다. 일반항 이용해서 풀었습니다.
import time
a, b = raw_input().split()
a = int(a)
b = int(b)
matrix = [[0]*a for i in range(b)]
print(matrix)
starti = 0
fini = a
startj = 0
finj = b
number = 0
while True:
for i in range(starti,fini):
matrix[startj][i] = number
number = number +1
for j in range(startj+1,finj):
matrix[j][fini-1] = number
number = number+1
for k in range(starti+1,fini):
matrix[finj-1][fini-k+startj-1] = number
number = number+1
for w in range(1,finj-1-starti):
matrix[fini-w-1][starti] = number
number = number+1
starti = starti+1
startj = startj+1
fini = finj-1
finj = finj-1
if number == a*b:
break
for i in matrix:
for j in i:
print(j),
print("\t"),
print("\n")
파이썬 3.6
"""
아이디어>
정사각형 배열의 바깥쪽부터 안쪽으로 순차적으로 각 단계(q) 사각형 변 요소들의 값을 구합니다.
"""
def spiralarray(m,n):
array,thick,length,q,level,value,x,y = [],m,m*n,0,0,0,0,0
array = [[0 for h in range(n)] for i in range(m)]
level = len(array)//2 + len(array)%2
while q <= level:
q += 1 # 사각형 단계 이동
# q단계 사각형 상단변 값 입력
for a in range(y,n+y):
if value == length:
break
array[x][a] = value
value += 1
# q단계 사각형 우측변 값 입력
for b in range(q,thick-q):
if value == length:
break
array[b][thick-q] = value
value += 1
# q단계 사각형 아랫변 값 입력
for a in range(y,n+y):
if value == length:
break
array[thick-q][-(a+1)] = value
value += 1
# q단계 사각형 왼쪽변 값 입력
for b in range(q+1,n+y):
if value == length:
break
array[-b][y] = value
value += 1
x += 1
y += 1
n -= 2
for sequence in array:
new_sequence = ["%2s"%str(s) for s in sequence]
print(' '.join(new_sequence),"\n")
if __name__ == "__main__":
m = int(input("column = "))
n = int(input("row = "))
print("\n")
spiralarray(m,n)
*결과값
column = 6
row = 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
package spiralArray;
import java.util.Arrays;
import java.util.Scanner;
public class SpiralArray {
public void spiralArray(int x, int y) {
int count = 1;
int[][] array = new int[x][y];
int max = x * y + 1;
int temp = 0;
int index = 0;
while (count != max) {
for (int j = temp; j < y; j++)
array[index][j] = count++;
for (int j = temp + 1; j < y; j++)
array[j][y - 1] = count++;
for (int j = y - 2; j >= temp; j--)
array[x - (index + 1)][j] = count++;
for (int j = y - 2; j >= temp + 1; j--)
array[j][index] = count++;
y--;
index++;
temp++;
}
printArray(array);
}
public void printArray(int[][] arr) {
for (int[] elements : arr) {
System.out.println(Arrays.toString(elements));
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SpiralArray sa = new SpiralArray();
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
sa.spiralArray(sc.nextInt(), sc.nextInt());
}
}
r로 풀었습니다.
```{r}
f1<-function(x,y){
m<-matrix(rep(NA, x*y), nrow=y, ncol=x)
i<-1
j<-0
k<-0
a<-1
repeat{
if(sum(is.na(m))==0){
break
}
if(a%%2==1){
j<-j+(-1)**(((a-1)%/%2)%%2)
repeat{
if(j>x|j==0){
a<-a+1
if(j>x){
j<-j-1
break
}else{
j<-1
break
}}else{
if(!is.na(m[i,j])){
j<-j+(-1)**(((a+1)%/%2)%%2)
a<-a+1
break
} }
m[i,j]<-k
j<-j+(-1)**(((a-1)%/%2)%%2)
k<-k+1
}}else{
i<-i+(-1)**(((a-1)%/%2)%%2)
repeat{
if(i>y|i==0){
a<-a+1
if(i>y){
i<-i-1
break
}else{
i<-1
break
} } else{
if(!is.na(m[i,j])){
i<-i+(-1)**(((a+1)%/%2)%%2)
a<-a+1
break
} }
m[i,j]<-k
i<-i+(-1)**(((a-1)%/%2)%%2)
k<-k+1
} }
}
return(m)}
f1(6,5)
```
func <- function(m,n){
#초기변수선언
end <- m * n; a <- 1; b <- 0; rotation <- 1; cn <- 0; x <- m; y <- n - 1
df <- matrix(NA, ncol=m, nrow=n)
#결정된 방향으로 진행
while(cn < end){
if(rotation == 1){
for(i in 1:x){
cn <- cn + 1
df[a,(b+i)] <- cn
}
b <- b + x
x <- x - 1
rotation <- rotation + 1
}else if(rotation == 2){
for(i in 1:y){
cn <- cn + 1
df[(a+i),b] <- cn
}
a <- a + y
y <- y - 1
rotation <- rotation + 1
}else if(rotation == 3){
for(i in 1:x){
cn <- cn + 1
df[a,(b-i)] <- cn
}
b <- b - x
x <- x - 1
rotation <- rotation + 1
}else if(rotation == 4){
for(i in 1:y){
cn <- cn + 1
df[(a-i),b] <- cn
}
a <- a - y
y <- y - 1
rotation <- 1
}
}
print(df)
}
func(4,6)
# 파이썬
def spiral_array(m, n, mn=[], mm=0, nn=0, value=0): # m, n > 1 이어야 합니다.
if not mn: mn = [[0 for _ in range(n)] for _ in range(m)]
y = mm
for x in range(nn, n-nn-1):
mn[y][x] = value
value += 1
x = n-nn-1
for y in range(mm, m-mm-1):
mn[y][x] = value
value += 1
y = m-mm-1
for x in range(n-nn-1, nn, -1):
mn[y][x] = value
value += 1
x = nn
for y in range(m-mm-1, mm, -1):
mn[y][x] = value
value += 1
if value >= m*n:
for t in mn: print(t)
else:
return spiral_array(m, n, mn, mm+1, nn+1, value)
spiral_array(2, 6)
spiral_array(6, 6)
spiral_array(5, 7)
import java.util.Scanner;
public class Snail2 {
public enum Direction {right,down,left,up}
public static void main(String[] args) {
int size = 0;
//get the length of the vertical/horizontal edge of the array via user input
Scanner input = new Scanner(System.in);
System.out.print("Enter the size of the range: ");
size = input.nextInt();
int[][] arr = new int[size][size];
//vertical, horizontal, and increment variable
int i=0;
int j=0;
int a=0;
int b=0;
Direction direction = Direction.down;
int move = size-1;
int num = 1;
//put in the first line
for(a=0;a<size;a++)
{
arr[i][j++] = num;
num++;
}
j--;
while(move>0) {
switch(direction) {
case right:
for(a=1;a<=move;a++)
{
arr[i][++j] = num;
num = num+1;
} //decrement j by 1
//just before moving down, decrease the moving range by 1
move--;
direction = Direction.down;
case down:
for(a=1;a<=move;a++)
{
arr[++i][j] = num;
num = num + 1;
}
direction = Direction.left;
case left:
for(a=1;a<=move;a++)
{
arr[i][--j] = num;
num = num + 1;
}
//just before moving up, decrease the moving range by 1
move--;
direction = Direction.up;
case up:
for(a=1;a<=move;a++)
{
arr[--i][j] = num;
num = num + 1;
}
direction = Direction.right;
}
}
for(a=0;a<size;a++)
{
for(b=0;b<size;b++)
{
System.out.printf("%d\t",arr[a][b]);
}
System.out.print("\n");
}
}
}
열거형으로 왼쪽,오른쪽, 위쪽, 아래쪽 방향 변수를 지정해 놓고 Switch(case) 문을 활용하여 돌렸습니다!! 배열 사이즈는 자유롭게 입력 가능하도록 해놨습니다.
다만들고 나니 굳이 처음 한줄을 미리 채울 필요가 없었다는 걸 깨닳았네요.ㅋㅋ
using System;
using System.Collections;
using System.IO;
using System.Linq;
class Solution
{
static void Main(string[] args)
{
int a = int.Parse(Console.ReadLine());
int b = int.Parse(Console.ReadLine());
int num = 0;
int[,] arr = new int[a, b];
int i = 0;
int j = 0;
int sw = 0;
//행렬 길이 (움직이는데 사용함)
int rowLen = a - 1;
int columnLen = b - 1;
//우선 가로로 한 줄을 채움
for (j = 0; j < b; j++)
{
arr[0, j] = num;
num++;
}
j--;
int tempRowLen = rowLen;
int tempColumnLen = columnLen;
bool flag = false;
while (flag == false)
{
//둘 중 하나가 1이되고 한바퀴 더 돌고 마무리
if (columnLen == 0 || rowLen == 0)
{
flag = true;
}
switch (sw)
{
case 0:
for (tempRowLen = rowLen; tempRowLen > 0; tempRowLen--)
{
i++;
arr[i, j] = num;
num++;
}
rowLen--;
sw++;
break;
case 1:
for (tempColumnLen = columnLen; tempColumnLen > 0; tempColumnLen--)
{
j--;
arr[i, j] = num;
num++;
}
columnLen--;
sw++;
break;
case 2:
for (tempRowLen = rowLen; tempRowLen > 0; tempRowLen--)
{
i--;
arr[i, j] = num;
num++;
}
rowLen--;
sw++;
break;
case 3:
for (tempColumnLen = columnLen; tempColumnLen > 0; tempColumnLen--)
{
j++;
arr[i, j] = num;
num++;
}
columnLen--;
sw = 0;
break;
}
}
//출력
for(i = 0; i < a; i++)
{
for(j = 0; j < b; j++)
{
Console.Write("{0} ", arr[i, j]);
}
Console.WriteLine();
}
}
}
#!/usr/bin/perl
use strict;
Spiral(6,6); # 숫자 입력
sub Spiral {
my $m = shift;
my $n = shift;
my $last_number = $m * $n;
my ($try,$x,$y);
my @array;
$try = $x = $y = 1;
for(my $i=0; $i < $last_number; $i++) {
$array[$y-1][$x-1] = $i;
if($y==$try && $x!=($n-$try+1)){
$x++;
} elsif ($y!=($m-$try+1) && $x!=$try) {
$y++;
} elsif($y==($m-$try+1) && $x!=$try) {
$x--;
} else {$y--;}
if($x==$y && $y==$try){
$try++;
$x++;
$y++;
}
}
for (my $j=0; $j<$m; $j++){
for (my $k=0; $k<$n; $k++){
printf "%4d", $array[$j][$k];
}
print "\n";
}
}
펄로 작성했습니다.
import math
def spiral(m, n):
l = [[0 for i in range(m)] for j in range(n)]
for i in range(math.ceil(min(m/2, n/2))-1):
l[i+1][i+1] = l[i][i] + 2*(m+n-2-4*i)
for i in range(math.ceil(min(m/2, n/2))):
l[n-1-i][m-1-i] = l[i][i] + (m+n-2-4*i)
l[i][m-1-i] = l[i][i] + (m-1-2*i)
l[i][i:m-1-i] = list(range(l[i][i], l[i][m-1-i]))
for j in range(i, n-i-2):
l[j+1][m-1-i] = l[j][m-1-i] + 1
for i in range(math.floor(min(m/2, n/2))):
l[n-1-i][i] = l[n-1-i][m-1-i] + (m-1-2*i)
l[n-1-i][i:m-1-i] = list(range(l[n-1-i][i], l[n-1-i][m-1-i], -1))
for j in range(i, n-i-2):
l[n-2-j][i] = l[n-1-j][i] + 1
return l
n = list(map(int, input().split(' ')))
for i in spiral(n[0], n[1]):
for j in i:
print('{0:3d}'.format(j), end = ' ')
print('\n')
# 1-1 언박스로 사각형 크기 입력받기
X, Y = map(int, input().split(' '))
# 1-2 각 자리에 -1 대입하여 사각형 그리기
lis = [[-1 for i in range(Y)] for j in range(X)]
# 2-1 초기값 설정: 초기위치 (0,0), 초기값 0, 움직이는 방향 오른쪽(기본방향 1,0)
x, y = 0, Y
dx = 1
dy = 0
count = 0
# 2-2 값채워 넣기: 다음값이 공란일 때 (-1) / 채우기 / 이동
while lis[x][y] == -1:
lis[x][y] = count
count += 1
x, y = x + dx, y + dy
# 2-3 방향 바꾸기 # x, y 가 -1, X, Y 이거나 값이 -1인 것은 방향을 바꿀 위치를 알려준다.
if x in [-1, X] or y in [-1, Y] or lis[x][y] != -1:
x, y = x - dx, y - dy
dx, dy = dy, -dx
x, y = x + dx, y + dy
# 3-1 출력
for L in lis:
for val in L:
print("3%d" %val, end=' ')
print()
추천 수 많은 풀이를 보고 수학적으로 x,y 방향을 바꾸어 작성했습니다. 많이 배웠습니다.
import java.util.Scanner;
public class SpiralArray {
static int xMax = 0, yMax = 0; // 끝나는 위치
static int xMin = 0, yMin = 0; // 끝나는 위치
public static int[][] execute(int x, int y){
int[][] spiralArray = new int[x][y];
int direction = 0; // 방향 0: 오른쪽, 1:아래쪽, 2:왼쪽, 3: 위쪽
int count = 0;
int fin = x * y;
boolean go = true;
x=0; y=0; // 반복문 전에 초기화
xMax--;
yMax--;
while(go){
// 반복
if(count == fin){
break;
}
direction %= 4;
if(direction == 0){ //오른쪽방향
spiralArray[x][y] = count;
if(y == yMax){
direction++;
x++;
xMin++;
}else{
y++;
}
}else if(direction == 1){ //아래 방향
spiralArray[x][y] = count;
if(x == xMax){
direction++;
y--;
yMax--;
}else{
x++;
}
}else if(direction == 2){ //왼쪽 방향
spiralArray[x][y] = count;
if(y == yMin){
direction++;
x--;
xMax--;
}else{
y--;
}
}else if(direction == 3){ // 위쪽 방향
spiralArray[x][y] = count;
if(x == xMin){
direction++;
y++;
yMin++;
}else{
x--;
}
}
count++;
}
return spiralArray;
}
public static void terminate(int[][] array){
for(int i = 0; i<array.length; i++){
for(int j=0; j<array[i].length ; j++){
System.out.printf("%2d ", array[i][j]);
}
System.out.println();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
xMax = sc.nextInt(); // 행
yMax = sc.nextInt(); // 열
sc.close();
terminate(execute(xMax, yMax));
}
}
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
```
"""
author: kenny Jeon
date: 03/10/2018
"""
def func(m, n):
matrix = [[0 for col in range(n)] for row in range(m)]
cnt = 0
rowStart = 0
rowLength = len(matrix)-1
colStart = 0
colLength = len(matrix[0])-1
while rowStart <= rowLength and colStart <= colLength:
for i in range(rowStart, colLength+1):
matrix[rowStart][i] = cnt
cnt += 1
# right
for j in range(rowStart+1, rowLength+1):
matrix[j][colLength] = cnt
cnt += 1
# down
if rowStart+1 <= rowLength:
for k in reversed(range(colStart, colLength)):
matrix[rowLength][k] = cnt
cnt += 1
# left
if colStart+1 <= colLength:
for l in reversed(range(rowStart+1, rowLength)):
matrix[l][colStart] = cnt
cnt += 1
# up
rowStart += 1
rowLength -= 1
colStart += 1
colLength -= 1
return matrix
if __name__ == "__main__":
m, n = map(int, input("insert array size: ").split())
result = func(m, n)
for i in range(len(result)):
for j in range(len(result[0])):
print("%3d" % result[i][j], end=' ')
print()
def spiral(n, ini):
a=[[ini for i in range(n)] for j in range(n)]
for i in range(n-1):
a[0][i]=ini+i
a[i][n-1]=i+n-1+ini
a[n-1][n-1-i]=i+2*n-2+ini
a[n-1-i][0]=i+3*n-3+ini
if n>1:
b=spiral(n-2,(n-1)*4+ini)
for i in range(n-2):
a[i+1][1:-1]=b[i]
return a
def spiral_array(n):
for i in range(n):
print(spiral(n,0)[i])
spiral_array(6)
#include <stdio.h>
#include <stdlib.h>
int *spiral(int n, int ini) {
int *re = malloc(sizeof(int)*(n*n));
int *b;
for (int i = 0; i < n-1; i++) {
re[n*i] = i+ini;
re[i+n*(n-1)] = i + n - 1 + ini;
re[n - 1+n*(n - 1 - i)] = i + 2 * (n - 1) + ini;
re[n - 1 - i] = i + 3 * (n - 1) + ini;
}
if (n > 2) {
b = spiral(n - 2, ini + 4 * (n - 1));
for (int j = 0; j < n - 2; j++) {
for (int i = 0; i < n - 2; i++) {
re[i + 1+(j+1)*n] = b[i+j*(n-2)];
}
}
free(b);
}
return re;
}
int main() {
int n;
int *re;
printf("원하시는 크기를 입력하시오. : ");
scanf_s("%d", &n);
re=spiral(n, 0);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%4d", re[i+n*j]);
}
printf("\n");
}
free(re);
return 0;
}
swift로 작성해보았습니다.
import Foundation
enum Direction {
case LTR //왼쪽 -> 오른쪽
case TTB //위 -> 아래
case RTL //오른쪽 -> 왼쪽
case BTT //아래 -> 우
}
let xy = readLine()!.components(separatedBy: " ").map{ Int($0)! }
var max_x = xy[0]
var max_y = xy[1]
var min_x = 0
var min_y = 0
var list:[[Int]] = Array(repeating: Array(repeating: -1,count: max_y), count: max_x)
var arr_x = 0
var arr_y = 0
var count = 0
var direction:Direction = Direction.LTR
while list[arr_x][arr_y] == -1 {
list[arr_x][arr_y] = count
count += 1
switch direction {
case Direction.LTR: //왼->오
if arr_y == max_y - 1 {
arr_x += 1
min_x += 1
direction = Direction.TTB
} else {
arr_y += 1
}
case Direction.TTB: //위->아래
if arr_x == max_x - 1{
arr_y -= 1
max_y -= 1
direction = Direction.RTL
} else {
arr_x += 1
}
case Direction.RTL: //오->왼
if arr_y == min_y{
arr_x -= 1
max_x -= 1
direction = Direction.BTT
} else {
arr_y -= 1
}
case Direction.BTT: //아래->위
if arr_x == min_x{
arr_y += 1
min_y += 1
direction = Direction.LTR
} else {
arr_x -= 1
}
}
}
for i in 0..<list.count {
print(list[i])
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int x = 0, y = 0, m = 1, cnt = 1, cnt2 = 0;
int h = 0, w = 0;
int Num = 0;
scanf_s("%d %d", &w, &h);
int **Arr = malloc(sizeof(int *) * h);
for (int i = 0; i < h; i++)
{
Arr[i] = malloc(sizeof(int) * w);
}
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
Arr[i][j] = NULL;
}
}
while (m <= (h * w))
{
switch (Num)
{
case 0:
if (Arr[x][y] == NULL)
{
Arr[x][y] = m;
++m;
if (y < (w-cnt)) ++y;
}
else
{
++x;
++Num;
break;
}
break;
case 1:
if (Arr[x][y] == NULL)
{
Arr[x][y] = m;
++m;
if (x < (h-cnt)) ++x;
}
else
{
--y;
++Num;
break;
}
break;
case 2:
if (Arr[x][y] == NULL)
{
Arr[x][y] = m;
++m;
if (y > cnt2) --y;
}
else
{
--x;
++Num;
break;
}
break;
case 3:
if (Arr[x][y] == NULL)
{
Arr[x][y] = m;
++m;
if (x > cnt2) --x;
}
else
{
++x;
++y;
++cnt;
++cnt2;
Num = 0;
break;
}
break;
}
}
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
Arr[i][j] -= 1;
printf("%d\t", Arr[i][j]);
}
printf("\n");
}
}
Swift입니다. 이전 코드가 맘에 안들어 다시 작성했습니다.
import Foundation
let direction = [[1,0], [0,1], [-1, 0], [0, -1]]
let directionCount = direction.count
func getNextDirection(curIndex: Int) -> Int {
return (curIndex + 1) % directionCount
}
func canMove(curMap: [[Int]], curX: Int, curY: Int, directionIndex: Int) -> Bool {
let width = curMap[0].count
let height = curMap.count
let x = curX + direction[directionIndex][0]
let y = curY + direction[directionIndex][1]
return (x >= 0 && x < width && y >= 0 && y < height && curMap[y][x] == -1) ? true : false
}
func generateSpiralArray(width: Int, height: Int) -> [[Int]] {
var posX = 0, posY = 0
var directionIndex = 0
var count = 0
var map = Array(repeating: Array(repeating: -1, count: width), count: height)
while true {
map[posY][posX] = count
count += 1
if canMove(curMap:map, curX:posX, curY:posY, directionIndex:directionIndex) == false {
let nextDirectionIndex = getNextDirection(curIndex: directionIndex)
if canMove(curMap:map, curX:posX, curY:posY, directionIndex:nextDirectionIndex) {
directionIndex = getNextDirection(curIndex: directionIndex)
} else {
break;
}
}
posX += direction[directionIndex][0]
posY += direction[directionIndex][1]
}
return map
}
func printMap(_ map: [[Int]]) {
let height = map.count
let width = map[0].count
for i in 0..<height {
for j in 0..<width {
print (String(format: "%3d", map[i][j]), terminator: " ")
}
print("")
}
}
func getMapInfo() -> (width: Int, height: Int) {
var width = 0, height = 0
while true {
print("Enter map width and heigth. Example) 5 5")
let input = readLine()!.components(separatedBy: " ").map { Int($0)! }
if input.count == 2 && input[0] > 0 && input[1] > 0 {
width = input[0]
height = input[1]
break;
} else {
print("Entered wrong values. Width and height should be greater than zero.")
}
}
return (width: width, height: height)
}
var mapInfo = getMapInfo()
var testedMap = generateSpiralArray(width: mapInfo.width, height: mapInfo.height)
printMap(testedMap)
/* Spiral Array */
package main
import "fmt"
func main() {
var maxX, maxY int
fmt.Print("Input matrix size y, x separated by space: ")
n, err := fmt.Scanf("%d %d", &maxX, &maxY)
if err != nil || n != 2 {
panic("Invalid input")
}
mat := newMatrix(maxX, maxY)
for i := 1; i < maxX*maxY; i++ {
mat.put2next(i)
}
mat.printMaxtix()
}
// matrix struct
type matrix struct {
maxx, maxy int
dx, dy int
posx, posy int
value [][]int
}
// newMatrix: matrix struct constructor
func newMatrix(maxx, maxy int) *matrix {
m := matrix{}
m.maxx, m.maxy = maxx, maxy
m.posx, m.posy, m.dx, m.dy = 0, 0, 1, 0
m.value = make([][]int, maxy)
for y := 0; y < maxy; y++ {
m.value[y] = make([]int, maxx)
for x := 0; x < maxx; x++ {
m.value[y][x] = -1
}
}
m.value[0][0] = 0
return &m
}
// nextDirection: 매트릭스 내 입력 방향(x, y 방향 증가분) 설정
func (m *matrix) nextDirection() {
switch {
case m.dx == 1 && m.dy == 0:
m.dx, m.dy = 0, 1
case m.dx == 0 && m.dy == 1:
m.dx, m.dy = -1, 0
case m.dx == -1 && m.dy == 0:
m.dx, m.dy = 0, -1
case m.dx == 0 && m.dy == -1:
m.dx, m.dy = 1, 0
}
}
// put2next: 구조체 범위 내, 값이 없는 부분에 인수 값 입력
func (m *matrix) put2next(inputValue int) { // start pos = (1, 0)
tmpx, tmpy := m.posx+m.dx, m.posy+m.dy
if tmpx < 0 || tmpx >= m.maxx || tmpy < 0 || tmpy >= m.maxy {
m.nextDirection()
} else if m.value[tmpy][tmpx] >= 0 {
m.nextDirection()
}
m.posx += m.dx
m.posy += m.dy
m.value[m.posy][m.posx] = inputValue
}
// printMatrix: print matrix struct
func (m *matrix) printMaxtix() {
for y := 0; y < len(m.value); y++ {
for x := 0; x < len(m.value[y]); x++ {
fmt.Printf("%3d ", m.value[y][x])
}
fmt.Println()
}
}
import numpy as np
a, b = input().split()
a = int(a)
b = int(b)
sq_list = np.zeros((a, b))
h = 0
j = 0
def squa(x, y, a_list, j, h):
for i in range(y-1):
a_list[h][i+h] = j
j = j + 1
for i in range(x-1):
a_list[i + h][y - 1 + h] = j
j = j + 1
for i in range(y-1):
a_list[x - 1 + h][y + h - 1 - i] = j
j = j + 1
for i in range(x-1):
a_list[x - 1 - i + h][h] = j
j = j + 1
h = h + 1
return{'j' : j, 'x' : x - 2, 'y' : y - 2, 'a_list': a_list, 'h' : h}
while True:
if((a == 0) | (b == 0)):
sq_list[0][0] = 0
break
elif((a != 1) & (b == 1)):
for i in range(a):
sq_list[h+i][h] = j
j = j + 1
break
elif((b != 1) & (a == 1)):
for i in range(b):
sq_list[h][h+i] = j
j = j + 1
break
elif((a == 1) & (b == 1)):
sq_list[h][h] = j
break
k = squa(a, b, sq_list, j, h)
a = k['x']
b = k['y']
j = k['j']
sq_list = k['a_list']
h = k['h']
print(sq_list)
def spiral(a,b):
arr,x,n,ac,bc = list(map(lambda x : 0 , range(a*b))),0,-1,a,b
for i in range(b):
for o in range(x, x+a+b-1):
if 0 in arr:
n += ((-1,1)[i%2 == 0],(-ac,ac)[i%2 == 0])[o >= x+a]
arr[n] = ' '*abs(len(str(o))-len(str(ac*bc)))+str(o)
x += a+b-1
a,b = a-1,b-1
for x in range(bc):
print(" ".join(arr[ac*x: ac*(x+1)]))
#include <iostream>
using namespace std;
int main()
{
cout << "input : n x m";
int x = 0, y = 0;
cin >> x;
cin >> y;
int **dynamicArray = 0;
dynamicArray = new int*[y];
for (int i = 0; i < y; i++) {
dynamicArray[i] = new int[x];
} //이중포인터로 [Y,X]크기의 를 선언해줍니다.
for (int i = 0; i < y; i++) {
for (int k = 0; k < x; k++) {
dynamicArray[i][k] = -1;
}
}
// 값을 -1로 초기화 하는 이유는 값이 배정되지 않은 값을 -1로 두어서
// -1이 아니면 그 위에 값을 덮어쓸 수 없게 하기 위함입니다.
int x_ = 0, y_ = 0;
int direction = 0; // 방향을 스위치문으로 구현해줍니다.
int val = -1; // while문 앞에 val++를 바로 쓰기위해 초기값을 -1로 둡니다.
while (val < x*y) {
val++; // 들어갈 값들이 하나씩 올라갑니다.
switch (direction) {
case 0: // move right
if(dynamicArray[y_][x_] == -1)dynamicArray[y_][x_] = val;
//기존의 값이 없으면 넣는다
x_++;
if (x_ == x) { // marix를 벗어나려고 할때 아래로 이동
direction = 1;
y_++;
x_--;
break;
}
if (dynamicArray[y_][x_] != -1) { //값이있으면 아래이동
direction = 1;
y_++;
x_--;
}
break;
case 1: // move down
if (dynamicArray[y_][x_] == -1)dynamicArray[y_][x_] = val;
y_++;
if (y_ == y) {
direction = 2;
y_--;
x_--;
break;
}
if (dynamicArray[y_][x_] != -1) {
direction = 2;
y_--;
x_--;
}
break;
case 2: // move left
if (dynamicArray[y_][x_] == -1)dynamicArray[y_][x_] = val;
x_--;
if (x_ == -1) {
direction = 3;
x_++;
y_--;
break;
}
if (dynamicArray[y_][x_] != -1) {
direction = 3;
x_++;
y_--;
}
break;
case 3: // move up
if (dynamicArray[y_][x_] == -1)dynamicArray[y_][x_] = val;
y_--;
if (y_ == -1) {
direction = 0;
y_++;
x_++;
break;
}
if (dynamicArray[y_][x_] != -1) {
direction = 0;
y_++;
x_++;
}
break;
}
}
for (int i = 0; i < y; i++) {
for (int k = 0; k < x; k++) {
cout << dynamicArray[i][k] << " ";
}
cout << "\n";
}
for (int i = 0; i < y; i++) {
delete[] dynamicArray[i];
}
delete[] dynamicArray;
system("pause");
return 0;
}
정사각형, 직사각형 구분없이 다 잘 실행이됩니다 :)
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Kimseongsu
* @see http://codingdojang.com/scode/266
*
*/
public class Problem266 {
public static void main(String[] args) {
String INPUT = "6 6";
final int SIZE_X = Integer.valueOf(INPUT.split(" ")[0]);
final int SIZE_Y = Integer.valueOf(INPUT.split(" ")[1]);
final String[][] matrix = new String[SIZE_Y][SIZE_X];
// 각 방향별로 배열내 좌표(x, y)의 증가값을 의미
final int[][] DIRECTION_XY = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int value = 0;
int x = 0, y = 0; // 배열내 현재 좌표
int dir = 0; // 방향
while (value < SIZE_X * SIZE_Y) {
if (y < 0 || y >= SIZE_Y || x < 0 || x >= SIZE_X || matrix[y][x] != null) {
// 현재 위치에 값을 넣을 수 없는경우: 뒤로 하나 후퇴 & 방향 전환
x -= DIRECTION_XY[dir][0];
y -= DIRECTION_XY[dir][1];
dir = (dir + 1) % DIRECTION_XY.length;
} else {
// 값 입력
matrix[y][x] = String.valueOf(value);
value++;
}
// 다음 위치로 이동
x += DIRECTION_XY[dir][0];
y += DIRECTION_XY[dir][1];
}
// print result
final int VALUE_LENGTH = String.valueOf(value).length(); // 값의 최대 길이. pretty print를 위해.
final String format = "%" + VALUE_LENGTH + "s";
for (int i=0; i<matrix.length; i++) {
System.out.println(
Stream.of(matrix[i]).map(n -> String.format(format, n)).collect(Collectors.joining(" "))
);
}
}
}
public enum Direction { // 방향을 나타내는 enum입니다~
RIGHT(1), BOTTOM(2), LEFT(3), TOP(4);
private int value;
private Direction(int value) {
this.value = value;
}
}
public class Sprial {
public void sprialArray(int row, int col) {
int[][] arr = new int[row][col];
// -1로 초기화
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
arr[i][j] = -1;
}
}
int num = 0; // 시작 숫자
int rIdx = 0, cIdx = 0; // row, col에 대한 index
Direction direction = Direction.RIGHT;
while( num < row * col ) {
arr[rIdx][cIdx] = num++;
switch ( direction ) {
case RIGHT:
if( cIdx+1<col && arr[rIdx][cIdx+1] == -1 ){
cIdx++;
}else {
direction = Direction.BOTTOM;
rIdx++;
}
break;
case BOTTOM:
if( rIdx+1<row && arr[rIdx+1][cIdx] == -1 ){
rIdx++;
}else {
direction = Direction.LEFT;
cIdx--;
}
break;
case LEFT:
if( cIdx-1>=0 && arr[rIdx][cIdx-1] == -1 ){
cIdx--;
}else {
direction = Direction.TOP;
rIdx--;
}
break;
case TOP:
if( rIdx-1>=0 && arr[rIdx-1][cIdx] == -1 ){
rIdx--;
}else {
direction = Direction.RIGHT;
cIdx++;
}
break;
default:
break;
}
}
}
}
import java.util.Scanner;
public class Sprial_Array {
private static int num;
private Integer matrix[][];
public Sprial_Array(int num) {
this.num = num;
this.matrix = new Integer[num][num];
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
Sprial_Array matrix = new Sprial_Array(num);
//null로 자동 초기화
matrix.matrix[0][0] = 0;
matrix.right(0, 0); // start
for (int i = 0; i < num; i++) { // 이차원 배열 출력
for (int j = 0; j < num; j++) {
System.out.print(matrix.matrix[i][j] + "\t");
}
System.out.println();
}
}
public void up(int i, int j) {
int number = matrix[i][j];
if (number == num * num - 1) return;
i--;
do {
if (matrix[i][j] == null) {
matrix[i][j] = ++number;
if (i == 0) {
right(i, j);
break;
}
} else {
right(i + 1, j);
break;
}
i--;
} while (0 <= i && 0 <= j);
}
public void down(int i, int j) {
int number = matrix[i][j];
if (number == num * num - 1) return;
i++;
do {
if (matrix[i][j] == null) {
matrix[i][j] = ++number;
if (i == num - 1) {
left(i, j);
break;
}
} else {
left(i - 1, j);
break;
}
i++;
} while (i < num && j < num);
}
public void left(int i, int j) {
int number = matrix[i][j];
if (number == num * num - 1) return;
j--;
do {
if (matrix[i][j] == null) {
matrix[i][j] = ++number;
if (j == 0) {
up(i, j);
break;
}
} else {
up(i, j + 1);
break;
}
j--;
} while (0 <= i && 0 <= j);
}
public void right(int i, int j) {
int number = matrix[i][j];
if (number == num * num - 1) return;
j++;
do {
if (matrix[i][j] == null) {
matrix[i][j] = ++number;
if (j == num - 1) {
down(i, j);
break;
}
} else {
down(i, j - 1);
break;
}
j++;
} while (i < num && j < num);
}
}
//어렵네요...
row, col = map(int, input().split())
i=0
j=0
mat=[]
num = 0
FULL = 1
R =row
C=col
##점점 좁아지는 메트릭스의 면적을 표시하기 위해 총 네개의 변수가 필요하다.
left_side = 0
top_side = 1
mat = [[-1 for x in range(col)] for y in range(row)]
def Check():
print("CHECK")
global i, j, FULL
global mat
if mat[i][j] != -1:
print("FULL!!")
FULL = 0
def Right():
print("R")
global i, j, num, col
global mat
while(1):
mat[i][j] = num
num+=1
j+=1
if j == col: #오른쪽으로 끝까지 간 경우
j-=1 #범위를 넘어섰기 때문에 다시 1을 줄여준다.
col-=1 #열(col)의 범위를 1줄여준다.
i+=1 #이후 Down을 실행하기 떄문에 1칸 밑으로 내려준다.
break
def Down():
print("D")
global i, j, num, row
global mat
while(1):
mat[i][j] = num
num+=1
i+=1
if i == row:
i-=1 #범위를 넘어섰기 때문에 다시 1을 줄여준다.
row-=1 #행(row)의 범위를 1줄여준다.
j-=1 #이후 Left을 실행하기 떄문에 1칸 왼쪽으로 밀어준다.
break
def Left():
print("L")
global i, j, num, left_side
global mat
while(1):
mat[i][j] = num
num+=1
j-=1
if j < left_side:
j+=1
left_side+=1
i-=1
break
def Up():
print("U")
global i, j, num, top_side
global mat
while(1):
mat[i][j] = num
num+=1
i-=1
if i < top_side:
i+=1
top_side+=1
j+=1
break
while(1):
Right()
Check()
if FULL == 0:
break
Down()
Check()
if FULL == 0:
break
Left()
Check()
if FULL == 0:
break
Up()
Check()
if FULL == 0:
break
for i in range(R):
for j in range(C):
print("%3d" %mat[i][j], end="")
if j==(C-1):
print()
def p266():
# get row, col
X, Y = (int(x) for x in input("input 2 number: ").split(" "))
# fill matrix with -1
matrix = [[-1 for i in range(Y)] for j in range(X)]
x = y = 0
dx = 0
dy = 1
seq = 0
while matrix[x][y] == -1:
matrix[x][y] = seq
seq += 1
x, y = x+dx, y+dy
if x in [-1, X] or y in [-1, Y] or matrix[x][y] != -1:
x, y = x - dx, y - dy # prev xy
dx, dy = dy, -dx # new clock-wise
x, y = x+dx, y+dy # new xy
for r in matrix:
print(r)
#####################################
if __name__ == "__main__":
p266()
val Array(n , m) = Console.readLine().split(" ").map(_.toInt)
def spiralArray(N:Int, M:Int):List[List[Int]] = {
val mat = Array.fill(N)(Array.fill(M)(0))
val direction = List((0, 1), (1, 0), (0, -1), (-1, 0)) // spiral
mat(0)(0) = -1
var i = 0
var j = 0
var idx = 0
var v = 1
while(v < N*M){
i += direction(idx)._1
j += direction(idx)._2
while(i >= 0 && i < N && j >=0 && j < M && mat(i)(j) == 0){
mat(i)(j) = v
i += direction(idx)._1
j += direction(idx)._2
v += 1
}
i -= direction(idx)._1
j -= direction(idx)._2
idx = (idx+1)%4
}
mat(0)(0) = 0
mat.map(_.toList).toList
}
def spiral(m,n):
size = m * n
mylist = ["*" for i in range(size)]
for i in range(m) : mylist[i] = i
index = m -1
value = m -1
pattern = [m,-1,-m,1]
from itertools import cycle
for pat in cycle(pattern):
while True :
index += pat
value += 1
if index < size and mylist[index] == "*":
mylist[index] = value
else :
index -= pat
value -= 1
break
if "*" not in mylist :
for i,a in enumerate(mylist,1):
print("{:2d}".format(a), end = " ")
if i % m == 0 : print("")
return "END"
print(spiral(6,6))
#include<iostream>
#include"stdafx.h"
int main()
{
vector<vector<int>> matrix(10,vector<int>(10));
cout << matrix[1][1];
int num = 0;
int i = 0, j = 0;
int what_cal = 0;
int garo=0, sero=1;
int row,column = 0;
cout << "Input row and column:";
cin >> row >> column;
while (num < row*column)
{
if (what_cal % 4 == 0)
{
i = garo;
while (i<column - garo)
{
matrix[j][i++] = num++;
}
i--;
what_cal++;
}
else if (what_cal % 4 == 1)
{
while (j < row - sero)
{
matrix[++j][i] = num++;
}
what_cal++;
}
else if (what_cal % 4 == 2)
{
while (i > garo)
{
matrix[j][--i] = num++;
}
what_cal++;
garo++;
}
else if (what_cal % 4 == 3)
{
while (j > sero)
{
matrix[--j][i] = num++;
}
what_cal++;
sero++;
}
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
if(matrix[i][j]<10)
cout <<" "<< matrix[i][j];
else
cout<<" "<<matrix[i][j];
}
cout << endl;
}
}
코드 드럽습니다 보지 마세요
def spiral_array(x, y):
result = [[0 for xaxis in range(x)] for yaxis in range(y)]
xaxis = -1
yaxis = 0
xy = 0
for i in range(x * y):
if not xy % 4: xaxis += 1
elif xy % 4 == 1: yaxis += 1
elif xy % 4 == 2: xaxis -= 1
else: yaxis -= 1
try:
if result[yaxis][xaxis] or (xaxis == yaxis == 0 and result[0][1]):
if not xy % 4: xaxis -= 1
elif xy % 4 == 1: yaxis -= 1
elif xy % 4 == 2: xaxis += 1
else: yaxis += 1
xy += 1
if not xy % 4: xaxis += 1
elif xy % 4 == 1: yaxis += 1
elif xy % 4 == 2: xaxis -= 1
else: yaxis -= 1
except:
if not xy % 4: xaxis -= 1
elif xy % 4 == 1: yaxis -= 1
elif xy % 4 == 2: xaxis += 1
else: yaxis += 1
xy += 1
if not xy % 4: xaxis += 1
elif xy % 4 == 1: yaxis += 1
elif xy % 4 == 2: xaxis -= 1
else: yaxis -= 1
result[yaxis][xaxis] += i
return result
answer = input().split()
for run in spiral_array(int(answer[0]), int(answer[1])):
for prt in run:
if prt < 10: print(' ' + str(prt), end=' ')
else: print(' ' + str(prt), end=' ')
print()
# 실행후 6 6과 같이 입력
Python 3입니다
2차원 리스트를 활용했고요
xaxis변수로 x좌표를, yaxis변수로 y좌표를 제어하고 xy변수로 방향을 설정했습니다
만약 x좌표와 y좌표를 통한 값이 이미 채워져 있거나 리스트를 벗어났을 경우에는 방향을 바꾸는 방식입니다
package h10_spiral_array; import java.util.Scanner; public class SpriralArray {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int r1, r2, n, i, j, direction;
r1=in.nextInt(); r2=in.nextInt(); //값 두개 입력받기
int total=r1*r2;
int[][] arr=new int[r1][r2];
boolean[][] check=new boolean[r1][r2];
for(i=0;i<r1;i++) for(j=0;j<r2;j++) check[i][j]=false; //check배열 초기화
n=0; i=0; j=0; direction=0; //direction 방향 0:east, 1:south, 2:west, 3:north
while(n<total){
if(i>=0&&i<r1&&j>=0&&j<r2&& check[i][j]==false){ //값 차례대로 넣기
arr[i][j]=n; check[i][j]=true; n++;
if(direction==0) j++;
else if(direction==1) i++;
else if(direction==2) j--;
else if(direction==3) i--;
}
else{ //한 방향으로 끝까지 갔을 경우 방향 바꾸기
if(direction==0){ direction=1; j--; i++; }
else if(direction==1){ direction=2; i--; j--; }
else if(direction==2){ direction=3; j++; i--; }
else if(direction==3){ direction=0; i++; j++; }
}
}
for(i=0;i<r1;i++){ //값 출력하기. 일단 total이 100미만인 경우만 생각했어요^^
for(j=0;j<r2;j++){
if(arr[i][j]<10) System.out.print(" ");
System.out.print(arr[i][j]+" ");
} System.out.println();
}
}
}
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("숫자를 입력 : ");
String input = sc.nextLine();
int x = Integer.valueOf(input.substring(0, 1));
int y = Integer.valueOf(input.substring(2, 3));
// int x = 20, y = 20;
int num = 0;
int[][] array = new int[x][y];
for (int k = 0; k < x - 2; k++) {
for (int i = 0 + k; i < x - k; i++) {
array[k][i] = num++;
}
for (int i = 1 + k; i < x - k; i++) {
array[i][x - 1 - k] = num++;
}
for (int i = 1 + k; i < x - k; i++) {
array[x - 1 - k][x - i - 1] = num++;
}
for (int i = 1 + k; i < x - 1 - k; i++) {
array[x - i - 1][k] = num++;
}
}
System.out.println();
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
System.out.print(String.format("%3d ", array[i][j]));
}
System.out.println();
}
}
}
Python
n = 6
mat = [[-1 for i in range(n)] for j in range(n)]
cnt = 0
x = y = 0
dx = 0
dy = 1
while mat[x][y] == -1:
mat[x][y] = cnt
cnt += 1
x += dx
y += dy
if x in [-1, n] or y in [-1, n] or mat[x][y] != -1:
x -= dx
y -= dy
dx, dy = dy, -dx
x += dx
y += dy
for i in range(n):
for j in range(n):
print("{:3d}".format(mat[i][j]),end="")
print()
import java.util.Arrays;
import java.util.Scanner;
public class SpiralArray {
int[][] spiralArray;
// 각 iteration 마다 주어지는 x,y boundary
int[] dim1Range = new int[2];
int[] dim2Range = new int[2];
int x = 0;// 현재 위치한 좌표
int y = 0;// 현재 위치 좌표
int num = 0; // 증가하며 채워지는 요소값
int maxNum; // 요소값에서 최댓값
int dim1; // 행의 수 - main함수에서 사용할 것: spiralArray[0] ~ spiralArray[n] 까지 뽑을 때
public void setDimension(int dim1, int dim2) {
// 콘솔로 dimension 입력값을 받아 초기값들을 setting
Scanner sc = new Scanner(System.in);
dim1 = Integer.parseInt(sc.next());
dim2 = Integer.parseInt(sc.next());
this.dim1 = dim1;
this.spiralArray = new int[dim1][dim2];
this.maxNum = dim1*dim2-1;
this.dim1Range[0] = 0;
this.dim1Range[1] = dim1;
this.dim2Range[0] = 0;
this.dim2Range[1] = dim2;
}
// 실제로 내부값을 채우는 메서드
public void leftToright() {
for (int i = this.dim2Range[0] ; i < this.dim2Range[1] ; i++) {
this.spiralArray[this.y][i] = this.num;
this.num++;
this.x = i;
}
}
public void topTobottom() {
for (int j = this.dim1Range[0] + 1 ; j < this.dim1Range[1] ; j++) {
this.spiralArray[j][this.x] = this.num;
this.num++;
this.y = j;
}
}
public void rightToleft() {
for (int i = this.dim2Range[1]-2 ; i >= this.dim2Range[0] ; i--) {
this.spiralArray[this.y][i] = this.num;
this.num++;
this.x = i;
}
}
public void bottomTotop() {
for (int j = this.dim1Range[1]-2 ; j >= this.dim1Range[0] + 1 ; j--) {
this.spiralArray[j][this.x] = this.num;
this.num++;
this.y = j;
}
}
// 위의 4개의 메서드를 이용하여 spiralArray의 요소값을 채우고 반환하는 메서드
public int[][] getSprialArray() {
while (this.num <= this.maxNum) {
leftToright();
topTobottom();
rightToleft();
bottomTotop();
this.dim1Range[0] += 1;
this.dim1Range[1] -= 1;
this.dim2Range[0] += 1;
this.dim2Range[1] -= 1;
}
return this.spiralArray;
}
// 메인함수
public static void main(String[] args) {
SpiralArray sa = new SpiralArray();
sa.setDimension(6, 6);
sa.getSprialArray();
int nRow = sa.dim1;
for (int row=0; row < nRow ; row++) {
System.out.println(Arrays.toString(sa.spiralArray[row]));
}
}
}
def SpiralArray(n):
move_list = [[0,1], [1,0], [0,-1], [-1,0]] # 오른쪽, 아래쪽 왼쪽, 위쪽 순
loc = [0,-1] # 첫 시작점이 movement가 더해졋을때 [0,0]이 되도록 하려고
mat = [[-1 for _ in range(n)] for _ in range(n)]
movement = move_list[0]
move_idx=0
for i in range(n*n):
loc[0] = loc[0] + movement[0]
loc[1] = loc[1] + movement[1] # 다음 위치로 움직인다 ! 이동방향은 처음에는 오른쪽임.
if loc[0] >=n or loc[0]<0 or loc[1]>=n or loc[1]<0 or mat[loc[0]][loc[1]] !=-1:
# 새롭게 움직인 위치에 이미 숫자가 채워져있거나 인덱스가 범위를 벗어난다면 방향을 틀도록함( 오른 > 아래 > 왼 > 위 순)
loc[0] = loc[0] - movement[0]
loc[1] = loc[1] - movement[1] # 다시 하나 물르고,
move_idx = move_idx +1
movement = move_list[move_idx%4] # 방향 틀고,
loc[0] = loc[0] + movement[0]
loc[1] = loc[1] + movement[1] # 튼 방향으로 다시 이동 !
mat[loc[0]][loc[1]]=i
return(mat)
sizeOfMatrix = {"rows":6, "cols":6}
dirPos = [[0,1],[1,0],[0,-1],[-1,0]]
curPos = [0,0]
curDir = 0
# 주어진 사이즈 만큼의 연속된 숫자리스트 만들
fillNumList = tuple(range(0,sizeOfMatrix['rows'] * sizeOfMatrix['cols']))
#빈 매트릭스 만들
emptyMatrix = [['' for r in range(sizeOfMatrix['cols'])] for c in range(sizeOfMatrix['rows'])]
# 주어진 좌표에 값을 채울 수 있으면 True 를 return 한다.
def isFilledValue(pos):
ret = True
if (emptyMatrix[pos[0]][pos[1]] == '') :
ret = False
return ret;
# 방향을 변경한다.
def changeDir(cDir):
cDir = (cDir+1) % 4;
return cDir;
# 좌표를 가져온다.
def getNextPos(curP, curD):
dirP = dirPos[curD]
nextP = [curP[0] + dirP[0], curP[1] + dirP[1]]
if ((nextP[0] >= 0 and nextP[0] < sizeOfMatrix['rows']) and (nextP[1] >= 0 and nextP[1] < sizeOfMatrix['cols'])) :
return nextP;
else:
return curP;
# 매트릭스 출
def printMatrix(m):
for r in m:
for c in r:
print('%3s'%(str(c)),end=' ')
print('\n')
# Main
for n in fillNumList:
if (isFilledValue(curPos) == False):
emptyMatrix[curPos[0]][curPos[1]] = n
if (isFilledValue(getNextPos(curPos, curDir)) == True):
curDir = changeDir(curDir)
curPos = getNextPos(curPos, curDir)
printMatrix(emptyMatrix)
using System;
namespace CD002
{
class Program
{
static void Main(string[] args)
{
var mat = new Matrix(6, 6);
mat.DisplayMatrix();
}
}
class Matrix
{
private int[,] Mat;
private readonly int EndValue;
// 좌표 및 증가분 초기화
private int IdxX = -1, IdxY = 0, Dx = 1, Dy = 0;
public Matrix(int ysize, int xsize)
{
// 음의 값으로 매트릭스 초기화
Mat = new int[ysize, xsize];
for (int y = 0; y < ysize; y++)
{
for (int x = 0; x < xsize; x++)
{
Mat[y, x] = -1;
}
}
EndValue = ysize * xsize - 1;
GenerateMatrix(); // 매트릭스 생성
}
// 매트릭스 생성
private void GenerateMatrix()
{
for (int i = 0; i <= EndValue; i++)
{
CheckNext();
IdxX += Dx; IdxY += Dy;
Mat[IdxY, IdxX] = i;
}
}
// 다음 입력 점이 범위를 벗어나거나 값이 이미 설정돼 있는 경우 증가 방향(Dy, Dx) 전환
private void CheckNext()
{
bool check = true;
if (IdxX + Dx == Mat.GetLength(1) || IdxX + Dx < 0 || IdxY + Dy == Mat.GetLength(0) || IdxY + Dy < 0)
{
check = false;
}
else if (Mat[IdxY + Dy, IdxX + Dx] >= 0)
{
check = false;
}
if (!check)
{
int tmp = Dy;
Dy = Dx;
Dx = -tmp;
}
}
public void DisplayMatrix()
{
for (int y = 0; y < Mat.GetLength(0); y++)
{
for (int x = 0; x < Mat.GetLength(1); x++)
{
Console.Write($"{Mat[y, x],3} ");
}
Console.WriteLine();
}
}
}
}
<자바입니다> import java.io.BufferedReader; import java.io.InputStreamReader;
class Main {
static int n, m, r=0, c=0, a=2,map[][];
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] s = br.readLine().split(" ");
n = Integer.parseInt(s[0]);
m = Integer.parseInt(s[1]);
map = new int[n][m];
map[0][0] = 1;
while(a<=n*m) {
while (c+1<n && map[r][c+1] == 0) // 열 ++
map[ r][++c] = a++;
while ( r+1<m && map[r+1][c] ==0) // 행 ++
map[++ r][c] = a++;
while (0<=c-1 && map[r][c-1] == 0) // 열--
map[ r][--c] = a++;
while (0<= r-1 && map[r-1][c] == 0) // 행--
map[-- r][c] = a++;
}
// 출력
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++)
System.out.printf("%5d",map[i][j]);
System.out.println();
}
}
} 넘 쉽네요 ```
input_data = input()
row = int(input_data.split(" ")[0])
col = row = int(input_data.split(" ")[1])
lists = [[-1 for i in range(row)] for j in range(col)]
pos_x = 0
pos_y = 0
row_start = 1
col_start = 0
row_last = row-1
col_last = col-1
dir = 0
for index in range(row*col):
lists[pos_y][pos_x] = index
print ("%d, %d"%(pos_x, pos_y))
if dir == 0:
pos_x += 1
elif dir == 1:
pos_y += 1
elif dir == 2:
pos_x -= 1
elif dir == 3:
pos_y -= 1
if dir == 0 and pos_x == col_last:
dir = 1
col_last -= 1
if dir == 1 and pos_y == row_last:
dir = 2
row_last -= 1
if dir == 2 and pos_x == col_start:
dir = 3
col_start += 1
if dir == 3 and pos_y == row_start:
dir = 0
row_start += 1
for list in lists:
print(list)
import numpy as np
import sys
r,c = map(int, input("input mxn : ").split(' '))
m = (-1) * np.ones((r,c), dtype=np.int64)
move = np.array([[0,1], [1,0], [0,-1], [-1,0]])
cur_pos = np.array([0,0])
# forward first (0:forward, 1:down, 2:backward, 3:up)
direction = 0
number = 0
while 1:
while m[cur_pos[0],cur_pos[1]] == -1:
m[cur_pos[0],cur_pos[1]] = number
number += 1
n = cur_pos + move[direction]
if n[0] in [-1,r] or n[1] in [-1,c] or m[n[0],n[1]] != -1:
break
cur_pos = n
if number >= int(r) * int(c):
break
direction = (direction+1) % len(move)
cur_pos = cur_pos + move[direction]
print("{}".format(m))
'''
위의 코드보다 아래가 좀더 깔끔한 듯...
'''
import numpy as np
import sys
r,c = map(int, input("input mxn : ").split(' '))
m = (-1) * np.ones((r,c), dtype=np.int64)
move = np.array([[0,1], [1,0], [0,-1], [-1,0]])
cur_pos = np.array([0,0])
# forward first (0:forward, 1:down, 2:backward, 3:up)
direction = 0
number = 0
while m[cur_pos[0],cur_pos[1]] == -1:
m[cur_pos[0],cur_pos[1]] = number
number += 1
n = cur_pos + move[direction]
if n[0] in [-1,r] or n[1] in [-1,c] or m[n[0],n[1]] != -1:
direction = (direction+1) % len(move)
cur_pos = cur_pos + move[direction]
continue
cur_pos = n
print("{}".format(m))
sixsix = input("hit 6 6")
if sixsix == "6 6":
print("""
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
""")
string = input("ex) 5 5 $")
numbers = string.split(" ")
one = int(numbers[0])
two = int(numbers[1])
num = 0
row = 0
col = -1
switch = 1
round = one
matrix = [[0]*one for i in range(two)]
while round!=0:
for i in range(round):
col+=switch
num+=1
matrix[row][col] = num
round-=1
for i in range(round):
row+=switch
num+=1
matrix[row][col] = num
switch*=(-1)
namespace Sperial_Array
{
class Program
{
static void Main(string[] args)
{
int nFst, nSec;
string[] strInput = Console.ReadLine().Split(' ');
bool result1 = int.TryParse(strInput[0], out nFst);
bool result2 = int.TryParse(strInput[1], out nSec);
if (result1 && result2)
Sperial(nFst, nSec);
else
Console.WriteLine("숫자를 입력하세요");
}
static void Sperial(int a, int b)
{
int nLen = a;
int x = 0, z = 0;
int y = -1;
int nPosition = 1;
int[,] nArray = new int[a, b];
for (int i = 0; i < (a + b) - 1; i++)
{
for (int k = 0; k < nLen; k++)
{
y += nPosition;
nArray[x, y] = z;
z++;
}
nLen--;
for (int k = 0; k < nLen; k++)
{
x += nPosition;
nArray[x, y] = z;
z++;
}
nPosition = - nPosition;
}
for (int i = 0; i < nArray.GetLength(0); i++)
{
for (int j= 0; j < nArray.GetLength(1); j++)
{
Console.Write(nArray[i,j].ToString() + "\t");
}
Console.WriteLine();
}
}
}
}
#입력 및 matrix 생성
row, column = input().split()
row = int(row)
column = int(column)
mat = [[0]*(column+1) for i in range(row+1)]
for i in range(0,row+1): mat[i][column] = 1
for j in range(0,column+1): mat[row][j] = 1
#계산 부분
i=0; j=0; state=0
for count in range(0,row*column):
mat[i][j] = count
if state==0:
if(mat[i][j+1] == 0):
j += 1;
else: i+=1; state=1
elif state==1:
if(mat[i+1][j] == 0):
i += 1;
else: j-=1; state=2
elif state==2:
if(mat[i][j-1] == 0):
j -= 1;
else: i-=1; state=3
elif state==3:
if(mat[i-1][j] == 0 and i!=1):
i -= 1;
else: j+=1; state=0
#출력 부분
for i in range(0,row):
for j in range(0,column):
print(mat[i][j], end=" ")
print()
package Spiral_Array;
import java.util.Scanner;
public class Spiral_Array {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int row = sc.nextInt();
int colum = sc.nextInt();
int number = 0;
int[][] array = new int[row][colum];
int i = 0;
int j = 0;
final int right = 1;
final int down = 2;
final int left = 3;
final int up = 4;
int count = row*colum;
int cycle = 0;
int direction = right;
for (; number<count; number++) {
switch(direction) {
case right:
array[i][j++] = number;
if(j == colum-i) {
direction = down;
j = colum-1-cycle;
i = 1+cycle;
}
break;
case down:
array[i++][j] = number;
if(i == row-cycle) {
direction = left;
j = row-2-cycle;
i = colum-1-cycle;
}
break;
case left:
array[i][j--] = number;
if(j == cycle-1) {
direction = up;
j = cycle;
i = row-2-cycle;
}
break;
case up:
array[i--][j] = number;
if(cycle == i) {
direction = right;
j++;
i++;
cycle++;
}
break;
}
}
for(int k=0; k<row; k++) {
for(int l=0; l<colum; l++) {
System.out.print("\t"+ array[k][l]);
}
System.out.println();
}
}
}
파이썬. 라인은 좀 길지만 가독성 높도록 만들어 봤습니다! 방향이 꺾이는 숫자 리스트를 찾는 gernerate 함수를 하나 만들어서 이 숫자가 나올 때 마다 방향을 전환합니다. 방향 전환에 사용되는 변수는 sw입니다.
# 방향이 꺾이는 숫자 찾는 알고리즘
def generate(a,b):
c = [a - 1]
e = a*b - 1
while c[-1] != e:
b -= 1
c.append(c[-1] + b)
a -= 1
c.append(c[-1] + a)
return c
#입력
a, b = map(int,input().split())
# 배역 0으로 초기화
c = []
for i in range(b):
c.append([0] * a)
x, y, z, sw = 0, 0, 0, 1
gen = generate(a,b)
for i in range(a*b):
c[x][y] = i
if i in gen:
sw += 1
sw = sw % 4
if sw == 0: x -= 1# 위쪽
elif sw == 1: y += 1# 오른쪽
elif sw == 2: x += 1# 아래쪽
elif sw == 3: y -= 1# 왼쪽
for x1 in c:
for y1 in x1:
print('%3d'%y1, end="")
print()
C언어로 했습니다. 중간에 이상한 로직 하나 틀려먹어서 꼬박 6-11시 까지 삽질 했네요 ^_^ 다른 분들의 풀이 참조를 조금 해서 풀이방법을 조금 얻어갔습니다 ^^
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define RIGHT 0
#define DOWN 1
#define LEFT 2
#define UP 3
int main()
{
int x,y;
scanf("%d %d", &x, &y); //x와 y의 숫자 받기
//2차원 배열 선언
int **arr;
arr = (int**)malloc(sizeof(int*)*x);
for(int i = 0; i < x; i++) arr[i] = (int*)malloc(sizeof(int) * y );
int x_ = 0, y_ = 0; // 움직일 좌표
int MAX_x = x-1; //x 의 끝좌표
int MAX_y = y-1; //y 의 끝좌표
int MIN_x = 0; //x 의 미니멈 좌표
int MIN_y = 0; //y 의 미니멈 좌표
int direction = RIGHT; //움직이는 방향 조절
int num = 0;
while(true)
{
arr[x_][y_] = num++;
//printf("%d", num);
//printf("%d", arr[x_][y_]);
switch ( direction )
{
case RIGHT:
if( y_ == MAX_y )
{
direction = DOWN; MIN_x ++; x_++;
}
else
{
y_++;
}
break;
case DOWN:
if( x_ == MAX_x )
{
direction = LEFT; MAX_y --; y_--;
}
else
{
x_++;
}
break;
case LEFT:
if( y_ == MIN_y )
{
direction = UP; MAX_x --; x_--;
}
else
{
y_--;
}
break;
case UP:
if( x_ == MIN_x )
{
direction = RIGHT; MIN_y ++; y_++;
}
else
{
x_--;
}
break;
default : break;
}
if(num == x * y )
break;
}
for(int i = 0; i < x; i ++)
{
for(int j = 0; j < y; j ++ )
{
printf("%3d", arr[i][j]);
}
printf("\n");
}
}
재귀함수를 사용하여 풀었습니다.
def circle_index(i,j,n,l,res):
if not l>0:
return
for w in range(l):
res[j][i+w]=n
n+=1
for h in range(l-1):
res[j+h+1][i+l-1]=n
n+=1
for w in range(l-1):
res[j+l-1][i+l-2-w]=n
n+=1
for h in range(l-2):
res[j+l-2-h][i]=n
n+=1
circle_index(i+1,j+1,n,l-2,res)
return
def draw_circle():
n=input()
n=int(n)
res = [[-1]*n for i in range(n)]
circle_index(0,0,0,n,res)
for i in range(n):
print(res[i])
맞게는 나오는거같아요..
import java.util.Scanner;
// http://codingdojang.com/scode/266
public class cd266 {
public static void main(String[] args) {
// input
Scanner scanner = new Scanner(System.in);
String in = scanner.nextLine();
if (in.split(" ").length != 2) {
System.out.println("input error");
System.exit(0);
}
String[] inArray = in.split(" ");
int x = Integer.parseInt(inArray[0]);
int y = Integer.parseInt(inArray[1]);
int nextNum = 0;
int cx=0, cy=0;
// create array args 2
int[][] sprial = new int [x+1][y+1];
// init
for (int i=0; i<x; i++) {
for (int j=0; j<y; j++) {
sprial[i][j]=-1;
}
}
while(true) {
// break
if (nextNum >= (x * y)) break;
// fill
if (sprial[cx][cy] == -1) {
sprial[cx][cy] = nextNum;
}
// next direction
if ((cx == 0 || (cx > 0 && sprial[cx-1][cy] != -1)) && cy+1 < y && sprial[cx][cy+1] == -1) {
// 위에가 막혀있으면 오른쪽으로.
cy++;
} else if ((cy + 1 == y || sprial[cx][cy+1] != -1) && cx + 1 < x && sprial[cx +1][cy] == -1) {
// 오른족이 막혀있거나 아래가 -1 이면 아래로.
cx++;
} else if ((cx + 1 == x || sprial[cx+1][cy] != -1) && cy - 1 > -1 && sprial[cx][cy - 1] == -1) {
// 아래가 막히거나 왼쪽이 -1 이면 왼쪽으로
cy--;
} else if (sprial[cx - 1][cy] == -1) {
cx--;
}
if (cx == -1 || cy == -1) {
break;
}
nextNum++;
}
// pretty fill blank length
int blank = String.valueOf(x*y).length();
// print
for (int i=0; i<x; i++) {
for (int j=0; j<y; j++) {
System.out.print(String.format("%" + blank + "s ", sprial[i][j]));
}
System.out.println();
}
}
}
11 11 0 1 2 3 4 5 6 7 8 9 10 39 40 41 42 43 44 45 46 47 48 11 38 71 72 73 74 75 76 77 78 49 12 37 70 95 96 97 98 99 100 79 50 13 36 69 94 111 112 113 114 101 80 51 14 35 68 93 110 119 120 115 102 81 52 15 34 67 92 109 118 117 116 103 82 53 16 33 66 91 108 107 106 105 104 83 54 17 32 65 90 89 88 87 86 85 84 55 18 31 64 63 62 61 60 59 58 57 56 19 30 29 28 27 26 25 24 23 22 21 20
public class SprialArray {
private static final int[] DirectionX = {1, 0, -1, 0};
private static final int[] DirectionY = {0, 1, 0, -1};
private static int map[][];
private static int N,M; // N:가로 M:세로
public static void main(String[] args) {
mapSetting();
int x=0 ,y=0, flag=0;
map[y][x] = 0;
for(int i=0; i<N*M-1; i++) {
int newY = y + DirectionY[flag];
int newX = x + DirectionX[flag];
//인덱스 범위 초과 하거나 숫자가 입력되어 있을시 방향을 바꿔준다
if(newX<0 || newY<0 || newX >= N || newY >= M || map[newY][newX]!=-1) {
flag++;
if(flag == 4) {
flag = 0;
}
newY = y + DirectionY[flag];
newX = x + DirectionX[flag];
}
x = newX;
y = newY;
map[y][x] = i+1;
}
printMap();
}
public static void mapSetting() {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
M = sc.nextInt();
map = new int[M][N];
for(int i=0;i<M;i++) {
for(int j=0;j<N;j++) {
map[i][j] = -1;
}
}
}
public static void printMap() {
for(int i=0;i<M;i++) {
for(int j=0;j<N;j++) {
System.out.printf("%3d ", map[i][j]);
}
System.out.println();
}
}
}
위와는 달리 재귀를 사용해봤어요.
public class SprialArray2 {
private static final int[] DirectionX = {1, 0, -1, 0};
private static final int[] DirectionY = {0, 1, 0, -1};
private static int map[][];
private static int N,M; // N:가로 M:세로
public static void main(String[] args) {
mapSetting();
insert(0,0,0,0);
printMap();
}
public static void mapSetting() {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
M = sc.nextInt();
map = new int[M][N];
for(int i=0;i<M;i++) {
for(int j=0;j<N;j++) {
map[i][j] = -1;
}
}
}
public static void printMap() {
for(int i=0;i<M;i++) {
for(int j=0;j<N;j++) {
System.out.printf("%3d ", map[i][j]);
}
System.out.println();
}
}
public static void insert(int x, int y,int flag, int num) {
if(x<0 || y<0 || x >= N || y >= M || map[y][x]!=-1) {
return;
}
map[y][x] = num;
int newY = y + DirectionY[flag];
int newX = x + DirectionX[flag];
if(newX<0 || newY<0 || newX >= N || newY >= M || map[newY][newX]!=-1) {
flag++;
if(flag == 4) {
flag = 0;
}
newY = y + DirectionY[flag];
newX = x + DirectionX[flag];
}
insert(newX, newY, flag, num+1);
}
}
int board[100][100]; int R,C; int dir[4][2] = { {0,1}, {1,0}, {0,-1}, {-1,0} };
int valid_ragne(int y, int x) { if( y<0 || y>=R ) return 0; if( x<0 || x>=C ) return 0; if( board[y][x] != -1 ) return 0; return 1; }
int main() { int y, x; int i,j; int count=0;
scanf("%d %d",&R, &C);
memset(board, -1, sizeof(int)*100*100);
y=x=0;
board[0][0] = count++;
while( count < R*C )
{
for(i=0; i<4; i++)
{
while( 1 )
{
y = y+dir[i][0];
x = x+dir[i][1];
if( valid_ragne(y,x) == 0 )
{
y = y-dir[i][0];
x = x-dir[i][1];
break;
}
board[y][x] = count++;
}
}
}
for(i=0; i<R; i++)
{
printf("\n");
for(j=0; j<C; j++)
{
printf("%2d ", board[i][j]);
}
}
return 0;
}
def getValue(n):
if n % 2 == 0:
return 1
return -1
def printSpiral(s):
for l in s:
for n in l:
print('{:2}'.format(n), end=' ')
print()
row, col, n = 0, 0, 0
line = 6
spiral = [[0 for i in range(line)] for j in range(line)]
for i in range(line):
for j in range(line-i):# left/right
spiral[col][row] = n
row += getValue(i)
n += 1
row += getValue(i+1)
col += getValue(i)
for k in range(line-i-1):# down/up
spiral[col][row] = n
col += getValue(i)
n += 1
row += getValue(i+1)
col += getValue(i+1)
printSpiral(spiral)
int DIR = R;
private static final int R = 0;
private static final int L = 1;
private static final int U = 2;
private static final int D = 3;
int value = 0;
int nowX = 0;
int nowY = 0;
int go = 6;
static int intArr[][]= new int[6][6];
public static void main(String[] args) {
setArray(1);
}
public void setArray(int count) {
if (go == 0)
return;
int i = 0;
switch (DIR) {
case R:
for (i = 0; i < go; i++) {
intArr[nowY][nowX + i] = value;
value++;
}
nowX = nowX + i - 1;
nowY++;
DIR = D;
break;
case L:
for (i = 0; i < go; i++) {
intArr[nowY][nowX - i] = value;
value++;
}
nowX = nowX - i + 1;
nowY--;
DIR = U;
break;
case U:
for (i = 0; i < go; i++) {
intArr[nowY - i][nowX] = value;
value++;
}
nowY = nowY - i + 1;
nowX++;
DIR = R;
break;
case D:
for (i = 0; i < go; i++) {
intArr[nowY + i][nowX] = value;
value++;
}
nowY = nowY + i - 1;
nowX--;
DIR = L;
break;
}
count--;
if(count==0) {
go--;
setArray(2);
} else {
setArray(count);
}
}
#include <iostream>
using namespace std;
int main() {
int N, i = 0;
cin >> N;
printf("\n");
// array initialize
int **Arr = new int*[N];
for (i; i < N; ++i) {
Arr[i] = new int[N];
memset(Arr[i], 0, sizeof(int)*N);
}
int PathChecker = 1;
int InputNumber = 0;
int SquareChecker = N;
int loc_X = -1;
int loc_Y = 0;
int j;
while (1) {
for (i = 0; i < SquareChecker; ++i) {
loc_X += PathChecker;
Arr[loc_Y][loc_X] = InputNumber;
++InputNumber;
}
--SquareChecker;
if (SquareChecker < 0) break;
for (j = 0; j < SquareChecker; ++j) {
loc_Y += PathChecker;
Arr[loc_Y][loc_X] = InputNumber;
++InputNumber;
}
PathChecker = -1 * PathChecker;
}
for (i = 0; i < N; ++i) {
for (j = 0; j < N; ++j) {
printf("%2d ",Arr[i][j]);
}
printf("\n");
}
//system("pause");
return 0;
}
개선중입니다.
def createMatrix(maxrow:Int, maxcol:Int) = {
val max = maxrow * maxcol
val up:(Int,Int) = (-1,0)
val down:(Int,Int) =(1,0)
val left:(Int,Int) =(0,-1)
val right:(Int,Int) =(0,1)
object vector{
var loc:(Int,Int) = (0,0)
var direct:(Int,Int) = right
def expected :(Int,Int)= {
(loc._1 + direct._1, loc._2 + direct._2)
}
//right,down, left, up
def nextpos(
matrix:Map[(Int,Int),Int],n:Int):(Int,Int) =
{
def dirmap = Map(right->down, down->left, left->up, up->right)
if
(expected._1 >= maxrow ||
expected._2 >= maxcol ||
expected._1 < 0 ||
expected._2 < 0 ||
matrix.contains(expected)
)
{
direct = dirmap(direct)
}
loc = expected
loc
}
}
var matrix:Map[(Int,Int),Int] = Map((0,0)->0)
(1 until max).foreach((i:Int)
=> matrix += (vector.nextpos(matrix,i) -> i)
)
for( a <- 0 until maxrow){
for( b <-0 until maxcol){
var n = matrix(a,b)
print(n)
print(' ')
}
println()
}
println()
}
x, y = map(int,input().split())
board = [[-1 for j in range(y)] for i in range(x)]
odd_switch = 0 #홀수번째
even_switch = 0 #짝수번째
n = 1 #전체 회전수
value = 0
dx = 0
dy = -1
jdx = 0
jdy = 0
first = '1'
while n < x*y:
#print('n:'+str(n))
for i in range(x):
#print(' i:'+str(i))
if n%2 == 0:
if even_switch == 0:
dx = dx + 1
else:
dx = dx - 1
else:
if odd_switch == 0:
dy = dy + 1
else:
dy = dy - 1
#print('dx:'+str(dx)+','+'dy:'+str(dy)+','+'value:'+str(value))
if first != '1':
if dx < 0:
dx = 0
if dx >= x:
dx = dx - 1
if dy < 0:
dy = 0
if dy >= y:
dy = dy - 1
first = '0'
#print(' dx:'+str(dx)+','+'dy:'+str(dy)+','+'value:'+str(value))
if board[dx][dy] == -1:
board[dx][dy] = value
jdx = dx
jdy = dy
else:
dx = jdx
dy = jdy
#print(' dx:'+str(dx)+','+'dy:'+str(dy))
break
value = value + 1
if n%2 == 0:
if even_switch == 0:
even_switch = 1
else:
even_switch = 0
else:
if odd_switch == 0:
odd_switch = 1
else:
odd_switch = 0
n = n + 1
for i in range(x):
for j in range(y):
print(f'{board[i][j]:3}', end='')
print()
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
// 입력 부분
Scanner sc = new Scanner(System.in);
System.out.print("가로 길이 입력 : ");
int len_x = sc.nextInt();
System.out.println("세로 길이 입력 : ");
int len_y = sc.nextInt();
// 배열 초기화
int[][] arr = new int[len_y][len_x];
int f1,f2;
for(f1=0;f1<len_y;f1++)
{
for(f2=0;f2<len_x;f2++)
{
arr[f1][f2] = -1;
}
}
// 배열 집어넣기.
int cnt=0;
int pos_x=0,pos_y=0;
int[] dir_x = {1,0,-1,0};
int[] dir_y = {0,1,0,-1};
int dir=0;
while(cnt < len_x*len_y)
{
arr[pos_y][pos_x] = cnt++;
pos_x+=dir_x[dir];
pos_y+=dir_y[dir];
//System.out.println(cnt);
if(pos_x <0 || pos_x >= len_x || pos_y<0||pos_y >= len_y || arr[pos_y][pos_x]!=-1 )
{
pos_x-=dir_x[dir];
pos_y-=dir_y[dir];
dir = (dir+1) %4;
pos_x+=dir_x[dir];
pos_y+=dir_y[dir];
}
}
// show
for(f1=0;f1<len_y;f1++)
{
for(f2=0;f2<len_x;f2++)
{
System.out.printf("%3d ",arr[f1][f2]);
}
System.out.println("");
}
}
}
#include <iostream>
#include <string.h>
using namespace std;
int main(){
int x=0 , y=0;
char rotate=0;
cin >> x >> y ;
if(x<0&&x>99) return 0;
if(y<0&&y>99) return 0;
int **buff= new int*[y];
for(int i=0;i<y;i++){
buff[i]=new int[x];
memset(buff[i],0,sizeof(int)*x);
}
int cx=0,cy=0;
for(int i=0;i<x*y;i++){
buff[cy][cx]=i+1;
switch(rotate){
case 0:
if (cy>0) if(buff[cy-1][cx]==0) {
cy--;
break;
}
cx++,rotate++;
break;
case 1:
if (cx+1<x) if(buff[cy][cx+1]==0){
cx++;
break;
}
cy++,rotate++;
break;
case 2:
if (cy+1<y) if(buff[cy+1][cx]==0) {
cy++;
break;
}
cx--,rotate++;
break;
case 3:
if (cx>0) if(buff[cy][cx-1]==0){
cx--;
break;
} cy--,rotate=0;
break;
}
}
for(int i=0;i<x;i++){
for (int j=0;j<y;j++)
{
cout<<buff[i][j]-1<<"\t";
}
cout<< endl;
}
for(int i=0;i<y;i++){
delete[] buff[i];
}
delete[] buff;
}
int main() { int arr[garo][sero] = { 0 }; int k = 0, l = 0; int num=0; int i=0, j=0;
while (num<garo*sero) {
for (i = 0+l; i < garo-l ; i++) {
arr[j][i] = num;
num++;
}
i--;
for (j = 1+k; j < sero-k ; j++) {
arr[j][i] = num;
num++;
}
j--;
for (i= garo-l-2; i >= 0+l; i--) {
arr[j][i] = num;
num++;
}
i++;
//1로 가야됨
for (j=sero-k-2; j>0+k ; j--) {
arr[j][i] = num;
num++;
}
j++;
l++;
k++;
}
for (i = 0; i < garo; i++) {
for (j = 0; j < sero; j++)
printf("%d ",arr[i][j]);
printf("\n");
}
}
def nasun(m, n):
a = [[ 0 for i in range(m)] for j in range(n) ]
drt = [(1, 0), (0, 1), (-1, 0), (0, -1)]
drt_s = 0
x, y = (0,0)
a[0][0] = 1
for i in range(1, m*n + 1):
x2, y2 = x + drt[drt_s][0], y + drt[drt_s][1]
try :
if a[y2][x2] == 0:
''' '''
else :
drt_s += 1
if drt_s == 4 : drt_s = 0
x2, y2 = x + drt[drt_s][0], y + drt[drt_s][1]
except:
drt_s += 1
if drt_s == 4 : drt_s = 0
x2, y2 = x + drt[drt_s][0], y + drt[drt_s][1]
x, y = x2, y2
a[y][x] = i
a[0][0] = 0
print( a )
return
nasun(6, 6)
X = int(input(' '))
Y = int(input(' '))
lis = [[-1 for i in range(Y)] for j in range(X)]
x,y = 0,0
dx,dy = 0,1
count = 0
s = ""
while lis[x][y] == -1:
lis[x][y] = count
count+=1
x,y = x+dx,y+dy
if x in [-1,X] or y in [-1,Y] or lis[x][y] != -1:
x,y = x-dx,y-dy
dx,dy = dy,-dx
x,y = x+dx,y+dy
for L in lis:
for val in L:
s += str(val)+"\t"
print(s)
s = ""
print('\n')
def spiral(num):
n_list = [[0 for x in range(num)] for y in range(num)]
'''
low high
low 0 1 3
8 9 4
high 7 6 5
'''
n = 0
low = 0
high = num - 1
count = int((num + 1) / 2)
for i in range(count):
for j in range(low, high+1):
n_list[i][j] = n
n += 1
for j in range(low+1, high+1):
n_list[j][high] = n
n += 1
for j in range(high-1, low-1, -1):
n_list[high][j] = n
n += 1
for j in range(high-1, low, -1):
n_list[j][low] = n
n += 1
low += 1
high -= 1
for i in range(num):
for j in range(num):
print(n_list[i][j], end='\t')
print()
def main():
user_input = int(input("N x N (ex. 4 -> 4 x 4): "))
spiral(user_input)
if __name__ == '__main__':
main()
matrix = input()
# 행이 세로 열이 가로
max_row = int(matrix.split()[0])
max_column = int(matrix.split()[1])
max_number = max_row * max_column - 1
# 칸 만들기
matrix_list = []
temp = []
for r in range(max_row):
for c in range(max_column):
temp.append(0)
matrix_list.append(temp)
temp = []
# 변수 설정
number = 0
start_row = 0
start_column = 0
end_row = max_row - 1
end_column = max_column - 1
row = 0
column = 0
count = 0
# 나선형 만들기
while count < int(min(max_row, max_column) / 2 + 0.5):
while column < end_column:
matrix_list[row][column] = number
number += 1
column += 1
while row < end_row:
matrix_list[row][column] = number
number += 1
row += 1
while column > start_column:
matrix_list[row][column] = number
number += 1
column -= 1
while row > start_row:
matrix_list[row][column] = number
number += 1
row -= 1
start_row += 1
start_column += 1
end_row -= 1
end_column -= 1
count += 1
row = start_row
column = start_column
# 출력
for i in range(max_row):
print(matrix_list[i])
한바퀴 채우는 식을 만들고 값이 채워지는 시작점을 0,0 -> 1,1순으로 되게하여 반복문을 만들었습니다
matrix = [] matrix.append([0, 1, 2, 3, 4, 5]) matrix.append([19, 20, 21, 22, 23, 6]) matrix.append([18, 31, 32, 33, 24, 7]) matrix.append([17, 30, 35, 34, 25, 8]) matrix.append([16, 29, 28, 27, 26, 9]) matrix.append([15, 14, 13, 12, 11, 10])
width = 6 height = 6 startx = 0 starty = 0
while startx < (width - startx) and starty < (height - starty): for x in range(startx, width-startx): print(matrix[starty][x], end=' ') for y in range(1+starty, height-starty): print(matrix[y][x], end=' ') for x in range(width-(2 + startx), startx-1, -1): print(matrix[y][x], end=' ') for y in range(height-(2 + starty), starty, -1): print(matrix[y][x], end=' ') startx+=1 starty+=1
matrix = []
matrix.append([0, 1, 2, 3, 4, 5])
matrix.append([19, 20, 21, 22, 23, 6])
matrix.append([18, 31, 32, 33, 24, 7])
matrix.append([17, 30, 35, 34, 25, 8])
matrix.append([16, 29, 28, 27, 26, 9])
matrix.append([15, 14, 13, 12, 11, 10])
width = 6
height = 6
startx = 0
starty = 0
while startx < (width - startx) and starty < (height - starty):
for x in range(startx, width-startx):
print(matrix[starty][x], end=' ')
for y in range(1+starty, height-starty):
print(matrix[y][x], end=' ')
for x in range(width-(2 + startx), startx-1, -1):
print(matrix[y][x], end=' ')
for y in range(height-(2 + starty), starty, -1):
print(matrix[y][x], end=' ')
startx+=1
starty+=1
public class SpiralArray {
private enum Direction {right, left, up, down};
public static void main(String[] args) {
// 회전하며 숫자를 배열하는 배열
// 입력값
int input_x = 6;
int input_y = 6;
int[][] array = new int[input_y][input_x];
Direction direction = Direction.right;
int xIdx = 0, yIdx = 0;
int cnt=1;
for(int num=0; num < input_x*input_y; num++)
{
array[yIdx][xIdx] = num;
switch(direction)
{
case right:
if(xIdx+cnt < input_x)
{
xIdx++;
}
else
{
direction = Direction.down;
yIdx++;
}
break;
case down:
if(yIdx+cnt < input_y)
{
yIdx++;
}
else
{
direction = Direction.left;
xIdx--;
}
break;
case left:
if(xIdx-cnt >= 0)
{
xIdx--;
}
else
{
direction = Direction.up;
yIdx--;
cnt++;
}
break;
case up:
if(yIdx-cnt >= 0)
{
yIdx--;
}
else
{
direction = Direction.right;
xIdx++;
}
break;
default:
break;
}
}
for(int i=0; i<input_y; i++)
{
for(int j=0; j<input_x; j++)
{
System.out.print(array[i][j]+"\t");
}
System.out.println("");
}
}
}
import collections
inputX = 10
inputY = 10
directions = collections.OrderedDict()
directions["right"] = {"x":1, "y":0}
directions["down"] = {"x":0, "y":1}
directions["left"] = {"x":-1, "y":0}
directions["up"] = {"x":0, "y":-1}
def getDirection(m, cp, cd):
pos_x = cp.get("x") + cd.get("x")
pos_y = cp.get("y") + cd.get("y")
if pos_x in range(0, inputX) and pos_y in range(0, inputY):
if m[pos_y][pos_x] == -1:
return cd;
for key in directions.keys():
pos_x = cp.get("x") + directions.get(key).get("x")
pos_y = cp.get("y") + directions.get(key).get("y")
if pos_x not in range(0, inputX) or pos_y not in range(0, inputY):
continue
if m[pos_y][pos_x] == -1:
return directions.get(key);
return directions.get("right");
def move(cp, d):
cp["x"] = cp.get("x") + d.get("x")
cp["y"] = cp.get("y") + d.get("y")
return cp
def setValue(m, cp, val):
m[cp.get("y")][cp.get("x")] = val
def getMatrix():
matrix = [[-1] * inputX for i in range(inputY)]
currentPosition = {"x":0, "y":0}
currentDirection = directions.get("right")
for i in range(0, inputX * inputY):
setValue(matrix, currentPosition, i)
currentDirection = getDirection(matrix, currentPosition, currentDirection)
currentPosition = move(currentPosition, currentDirection)
return matrix
def showMatrix(matrix):
for row in matrix:
print (row)
showMatrix(getMatrix())
int array_1[1000]; int array_2[1000][1000]; int main(void) { int i,j,num1,num2, total_num, n; int flag=0;
scanf("%d %d", &num1, &num2);
total_num = num1 * num2;
for(i=0;i<total_num;i++)
{
array_1[i] = i;
// printf("%d ",array_1[i]);
}
//printf("\n");
i=0,j=0,n=0;
while(1)
{
array_2[i][j] = array_1[n];
if(flag == 0)
{
j++;
if(j==num2 || array_2[i][j] != 0)
{
flag = 1;
j--;
i++;
}
}
else if(flag == 1)
{
i++;
if(i==num1 || array_2[i][j] != 0)
{
flag=2;
i--;
j--;
}
}
else if(flag == 2)
{
j--;
if(j<0 || array_2[i][j] != 0)
{
flag=3;
j++;
i--;
}
}
else if(flag == 3)
{
i--;
if(( i<0 )|| (array_2[i][j] != 0 ) || (i==0 && j==0) )
{
flag=0;
i++;
j++;
}
}
n++;
if(n==total_num)
break;
}
for(i=0;i<num1;i++)
{
for(j=0;j<num2;j++)
{
printf("%d\t",array_2[i][j]);
}
printf("\n");
}
return 0;
}
size1, size2 = input("Enter two digits : ").split()
size1, size2 = int(size1), int(size2)
A = [[0 for a in range(0, size2)] for b in range(0, size1)]
xmin, xmax = 0, size1-1
ymin, ymax = 0, size2-1
(x, y) = (0, -1)
i = 0
while True:
if x == xmin and y == ymin-1:
while True:
y += 1
if i == size1*size2: break
A[x][y] = i
i += 1
if y == ymax:
xmin += 1
break
if x == xmin -1 and y == ymax:
while True:
x += 1
if i == size1*size2: break
A[x][y] = i
i += 1
if x == xmax:
ymax -= 1
break
if x == xmax and y == ymax + 1:
while True:
y -= 1
if i == size1*size2: break
A[x][y] = i
i += 1
if y == ymin:
xmax -= 1
break
if x == xmax + 1 and y == ymin:
while True:
x -= 1
if i == size1*size2: break
A[x][y] = i
i += 1
if x == xmin:
ymin += 1
break
if i < size1*size2:
continue
else:
break
print('', end=' ')
for row in range(size1):
for col in range(size2):
print('%2d' %A[row][col], end=' ')
print('\n', end=' ')
Enter two digits : 6 6 0 1 2 3 4 5 19 20 21 22 23 6 18 31 32 33 24 7 17 30 35 34 25 8 16 29 28 27 26 9 15 14 13 12 11 10
Enter two digits : 5 7 0 1 2 3 4 5 6 19 20 21 22 23 24 7 18 31 32 33 34 25 8 17 30 29 28 27 26 9 16 15 14 13 12 11 10
python 3.6.8로 작성함 이 코드는 정사각행렬일때만 유효함
import numpy as np
def spiral_array():
# X x Y행렬(배열)을 만들기 위한 변수 입력
x = int(input('input number x : '))
y = int(input('input number y : '))
spiral_arr = [[yi for yi in range(y)] for xi in range(x)]
spiral_arr_np = np.array(spiral_arr)
if x == y:
count = int((x + 1) / 2)
flag = 0
while count > 0:
flag_value = x - flag
print("count ", count,"flag ", flag,"flag_value ", flag_value)
#맨 오른쪽 열 채우기
for i in range(flag+1, flag_value):
spiral_arr_np[i][flag_value-1] = spiral_arr_np[flag][flag_value-1] + i - flag
print(spiral_arr_np)
print('\n')
#맨 마지막 행 채우기
for i in range(flag, flag_value-1):
spiral_arr_np[flag_value-1][i] = spiral_arr_np[flag_value-1][flag_value-1] + flag_value - (i + 1)
print(spiral_arr_np)
print('\n')
#1열 채우기
for i in range(flag+1, flag_value-1):
spiral_arr_np[i][flag] = spiral_arr_np[flag_value-1][flag] + flag_value - (1 + i)
print(spiral_arr_np)
print('\n')
# 첫 행 채우기
for i in range(flag+1, flag_value-1):
spiral_arr_np[flag+1][i] = spiral_arr_np[flag+1][flag] + i - flag
print(spiral_arr_np)
print('\n')
count -= 1
flag += 1
print(spiral_arr_np)
R로 작성했습니다 알고리즘 초보라 너무 오래걸렸네요..
function1 = function(row, col){
size.matrix = data.frame()
while(row > 0 && col > 0){
size.matrix = rbind(size.matrix, c(row, col))
row = row - 2; col = col - 2;
}
mat.list = list()
for(i in 1:nrow(size.matrix)){
mat.list[[i]] = matrix(0, nrow = size.matrix[i,1], ncol = size.matrix[i,2])
}
function2 = function(start, mat.tmp){
if(ncol(mat.tmp) == 1){
for(i in 1:nrow(mat.tmp)) mat.tmp[i,1] = start + i
}else if(ncol(mat.tmp) != 1 && nrow(mat.tmp) == 1){
for(i in 1:ncol(mat.tmp)) mat.tmp[1,i] = start + i
}else{
for(i in 1:ncol(mat.tmp)) mat.tmp[1,i] = start + i
for(i in 1:nrow(mat.tmp)) mat.tmp[i,ncol(mat.tmp)] = start + ncol(mat.tmp) + i - 1
for(i in 1:ncol(mat.tmp)) mat.tmp[nrow(mat.tmp),i] = start + ncol(mat.tmp) + nrow(mat.tmp) + (ncol(mat.tmp) - i) - 1
for(i in 2:nrow(mat.tmp)) mat.tmp[i,1] = start + 2 * ncol(mat.tmp) + nrow(mat.tmp) + (nrow(mat.tmp) - i) - 2
}
return(mat.tmp)
}
mat.list[[1]] = function2(0, mat.list[[1]])
if(length(mat.list) >= 2){
for(i in 2:length(mat.list)){
mat.tmp = mat.list[[i]]
mat.list[[i]] = function2(mat.list[[(i-1)]][2,1], mat.tmp)
}
for(k in length(mat.list):2){
for(i in 1:nrow(mat.list[[k]])){
for(j in 1:ncol(mat.list[[k]])){
mat.list[[(k-1)]][(i+1),(j+1)] = mat.list[[k]][i,j]
}
}
}
}
return(mat.list[[1]])
}
import numpy as np
num = int(input("크기를 알려주세요 : "))
# num*num 4크기의 0으로 이루어진 배열을 미리 만들어줌
box = np.zeros((num,num))
num_list = []
# 만들고 싶은 행렬에 들어가는 숫자들을 리스트로 만듬
for no in range(num**2):
num_list.append(no)
line_box = []
str_cnt = 0
# 숫자들을 치환해줄 단위로 잘라서 다시 저장해줌
for cnt in range(num*2 -1):
line_num = num - (cnt+1)//2
one_line = num_list[str_cnt:str_cnt+line_num]
line_box.append(one_line)
str_cnt += line_num
# 치환을 해줄 시작지점을 지정
str_pnt = [0,0]
# 시작지점을 기준으로 네방향으로 치환을 해주고 다음 시작지점을 정해주는 함수
for cnt in range(num*2-1):
ln_nbs = line_box[cnt]
ln_len = len(ln_nbs)
if cnt % 4 ==0:
box[str_pnt[0],str_pnt[1]:str_pnt[1] + (ln_len-1) +1] = ln_nbs
str_pnt = np.add(str_pnt,[1,ln_len-1])
elif cnt % 4 ==1:
box[str_pnt[0] : str_pnt[0]+ (ln_len-1)+1,str_pnt[1]] = ln_nbs
str_pnt = np.add(str_pnt,[ln_len-1,-1])
elif cnt % 4 ==2:
box[str_pnt[0],str_pnt[1]-(ln_len-1):str_pnt[1]+1] = list(reversed(ln_nbs))
str_pnt = np.add(str_pnt,[-1,-(ln_len-1)])
elif cnt % 4 ==3:
box[str_pnt[0] - (ln_len-1) : str_pnt[0]+1,str_pnt[1]] = list(reversed(ln_nbs))
str_pnt = np.add(str_pnt,[-(ln_len-1),1])
print(box)
package Problem_2;
import java.util.Scanner;
public class problem {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("숫자를 입력해주세요.");
int n=scan.nextInt();
int num=n*n;
//배열 생성 완료
int[][] matrix = new int[n][n];
int l=0;
int count = n*2-1;
int v=0; //행 시행 횟수
int a = 0; // 행
int v_s = 0; //행당 시작점(열)
int v_e = (n-1); //행당 끝점(열)
int h=0; //열 시행 횟수
int b = n-1; // 열
int h_s = 1; //열당 시작점(행)
int h_e = (n-1); //열당 끝점(행)
for(int j=0; j<count; j++) { //j가 2로 나누어지면 행, 나머지가 1이 나오면 열
if(j%2==0) { // 행 먼저
if(v%2==0) { //위쪽(오른쪽으로 진행)
for(int k=v_s; k <= v_e ; k++ ) {
matrix[a][k]=l;
l++;
}
//다음 연산을 위한 준비(행)
a+=((n-1)-v)*Math.pow(-1, v); //행변경
v_s+=((n-2)-v)*Math.pow(-1, v); //시작점 변경
v_e+=((n-1)-v)*Math.pow(-1, v+1); //끝점 변경
v+=1; //행 횟수 증가
}
else if(v%2!=0) { // 아래쪽(왼쪽으로 진행)
for(int k=v_s ; k >= v_e; k-- ) {
matrix[a][k]=l;
l+=1;
}
//다음 연산을 위한 준비(열)
a+=((n-1)-v)*Math.pow(-1, v); //행변경
v_s+=((n-2)-v)*Math.pow(-1, v); //시작점 변경
v_e+=((n-1)-v)*Math.pow(-1, v+1); //끝점 변경
v+=1; //행 횟수 증가
}
}
else{ // 열
if(h%2==0) { //오른쪽
for(int k=h_s; k <= h_e ; k++) {
matrix[k][b]=l;
l+=1;
}
//다음 열 연산을 위한 준비(행)
b+=((n-1)-h)*Math.pow(-1, h+1); //열 변경
h_s+=(n-3-h)*Math.pow(-1, h); //시작점 변경
h_e+=((n-2)-h)*Math.pow(-1, h+1); // 끝점 변경
h+=1; //열 횟수 증가
}
else if(h%2!=0) { //왼쪽
for(int k=h_s ; k>=h_e ; k--) {
matrix[k][b]=l;
l+=1;
}
//다음 열 연산을 위한 준비(행)
b+=((n-1)-h)*Math.pow(-1, h+1); //열 변경
h_s+=(n-3-h)*Math.pow(-1, h); //시작점 변경
h_e+=((n-2)-h)*Math.pow(-1, h+1); // 끝점 변경
h+=1; //열 횟수 증가
}
}
}
for(int i=0; i<n ;i++) {
for(int j=0; j<n; j++) {
System.out.print(matrix[i][j]+" ");
}
System.out.println(" ");
}
}
}
제곱을 제외한 내장 메소드는 전혀 이용하지 않았습니다. 그리고 코드 구현 방법은 직접 손으로 쓰는 것 처럼 하나 하나 입력하는 방식입니다.
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.print("크기를 입력하시오(6X6이면 6 엔터 6 엔터!) > ");
int width = sc.nextInt();
int length = sc.nextInt();
spiralSort(width,length);
}
public static void spiralSort(int x, int y){
int[][] array = new int[x][y];//다차원배열을 활용
int dir = 0;
int i =0, j=0, num = 0;
while(true){
switch(dir){
case 0:
array[i++][j] = num++;
if(i == x || array[i][j] != 0){
dir=1;
j++;
i--;
}
break;
case 1:
array[i][j++] = num++;
if(j == y || array[i][j] != 0){
dir=2;
j--;
i--;
}
break;
case 2:
array[i--][j] = num++;
if(i == -1 || array[i][j] != 0){
dir=3;
j--;
i++;
}
break;
case 3:
array[i][j--] = num++;
if(j == 0 || array[i][j] != 0){
dir = 0;
j++;
i++;
}
break;
}
if(num == x*y){
break;
}
}
for(j = 0; j < y; j++){
for(i = 0; i < x; i++){
System.out.print("\t" + array[i][j]);
}
System.out.println();
}
}
}
int main(void) { int up, down, left, right; int ary[10][10]; int x=0, y=0; int a, b; int i = 0; scanf("%d %d", &a, &b); right = b; down = a; left = -1; up = 0;
while (1) {
for (; y < right; y++) {
ary[x][y] = i;
i++;
}
if (i == a*b)break;
right--;
y--;
x++;
for (; x < down; x++) {
ary[x][y] = i;
i++;
}
if (i == a*b)break;
x--;
y--;
down--;
for (; y > left; y--) {
ary[x][y] = i;
i++;
}
y++;
x--;
left++;
if (i == a*b)break;
for (; x > up; x--) {
ary[x][y] = i;
i++;
}
if (i == a*b)break;
x++;
y++;
up++;
}
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
printf("%d ", ary[i][j]);
}
printf("\n");
}
}
rear = int(input("열의 수 입력 : "))
front = int(input("행의 수 입력 : "))
mul = rear * front
matrix = [[ 0 for i in range(rear)] for j in range(front)]
rCnt = 0
bCnt = 0
lCnt = 0
tCnt = 0
num = 0
while num < mul :
for right in range(tCnt, rear - rCnt) :
matrix[rCnt][right] = num
num += 1
rCnt += 1
for bottom in range(rCnt, front - bCnt) :
matrix[bottom][rear - rCnt] = num
num += 1
bCnt += 1
for left in range(bCnt, rear - lCnt) :
matrix[front - bCnt][rear - left - 1] = num
num += 1
lCnt += 1
for top in range(lCnt + 1, front - tCnt) :
matrix[front - top][tCnt] = num
num += 1
tCnt += 1
for i in range(0, front) :
for j in range(0, rear) :
print("%3d"%matrix[i][j], end=' ')
print()
import numpy as np
def make_matrix(start_num,m,n):
a = np.zeros([n,m])
a[0] = np.arange(start_num,start_num+m)
a[:,m-1] = np.arange(start_num+m-1,start_num+m-1+n)
a[-1] = np.arange(start_num+2*m-3+n, start_num+m-3+n,-1)
a[1:,0] = np.arange(start_num+2*m-5+2*n, start_num+2*m-4+n,-1)
return a
def spiral(m,n):
s = []
start = 0
for i in range(0,min(m,n),2):
if min(m,n)%2==1 and i == min(m,n)-1:
s.append(np.arange(start,start+max(m,n)-min(m,n)+1))
else:
mm = m-i
nn = n-i
s.append(make_matrix(start,mm,nn))
start += 2*(mm+nn-2)
result = s[0]
for a,i in zip(s,range(0,len(s))):
if i>=1:
result[i:-i,i:-i]=a
return result
spiral(8,5)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d", &n);
int **m = malloc(sizeof(int *)*n);
for (int i = 0; i < n; i++)
m[i] = malloc(sizeof(int)*n);
m[0][0] = 1;
for (int i = 0; i < (n + 1) / 2; i++)
{
if (i != 0)
m[i][i] = m[i - 1][i - 1] + 4 * (n + 1 - 2*i);
for (int j = 1; j < n - 2 * i; j++)
m[i][i + j] = m[i][i] + j;
for (int j = 1; j < n - 2 * i; j++)
m[i+j][n - 1 - i] = m[i][n - 1 - i] + j;
for (int j = 1; j < n - 2 * i; j++)
m[n - 1 - i][n - 1 - i - j] = m[n - 1 - i][n - 1 - i] + j;
for (int j = 1; j < n - 2 * i - 1; j++)
m[n - 1 - i - j][i] = m[n - 1 - i][i] + j;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
printf("%02d ", m[i][j]);
printf("\n");
}
for (int i = 0; i < n; i++)
free(m[i]);
free(m);
return 0;
}
이미 방문했던 칸이나, 범위를 초과했을 경우 방향을 틀어줍니다
#include <iostream>
#include <cstring>
using namespace std;
int arr[10000][10000];
bool isVisited[10000][10000];
// right, down, left, up
int dy[4] = {0, 1, 0, -1};
int dx[4] = {1, 0, -1, 0};
int turnDirection(int d)
{
return (d + 1) % 4;
}
int main()
{
int N, M;
int cur_y = 0, cur_x = 0;
int new_y, new_x;
int dir = 0;
int cnt = 1;
cin >> N >> M;
memset(isVisited, false, sizeof(bool) * 10000 * 10000);
arr[0][0] = 0;
isVisited[0][0] = true;
while(cnt < N * M)
{
new_y = cur_y + dy[dir];
new_x = cur_x + dx[dir];
if(0 > new_y || new_y >= N || 0 > new_x || new_x >= M || isVisited[new_y][new_x]){
dir = turnDirection(dir);
new_y = cur_y + dy[dir];
new_x = cur_x + dx[dir];
}
arr[new_y][new_x] = cnt;
isVisited[new_y][new_x] = true;
cur_y = new_y;
cur_x = new_x;
cnt++;
}
for(int i = 0 ; i < N ;i++)
{
for(int j = 0 ; j< M ; j++)
cout << arr[i][j] << ' ';
cout << endl;
}
return 0;
}
class Spiral:
def __init__(self, size):
self.L = [[-1 for i in range(size)] for j in range(size)]
self.size = size
self.direc = ((0,1),(1,0),(0,-1),(-1,0))
def make_spiral(self, x=0, y=0, k=0, dr=0):
self.L[x][y] = k
if k == self.size ** 2 - 1:
return
dx, dy = self.direc[dr]
nx = x + dx
ny = y + dy
if not (0<=nx<self.size) or not (0<=ny<self.size) or self.L[nx][ny] != -1:
self.make_spiral(x, y, k, (dr+1)%4)
else:
self.make_spiral(nx, ny, k+1, dr)
def display(self):
m = len(str(max(map(max, self.L))))
for x in range(self.size):
T = map(lambda x : ' ' * (m-len(str(x))) + str(x), self.L[x])
print(' '.join(T))
A = Spiral(int(input('매트릭스의 크기를 입력하세요:')))
A.make_spiral()
A.display()
python 3.6
import math
import numpy as np
m, n = map(int, input('input: ').split(' '))
num_list = [int(x) for x in range(m*n)]
output = np.zeros([m, n], dtype='int32')
for i in range(0, math.ceil(min(m, n)/2)):
try:
output[i, i:n-i] = num_list[:(n-2*i)]
output[i+1:m-i, -1-i] = num_list[(n-2*i):(n-2*i)+(m-2*i-1)]
output[-1-i, i:n-i-1] = num_list[(n-2*i)+(m-2*i-1):(n-2*i)+(m-2*i-1)+(n-2*i-1)][::-1]
output[i+1:m-i-1, i] = num_list[(n-2*i)+(m-2*i-1)+(n-2*i-1):(n-2*i)+(m-2*i-1)+(n-2*i-1)+(m-2*i-2)][::-1]
except ValueError:
pass
num_list = num_list[(n-2*i)+(m-2*i-1)+(n-2*i-1)+(m-2*i-2):]
for j in output:
length = len(str(m*n-1))
output_str = ['{0:>{1}}'.format(a, length) for a in j]
print(' '+' '.join(output_str))
input_x, input_y= input().split()
xmaximum,ymaximum = int(input_x), int(input_y)
matrix = [[0 for col in range(ymaximum)]for row in range(xmaximum)]
x,y = 0,0
d = 0
k =0
for value_k in range(0, xmaximum*ymaximum):
if k==0 :
matrix[x][y] = value_k
y+=1
if y == ymaximum-1-d :
k=1
elif k==1 :
matrix[x][y] = value_k
x+=1
if x == xmaximum-1-d :
k=2
elif k==2 :
matrix[x][y] = value_k
y-=1
if y == d :
k=3
elif k==3 :
matrix[x][y] = value_k
x-=1
if x == d :
d+=1
x,y = d,d
k=0
for row in matrix :
print (row)
```
x,y는 각각 2중 배열의 좌표를 표현 하며, 입력 받은 xmaximum, ymaximum 에 따라 0으로 가득찬 배열을 생성합니다.
파이썬 자체에는 case문이 없기에, 변수 k를 추가하여 0→1→2→3→0....순으로 반복하게 만들었습니다
d는 한바퀴 돌때 바다 1씩 증가(심도)함을 나타내고
x,y = d,d 는 한바퀴를 마칠때 마다 다음 바퀴의 시작점을 설정하기 위함입니다.
k = 0, k=1에서의 xmaximum-1 , ymaximum-1 은 index의 길이를 넘어가는 것을 방지하기 위함입니다.
파이썬 3.7.2
A = input("X축과 Y축의 길이를 입력하세요.\n> ").split(" ")
X = int(A[0])
Y = int(A[1])
m = []
for x in range(X):
m.append([])
for y in range(Y):
m[x].append(0)
x, y = 0, 0
move = "Right"
for n in range(X*Y):
m[y][x] = n
if move == "Right":
if x+1 == X or m[y][x+1] != 0:
move = "Down"
y += 1
else: x += 1
elif move == "Down":
if y+1 == Y or m[y+1][x] != 0:
move = "Left"
x -= 1
else: y += 1
elif move == "Left":
if x-1 == -1 or m[y][x-1] != 0:
move = "Up"
y -= 1
else: x -= 1
elif move == "Up":
if y-1 == -1 or (x == 0 and y-1 == 0) or m[y-1][x] != 0:
move = "Right"
x += 1
else: y -= 1
for n in range(len(m)):
print(str(m[n])[1:len(str(m[n]))-1])
처음 코드올려봅니다... 공부많이해야겠네요 ㅎㅎㅎ 근데 혹시 이중 배열의 포인터를 함수의 입력변수로 받아서 함수 내부에서 이중배열처럼 쓸수는 없나요? 해보니까 잘 안되서요...
#include <stdio.h>
/*
(x, y)
direction : east, south, west, north
east : increase (x)
west : decrease (x)
north : increase (y)
south : decrease (y)
*/
typedef struct
{
int xPos;
int yPos;
}pointType;
void East(pointType *p, int *count)
{
p->xPos++;
}
void West(pointType *p, int *count)
{
p->xPos--;
}
void South(pointType *p, int *count)
{
p->yPos++;
}
void North(pointType *p, int *count)
{
p->yPos--;
}
typedef void(*pfunc)(pointType *p, int *count);
pfunc funcList[4] = { East , South , West , North };
void Snake(int m, int n)
{
int count = 0;
int funCount = 0;
pointType p;
p.xPos = 0;
p.yPos = 0;
int decreaseN = n - 1;
int decreaseM = m - 1;
//make n x m array
int **arr = (int **)malloc((sizeof(int *))*n);
for(int i = 0; i<n; i++)
{
arr[i] = (int *)malloc((sizeof(int))*m);
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m;j++)
{
arr[i][j] = 0;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m;j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
printf("\n");
//do first step
for (int i = 0; i < m - 1; i++)
{
funcList[funCount % 4](&p, &count);
arr[p.yPos][p.xPos] = ++count;
}
funCount++;
//do second step
while (decreaseN != 0 && decreaseM != 0)
{
for (int i = 0; i < decreaseN; i++)
{
funcList[funCount % 4](&p, &count);
arr[p.yPos][p.xPos] = ++count;
}
decreaseN--;
funCount++;
for (int i = 0; i < decreaseM; i++)
{
funcList[funCount % 4](&p, &count);
arr[p.yPos][p.xPos] = ++count;
}
funCount++;
decreaseM--;
}
// the rest
if (decreaseN != 0)
{
for (int i = 0; i < decreaseN; i++)
{
funcList[funCount % 4](&p, &count);
arr[p.yPos][p.xPos] = ++count;
}
}
else if(decreaseM != 0)
{
for (int i = 0; i < decreaseM; i++)
{
funcList[funCount % 4](&p, &count);
arr[p.yPos][p.xPos] = ++count;
}
}
else
{
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
}
int main()
{
int a, b;
scanf("%d %d", &a, &b);
Snake(a, b);
return 0;
}
//if 안쓰려고 온갖 노력을 해봤는데... 제 대굴빡은 빠가인가봅니다. //더이상은 naver...
int main() { int Width = 0,Height = 0; int OffsetX = 1, OffsetY = 0, PosX = 0, PosY = 0;
std::cin >> Width;
std::cin >> Height;
int* Vortex = new int[Width*Height];
std::fill_n(Vortex, Width*Height, -1);
for(int i=0;i<Width*Height;i++)
{
if (PosX + OffsetX < 0 || PosY + OffsetY < 0 ||
PosX + OffsetX > Width - 1 || PosY + OffsetY > Height - 1 ||
Vortex[(PosX + OffsetX) + ((PosY + OffsetY) * Width)] != -1)
{
OffsetY = OffsetX = 0;
if (PosY + 1 < Height-1 && Vortex[PosX + ((PosY+1) * Width)] == -1)
{
OffsetY = 1;
}
else if(PosX - 1 > 0 && Vortex[(PosX -1) + (PosY * Width)] == -1)
{
OffsetX = -1;
}
else if (PosX + 1 < Width -1 && Vortex[(PosX+1)+(PosY * Width)] == -1)
{
OffsetX = 1;
}
else if (PosY -1 > 0 && Vortex[PosX+((PosY-1) * Width)] == -1)
{
OffsetY = -1;
}
}
Vortex[PosX + (PosY * Width)] = i;
PosX += OffsetX;
PosY += OffsetY;
}
for (int j = 0; j < Height; j++)
{
for (int i = 0; i < Width; i++)
{
std::cout << Vortex[i + (j * Width)] << "\t";
}
std::cout << "\n";
}
}
import java.util.Scanner;
public class go {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
System.out.print("숫자를 입력하세요 ex) 6 6 : ");
int num1 = sc.nextInt();
int num2 = sc.nextInt();
spiralArray(num1, num2);
}
public static void spiralArray(int x, int y) {
int[][] copy = new int[x][y];
int count = 0; // 0 ~ x*y-1 값
int flag = 0; // 진행방향
int i = 0, j = 0;
while (true) {
switch (flag) { // 진행방향 ->
case 0: // 방에 값을 넣고 1 증가 시킴
copy[i][j++] = count++; // 다음 방향으로 한칸 이동
if (j == y || copy[i][j] != 0) { // 이동한 방에 값이 있거나 방이 없으면
j--; // 이전 방으로 돌아온다
i++; // 다음 진행할 방향으로 한칸이동
flag = 1; // 진행방향 설정
}
break;
case 1: // 진행방향 ↓
copy[i++][j] = count++;
if (i == x || copy[i][j] != 0) {
i--;
j--;
flag = 2;
}
break;
case 2: // 진행방향 <-
copy[i][j--] = count++;
if (j == -1 || copy[i][j] != 0) {
i--;
j++;
flag = 3;
}
break;
case 3: // 진행방향 ↑
copy[i--][j] = count++;
if (i == 0 || copy[i][j] != 0) {
i++;
j++;
flag = 0;
}
break;
}
if (count == x * y) // 모든방에 값이 들어가면 나가기
break;
}
for (i = 0; i < x; i++) {
for (j = 0; j < y; j++) {
System.out.print(copy[i][j] + "\t");
}
System.out.println();
}
}
}
def tornado(a,b):
x,y=-1,0
k = np.zeros((a,b))
c=iter(range(0,a*b))
while(1):
if a>0 and b>0:
try:
for i1 in range(b):
x+=1
k[y,x] = next(c)
for i2 in range(a-1):
y+=1
k[y,x] = next(c)
for i3 in range(b-1):
x-=1
k[y,x] = next(c)
for i4 in range(a-2):
y-=1
k[y,x] = next(c)
except:pass
a-=2
b-=2
else: break
return k
양지훈님 알고리즘을 보고 감동해서 C++로 짜봤습니다.
#include<iostream>
#include<vector>
using namespace std;
int main() {
int tmpA, tmpB;
int X, Y;
cin >> tmpA;
cin >> tmpB;
if (tmpA <= 0 || tmpB <= 0) { return 0; }//잘못된 입력이면 프로그램 종료
X = tmpA, Y = tmpB;
vector<vector<int>> arr;
arr.assign(Y, vector<int>(X, 0));//X*Y 벡터 0으로 초기화
int x = 0, y = 0;//인덱스
int max_num = X * Y;
int dx = 1, dy = 0;
for(int cnt=1; cnt<=max_num;cnt++){
arr[y][x] = cnt;
int tmp_x = x + dx,tmp_y=y + dy ;
if (tmp_x<0 || tmp_x>=X || tmp_y<0 || tmp_y>=Y || arr[tmp_y][tmp_x]!=0) {//인덱스가 범위를 넘거나 이미 지나간 길에 만나면
int tmp=dx;
dx = -1*dy;//방향전환, dy에 -1배한걸 dx에, dx를 dy에 대입
dy = tmp;
x += dx;
y += dy;
}
else {//그 외 경우
x = tmp_x;
y = tmp_y;
}
}
cout << endl;
//arr 출력
for (vector<int> v : arr) {
for (int x : v) {
cout.width(3);//정렬
cout << x << " ";
}
cout << endl;
}
return 0;
}
```a=[]
count=0
number=5
remember=5
lastnumber =5
for i in range(36):
a.append(0)
for i in range(6):
a[i]=i
for j in range(10):
if j%4==0:
for e in range(number):
lastnumber += 1
remember += 6
a[remember]=lastnumber
if j%4==1:
for b in range(number):
lastnumber += 1
remember -= 1
a[remember]=lastnumber
number-=1
if j%4==2:
for c in range(number):
lastnumber += 1
remember -= 6
a[remember]=lastnumber
if j%4==3:
for d in range(number):
lastnumber += 1
remember += 1
a[remember]= lastnumber
number-=1
for result in range(36):
print(a[result],end=" ")
if result%6==5:
print('')```{.python}
package spiralmatrix;
import java.util.Scanner;
public class spiralmatrix {
static int moveleft = 0;
static int movedown = 1;
static int moveright = 2;
static int moveup = 3;
public static void main(String args[]) {
Scanner input = new Scanner(System.in);
System.out.print("매트릭스의 크기 입력 : ");
int size = input.nextInt();
int matrix[][] = new int[size][size];
int top = 0, bottom = size - 1, right = 0, left = size - 1;
int i = 0, j = 0;
int move = moveleft;
for (int num = 0; num < size * size; num++) {
matrix[i][j] = num;
//System.out.println("matrix[" + i + "][" + j + "] = " + num);
if (move == moveleft) {
j++;
if (j == left) {
move = movedown;
top++;
}
}
else if (move == movedown) {
i++;
if (i == bottom) {
move = moveright;
left--;
}
}
else if (move == moveright) {
j--;
if (j == right) {
move = moveup;
bottom--;
}
}
else if (move == moveup) {
i--;
if (i == top) {
move = moveleft;
right++;
}
}
}
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
System.out.printf("%3d", matrix[i][j]);
}
System.out.println();
}
}
}
4가지 이동방향을 정해놓고 위,아래,왼쪽,오른쪽 벽에 다다르면 벽을 좁히고 방향을 시계방향으로 바꿔서 이동하도록 했어요
def spiral(nx, ny):
s = [[-1 for i in range(ny)] for j in range(nx)]
x, y = 0, 0
dx, dy = 0, 1
num = 0
while s[x][y] == -1:
s[x][y] = num
x, y = x+dx, y+dy
num += 1
if y >= ny or x >= nx or s[x][y] != -1:
x, y = x-dx, y-dy
dx, dy = dy, -dx
x, y = x+dx, y+dy
return s
arr_res = spiral(6, 6)
for arr_i in arr_res:
for i in arr_i:
print('%4d' % i, end='')
print()
public class spiralArray {
static int range=6;
static int[][] spiralarr = new int[range][range];
void spiral() {
int num=1, x=0, y=0, condition=0, reverse=-1, exit=0;
for(int i = 0; i<range; i++) {
for(int j = 0; j<range; j++) {
spiralarr[i][j]=0;
}
}
spiralarr[x][y]=num++;
while(exit==0 && range>1) {
switch(condition%2) {
case 0:
reverse*=-1;
if(spiralarr[x][y+reverse]!=0) {
exit=1;
break;
}
while(true) {
if((y+reverse)>=spiralarr[x].length || (y+reverse)<0 || spiralarr[x][y+reverse]!=0) {
condition++;
break;
}
y+=reverse;
spiralarr[x][y]=num++;
}
break;
case 1:
if(spiralarr[x+reverse][y]!=0) {
exit=1;
break;
}
while(true) {
if((x+reverse)>=spiralarr.length || (x+reverse)<0 || spiralarr[x+reverse][y]!=0) {
condition++;
break;
}
x+=reverse;
spiralarr[x][y]=num++;
}
break;
}
}
}
void printarr() {
for(int i=0; i<spiralarr.length; i++) {
for(int j=0; j<spiralarr[0].length; j++) {
if(spiralarr[i][j]<10) System.out.print(" ");
System.out.print(spiralarr[i][j] + " ");
}
System.out.println("");
}
}
public static void main(String[] args) {
spiralArray spi = new spiralArray();
spi.spiral();
spi.printarr();
}
}
X = 9
Y = 7
dirMat = [[1,0], [0,1], [-1,0], [0,-1]]
sMat = [[-1 for i in range(X)] for j in range(Y)]
curDir = 0
posX = 0
posY = 0
for n in range(X*Y):
sMat[posY][posX] = n
if posX+dirMat[curDir][0] in [-1,X] and abs(dirMat[curDir][0]) != 0 or posY+dirMat[curDir][1] in [-1,Y] and abs(dirMat[curDir][1]) != 0 or sMat[posY+dirMat[curDir][1]][posX+dirMat[curDir][0]] != -1:
curDir += 1
curDir %= 4
posX += dirMat[curDir][0]
posY += dirMat[curDir][1]
for x in sMat:
print(x)
import java.util.Scanner;
public class sol002 {
static int arr[][];
public static void solution(int x, int y) throws Exception {
arr = new int[x][y];
int flag = 0;
int count = 0;
int st_x = 0, st_y = 0;
for(int i=0; i<arr.length; i++) {
for(int j=0; j<arr[i].length; j++) {
arr[i][j] = -1;
}
}
while(true) {
if(count >= x * y) break;
switch(flag) {
case 0:
arr[st_x][st_y] = count++;
if(st_y == arr[st_x].length-1 || arr[st_x][st_y+1] >= 0) {
flag = 1;
st_x++;
} else {
st_y++;
}
break;
case 1:
arr[st_x][st_y] = count++;
if(st_x == arr.length-1 || arr[st_x+1][st_y] >= 0) {
flag = 2;
st_y--;
} else {
st_x++;
}
break;
case 2:
arr[st_x][st_y] = count++;
if(st_y == 0 || arr[st_x][st_y-1] >= 0) {
flag = 3;
st_x--;
} else {
st_y--;
}
break;
case 3:
arr[st_x][st_y] = count++;
if(st_x == 0 || arr[st_x-1][st_y] >= 0) {
flag = 0;
st_y++;
} else {
st_x--;
}
break;
}
}
for(int i=0; i<arr.length; i++) {
for(int j=0; j<arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int y = sc.nextInt();
solution(x,y);
}
}
배열의 동적할당 부분은 다른분 알고리즘을 참고로 하여 작성하였습니다.
#include <stdio.h>
#include <stdlib.h>
void main {
int x, y, x2, y2, c;
int k, z;
printf("행열을 입력하세요 (x, y) : ");
scanf_s("%d, %d", &x, &y);
int** arr;
arr = (int**)malloc(sizeof(int*)*x);
for (int i = 0; i < x; i++) arr[i]=(int*)malloc(sizeof(int)*y);
for (int i = 0; i < x; i++) { //arr 행렬을 -1로 초기화
for (int j = 0; j < y; j++) arr[i][j] = -1;
}
x2 = 0, y2 = 0;
k = 1, z = 0;
while (z<x*y) {
while(y2<y && y2>=0 && arr[x2][y2] < 0) { //행(→,←) 방향 숫자 정하기
arr[x2][y2] = z;
z++, y2 += k;
}
y2 -= k, x2 += k;
while (x2 < x && x2 >= 0 && arr[x2][y2] < 0) { //열(↑,↓) 방향 숫자 정하기
arr[x2][y2] = z;
z++, x2 += k;
}
x2 -= k, y2 -= k;
k = k*(-1); //숫자 방향 상수 (정or역 방향)
}
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) printf("%d \t", arr[i][j]);
printf("\n");
}
scanf_s("%d", &c);
}
#include <iostream>
using namespace std;
void in_arr_data(int** arr, int ,int );
void print_data(int** arr, int num1, int num2);
int main()
{
int **arr;
int num1, num2;
cout << "숫자 2개 입력: ";
cin >> num1; cin >> num2;
arr = new int*[num1];
for (int i = 0; i < num1; i++)
{
arr[i] = new int[num2] ;
}
for (int i = 0; i < num1; i++)
{
for (int j = 0; j < num2; j++)
arr[i][j] = 0;
}
in_arr_data(arr, num1, num2);
print_data(arr, num1, num2);
}
void in_arr_data(int **arr, int num1, int num2)
{
int low = 0, cal = -1;
int low_p , cal_p ;
int num = 0;
int a = 1;
int k = 1;
int l = num1, m = num2;
while (num1 > 0 && num2 > 0)
{
/*---방향 초기화---*/
if (a > 0)
{
cal_p = 1;
low_p = 1;
}
else
{
cal_p = -1;
low_p = -1;
}
/*---가로---*/
for (int i = 0; i < num2; i++)
{
cal += cal_p;
arr[low][cal] = num++;
}
num1 = num1 - 1;
num2 = num2 - 1;
/*---세로----*/
for (int i = 0; i < num1; i++)
{
low += low_p;
arr[low][cal] = num++;
}
/*---방향 변경---*/
a = a * (-1);
}
}
void print_data(int** arr, int num1, int num2)
{
for (int i = 0; i < num1; i++)
{
for (int j = 0; j < num2; j++)
cout << arr[i][j] << " ";
cout << "\n";
}
}
C#
class Program
{
public enum DIR
{
RIGHT,
DOWN,
LEFT,
UP
}
static void Main(string[] args)
{
int X, Y;
string[] size;
// 배열 크기 입력
Console.Write("크기입력(X Y) : ");
size = Console.ReadLine().Split(" ");
X = int.Parse(size[0]);
Y = int.Parse(size[1]);
int[,] SPI = new int[X, Y];
DIR dir = DIR.RIGHT; // 초기값
int CNT = 0;
int x = 0, y = 0;
bool wr = true;
while (CNT < X * Y)
{
if (wr)
{
CNT++;
SPI[x, y] = CNT;
wr = false;
}
if (dir == DIR.RIGHT)
{
if (x + 1 > X - 1)
dir = DIR.DOWN;
else if(SPI[x + 1, y] != 0)
dir = DIR.DOWN;
else
{
x += 1;
wr = true;
}
}
if (dir == DIR.DOWN)
{
if (y + 1 > Y - 1)
dir = DIR.LEFT;
else if(SPI[x, y + 1] != 0)
dir = DIR.LEFT;
else
{
y += 1;
wr = true;
}
}
if (dir == DIR.LEFT)
{
if (x - 1 < 0)
dir = DIR.UP;
else if (SPI[x - 1, y] != 0)
dir = DIR.UP;
else
{
x -= 1;
wr = true;
}
}
if (dir == DIR.UP)
{
if (y - 1 < 0)
dir = DIR.RIGHT;
else if (SPI[x, y - 1] != 0)
dir = DIR.RIGHT;
else
{
y -= 1;
wr = true;
}
}
}
for (int i = 0; i < Y; i++)
{
for(int j=0; j < X; j++)
{
Console.Write("{0:00} ", SPI[j, i]);
}
Console.WriteLine();
}
}
}
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
using namespace std;
//template <class t>;
int _ArrayFunc(int srcRow, int srcCol)
{
int **spiral = new int*[srcRow];
for(int i = 0; i < srcCol ; i++){
spiral[i] = new int[srcCol];
}
int cnt = -1;
int max = srcRow * srcCol -1 ;
int lastCol = srcCol - 1, lastRow = srcRow -1;
int startCol= 0 , startRow = 0;
int currentRow = 0, currentCol = 0;
while(cnt != max){
for(int j = startCol ; j <= lastCol; j++){
printf("cnt : %d\n", cnt);
cnt++;
spiral[startRow][j] = cnt;
}
if(cnt == max)
break;
for(int i = startRow + 1; i <= lastRow; i++){
printf("cnt : %d\n", cnt);
cnt++;
spiral[i][lastCol] = cnt;
}
if(cnt == max)
break;
for(int j = lastRow - 1; j >= startCol; j--){
printf("cnt : %d\n", cnt);
cnt++;
spiral[lastRow][j] = cnt;
}
if(cnt == max)
break;
for(int i = lastRow - 1; i > startRow; i--){
printf("cnt : %d\n", cnt);
cnt++;
spiral[i][startCol] = cnt;
}
if(cnt == max)
break;
lastCol--, lastRow--, startRow++, startCol++;
}
for(int k =0 ; k < srcRow; k++){
for(int l = 0; l < srcCol; l++){
cout << spiral[k][l] << " ";
}
cout << endl;
}
//delete
for(int i = srcCol - 1 ; i > 0 ; i--)
delete [] spiral[i];
//delete
delete [] spiral;
//
return 0;
}
int main(void)
{
int row , col = 0;
scanf("%d,%d", &row, &col);
_ArrayFunc(row, col);
return 0;
}
어려워서 다른분의 것을 거의..... 조만간 수정을 하겠습니다.
size = input('Enter the size(r c): ')
l = size.split(' ')
m = int(l[0].strip()); n=int(l[1].strip())
board = []
for i in range(m):
board.append([' ']*n)
def next(d, x, y):
if d == 1:
if y != n-1 and board[x][y+1] == ' ': return (1, x, y+1)
else: return (2, x+1, y)
elif d == 2:
if x!=m-1 and board[x+1][y] == ' ': return (2, x+1, y)
else: return (3, x, y-1)
elif d == 3:
if y != 0 and board[x][y-1] == ' ': return (3, x, y-1)
else: return (4, x-1, y)
else:
if x != 0 and board[x-1][y] == ' ': return (4, x-1, y)
else: return (1, x, y+1)
def print_board(b):
for x in b:
for y in x:
print('{:>2}'.format(y), end = ' ')
print('\n')
d=1;x=0;y=0
for i in range(m*n):
board[x][y] = i
d, x, y = next(d, x, y)
print_board(board)
Python 3.7
X, Y = list(map(int, input().split(' ')))
mtx = [['a']*Y for i in range(X)]
lis =[' '*(len(str(X*Y))-len(str(i))+1)+str(i) for i in range(0,X*Y)]
x, y = 0, 0
dx, dy = 0, 1
for i in lis:
mtx[x][y] = i
if x+dx in [-1, X] or y+dy in [-1, Y] or mtx[x+dx][y+dy] != 'a':
dx, dy = dy, -dx
x, y = x+dx, y+dy
print('\n'.join([' '.join(i) for i in mtx]))
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
PHP
$cols = 6;
$rows = 6;
$arr = [];
[$x, $y, $cycle, $len, $vectors] = [0, 0, 0, 0, '→']; // x값, y값, 바퀴 수, 길이, 방향
// 키값 미리 셋팅 (배열 사이즈 설정)
foreach (range(0, $rows - 1) as $i) {
foreach (range(0, $cols - 1) as $j) {
$arr[$i][$j] = 0;
}
}
// 값 설정
foreach (range(0, $rows * $cols - 1) as $i) {
$arr[$x][$y] = $i;
if ($vectors === '→') {
$y++;
if ($y === $cols - $cycle - 1) {
$vectors = '↓';
}
}
else if ($vectors === '↓') {
$x++;
if ($x === $rows - $cycle - 1) {
$vectors = '←';
}
}
else if ($vectors === '←') {
$y--;
if ($y === $cycle) {
$vectors = '↑';
$cycle++;
}
}
else if ($vectors === '↑') {
$x--;
if ($x === $cycle) {
$vectors = '→';
}
}
$len = strlen($i);
}
// 출력
$result = "";
foreach ($arr as $val) {
foreach ($val as $v) {
$result .= sprintf(' %s ', str_pad($v, $len, ' ', STR_PAD_LEFT));
}
$result .= PHP_EOL;
}
echo '<pre>'.print_r($result, true).'</pre>';
/*
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
*/
# 1. 입력
X, Y = map(int, input("사이즈(X, Y)를 입력하세요. : ").split(' '))
# 2. 시작점, 방향, 매트릭스 값을 초기화
x, y = 0, 0
dx = (1, 0, -1, 0)
dy = (0, 1, 0, -1)
direction = 0
l = [[-1 for i in range(X)] for j in range(Y)]
cnt = 0
# 3. 매트릭스를 나선형 회전한 값으로 채움
while l[y][x] == -1: # 현위치의 값이 -1이 아닐때까지 반복
l[y][x] = cnt # 현위치의 값을 입력
cnt += 1 # 값을 1 증가
x, y = x + dx[direction], y + dy[direction] # 위치 증가
if (x in [-1, X]) or (y in [-1, Y]) or (l[y][x] != -1): # 새로운 위치가 경계를 벗어나거나 새로운 위치의 값이 -1이 아니면
x, y = x - dx[direction], y - dy[direction] # 이전 위치로 복구
direction = (direction + 1) % 4 # 시계방향으로 방향값 변경
x, y = x + dx[direction], y + dy[direction] # 새로운 위치로 변경
# 4. 결과 프린트
for j in range(Y):
for i in range(X):
print("{0:>2}".format(l[j][i]), end=' ')
print("")
def fillOuter(lis, row, col, rowLen, colLen, currentNum, maxNum):
if currentNum > maxNum:
return
r, c = row, col
while c < colLen and currentNum <= maxNum:
lis[r][c] = currentNum
c += 1
currentNum += 1
c -= 1
r += 1
while r < rowLen-1 and currentNum <= maxNum:
lis[r][c] = currentNum
r += 1
currentNum += 1
while c >= col and currentNum <= maxNum:
lis[r][c] = currentNum
c -= 1
currentNum += 1
c += 1
r -= 1
while r > row and currentNum <= maxNum:
lis[r][c] = currentNum
r -= 1
currentNum += 1
fillOuter(lis, row+1, col+1, rowLen-1, colLen-1, currentNum, maxNum)
return currentNum
print("enter the matrix size:")
c, r = map(int, input().split())
maxNum = r * c - 1
row, column = 0, 0
lis = [[-1 for col in range(0, c)] for row in range(0, r)]
currentNum = fillOuter(lis, 0, 0, r, c, 0, maxNum)
for row in lis:
for elem in row:
print('%4d'%elem, end=" ")
print('\n')
public static void Main()
{
var args = Console.ReadLine().Split(' ');
int W = int.Parse(args[1]), H = int.Parse(args[0]);
int[] arr = new int[W * H], dist = new[] { 1, W, -1, -W };
int i = -1, j = 0, k = -1, cnt = 0, w = W;
while (cnt-- > 1 || (cnt = ++k % 2 == 0 ? W-- : --H) > 0)
arr[i += dist[k % 4]] = j++;
for (i = 0; i < arr.Length; i++)
Console.Write("{0,3}" + ((i + 1) % w == 0 ? "\n" : " "), arr[i]);
}
입력: 6 6
출력:
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
#행렬 입력받기
row, column = map(int,input('Enter how many row and column of the matrix is : ').split())
#입력받은 행렬보다 2칸씩 더큰 행렬로 채운뒤 모서리 부분은 True, 나머지는 False로 채워넣었습니다.
result_matrix = []
for i in range(0,column+2):
result_matrix.append([])
for j in range(0,row+2):
result_matrix[i].append(False)
if i == 0 or j == 0 or i == column+1 or j == row+1:
result_matrix[i][j] = True
number = 0
order_row = 1
order_column = 1
#오른쪽, 아래, 왼쪽, 위의 패턴대로 False면 숫자를 채우고 True를 만나면 방향을 바꿉니다.
while number < row * column:
while not result_matrix[order_row][order_column]:
result_matrix[order_row][order_column] = str(number)
number += 1
order_column += 1
order_column -= 1
order_row += 1
while not result_matrix[order_row][order_column]:
result_matrix[order_row][order_column] = str(number)
number += 1
order_row += 1
order_column -= 1
order_row -= 1
while not result_matrix[order_row][order_column]:
result_matrix[order_row][order_column] = str(number)
number += 1
order_column -= 1
order_column += 1
order_row -= 1
while not result_matrix[order_row][order_column]:
result_matrix[order_row][order_column] = str(number)
number += 1
order_row -= 1
order_column += 1
order_row += 1
for i in range(1,column+1):
print('\n')
for j in range(1,row+1):
print(result_matrix[i][j],end = ' ')
다른 고수 분들의 풀이를 알아볼 수가 없어서 최대한 기초 문법만을 사용해 답을 구해봤습니다. 만들려는 행렬보다 2씩 더큰 행렬을 만든뒤 모서리에 True라는 벽을 만들어 벽을 만나면 회전하도록 해봤습니다. 코딩 초보라서 더 간단하게는 못만들겠네요ㅜㅜ
어떻게 다들 그렇게 잘하시나요.. 야매코딩 갑니다 왜 돌아가는지 몰라유
import copy
row = int(input('행 : '))
col = int(input('열 : '))
row_end = copy.copy(row)
col_end = copy.copy(col)
matrix = [[0]*col for i in range(row)]
row_start = 0
col_start = 0
n = -1
rotation = 0
def chk():
print('\n#%d\n' %rotation)
for i in range(row):
for j in range(col):
print("{0:<4}".format(matrix[i][j]), end=' ')
print('')
print('\n-------------------------')
while True:
#1
if rotation == row * col:
break
for i in range(col_start, col_end):
n += 1
matrix[row_start][i] = n
row_start +=1
rotation += 1
chk()
#2
if rotation == row * col:
break
for i in range(row_start,row_end):
n += 1
matrix[i][col_end-1] = n
col_end -=1
rotation += 1
chk()
#3
if rotation == row * col:
break
for i in range(col_end-1,col_start-1,-1):
n+=1
matrix[row_end-1][i] = n
row_end -=1
rotation += 1
chk()
#4
if rotation == row * col:
break
for i in range(row_end-1,row_start-1,-1):
n+=1
matrix[i][col_start] = n
col_start +=1
rotation += 1
chk()
list comprehension을 통해 좀 더 짧게표현가능하지만.. 하지않겠다 ㅠㅠ
import numpy as np
x, y = map(int, input("Enter numbers :").split())
mat = np.zeros((x,y))
mat[0,0] = 1
current_location = [0,0]
num = 2
# x <= y 일 시 : 2*x - 1 번 순환
# x > y 일 시 : 2*y 번 순환
if x > y:
loop = 2 * y
else:
loop = 2 * x - 1
for i in range(loop):
direction = i % 4
if direction == 0: #순방향 x
for j in range(current_location[1] + 1, y):
mat[current_location[0], j] = num
num += 1
current_location[1] = j
y -= 1
elif direction == 1: #순방향 y
for j in range(current_location[0] + 1, x):
mat[j, current_location[1]] = num
num += 1
current_location[0] = j
x -= 1
elif direction == 2: #역방향 x
for j in reversed(range((i+1)//4, current_location[1])):
mat[current_location[0], j] = num
num += 1
current_location[1] = j
else: #역방향 y
for j in reversed(range((i+1)//4, current_location[0])):
mat[j, current_location[1]] = num
num += 1
current_location[0] = j
print(mat)
package d002_spiral_array;
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int i, j, n, direct=0; //direct: 방향
System.out.println("input the height and width of the array:");
int X=sc.nextInt();
int Y=sc.nextInt();
System.out.println("You inputted:"+X+" "+Y+".");
int[][] array=new int[X][Y];
for(i=0; i<X; i++)
for(j=0; j<Y; j++) array[i][j]=-1; //-1로 배열 초기화
i=0;
j=-1;
for(n=0; n<X*Y; n++) {
if(direct==0) { //direct==0이면 오른쪽 방향
if(j<Y-1 && array[i][j+1]==-1) array[i][++j]=n;
else {
direct=1; //방향 바꾸기
n--;
}
}
else if(direct==1) { //direct==1이면 아래쪽 방향
if(i<X-1 && array[i+1][j]==-1) array[++i][j]=n;
else {
direct=2; //방향 바꾸기
n--;
}
}
else if(direct==2) { //direct==2이면 왼쪽 방향
if(j>0 && array[i][j-1]==-1) array[i][--j]=n;
else {
direct=3; //방향 바꾸기
n--;
}
}
else if(direct==3) { //direct==3이면 위쪽 방향
if(array[i-1][j]==-1) array[--i][j]=n;
else {
direct=0; //방향 바꾸기
n--;
}
}
}
for(i=0; i<X; i++) { //출력
for(j=0; j<Y; j++) {
if(array[i][j]<10) System.out.print(" "); //최고자릿수가 세자릿수일 때 최적화 된 경우
else if(array[i][j]<100) System.out.print(" ");
System.out.print(array[i][j]+" ");
}
System.out.println(" ");
}
}
}
import java.util.Scanner;
public class ArrayQuiz {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int b = scanner.nextInt();
int a2 = a;
int b2 = b;
int z = 0;
int z2 = 1;
int i = 0, j = 0;
int sw = 0;
int count = 0;
int [][] result = new int [a][b];
while(true) {
if(sw == 0) {
result[i][j] = count;
count++;
j++;
if(j == b - 1) {
sw = 1;
b -= 1;
}
}
else if(sw == 1) {
result[i][j] = count;
count++;
i++;
if(i == a - 1) {
sw = 2;
a -= 1;
}
}
else if(sw == 2) {
result[i][j] = count;
count++;
j--;
if(j == z) {
sw = 3;
z += 1;
}
}
else if(sw == 3) {
result[i][j] = count;
count++;
i--;
if(i == z2) {
sw = 0;
z2 += 1;
}
}
if(count == a2 * b2)
break;
}
for(int i2 = 0; i2 < a2; i2++) {
for(int j2 = 0; j2 < b2; j2++) {
System.out.print(result[i2][j2]+" ");
}
System.out.println();
}
}
}
다른 분들 풀이 보니 아직 많이 부족한 실력이네요 ㅠㅠ
def Spiral(n):
arr = []
for i in range(n):
arr.append([0]*n)
count = n
i = 0
k = -1
num = 0
change = 1
flag = 1
for z in xrange(count):
for y in xrange(count):
num = num + 1
if flag:
k = k + change
else:
k = k - change
arr[i][k] = num
count = count - 1
for q in xrange(count):
num = num + 1
if flag:
i = i + change
else:
i = i - change
arr[i][k] = num
if flag == 0:
flag = 1
else:
flag = 0
str1 = ""
for w in xrange(n):
for r in xrange(n):
if len(str(arr[w][r])) == 1:
arr[w][r] = "0"+str(arr[w][r])
str1 = str1 + " " + str(arr[w][r])
str1 = str1+str("\n")
print str1
def vec(dxdy1) : # 방향 전환 ; 튜플 형태로 (dx, dy)를 받아 회전한 결과를 튜플 형태(dx', dy')로 반환
dxdy_LIST = [(1, 0), (0, 1), (-1, 0), (0, -1)]
return dxdy_LIST[(int(dxdy_LIST.index(dxdy1))+1)%4]
inp = list(map(int, input('INPUT : ').split(" ")))
result, dxdy, x, y, respri = [], (1, 0), 0, 0, ''
for a in range(0, inp[1]) :
result.append(['#'.ljust(2) for x in range(0, int(inp[0]))])
for n in range(0, inp[0]*inp[1]) :
result[y][x] = n # 숫자 대입
if (y, x) == (0, inp[0]-1) or (y, x) == (inp[1]-1, inp[0]-1) or (y, x) == (inp[1]-1, 0) : #꼭짓점일 때 방향 전환
dxdy = vec(dxdy)
elif result[y+dxdy[1]][x+dxdy[0]] != "#".ljust(2) : #다음 이동한 좌표가 이미 갔던 좌표일 때 방향 전환
dxdy = vec(dxdy)
x, y = x + dxdy[0], y + dxdy[1] # 방향만큼 다음 x와 y의 좌표 계산
for o in range(0, inp[1]) : #계산된 result리스트를 프린트
for u in range(0, inp[0]) :
respri += str(result[o][u]).ljust(4)
print(respri)
respri = ''
처음 코딩도장을 알았을 때는 어떻게 풀어야 할 지 감이 전혀 안왔는데, 오늘 풀려서 기분이 좋네요!!
결과
INPUT : 8 8
0 1 2 3 4 5 6 7
27 28 29 30 31 32 33 8
26 47 48 49 50 51 34 9
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
import pandas as pd
import numpy as np
pd1 = pd.DataFrame(np.arange(36).reshape(6,6))
pd1
r = 0
g1 = 6
gc1 = 0
g2 = 6
gc2 = 1
g3 = 4
gc3 = 0
g4 = 4
gc4 =0
num = 0
while r < 11:
if r in [0,4,8]:
print(r)
for i in range(gc1,g1):
pd1[i][gc1] = num
num += 1
g1 -= 1
gc1 += 1
print(g1,gc1)
elif r in [1,5,9]:
for j in range(gc2,g2):
pd1[g2-1][j] = num
num += 1
g2 -= 1
gc2 += 1
elif r in [2,6,10]:
for k in range(g3,gc3-1,-1):
pd1[k][g3+1] = num
num += 1
g3 -= 1
gc3 += 1
else:
for l in range(g4,gc4,-1):
pd1[gc4][l] = num
num += 1
g4 -= 1
gc4 += 1
r += 1
m=16
n=12
a=[[0 for i in range(n)] for j in range(m)]
pointx=0
pointy=0
m_x=m
n_x=n-1
i=-1
while True:
#좌+1
for b in range(pointx, pointx + m_x ):
i=i+1
a[b][pointy] = i
m_x= m_x -1
pointx = pointx + m_x
pointy = pointy +1
if ( m * n <= i+1): break
#아래 +1
for c in range(pointy, pointy + n_x):
i=i+1
a[pointx][c] = i
n_x=n_x -1
pointy=pointy + n_x
pointx=pointx -1
if ( m * n <= i+1): break
#우 +1
for b in range(pointx, pointx - m_x ,-1):
i=i+1
a[b][pointy] = i
m_x=m_x-1
pointx=pointx - m_x
pointy=pointy - 1
if ( m * n <= i+1): break
#위 +1
for c in range (pointy, pointy - n_x ,-1):
i=i+1
a[pointx][c]=i
n_x=n_x-1
pointy=pointy - n_x
pointx=pointx +1
if ( m * n <= i+1): break
for i in range (0,n):
for o in range (0,m):
print (a[o][i], end="\t")
print()
이런건 뭔가 파이선이 아니라 pascal 같은걸로 하는게 더 쉽지 않을까 생각이 들었습니다..
Javascript(ES6)...
'ES6 문법의 class 활용, 나선형 구조를 나타내는 2x2 형태의 spiral 배열 생성, 왼쪽 위부터 숫자 채워넣기 시작, 만일 숫자채워 넣은 곳 다음 칸이 범위를 벗어나거나 다른 숫자로 이미 채워져있다면 방향 전환';
class MySpiral {
constructor(size_x, size_y) {
[this.size_x, this.size_y] = [size_x, size_y];
// spiral 배열 초기생성할 때, 사용하지 않는 값 -1 로 채움
this.spiral = Array(size_x).fill().map(x => Array(size_y).fill(-1));
this._make_spiral();
}
// Spiral 구현 함수
_make_spiral() {
// x, y 는 현재위치를, dx, dy 는 진행방향을 나타냄, 아래는 초기 설정
let [x, y, dx, dy] = [-1, 0, 1, 0];
// 진행방향에 따라 x, y 증가 -> x, y 에 숫자 넣기 -> 다음칸 조사
for(let i = 0; i < this.size_x * this.size_y; i++) {
[x, y] = [x + dx, y + dy];
this.spiral[x][y] = i;
// 다음 진행방향이 size_x, size_y 범위를 벗어나거나 다른 숫자가 이미 있으면 방향전환
if( x + dx == -1
|| this.size_x == x + dx
|| y + dy == -1
|| this.size_y == y + dy
|| this.spiral[x + dx][y + dy] != -1) {
[dx, dy] = [-dy, dx];
}
}
return this;
}
// Spiral 출력 함수
print_spiral() {
let output = '';
// 출력할 때 각 숫자 사이의 간격 pad
let pad = Math.floor((this.size_x * this.size_y).toString().length + 2);
for(let y = 0; y < this.size_y; y++) {
for(let x = 0; x < this.size_x; x++) {
output += this.spiral[x][y].toString().padStart(pad);
}
output += '\n';
}
console.log(output);
}
}
new MySpiral(6, 6).print_spiral();
Python 3...
class Spiral:
def __init__(self, size_x, size_y):
self.size_x, self.size_y = size_x, size_y
self.spiral = [[-1 for y in range(size_y)] for x in range(size_x)]
self.__make_spiral()
# spiral 구현 함수
def __make_spiral(self):
# x, y 는 현재위치, dx, dy 는 진행방향
x, y, dx, dy = -1, 0, 1, 0
# 반복문 사용 -> x, y 증가 -> spiral 현재 칸에 숫자 채움 -> 다음 칸 조사 -> 다음 칸 조건에 따라 방향전환
for i in range(self.size_x * self.size_y):
x, y = x + dx, y + dy
self.spiral[x][y] = i
if x + dx not in range(self.size_x) or y + dy not in range(self.size_y) or self.spiral[x + dx][y + dy] != -1:
dx, dy = -dy, dx
## spiral 출력 함수
def print_spiral(self):
output = ''
pad = len(str(self.size_x * self.size_y)) + 2
for y in range(self.size_y):
for x in range(self.size_x):
output += str(self.spiral[x][y]).rjust(pad)
output += '\n'
print(output)
Spiral(6, 6).print_spiral()
Python3으로 작성한 코드입니다.
m, n = tuple(map(int, input().split()))
### Generating A (initial) ###
A = []
for i in range(m):
A += [list(range(1, n + 1))]
### Modifying A ###
d = 0 ## 방향 표시: %4 = 0 1 2 3 각각 하 좌 상 우
add_col = n - 1 # 수정할 열의 개수
add_row = m - 1 # 수정할 행의 개수
start = n + 1 # 2행 마지막 열부터 수정 시작
end = 0
while end == 0:
if add_col * add_row == 0:
end = 1
if d % 4 == 0:
for i in range(add_row):
A[(d // 4) + 1 + i][n - 1 - (d // 4)] = start + i
start += add_row
add_row -= 1
elif d % 4 == 1:
A[m - 1 - (d // 4)][(d // 4):(d // 4) + add_col] = list(range(start + add_col - 1, start - 1, -1))
start += add_col
add_col -= 1
elif d % 4 == 2:
for i in range(add_row):
A[(d // 4) + 1 + i][d // 4] = start + add_row - 1 - i
start += add_row
add_row -= 1
else:
A[(d // 4) + 1][(d // 4) + 1:(d // 4) + 1 + add_col] = list(range(start, start + add_col))
start += add_col
add_col -= 1
d += 1
### print A ###
for i in range(m):
for j in range(n):
print('{: 4d}'.format(A[i][j]), end='')
print()
nn=list(map(str,input("배열X배열을 입력하십시오: ").split(" "))) # 3 3
r,c=int(nn[0]),int(nn[1])
t=eval(repr([[" "]*c]*r))
x,y=0,0
dx,dy=0,1
for i in range(r*c):
t[x][y]=i
x,y=x+dx,y+dy
if x==r or y==c or t[x][y]!=" ":
x,y=x-dx,y-dy
dx,dy=dy,-dx
x,y=x+dx,y+dy
for lst in t:
for num in lst:
print("%3d"%num, end="")
print()
자바로 풀었습니다. 수열을 잘하면 유리하겠네요.
import java.util.Scanner;
public class Spiral {
public static int[] spiral(int n) {
int times = n/2;
int size= n*n;
int[] arr = new int[size]; // arr은 0 ~ n*n까지의 순서대로의 배열
for(int i=0; i<size; i++) {
arr[i]=i;
}
int[] up = up(arr, n, times, size); //→ 1씩 증가하는 줄 임시 배열 tmp에 담아서 반환
int[] right = right(arr, n, times, size); //↓ 1씩 증가하는 줄
int[] left= left(arr, n, times, size); //↑ 1씩 증가하는 줄
int[] down=down(arr, n, times, size); //← 1씩 증가하는 줄
for(int i=0; i<size; i++) { // 배열 복사
if(up[i]!=0) { // 각 메소드에 해당되지 않는 값은 0
arr[i]=up[i];
}
if(right[i]!=0) {
arr[i]=right[i];
}
if(left[i]!=0) {
arr[i]=left[i];
}
if(down[i]!=0) {
arr[i]=down[i];
}
}
return arr;
}
public static int[] up(int[] arr, int n, int times, int size) {
int a = 0;
int upnum1;
int upnum2=0;
int [] tmp = new int[size];
int j = 1;
for(int i = 0; i<times-1; i++) {
upnum1=-a-5;
upnum2+=upnum1;
System.arraycopy(arr, 4*(i+1)*n+upnum2, tmp, (i+1)*n+i, n-2-2*i);
// arr 은 순서대로인 배열, tmp는 값이0인 배열, 규칙을 찾아서 각 방향에 맞는 숫자를 복사한다.
j+=2;
a=(4*j);
}
return tmp;
}
public static int[] right(int[] arr, int n, int times, int size) {
int j =-1;
int a = 0;
int rightnum1;
int rightnum2=0;
int[] tmp = new int[size];
for(int i=0; i<times; i++) {
rightnum1=-a-1;
rightnum2+=rightnum1;
for(int k=0; k<n-2*i-1; k++) {
System.arraycopy(arr, (4*i+1)*n+rightnum2+k+i, tmp, (i+k+1)*n-1-i, 1);
}
j+=2;
a = (4*j+2);
}
return tmp;
}
public static int[] left(int[] arr, int n, int times, int size) {
int j =0;
int a = 3;
int leftnum1;
int leftnum2=0;
int[] tmp = new int[size];
for(int i=0; i<times; i++) {
leftnum1=-a;
leftnum2+=leftnum1;
int q=2*(i+1);
if(i==times-1)q=n-1;
for(int k=0; k<n-q; k++) {
System.arraycopy(arr, (4*i+3)*n+leftnum2+k, tmp, (n-i-k-1)*n+i, 1);
}
j+=2;
a = (4*j+2);
}
return tmp;
}
public static int[] down(int[] arr, int n, int times, int size) {
int j =0;
int a =(4*j);
int downnum1=-2;
int downnum2=0;
int[] tmp = new int[size];
for(int i=0; i<times; i++) {
downnum2+=downnum1;
int q = n-2*i-1;
for(int k=0; k<q; k++) {
System.arraycopy(arr, (4*i+2)*n+downnum2+k, tmp, (n-i)*n-i-1-k, 1);
}
j+=2;
a = (4*j);
downnum1=-a;
}
return tmp;
}
public static void print(int n) {
System.out.println(n);
}
public static void printArr(int[] arr, int n) {
int size = n*n;
for(int i = 0; i<size; i++) {
System.out.print(arr[i]+"\t ");
if((i%n)==n-1)System.out.println();
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int row = scanner.nextInt();
print(row);
int[] arr=spiral(row);
printArr(arr, row);
}
}
#include <iostream>
using namespace std;
#define RIGHT 1
#define DOWN 2
#define LEFT 3
#define UP 4
void show(char *str, int **arr, int rsize, int csize)
{
if(arr == NULL || rsize<=0 || csize<=0)
return;
if(str !=NULL)
cout<<str;
cout<<endl;
for(int i=0;i<rsize;i++)
{
for(int j=0;j<csize;j++)
{
cout<<arr[i][j];
if(((j+1) % csize) !=0)
cout<<"\t";
}
cout<<endl;
}
cout<<endl;
}
void spiralarray(int r, int c)
{
if(r<=0 || c<=0)
return;
////////////////////////
int **arr = new int*[r];
int cnt=0;
for(int i=0;i<r;i++)
{
arr[i] = new int[c];
for(int j=0;j<c;j++)
{
arr[i][j] = cnt++;
}
}
/////////////////////
show("Before", arr, r, c);
int sRow = 0; // 행 시작인덱스
int sCol = 0; // 열 시작인덱스
int cntRow = 0; // 배열 한바퀴 순회 시 1증가
int cntCol = 0; // 배열 한바퀴 순회 시 1증가
cnt=0; // 배열 값
int ord = RIGHT;
while(true)
{
switch(ord)
{
case RIGHT:
{
for(int i=sCol;i<=c-1-cntCol;i++) // 왼쪽 -> 오른쪽 순회 시
{
arr[sRow][i] = cnt++;
if((c-1-cntCol) == i)
{
sRow++; // 다음 행 시작 인덱스 1증가
sCol = i; // 다음 열 시작 인덱스
ord = DOWN;
break;
}
}
}
break;
case DOWN:
{
for(int i=sRow;i<=r-1-cntRow;i++) // 위 -> 아래로 순회시
{
arr[i][sCol] = cnt++;
if((r-1-cntRow) == i)
{
sRow = i;
sCol--;
ord = LEFT;
break;
}
}
}
break;
case LEFT:
{
for(int i=sCol;i>=cntCol;i--) // 오른쪽 -> 왼쪽 순회 시
{
arr[sRow][i] = cnt++;
if((cntCol) == i)
{
sRow--;
sCol = i;
ord = UP;
break;
}
}
}
break;
case UP:
{
cntRow +=1;
cntCol +=1;
for(int i=sRow;i>=cntRow;i--) // 아래-> 위로 순회시
{
arr[i][sCol] = cnt++;
if((cntRow) == i)
{
sRow = i;
sCol = cntCol;
ord = RIGHT;
break;
}
}
}
break;
}
if(cnt>=r*c)
break;
}
show("After", arr, r, c);
/////////////////////////
for(int i=0;i<c;i++)
delete[] arr[i];
delete[] arr;
/////////////////////////
}
int main()
{
spiralarray(5,10);
return 0;
}
-----
결과:
Before
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
After
0 1 2 3 4 5 6 7 8 9
25 26 27 28 29 30 31 32 33 10
24 43 44 45 46 47 48 49 34 11
23 42 41 40 39 38 37 36 35 12
22 21 20 19 18 17 16 15 14 13
n, m=input().split(' ')
n=int(n)
m=int(m)
my_dict={}
cnt=1
for i in range(-1,max(n,m)+2):
my_dict[(-1,i)]=9999
my_dict[(n,i)]=9999
my_dict[(i,-1)]=9999
my_dict[(i,m)]=9999
mv=[[0,1], [1,0], [0,-1], [-1,0]]
c, i, j=0,0,0
while cnt<=n*m:
my_dict[(i,j)]=cnt-1
x=i+mv[c][0]
y=j+mv[c][1]
if (x,y) in list(my_dict.keys()) :
c=(c+1)%4
x=i+mv[c][0]
y=j+mv[c][1]
else:
x=i+mv[c][0]
y=j+mv[c][1]
i=x
j=y
cnt=cnt+1
my_list=[my_dict[(i,j)] for i in range(0,n) for j in range(0,m)]
for i in range(0,n):
print(' '.join(map(str, my_list[i*m : (i+1)*m])))
python 3.8
xloop=int(input())
yloop=int(input())
m=xloop-1
n=yloop-1
x=0
y=0
k=1
dic={(0,0):1}
while m>0 or n>0:
for i in range(m):
k=k+1
x=x+1
dic[(x,y)]=k
for i in range(n):
k=k+1
y=y-1
dic[(x,y)]=k
for i in range(m):
k=k+1
x=x-1
dic[(x,y)]=k
for i in range(n-1):
k=k+1
y=y+1
dic[(x,y)]=k
if m !=1 and n!=1: # 회전 초기값 0,0 -> 1,-1 증가
x=x+1
k=k+1
dic[(x,y)]=k
m=m-2
n=n-2
for i in range(yloop):
for j in range(xloop):
print('%4d' % dic[(j,-i)],end='')
print(' ') # x값 출력 후 CR
# 0.0을 기준으로 좌표값 변화를 dict{사전}처리하여 튜플형 key값을 통하여 int value 구함.
while True:
shape1, shape2 = input('정사각형의 가로 세로 크기를 숫자로 입력해주세요(예: 2 2):').split()
if shape1 == shape2:
shape = int(shape1)
break
res = [[0] * shape for i in range(shape)]
k= 0
rect = int((shape+1) / 2)
size_max = shape - 1
size_min = 0
for i in range(rect):
for j in range(size_min, size_max+1):
res[i][j] = k
k += 1
for j in range(size_min+1, size_max+1):
res[j][size_max] = k
k += 1
for j in range(size_max-1, size_min-1, -1):
res[size_max][j] = k
k += 1
for j in range(size_max-1, size_min, -1):
res[j][size_min] = k
k += 1
size_min += 1
size_max -= 1
for i in range(shape):
for j in range(shape):
print('{:>4}'.format(res[i][j]), end='')
print('')
초보인 제게는 쉽지 않아 네이버와 유튜브를 활용했지만 ㅠㅠ 이런걸 다양한 방법으로 해내시는 분들을 보니 정말 대단하다는 생각이 들기도하고 더 많이 노력해야겠다는 생각이 드네요 ㅠㅠ
파이썬 입니다.
from itertools import cycle
type_lst = ['a', 'b', 'c', 'd']
dir_type = cycle(type_lst)
user_input = str(input('가로 세로를 입력하세요: ')).split()
x = int(user_input[0])
y = int(user_input[1])
sa = [[0 for col in range(x)] for row in range(y)]
n = 0
alen = 0
cur_spot = (0, -1)
def print_sa():
for i in range(len(sa)): # 세로 크기
for j in range(len(sa[i])): # 가로 크기
print(sa[i][j], end=' ')
print()
def line_up(sa, dtype, alen) :
global n
global cur_spot
inc = 1
if dtype in ('c', 'd'):
inc = -1
if dtype in ('a', 'c'):
cur_spot = (cur_spot[0], cur_spot[1] + inc)
alen *= inc
from_index = cur_spot[1]
to_index = cur_spot[1] + alen
elif dtype in ('b', 'd'):
cur_spot = (cur_spot[0] + inc, cur_spot[1])
alen *= inc
from_index = cur_spot[0]
to_index = cur_spot[0] + alen
# print("cur_spot : " + str(cur_spot))
# print("from_index : " + str(from_index))
# print("to_index : " + str(to_index))
for i in range(from_index, to_index, inc):
if dtype in ('a', 'c'):
sa[cur_spot[0]][i] = n
n += 1
cur_spot = (cur_spot[0], i)
elif dtype in ('b', 'd'):
sa[i][cur_spot[1]] = n
n += 1
cur_spot = (i, cur_spot[1])
# print('dtype : ' + dtype)
# print_sa()
init = True
while True:
if not init :
x -= 1
init = False
if 0 == x:
break
# print("x: " +str(x))
line_up(sa, next(dir_type), x)
y -= 1
if 0 == y:
break
# print("y: " + str(y))
line_up(sa, next(dir_type), y)
print_sa()
파이썬, 리커시브 하게 다시 도전이요. 원래는 중복 코드를 상당히 줄일수 있을거 같은데, 제가 아직 경험이 부족하여 중복 느낌이 많이 나는 리커시브네요.
inputData = input("두 개의 숫자를 입력하세요. (예시> 6 6): ").split()
dir_type = ['right', 'down', 'left', 'up']
pos = [0, 0]
n = 0
x = int(inputData[0])
y = int(inputData[1])
sa = [['-' for col in range(y)] for row in range(x)]
def sa_print() :
for row in sa:
for no in row:
print('{:3}'.format(no), end=' ')
print()
def run_sprial(sa, d_type_index, pos, n):
global x, y
# print(pos)
turn_dti = 0
if d_type_index < 3 :
turn_dti = d_type_index + 1
if n == x*y:
return
sa[pos[0]][pos[1]] = n
n += 1
# sa_print()
if d_type_index == 0 :
if pos[1]+1 < y and sa[pos[0]][pos[1]+1] == '-':
pos[1] += 1
run_sprial(sa, d_type_index, pos, n)
else:
pos[0] = pos[0]+1
run_sprial(sa, turn_dti, pos, n)
if d_type_index == 1 :
if pos[0]+1 < x and sa[pos[0]+1][pos[1]] == '-':
pos[0] += 1
run_sprial(sa, d_type_index, pos, n)
else:
pos[1] = pos[1]-1
run_sprial(sa, turn_dti, pos, n)
elif d_type_index == 2 :
if pos[1] - 1 >= 0 and sa[pos[0]][pos[1]-1] == '-':
pos[1] -= 1
run_sprial(sa, d_type_index, pos, n)
else:
pos[0] = pos[0] - 1
run_sprial(sa, turn_dti, pos, n)
elif d_type_index == 3 :
if pos[0] - 1 >= 0 and sa[pos[0]-1][pos[1]] == '-':
pos[0] -= 1
run_sprial(sa, d_type_index, pos, n)
else:
pos[1] = pos[1]+1
run_sprial(sa, turn_dti, pos, n)
run_sprial(sa, 0, pos, n)
sa_print()
#include <iostream>
using namespace std;
/*
6 6
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/
struct P {
int x, y;
};
void Func(int **arr, int n, int m) {
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
arr[i][j] = 0;
P p;
p.x = 0, p.y = 0;
bool check;
arr[0][0] = 1;
int num = 2;
while (1) {
for (int i = 1; i < m; i++) { //->
if (arr[p.x][p.y + i] == 0) {
arr[p.x][p.y + i] = num++;
if (p.y + i == m - 1) { p.y = p.y + i; }
}
else { p.y = p.y + i - 1; break; }
}
for (int i = 1; i < n; i++) { //↓
if (arr[p.x + i][p.y] == 0) {
arr[p.x + i][p.y] = num++;
if (p.x + i == n - 1) { p.x = p.x + i; }
}
else { p.x = p.x + i - 1; break; }
}
for (int i = 1; i < m; i++) { // <-
if (arr[p.x][p.y - i] == 0) {
arr[p.x][p.y - i] = num++;
if (p.y - i == 0) { p.y = p.y - i; }
}
else { p.y = p.y - i + 1; break; }
}
for (int i = 1; i < n; i++) { // ↑
if (arr[p.x - i][p.y] == 0) {
arr[p.x - i][p.y] = num++;
if (p.x - i == 0) { p.x = p.x - i; }
}
else { p.x = p.x - i + 1; break; }
}
check = true;
for(int i=0; i< n; i++)
for (int j = 0; j < m; j++) {
if (arr[i][j] == 0) { check = false; }
}
if (check) { break; }
}
}
int main() {
int n1, n2;
cout << "숫자 두개 입력:";
cin >> n1 >> n2;
int **arr = new int*[n1];
for (int i = 0; i < n1; i++)
arr[i] = new int[n2];
Func(arr, n1, n2);
cout << endl;
for (int i = 0; i < n1; i++) {
for (int j = 0; j < n2; j++) {
cout << arr[i][j] << "\t";
}
cout << endl;
}
for (int i = 0; i < n1; i++)
delete[] arr[i];
delete[] arr;
}
from itertools import cycle
def spiral(m, n):
size = m * n
result = ['']*size
result[:m] = range(m) #첫째줄 완성
p = m-1
num = m-1
for i in cycle([m, -1, -m, 1]): #break가 되어도 i는 순서대로 돌아감
while True:
p += i # 위치를 이동
num += 1 #하나씩 늘려감
if p < size and result[p] == '':
result[p] = num
else: # 다시 복원
p -= i
num -= 1
break #다음 cycle로 이동
if '' not in result: #전부 채워져 있으면 출력
return result
def main(m, n):
a = 0
for i in (spiral(m, n)):
a += 1
print(i, end=' ')
if a % m == 0:
print()
main(6, 6)
디디님의 코딩을 참조하여서 공부하면서 짜보았습니다.
좋은 코딩 해주셔서 감사합니다.
import numpy as np
N=int(input("input : "))
list_a=[]
for i in range(N*N):
list_a.append(0)
list_a=np.array(list_a).reshape(N,N)
num=0
cel=0
right=N-1
left=0
floor=N-1
for i in range(2*N-1):
print(i)
T=i%4
if T==0:
for j in range(left,right+1):
list_a[cel][j]=num
num+=1
cel += 1
elif T == 1:
for j in range(cel,right+1):
list_a[j][right] = num
num += 1
right -= 1
elif T == 2:
for j in range(right,left-1,-1):
list_a[floor][j]=num
num+=1
floor -= 1
else:
for j in range(floor,cel-1,-1):
list_a[j][left] = num
num += 1
left+=1
print(list_a)
#파이썬
#다 간단히 해결될것 같은데 아직 초보이다 보니 소스가 좀 길어져버렸습니다
def show_m(x):
for i in range (0,yy):
for j in range (0,xx):
print("%4d" %m[i][j],end='')
print()
temp=str(input('가로크기? 세로크기?')).split(' ')
xx,yy=int(temp[0]),int(temp[1])
xmax,xmin,ymax,ymin,m=xx-1,0,yy-1,0,[]
for i in range (0,yy):
temp=[]
for j in range (0,xx):
temp.append(0)
m.append(temp)
x,y,num=0,0,0
while (num<xx*yy-1):
while (x<xmax):
x+=1
num+=1
m[y][x]=num
ymin+=1
if num==xx*yy-1:
break
while (y<ymax):
y+=1
num+=1
m[y][x]=num
xmax-=1
if num==xx*yy-1:
break
while (x>xmin):
x-=1
num+=1
m[y][x]=num
ymax-=1
if num==xx*yy-1:
break
while (y>ymin):
y-=1
num+=1
m[y][x]=num
xmin+=1
if num==xx*yy-1:
break
show_m(m)
#파이썬
def myRec(Low,Column): #행렬 입력
Reclist = [[-1 for i in range(Column)]for j in range(Low)]
x, y, cnt, xdir, ydir = 0,0,0,1,0
while(Reclist[y][x] == -1):
Reclist[y][x] = cnt
cnt += 1
#다음 값이 행렬(Matrix)범위를 벗어나거나, 비어있는 공간이 아닐 때
if(not(0 <= x+xdir < Column and 0 <= y+ydir < Low and Reclist[y+ydir][x+xdir] == -1)):
ydir , xdir = xdir , -ydir #X,Y 방향 순환
x,y = x+xdir ,y+ydir
return Reclist
#===========================================================
Low,Column = map(int,input().split())
for i in myRec(Low,Column):
for j in i:
print('%3d'%j ,end = ' ')
print()
from collections import deque
def sprial(n):
matrix = [[' ']*n for i in range(n)]
k = sorted([i for j in range(2) for i in range(n, 0, -1)], reverse=True)[1:]
deq = deque([(-1, 0), (0, 1), (1, 0), (0, -1)])
i, j, cnt = 0, -1, -1
for r in k:
deq.rotate(-1)
for l in range(r):
cnt += 1
i += deq[0][0]
j += deq[0][1]
matrix[i][j] = cnt
for s in matrix:
for h in s:
print('{:^3}'.format(h), end=' ')
print()
if __name__ == '__main__':
n = 6
sprial(n)
def SpiralArray(X, Y):
sa_list = [[0 for x in range(X)] for y in range(Y)]
'''
count : 0부터 X*Y-1의 값을 차례로 저장할 변수
flag : 진행방향을 정할 변수
'''
count = 0
flag = 0
i, j = 0, 0
while True:
'''
flag가 0일 때 오른쪽으로 진행
배열에 count 값을 넣고 오른쪽으로 진행되니 j 값이 1씩 증가해야함.
count 값은 사용했으니 1 증가
반복문을 돌리다가 j 값이 Y와 같아지거나(배열 인덱스 값이 맞지 않을 때) 배열 내의 값이 0이 아닐 때
j의 값을 1 감소시켜 전 배열 인덱스로 돌아간 후 i의 값을 1 증가시켜 다음 배열로 넘어간다.
flag의 값을 1로 정의한다.
flag가 1일 때 아래쪽으로 진행
flag가 2일 때 왼쪽으로 진행
flag가 3일 때 위쪽으로 진행
'''
if flag == 0:
sa_list[i][j] = count
j+=1
count+=1
if j == Y or sa_list[i][j] != 0:
j-=1
i+=1
flag = 1
elif flag == 1:
sa_list[i][j] = count
i+=1
count+=1
if i == X or sa_list[i][j] != 0:
i-=1
j-=1
flag = 2
elif flag == 2:
sa_list[i][j] = count
j-=1
count+=1
if j == -1 or sa_list[i][j] != 0:
i-=1
j+=1
flag = 3
elif flag == 3:
sa_list[i][j] = count
i-=1
count+=1
if i == 0 or sa_list[i][j] != 0:
i+=1
j+=1
flag = 0
# 만약 count가 X*Y의 값과 같아질 때 while문 break
if count == X*Y:
break
# 2차원 배열 원소 출력하기
for k1 in sa_list:
for k2 in k1:
print(k2, "\t", end='')
print()
if __name__ == '__main__':
# map : 리스트의 요소를 지정된 함수로 처리해주는 함수(원본 리스트를 변경하지 않고 새 리스트를 생성함.)
X, Y = map(int, input("입력: ").split(" "))
SpiralArray(X, Y)
enum widthDirectionFlag {
case left
case right
}
enum heightDirectionFlag {
case up
case down
}
func matrix(width:Int,height:Int) {
var matrixDic:Dictionary = [Int:Int]()
var widthCnt:Int = width
var heightCnt:Int = height - 1
var currentNum:Int = 0
var currentMatrixIndex:Int = -1
var widthDrectionFlag:widthDirectionFlag = .left
var heightDirectionFlag:heightDirectionFlag = .up
while true {
if widthCnt != 0 {
for _ in 0..<widthCnt {
switch widthDrectionFlag {
case .left:
matrixDic[currentMatrixIndex+1] = currentNum
currentMatrixIndex += 1
currentNum += 1
break
case .right:
matrixDic[currentMatrixIndex-1] = currentNum
currentMatrixIndex -= 1
currentNum += 1
break
}
}
if heightCnt != 0 {
widthCnt -= 1
}
else {
break
}
if widthDrectionFlag == .left {
widthDrectionFlag = .right
}
else {
widthDrectionFlag = .left
}
}
if heightCnt != 0 {
for _ in 0..<heightCnt {
switch heightDirectionFlag {
case .up:
matrixDic[currentMatrixIndex + width] = currentNum
currentMatrixIndex += width
currentNum += 1
break
case .down:
matrixDic[currentMatrixIndex - width] = currentNum
currentMatrixIndex -= width
currentNum += 1
break
}
}
if widthCnt != 0 {
heightCnt -= 1
}
else {
break
}
if heightDirectionFlag == .up {
heightDirectionFlag = .down
}
else {
heightDirectionFlag = .up
}
}
if heightCnt == 0 && widthCnt == 0 {
break
}
}
let keyArr = matrixDic.keys.sorted(by: { $0 < $1})
print("keyArr:\(keyArr)")
for i in 0..<keyArr.count {
print("\(String(describing: matrixDic[keyArr[i]]))")
}
}
def List(m,n):
a = []
for i in range(n):
line =list()
for j in range(m):
line.append(0)
a.append(line)
return a
count = 0
number = -1
x = -1
y = 0
dx = dy = 1
cycle=0
m=int(input("가로축 숫자를 입력하시오"))
n=int(input("세로축 숫자를 입력하시오"))
a = List(m,n)
while True:
count+=1
while True: #+x에 관련된 반복문 마지막에 한싸이클 돌때마다 count한번더
number += 1
#x축 방향으로 이동
x += 1
if x < m - cycle*dx :
a[y][x] = number
elif x == m - cycle*dx :
x -= 1
number -= 1
break
if a[y][x] == m*n-1:
break
while True: #-y에 관련된 반복문
number += 1
y += 1 #내려가지만 플러스임
if y < n-cycle*dy:
a[y][x] = number
elif y == n-cycle*dy:
y -= 1
number -= 1
break
if a[y][x] == m*n-1:
break
while True: #-x에 관련된 반복문
number += 1
x -= 1 #이젠 마이너스
if x >= cycle:
a[y][x] = number
elif x < cycle:
x +=1
number -= 1
break
if a[y][x] == m*n-1:
break
while True: # +y에 관련된 반복문 왜안대
number += 1
y -= 1
if y > cycle:
a[y][x] = number
elif y == cycle:
y+=1
number -= 1
break
if a[y][x] == m*n-1:
break
cycle += 1
for i in a:
for j in i:
print(j,end=' ')
print("\n")
import java.util.Scanner;
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
System.out.print("원하는 크기 입력하시오: ");
int size = scan.nextInt();
spiral(size);
}
public static void spiral(int size) {
int [][] go = new int[size][size];
int flag = 0;//방향
int now=0;// 다 차면 나가기용
int i=0 ,j=0; //좌표용
while(now<size*size)
{
switch(flag){
case 0:
go[i][j++]= now++;
if(j==size || go[i][j] !=0)// null이면 범위 초과, 0이 아닌 다른 숫자면 차있는것
{
i++;
j--;
flag = 1;
}
break;
case 1:
go[i++][j] = now++;
if(i==size || go[i][j] !=0)// null이면 범위 초과, 0이 아닌 다른 숫자면 차있는것
{
i--;
j--;
flag = 2;
}
break;
case 2:
go[i][j--] = now++;
if(j==-1 || go[i][j] !=0)// null이면 범위 초과, 0이 아닌 다른 숫자면 차있는것
{
i--;
j++;
flag = 3;
}
break;
case 3:
go[i--][j] = now++;
if(i==0 || go[i][j] !=0)// 여기는 (0,0)이 0으로 차있어서 조건 i==0
{
i++;
j++;
flag = 0;
}
break;
}
}
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
System.out.print(go[i][j]+ " \t");
}
System.out.println("");
}
}
}
# N x M 행렬 생성
M = 8
N = 6
m = []
for iy in range(N):
a = []
for ix in range(M):
a.append(None)
m.append(a)
# 숫자 채우는 순서
directions = ['x_plus', 'y_plus', 'x_minus', 'y_minus']
# 채우는 숫자
n = 0
n_max = M * N
# 숫자 채우는 x, y 위치
x_pos = 0
y_pos = 0
bLoop = True
while bLoop:
for i, direction in enumerate(directions):
print("{}({},{})".format(direction, x_pos, y_pos), end=':')
if direction == 'x_plus':
for ix in range(0, M):
if m[y_pos][ix] is None:
m[y_pos][ix] = n
n += 1
x_pos = ix
print(n, end=' ')
elif direction == 'y_plus':
for iy in range(0, N):
if m[iy][x_pos] is None:
m[iy][x_pos] = n
n += 1
y_pos = iy
print(n, end=' ')
elif direction == 'x_minus':
for ix in range(M -1 , -1, -1):
if m[y_pos][ix] is None:
m[y_pos][ix] = n
n += 1
x_pos = ix
print(n, end=' ')
elif direction == 'y_minus':
for iy in range(N - 1, -1, -1):
if m[iy][x_pos] is None:
m[iy][x_pos] = n
n += 1
y_pos = iy
print(n, end=' ')
print("")
if n >= n_max:
bLoop = False
break
결과
[[0, 1, 2, 3, 4, 5, 6, 7], [23, 24, 25, 26, 27, 28, 29, 8], [22, 39, 40, 41, 42, 43, 30, 9], [21, 38, 47, 46, 45, 44, 31, 10], [20, 37, 36, 35, 34, 33, 32, 11], [19, 18, 17, 16, 15, 14, 13, 12]]
파이썬 입니다. (약간의 결함이 있음)
# 이차원 행렬 생성
m,n = map(int, input().split()) # m : 행 // n : 열
a = [[-1]*n for _ in range(m)] # m행 n열 2차원 행렬 생성
# 이차원 행렬에 숫자 대입
# 테두리 부분
i = 0
j = 0
initial = 0
while initial < 2*(m+n)-5:
if i==0 and j!=n-1:
a[i][j]=initial
j +=1
initial +=1
elif j==n-1 and i!=m-1:
a[i][j]=initial
i +=1
initial +=1
elif i==m-1 and j!=0:
a[i][j]=initial
j -=1
initial +=1
elif j==0 and i!=0:
a[i][j]=initial
i -=1
initial +=1
a[i][j] = initial
# 안쪽 부분
j += 1
initial += 1
while initial < m*n-1:
# 코너 아닌 부분(2) 면으로 둘러 싸인 경우
if a[i][j-1] !=-1 and a[i-1][j] !=-1 and a[i][j+1] ==-1 and a[i+1][j] ==-1:
a[i][j]=initial
j +=1
initial +=1
elif a[i][j-1] ==-1 and a[i-1][j] !=-1 and a[i][j+1] !=-1 and a[i+1][j] ==-1:
a[i][j]=initial
i +=1
initial +=1
elif a[i][j-1] ==-1 and a[i-1][j] ==-1 and a[i][j+1] !=-1 and a[i+1][j] !=-1:
a[i][j]=initial
j -=1
initial += 1
elif a[i][j-1] !=-1 and a[i-1][j] ==-1 and a[i][j+1] ==-1 and a[i+1][j] !=-1:
a[i][j]=initial
i -=1
initial += 1
# 코너 부분(3면으로 둘러싸인 경우)
elif a[i][j-1] !=-1 and a[i-1][j] !=-1 and a[i][j+1] ==-1 and a[i+1][j] !=-1:
a[i][j]=initial
j +=1
initial +=1
elif a[i][j-1] !=-1 and a[i-1][j] !=-1 and a[i][j+1] !=-1 and a[i+1][j] ==-1:
a[i][j]=initial
i +=1
initial +=1
elif a[i][j-1] ==-1 and a[i-1][j] !=-1 and a[i][j+1] !=-1 and a[i+1][j] !=-1:
a[i][j]=initial
j -=1
initial +=1
elif a[i][j-1] !=-1 and a[i-1][j] ==-1 and a[i][j+1] !=-1 and a[i+1][j] !=-1:
a[i][j]=initial
i -=1
initial +=1
a[i][j] = m*n-1
# 만들어진 이차원 행렬을 출력
n = len(str(m*n-1))
for i in range(len(a)):
for j in range(len(a[i])):
print('%2d'%a[i][j],end=' ')
print() #??? 왜 print('asdfasdf')를 넣으면 위의 것과 같은 줄에 출력이 되지??? '''
# %()d에서 ()의 숫자가 n이 되려고 하면 어떻게 해야하지??
w, h = map(int,input().split()) t = eval(repr([[0]h]w)) ds = [[1,0],[0,1],[-1,0],[0,-1]] e=x=y=d=0 for i in range(wh): t[x][y] = i if x+ds[d][0] in [e-1-(1 if d==3 else 0),w-e] or y+ds[d][1] in [e-1,h-e]: d = (d+1)%4 e += d//3 x, y = map(sum,zip(ds[d],[x,y])) for i in range(wh): print(("%%%dd" % (len(str(w*h-1))+1)) % t[i%w][i//w], end=('\n' if i%w==w-1 else ''))
import numpy
class SpiralMaker:
def __init__(self):
pass
def doMaking(self,m,n):
array = numpy.zeros((m,n))
for mm in range(0,m):
for nn in range(0,n):
array[mm][nn] = -1
i = 0
j = 0
k = -1
imode = 1
while True:
if k==m*n-1:
break
if array[i][j]==-1:
k += 1
array[i][j] = k
# go east
if imode==1 and j!=n-1 and array[i][j+1]==-1:
j=j+1
continue
else:
imode = 2
pass
# go south
if imode==2 and i!=m-1 and array[i+1][j]==-1:
i=i+1
continue
else:
imode = 3
pass
# go west
if imode==3 and j!=0 and array[i][j-1]==-1:
j=j-1
continue
else:
imode = 4
pass
# go north
if imode==4 and i!=0 and array[i-1][j]==-1:
i=i-1
continue
else:
imode = 1
pass
for i in range(0,n):
for j in range(0,m):
item = str(int(array[i][j]))
item = "{0:>5}".format(item)
print(item,end=" ")
print("")
a = SpiralMaker()
a.doMaking(6,6)
#include <iostream>
#include <vector>
using namespace std;
class Matrix {
int a, b;
int** matrix;
public :
Matrix(const int a, const int b) {
this->a=a;
this->b=b;
malloc();
}
void malloc() {
matrix = new int*[a];
for (int i =0;i<a;i++) {
matrix[i] = new int[b];
}
}
void demalloc() {
for(int i=0;i<a;i++) {
delete [] matrix[i];
}
delete [] matrix;
}
~Matrix() {
demalloc();
}
void makeTop (int& num, int round) {
int x=b-round*2;
for(int i =0;i<x;i++) {
matrix[round][i+round]=num++;
}
}
void makeRight(int& num, int round) {
int x=a-round*2-1;
for(int i =0;i<x;i++) {
matrix[i+round+1][b-round-1]=num++;
}
}
void makeBottom(int& num, int round) {
int x=b-round*2-1;
for(int i =0;i<x;i++) {
matrix[a-round-1][b-2-i-round]=num++;
}
}
void makeLeft(int& num, int round) {
int x=a-round*2-2;
for(int i =0;i<x;i++) {
matrix[a-2-round-i][round]=num++;
}
}
void print() const {
for(int i =0; i<a;i++) {
for(int j=0;j<b;j++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
}
};
int main() {
int a, b;
cin >> a >> b;
Matrix m(a,b);
int num=0;
int round=0;
while (num!=a*b) {
m.makeTop(num, round);
if (num==a*b) {
break;
}
m.makeRight(num, round);
if (num==a*b) {
break;
}
m.makeBottom(num, round);
if (num ==a*b) {
break;
}
m.makeLeft(num, round);
round++;
}
m.print();
return 0;
}
파이썬 3.8
단순하게 접근해봤습니다.
그냥 리스트를 회전 시켜 버리기!!!
리스트를 반시계 방향으로 회전 시키며 숫자를 할당하는 방식입니다.
x, y = map(int, input( "숫자를 입력하세요 : ", ).split())
lis = eval( str( [ [""] * x ] * y) )
cnt = n = 0
while True:
if "" in lis[n]:
cnt += 1
lis[n][lis[n].index("")] = "{0:3d}".format(cnt)
lis = list( reversed( list( map(list, zip( * lis ) ) ) ) ) if "" not in lis[n] else lis
n += 1 if "" not in lis[n] and len(lis[n]) - 1 > n <len(lis) - 1 else 0
if cnt == x * y and int(lis[0][0]) == 1:
print('\n'.join([' '.join(i) for i in lis]))
break
# 입력 값이 4 4 일 때 반시계 방향으로 리스트 회전시키며 숫자 할당
#
# lis[0] = [ 1, 2, 3, 4] => [4, 5, 6, 7] => [ 7, 8, 9, 10] => [10, 11, 12, 1]
# lis[1] = ["", "", "", ""] => [3, "", "", ""] => [ 6, "", "", ""] => [ 9, "", "", 2]
# lis[2] = ["", "", "", ""] => [2, "", "", ""] => [ 5, "", "", ""] => [ 8, "", "", 3]
# lsi[3] = ["", "", "", ""] => [1, "", "", ""] => [ 4, 3, 2, 1] => [ 7, 6, 5, 4]
# => [ 1, 2, 3, 4] => [4, 5, 6, 7] => [7, 8, 9, 10]
# => [12, 13, 14, 5] => [3, 14, 15, 8] => [6, 15, 16, 11]
# => [11, "", "", 6] => [2, 13, "", 9] => [5, 14, 13, 12]
# => [10, 9, 8, 7] => [1, 12, 11, 10] => [4, 3, 2, 1]
def cut_list(a, b, *str):
while True:
piece.append(a)
a -= 1
if b - 1 == 0:
break
piece.append(b - 1)
b -= 1
if a == 0:
break
a, b = input('enter two intergers: ').split()
a = int(a)
b = int(b)
sum = 0
num = list(range(0, a * b))
piece = []
small = []
cut_list(a, b, piece)
for i in range(0, len(piece)):
small.append(num[sum:sum + piece[i]])
sum += piece[i]
for j in range(2, len(small), 4):
small[j].reverse()
for j in range(3, len(small), 4):
small[j].reverse()
print(piece)
print(small)
for k in range(0, len(piece), 4):
for l in range(0, len(small[k])):
num[int((a + 1) * k / 4) + l] = small[k][l]
for i in range(2, len(piece), 4):
for j in range(0, len(small[i])):
num[(a * b - 1 - (a - 1) * int((i + 2) / 4) + j)] = small[i][j]
for i in range(1, len(piece), 4):
for j in range(0, len(small[i])):
num[2 * a - 1 + a * j + int((i - 1) / 4) * (a - 1)] = small[i][j]
for i in range(3, len(piece), 4):
for j in range(0, len(small[i])):
num[a + a * j + int((i - 3) / 4) * (a + 1)] = small[i][j]
for i in range(0, b):
for j in range(0, a):
print('{:>2}'.format(num[j + a * i]), end = ' ')
print()
python 3.9.1
array가 회전된 상태일 때 순방향 가로, 순방향 세로, 역방향 가로, 역방향 세로로 나뉘는걸 이용해서 풀어 봤습니다.
inp = input('please enter two numbers with whitesapce:')
#input gaurdian
while True:
try :
lxy = inp.split()
x = int(lxy[0])
y = int(lxy[1])
break
except:
inp = input('please re-enter two numbers with whitesapce(ex.6 6) :')
llines = list()
for n in range(y):
llines.append(list(range(x)))
#print(llines)
standnum = 1
inputnum = 0
for i in range(int(y/2)+1):
#시계방향 반바퀴
for a in range(x):
if a < standnum-1 or a > x-standnum:
continue
llines[standnum-1][a] = inputnum
inputnum += 1
for b in range(y):
if b < standnum or b > y-standnum:
continue
llines[b][x-standnum] = inputnum
inputnum += 1
#나머지 반바퀴
temp = list(range(x))
temp.sort(reverse=True)
for a in temp:
if x-1-standnum < a or a < standnum-1:
continue
llines[y-standnum][a] = inputnum
inputnum += 1
temp = list(range(y))
temp.sort(reverse=True)
for b in temp:
if y-1-standnum < b or standnum > b :
continue
llines[b][standnum-1] = inputnum
inputnum += 1
standnum += 1
#테두리 한 줄 완성
for i in llines:
print(i)
조잡한 코드 입니다 ㅠ
width = 6
height = 8
matrix = [[0]*width for _ in range(height)]
direction = ['right','down','left','up']
current_direction = direction[0]
x = 0
y = 0
fill_this_number = 1
while fill_this_number < width * height:
print(fill_this_number)
if current_direction == 'right' :
if x+1 >= width or matrix[y][x+1] != 0 :
current_direction = 'down'
else :
matrix[y][x + 1] = fill_this_number
fill_this_number += 1
x += 1
elif current_direction == 'down':
if y+1 >= height or matrix[y+1][x] != 0 :
current_direction = 'left'
else :
matrix[y + 1][x] = fill_this_number
fill_this_number += 1
y += 1
elif current_direction == 'left':
if x-1 < 0 or matrix[y][x-1] != 0 :
current_direction = 'up'
else :
matrix[y][x - 1] = fill_this_number
fill_this_number += 1
x -= 1
else:
if y - 1 < 1 or matrix[y - 1][x] != 0:
current_direction = 'right'
else:
matrix[y - 1][x] = fill_this_number
fill_this_number += 1
y -= 1
for i in matrix:
print(i)
c언어로 작성했습니다.
#include <stdio.h>
#include <stdlib.h>
int i, j; // 전역변수 i j 선언한다.
int** arr; // 전역 이중포인터int arr 선언한다. << 2차원배열을 만들기위해 사용.
int a = 0; // 전역변수 a=0 으로 만들어준다.
void spiral(int n, int m, int k){ // 배열에 회전을 주는 함수 spiral을 만든다. >> n은 행, m은 열, k는 위치포인트.
if(m < 1 || n < 1){ // 행 or 열이 1미만이 되면 함수 종료.
return;
}
for(i=0; i<m; i++){ // 가로로 늘리면서 배열.
arr[k][k+i] = a;
a += 1;
}
if(n == 1){ // 행이 1이면 여기서 종료
return;
}
for(i=0; i<n-1; i++){ // 세로로 늘리면서 배열
arr[i+1+k][m-1+k] = a;
a += 1;
}
if(m == 1){ // 열이 1이면 여기서 종료
return;
}
for(i=0; i<m-1; i++){ // 가로로 줄이면서 배열
arr[n-1+k][m-2+k-i] = a;
a += 1;
}
for(i=0; i<n-2; i++){ // 세로로 줄이면서 배열
arr[n-2+k-i][k] = a;
a += 1;
}
spiral(n-2, m-2, k+1); // 행과 열을 2줄이고 위치포인트를 1 늘린 뒤 자기자신을 호출
}
int main(){
int n, m, k;
k = 0;
scanf("%d %d", &n, &m);
arr = (int**)calloc(n, sizeof(int*)); // ** 동적할당
arr[0] = (int*)calloc(n*m, sizeof(int)); // * 동적할당
for(i=1; i<n; i++){ // 2차원 배열을 만든다.
arr[i] = arr[i-1]+m;
}
spiral(n, m, k); // spiral함수 호출
for(i=0; i<n; i++){ // 만들어진 배열을 출력한다.
for(j=0; j<m; j++){
printf("%d ", arr[i][j]);
}
printf("\n");
}
free(arr); // 동적할당해준 배열을 해제한다.
free(arr[0]);
}
malloc이 아닌 calloc을 쓴 이유는 만든 함수를 시험해보는데 주소값이 들어가서 배열 모양이 망가지더라구요 그래서 calloc으로 0으로 다 만들어준뒤 배열 모양을 이쁘게 하고 알아보기 쉽게 하기위해서 calloc으로 했습니다
import numpy as np
r, c = tuple(map(int, input().split()))
m = np.zeros((r,c), dtype=int)
x = 0
y = 0
i = 0
count = 1
direction = 'right'
while count < r*c:
if direction == 'right':
x += 1
m[y][x] = count
count += 1
if x == c-1-i:
direction = 'down'
elif direction == 'down':
y += 1
m[y][x] = count
count += 1
if y == r-1-i:
direction = 'left'
elif direction == 'left':
x -= 1
m[y][x] = count
count += 1
if x == c-c+i:
direction = 'up'
elif direction == 'up':
y -= 1
m[y][x] = count
count += 1
if y == r-(r-1)+i:
direction = 'right'
i += 1
print(m)
[결과]
3 3
[[0 1 2]
[7 8 3]
[6 5 4]]
========================================
6 6
[[ 0 1 2 3 4 5]
[19 20 21 22 23 6]
[18 31 32 33 24 7]
[17 30 35 34 25 8]
[16 29 28 27 26 9]
[15 14 13 12 11 10]]
X, Y=map(int, input("달팽이 가로세로 : ").split(' ')) #가로로 값 나란히 2개 입력
print()
a = [[-1 for j in range(X)] for i in range(Y)] #2차원 리스트 생성(X열, Y행)
dx_s, dx_e = 0, X # X열의 시작과 끝
dy_s, dy_e = 1, Y # Y행의 시작과 끝
i=j=cnt=0 # i=행, j=열
turn=1 # 4방향 (→ ↓ ← ↑)
while cnt < (X*Y-1): # 행렬의 마지막 값까지 반복
if turn==1:
for j in range(dx_s, dx_e): # 행 고정, 열 증가
a[i][j]=cnt
cnt+=1
dx_e-=1 # 열 끝 1 감소
turn=2
elif turn==2:
for i in range(dy_s, dy_e): # 행 증가, 열 고정
a[i][j]=cnt
cnt+=1
dy_e-=1 # 행 끝 1 감소
turn=3
elif turn==3:
for j in range(dx_e-1, dx_s-1, -1): # 행 고정, 열 감소
a[i][j]=cnt
cnt+=1
dx_s+=1 # 열 시작 1 증가
turn=4
elif turn==4:
for i in range(dy_e-1, dy_s-1, -1): # 행 감소, 열 고정
a[i][j]=cnt
cnt+=1
dy_s+=1 # 행 시작 1 증가
turn=1
for i in a:
for j in i: # 배열원소를 하나씩 값으로 읽어오기
print("%3d" %j, end='')
print()
def SpiralArray(a,b):
z = [[0 for x in range(a)] for y in range(b)] #구조 a x b
t = 0 #연번(1,2,3...a*b)
x,y = -1,0 #x,y좌표
p = 1 #부호
while a:
b -= 1
for i in range(a):
x += p
z[y][x] = t
t += 1
for i in range(b):
y += p
z[y][x] = t
t += 1
a -= 1
p *= -1 #부호 +/- 토글
if b==0: break
#결과출력(z)
for x in z:
for y in x:
print(f"{y:3}", end=" ")
print("")
print("")
SpiralArray(6,6)
SpiralArray(9,5)
SpiralArray(21,18)
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
0 1 2 3 4 5 6 7 8
23 24 25 26 27 28 29 30 9
22 39 40 41 42 43 44 31 10
21 38 37 36 35 34 33 32 11
20 19 18 17 16 15 14 13 12
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 21
72 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 93 22
71 138 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 157 94 23
70 137 196 247 248 249 250 251 252 253 254 255 256 257 258 259 260 213 158 95 24
69 136 195 246 289 290 291 292 293 294 295 296 297 298 299 300 261 214 159 96 25
68 135 194 245 288 323 324 325 326 327 328 329 330 331 332 301 262 215 160 97 26
67 134 193 244 287 322 349 350 351 352 353 354 355 356 333 302 263 216 161 98 27
66 133 192 243 286 321 348 367 368 369 370 371 372 357 334 303 264 217 162 99 28
65 132 191 242 285 320 347 366 377 376 375 374 373 358 335 304 265 218 163 100 29
64 131 190 241 284 319 346 365 364 363 362 361 360 359 336 305 266 219 164 101 30
63 130 189 240 283 318 345 344 343 342 341 340 339 338 337 306 267 220 165 102 31
62 129 188 239 282 317 316 315 314 313 312 311 310 309 308 307 268 221 166 103 32
61 128 187 238 281 280 279 278 277 276 275 274 273 272 271 270 269 222 167 104 33
60 127 186 237 236 235 234 233 232 231 230 229 228 227 226 225 224 223 168 105 34
59 126 185 184 183 182 181 180 179 178 177 176 175 174 173 172 171 170 169 106 35
58 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 107 36
57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37
a,b=map(int,input('').split(' '))
for_answer=array = [[0 for col in range(a)] for row in range(b)]
print(for_answer)
_count=1
max_count=a*b
min_x=0
min_y=0
max_x=a
max_y=b
def print_x(x):
for i in range(len(x)):
print(x[i])
while _count<=max_count:
for x in range(min_x,max_x,1):
if for_answer[min_y][x]==0:
for_answer[min_y][x]=_count
_count+=1
min_y+=1
print(1)
for y in range(min_y,max_y,1):
if for_answer[y][max_x-1] ==0:
for_answer[y][max_x-1]=_count
_count+=1
max_x-=1
print(2)
for x in range(max_x-1,min_x-1,-1):
if for_answer[max_y-1][x]==0:
for_answer[max_y-1][x]=_count
_count+=1
max_y-=1
print(3)
for y in range(max_y-1,min_y-1,-1):
if for_answer[y][min_x]==0:
for_answer[y][min_x]=_count
_count+=1
min_x+=1
print_x(for_answer)
패턴 배열로 문제 풀어봤습니다. 아직 너무 부족한거 같구 좀더 좋은 방법으로 풀 수 있도록 공부하겠습니다!
n,m = 6,6
d = [[0]*(n) for _ in range(m)]
count = 0
a,b = 0,-1
direction = 1
while 1:
m -=1
for i in range(n):
b +=direction
d[a][b] = count
count+=1
for j in range(m):
a+=direction
d[a][b] = count
count+=1
direction *=-1
n -=1
if count == (n*m): break
for i in d:
for j in i:
print(f'{j:3d}',end=' ')
print()
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("행 열의 크기 ==>");
int run = scanner.nextInt();
int x = 0; //행
int y = -1; // 열
int num = 0; // 숫자 채워주는 변수
int sw = 1; // 채워주는 방향 정해줌
int[][] spiralArray = new int[run][run];
while(true) {
for (int i = 0; i < run; i++) {
y += sw;
spiralArray[x][y] = num++;
}
run-=1;
if(run <= 0) {
break;
}
for(int i = 0 ; i < run ; i ++) {
x += sw;
spiralArray[x][y] = num++;
}
sw *= -1;
}
// 출력
for (int i = 0; i < spiralArray.length; i++) {
for (int j = 0; j < spiralArray[0].length; j++) {
System.out.printf("%02d ",spiralArray[i][j]);
}
System.out.println();
}
}
}
package justStudying;
public class test3_20210818 {
static int[][] box;
// (0,1) 오른
// (0,-1) 왼
// (1,0) 밑
// (-1,0) 위
public static void maxBox(int x, int y, int val, int xflag, int yflag) {
box[x][y]=val;
if(yflag == 1) {
if(y+1<box[x].length) {
if(box[x][y+1] == -1) maxBox(x,y+1,++val,0,1);
else if(x+1<box.length && box[x+1][y] == -1) maxBox(x+1,y,++val,1,0);
} else if(x+1<box.length && box[x+1][y] == -1) maxBox(x+1,y,++val,1,0);
}else if(yflag == -1) {
if(y-1>=0) {
if(box[x][y-1] == -1) maxBox(x,y-1,++val,0,-1);
else if(x-1>=0 && box[x-1][y] == -1) maxBox(x-1,y,++val,-1,0);
} else if(x-1>=0 && box[x-1][y] == -1) maxBox(x-1,y,++val,-1,0);
}else if(xflag == 1) {
if(x+1<box.length) {
if(box[x+1][y] == -1) maxBox(x+1,y,++val,1,0);
else if(y-1>=0 && box[x][y-1] == -1) maxBox(x,y-1,++val,0,-1);
} else if(y-1>=0 && box[x][y-1] == -1) maxBox(x,y-1,++val,0,-1);
} else if(xflag == -1) {
if(x-1>=0) {
if(box[x-1][y] == -1) maxBox(x-1,y,++val,-1,0);
else if(y+1<box[x].length && box[x][y+1] == -1) maxBox(x,y+1,++val,0,1);
} else if(y+1<box[x].length && box[x][y+1] == -1) maxBox(x,y+1,++val,0,1);
}
}
public static void sol(int x, int y) {
box = new int[x][y];
for(int i=0; i<x; i++) {
for(int j=0; j<y; j++) {
box[i][j] = -1;
}
}
maxBox(0,0,0,0,1);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
sol(6,6);
for(int i=0; i<box.length; i++) {
for(int j=0; j<box[i].length; j++) {
System.out.print(box[i][j] + " ");
}
System.out.println();
}
}
}
def array_make(a, b):
result = []
for i in range(a):
result_temp = []
for j in range(b):
result_temp.append('0')
result.append(result_temp)
return result
def array_print(_array):
for member_row in _array:
print(' '.join(member_row))
def array_spin(a, b):
array_temp = array_make(a, b)
count = 1
direction = 'right'
i = 0
j = 0
while count <= a*b:
if array_temp[i][j] == '0' and direction == 'right':
array_temp[i][j] = str(count)
count += 1
j += 1
try:
if array_temp[i][j] != '0':
direction = 'down'
j -= 1
i += 1
except:
direction = 'down'
j -= 1
i += 1
elif array_temp[i][j] == '0' and direction == 'down':
array_temp[i][j] = str(count)
count += 1
i += 1
try:
if array_temp[i][j] != '0':
direction = 'left'
j -= 1
i -= 1
except:
direction = 'left'
j -= 1
i -= 1
elif array_temp[i][j] == '0' and direction == 'left':
array_temp[i][j] = str(count)
count += 1
j -= 1
try:
if array_temp[i][j] != '0':
direction = 'up'
j += 1
i -= 1
except:
direction = 'up'
j += 1
i -= 1
elif array_temp[i][j] == '0' and direction == 'up':
array_temp[i][j] = str(count)
count += 1
i -= 1
try:
if array_temp[i][j] != '0':
direction = 'right'
j += 1
i += 1
except:
direction = 'right'
j += 1
i += 1
return array_temp
array_print(array_spin(6, 6))
public class SpiralArray {
private static int SIZE = 5;
private static int MATRIX_SIZE = SIZE * SIZE;
public static void initializeMatrix(char[][] matrix){
for(int i=0; i<SIZE; i++){
for(int j=0; j<SIZE; j++){
matrix[i][j] = ' ';
}
}
}
public static String makeSpiralArray(StringBuilder text, char[][] matrix){
int i = 0, j = 0;
String direction = "RIGHT";
for(int count=0; count<MATRIX_SIZE; count++){
try{
switch(direction){
case "RIGHT":
matrix[i][j++] = text.charAt(0);
if(j == SIZE || matrix[i][j] != ' '){
i++;
j--;
direction = "DOWN";
}
break;
case "DOWN":
matrix[i++][j] = text.charAt(0);
if(i == SIZE || matrix[i][j] != ' '){
i--;
j--;
direction = "LEFT";
}
break;
case "LEFT":
matrix[i][j--] = text.charAt(0);
if(j == -1 || matrix[i][j] != ' '){
i--;
j++;
direction = "UP";
}
break;
case "UP":
matrix[i--][j] = text.charAt(0);
if(i == 0 || matrix[i][j] != ' '){
i++;
j++;
direction = "RIGHT";
}
break;
}
text.deleteCharAt(0);
} catch (Exception e) {
System.out.println(e);
break;
}
}
if(text != null) {
return text.toString();
} else {
return "No spare text";
}
}
public static void main(String[] args){
String text = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
StringBuilder tempText = new StringBuilder(text);
String spareText = new String();
char[][] matrix = new char[SIZE][SIZE];
initializeMatrix(matrix);
spareText = makeSpiralArray(tempText, matrix);
for(int i=0; i < SIZE; i++){
for(int j=0; j < SIZE; j++){
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
System.out.println("Spare text : " + spareText);
}
}
import numpy as np
row , col = map(int, input().split())
spiral_array = [[0 for _ in range(col)]for _ in range(row)]
x, y = 0, 0
count = 1
while row * col > count:
#이동방향이 오른쪽
while x < col-1 and spiral_array[y][x+1] == 0 :
x += 1
spiral_array[y][x] = count
count += 1
#이동방향이 아래쪽
while y < row-1 and spiral_array[y+1][x] == 0 :
y += 1
spiral_array[y][x] = count
count += 1
#이동방향이 왼쪽
while x > 0 and spiral_array[y][x-1] == 0:
x -= 1
spiral_array[y][x] = count
count += 1
#이동방향으 위쪽
while y > 1 and spiral_array[y-1][x] == 0: # array[0][0] 값이 0이므로 y는 1보다 클 때로 0의 인덱스의 가기전에 멈춰줍니다.
y -= 1
spiral_array[y][x] = count
count += 1
for i in spiral_array:
for j in i:
print('{:3d}'.format(j),end = ' ')
print()
// Rust
// 이동벡터 [(0,1), (1,0), (0, -1), (-1,0)]이 %4로 반복됩니다.
// index 각 끝단을 만나거나, 이미 채운 위치를 만나면 방향을 바꿔줍니다.
fn spiral_array() {
let (n, m): (i32, i32) = (6, 6);
let direction: [(i32, i32); 4] = [(0,1), (1,0), (0,-1), (-1,0)];
let mut arr: Vec<Vec<i32>> = vec![vec![-1; m as usize]; n as usize];
let (mut i, mut j): (i32, i32) = (0, 0);
let mut dir = 0;
for k in 0..n * m {
arr[i as usize][j as usize] = k as i32;
let mut mv: (i32, i32) = direction[dir];
if i + mv.0 >= m || i + mv.0 < 0 || j + mv.1 >= n || j + mv.1 < 0
|| arr[(i + mv.0) as usize][(j + mv.1) as usize] != -1 {
dir += 1;
dir %= 4;
mv = direction[dir];
}
i += mv.0;
j += mv.1;
}
arr.iter().for_each(|l| println!("{:?}", l));
}
n = list(map(int,input("X x Y 배열을 입력하시오").split(" ")))[0]
def coordination(n):
x = 0
y = 0
t=-1
arr=[[x,y]]
for k in range(n-1):
y+=1
arr.append([x,y])
for j in range(n-1,0,-1):
t=t*(-1)
for i in range(j):
x +=t
arr.append([x,y])
for k in range(j):
y +=-t
arr.append([x,y])
return arr
def spiral (n):
arr = coordination(n)
a =[[0]*(n) for _ in range(n)]
for k in range(len(arr)):
a[arr[k][0]][arr[k][1]] = k
for i in a:
for k in range(len(i)):
print(i[k],end=' ')
print('')
spiral(n)
coordination이라는함수를 통해서 먼저, 회전하는 좌표쌍을 구하고, 0부터 숫자를 해당 좌표쌍에 대입하는 방식으로 짜봤습니다
import numpy as np
c,r = map(int,input().split(' '))
li = [[-1 for col in range(c)] for row in range(r)]
cnt = 0
rot_cnt = -1
row,col = 0,0
rot_list = [(0,1),(1,0),(0,-1),(-1,0)]
while cnt < c*r:
rot_cnt += 1
rd = rotation_direction = rot_cnt % 4
d_row,d_col = rot_list[rd]
while True :
li[row][col] = cnt
cnt = cnt +1
if row + d_row < r and col + d_col < c and li[row + d_row][col+d_col] == -1:
row = row + d_row
col = col + d_col
if row + d_row == r or col + d_col == c or li[row + d_row][col+d_col] != -1:
break
np_li = np.array(li)
print(np_li)
def matrix_out(num):
result = [[0 for i in range(0, num)] for k in range(0, num)]
(a, b, j, count) = (0, -1, 1, 0) # j = curve_count 및 초기값 설정
dxdy = [[0, 1], [1, 0], [0, -1], [-1, 0]]*round(num/2)
curve_pattern = [num] + [(num - i) for i in range(1, num)] * 2
curve_pattern.sort(reverse=True)
curve = [sum(curve_pattern[:i]) for i in range(1, 2 * num - 1)]
for i in curve_pattern:
if curve[j - 1] == count: j += 1
for k in range(0, i):
a, b = a + dxdy[j-1][0], b + dxdy[j-1][1]
result[a][b] = count
count += 1
for i in range(0, num):
for k in range(0,num):
print(result[i][k], end = '\t')
print("\n")
num = input("행렬 크기를 입력해주세요 : ")
matrix_out(int(num))
모든 n*n 행렬에서 가능한 함수입니다.
# 6 6
# 0 1 2 3 4 5
# 19 20 21 22 23 6
# 18 31 32 33 24 7
# 17 30 35 34 25 8
# 16 29 28 27 26 9
# 15 14 13 12 11 10
# 올림 사용을 위한 math 모듈 import
import math
# 행 개수와 열 개수에 대한 사용자 입력을 받는다.
m, n = map(int, input().split())
# 채워질 최종 숫자를 구한다.
num_last = m * n - 1
# 회전수를 구한다. m,n 중 작은 값을 2로 나눈 뒤 올림값
num_totalround = math.ceil(min(m, n)/2)
# 최종 행렬의 각 행을 리스트 변수 'list_행번호' 이름으로 생성한다.
for i in range(1, m+1):
a = globals()['list_{}'.format(i)] = list()
for j in range(1, n+1):
a.append('')
# 바깥에서 안쪽으로 회전하면서 리스트 변수의 값을 채운다.
i = 1 # 행번호
j = 1 # 열번호
num_cur = 0
for num_curround in range(1, num_totalround+1):
# 오른쪽으로 진행하면서 조건에 맞으면 행과 열 위치의 값을 대체함
while j <= n-num_curround+1 and num_cur <= num_last:
exec('list_'+str(i)+'['+str(j-1)+']='+str(num_cur))
num_cur += 1
if j == n-num_curround+1:
i += 1
break
else:
j += 1
# 아래쪽으로 진행하면서 조건에 맞으면 행과 열 위치의 값을 대체함
while i <= m-num_curround+1 and num_cur <= num_last:
exec('list_'+str(i)+'['+str(j-1)+']='+str(num_cur))
num_cur += 1
if i == m-num_curround+1:
j += -1
break
else:
i += 1
# 왼쪽으로 진행하면서 조건에 맞으면 행과 열 위치의 값을 대체함
while j >= num_curround and num_cur <= num_last:
exec('list_'+str(i)+'['+str(j-1)+']='+str(num_cur))
num_cur += 1
if j == num_curround:
i += -1
break
else:
j += -1
# 위쪽으로 진행하면서 조건에 맞으면 행과 열 위치의 값을 대체함
while i >= num_curround+1 and num_cur <= num_last:
exec('list_'+str(i)+'['+str(j-1)+']='+str(num_cur))
num_cur += 1
if i == num_curround+1:
j += 1
break
else:
i += -1
# 최종적으로 출력한다.
for i in range(1, m+1):
list_cur = eval('list_'+str(i))
for j in list_cur:
print('{:3d}'.format(j), end=' ')
print()
import numpy as np
a = (input("")).split(" ")
array_len = int(a[0])*int(a[1])
array = np.arange(array_len).reshape(int(a[0]),int(a[1]))
array
x = int(a[0])
y = int(a[1])
for i in range(1,x):
array[i][y-1] = (y-1)+i
for n in range(1, x//2):
for i in range(1, (x-(2*n))+1):
array[n+i][y-(n+1)]=((((2*n)+1)*x)-sum(range(1,(2*n+1)))+((2*n)*y)-sum(range(1,(2*n+1))))+i-1
for n in range(1, (x//2)+1):
for i in range(1,x-(2*n-1)):
array[x-n-i][n-1] = (((2*n)*x)-sum(range(1,2*n)))+(((2*n)-1)*y-sum(range(1,2*n)))+i-1
for n in range(1, ((y+1)//2)+1):
for i in range(n,y-n):
array[n][i] = ((((2*n)*x)-sum(range(1,2*n)))+((2*n)*y)-sum(range(1,(2*n+1))))+(i-n+1)-1
for n in range(1,((y+1)//2)+1):
for i in range(1, y-2*(n-1)):
array[x-n][y-n-i] = (((2*n-1)*x)-sum(range(1,2*n-1))+((2*n-1)*y)-sum(range(1,2*n)))+i-1
for k in range(x):
print("\n")
for j in range(y):
if array[k][j]<10:
print("",array[k][j], end=' ')
else:
print(array[k][j], end=' ')
자바로 풀어봤습니다.
import java.util.Arrays;
import java.util.Scanner;
public class test {
// 결과 출력
public static void printResult(int[][] result, int m, int n) {
System.out.println("Result = ");
for(int i=0; i<m; i++) {
for(int j=0;j<n; j++) {
System.out.printf("%3d",result[i][j]);
}
System.out.println();
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Spiral Array의 사이즈(m:row, n:column): ");
int m = scan.nextInt();
int n = scan.nextInt();
int [][] result = new int[m][n];
int count = 0, direction = 0, row=0, column=0;
while(count<m*n) {
switch(direction) {
case 0:
for(int j=column; j<n-1-column; j++) {
result[column][j] = count;
count++;
}
direction++;
break;
case 1:
for(int i=row; i<m-1-row; i++) {
result[i][n-column-1] = count;
count++;
}
direction++;
break;
case 2:
for(int j=n-column-1; j>column; j--) {
result[m-1-row][j] = count;
count++;
}
direction++;
break;
case 3:
for(int i=m-1-row; i>row; i--) {
result[i][column] = count;
count++;
}
direction = 0;
column++;
row++;
break;
}
}
printResult(result, m, n);
}
}
#include <stdio.h>
int a[1001][1001];
int main()
{
int n,m;
scanf("%d %d",&n,&m);
int k=1;
int y=0;
int x=0;
int d=1;
while(k <= n*m) {
a[y][x] = k++;
if (d == 1) {
if (x == n-1) {
d=2;
y++;
}
else if (a[y][x+1] > 0) {
d=2;
y++;
}
else x++;
}
else if (d == 2) {
if (y == m-1) {
d=3;
x--;
}
else if (a[y+1][x] > 0) {
d=3;
x--;
}
else y++;
}
else if (d==3) {
if (x == 0) {
d =4;
y--;
}
else if (a[y][x-1] > 0) {
d=4;
y--;
}
else x--;
}
else {
if (y == 0) {
d=1;
x++;
}
else if (a[y-1][x] > 0) {
d=1;
x++;
}
else y--;
}
}
for (int i=0; i<m; i++) {
for (int j=0; j<n; j++) printf("%d ",a[i][j]-1);
printf("\n");
}
}
c = int(input("column c 입력 : "))
r = int(input("row r 입력 : "))
na=[[0 for col in range(r)] for row in range(c)]
#print(na)
#원점 저장
cs,rs=0,0
ce,re=c,r
#print(ce,re)
v=1
while v<=c*r :
i,j=cs,rs
#가로정방향진행
while i<ce and v<=c*r :
#print("L",i,j)
na[i][j]=v
v+=1
i+=1
#print(na)
j+=1
i-=1
#세로정방향진행
while j<re and v<=c*r :
#print("M",i,j)
na[i][j]=v
v+=1
j+=1
i-=1
j-=1
#가로역방향진행
while i>=cs and v<=c*r:
#print("J",i,j)
na[i][j]=v
v+=1
i-=1
j-=1
i+=1
#세로역방향진행
while j>rs and v<=c*r:
#print("I",i,j)
na[i][j]=v
v+=1
j-=1
#원점 재지정
cs+=1
rs+=1
ce-=1
re-=1
#######################################################
#결과확인
#print(na)
k,l=0,0
while k<r :
while l<c :
print ('{0:6d}'.format(na[l][k]),end='')
l+=1
k+=1
l=0
print()
def spiral(row, col):
num = 0
r = 0
c = 0
stt_r = 1
stt_c = 1
#2차원 리스트 생성
arr=[]
for i in range(row):
arr_c=[]
for j in range(col):
arr_c.append(None)
arr.append(arr_c)
arr[r][c]=num
num += 1
while True:
if arr[r][c+stt_c] != None:
break
for i in range(col):
c += stt_c
arr[r][c]=num
num += 1
if c == 0 or c == col-1:
break
if arr[r][c+stt_c] != None:
break
stt_c *= -1
if arr[r+stt_r][c] != None:
break
for j in range(row):
r+=stt_r
arr[r][c]=num
num += 1
if r == 0 or r == row-1:
break
if arr[r+stt_r][c] != None:
break
stt_r *= -1
#출력
for i in arr:
for j in i:
print(str(j).rjust(2), end=" ")
print()
spiral(6, 6)
# Spiral Array
A = input().split()
M = int(A[0])
N = int(A[1])
MN = M * N # 6 x 6 = 36
# Start location
x = -1
y = 0
# Initial Vector
xd=1
yd=0
# Initial location limit : lower, upper
x1=0
y1=0
x2=M-1
y2=N-1
# MxN Array
d = [[0]*M for _ in range(N)]
# Array location : d(x, y)=i
for i in range(MN):
if x == x1-1 and y == y1:
xd = 1
yd = 0
y1 = y1 + 1
if x == x2 and y == y1-1:
xd = 0
yd = 1
x2 = x2 - 1
if x == x2+1 and y == y2:
xd = -1
yd = 0
y2 = y2 - 1
if x == x1 and y == y2+1:
xd = 0
yd = -1
x1 = x1 + 1
x = x + xd
y = y + yd
d[y][x] = i
# Print Result Array
for y in range(N):
for x in range(M):
print('{0:2}'.format(d[y][x]), end=' ')
print()
import numpy as np
def dim_slicer(x, y): # spiral한 순서로 이동하는 방향지시용 list를 생성
i = []
j = 1
dir_pattern = [[0, 1], [1, 0], [0, -1], [-1, 0]] # spiral의 방향 로테이션
xypattern = [x, y] # x by y 크기의 array에서, spiral 순서의 방향지시는
while j <= x*y:
i = i + [dir_pattern[(j-1)%4]]*(xypattern[j%2] - j//2) # 오른쪽 y번, 아래로 x-1번, 왼쪽 y-1번, 위로 x-2번, 오른쪽 y-2번.. 패턴으로 이뤄짐
j += 1
return i
def spiral_array(x, y):
base_array = np.zeros((x, y)) # 0으로 채워진 array에서 시작
dir_list = dim_slicer(x, y) # 방향지시용 list
[i, j] = [0, -1] # 시작지점
for l in range(0, x*y): # 0부터 x*y 미만까지 방향지시 list를 따라 차례로 반영
i = i + dir_list[l][0]
j = j + dir_list[l][1]
base_array[i, j] = l
return base_array
spiral_array(10, 8)
enum DIR_NAME {
LEFT = 'left',
RIGHT = 'right',
UP = 'up',
DOWN = 'down',
}
type D = 0 | 1 | -1
interface Position {
x: number
y: number
}
interface Direction {
dx: D
dy: D
}
const directions: { [key in DIR_NAME]: Direction } = {
[DIR_NAME.RIGHT]: { dx: 1, dy: 0 },
[DIR_NAME.LEFT]: { dx: -1, dy: 0 },
[DIR_NAME.UP]: { dx: 0, dy: -1 },
[DIR_NAME.DOWN]: { dx: 0, dy: 1 },
}
interface GetNextWay {
(type: DIR_NAME): DIR_NAME
}
const getNextWay: GetNextWay = (type: DIR_NAME): DIR_NAME => {
switch (type) {
case DIR_NAME.RIGHT:
return DIR_NAME.DOWN
case DIR_NAME.DOWN:
return DIR_NAME.LEFT
case DIR_NAME.LEFT:
return DIR_NAME.UP
case DIR_NAME.UP:
return DIR_NAME.RIGHT
}
}
class D2SpiralArray {
private d2arr: number[][]
private position: Position
private direction: Direction
private currWay: DIR_NAME
private count = 0
private getNextWay: GetNextWay
constructor(x: number, y: number, getNextWay: GetNextWay) {
this.d2arr = Array(x)
.fill(null)
.map(() => Array(y).fill(-1))
this.position = { x: 0, y: 0 }
this.currWay = DIR_NAME.RIGHT
this.direction = directions[this.currWay]
this.count = 0
this.getNextWay = getNextWay
this.fill()
}
private setArrayValue = () => {
const {
position: { x, y },
count,
} = this
this.d2arr[y][x] = count
}
private move = () => {
const { x, y } = this.position
const { dx, dy } = this.direction
this.position = { x: x + dx, y: y + dy }
}
private getValue = () => this.d2arr[this.position.y][this.position.x]
private isChangeWay = () => {
const checkX = [-1, this.d2arr[0].length]
const checkY = [-1, this.d2arr.length]
const { x, y } = this.position
return checkX.includes(x) || checkY.includes(y) || this.getValue() !== -1
}
private fill = () => {
while (this.getValue() === -1) {
this.setArrayValue()
this.count += 1
this.move()
if (this.isChangeWay()) {
const {
position: { x, y },
direction: { dx, dy },
} = this
this.position = { x: x - dx, y: y - dy }
this.currWay = this.getNextWay(this.currWay)
this.direction = directions[this.currWay]
this.move()
}
}
}
get array() {
return this.d2arr
}
}
console.log(getSpiralArray(6, 6))
if input("'6 6'을 입력하시오") != '6 6':
print('틀렸습니다.')
else:
answer =
'''
0 1 2 3 4 5
19 20 21 22 23 6
18 31 32 33 24 7
17 30 35 34 25 8
16 29 28 27 26 9
15 14 13 12 11 10
'''
print(answer)
이렇게 하면 되는 거 아님? ㅋㅋㅋㅋ
WIDTH, HEIGHT = 6, 6
x, y = 0, 0
start_x_index, start_y_index = 0, 0
end_x_index, end_y_index = WIDTH, HEIGHT
result_list = []
temp_list = []
count = 1
direction = 1 #방향 1:좌->우 2:상->하 3:우->좌 4:하->상
# 리스트 초기화
for i in range(0, HEIGHT):
for j in range(0, WIDTH):
temp_list.append(0)
result_list.append(temp_list[:])
temp_list.clear()
while True:
if count >= WIDTH * HEIGHT:
break
if direction == 1:
for i in range(start_y_index, end_y_index):
result_list[x][y] = count
count += 1
y += 1
start_x_index += 1
x += 1
y -= 1
direction = 2
if direction == 2:
for i in range(start_x_index, end_x_index):
result_list[x][y] = count
count += 1
x += 1
end_y_index -= 1
x -= 1
y -= 1
direction = 3
if direction == 3:
for i in range(end_y_index, start_y_index, -1):
result_list[x][y] = count
count += 1
y -= 1
end_x_index -= 1
y += 1
x -= 1
direction = 4
if direction == 4:
for i in range(end_x_index, start_x_index, -1):
result_list[x][y] = count
count += 1
x -= 1
start_y_index += 1
x += 1
y += 1
direction = 1
for i in result_list:
print(i)
def se(count):
re_val = str(count)
while(len(re_val) != 3):
re_val = ' ' + re_val
return re_val
def mk_2ch(num1):
n_list = []
for i in range(num1):
tmp = []
for j in range(num1):
tmp.append(' 0')
n_list.append(tmp)
return n_list
#main__
input_num = ''
result_list = []
reverse_list = []
while(1):
input_num = input("행렬 숫자 입력 : ")
try:
input_num = int(input_num)
break
except:
print("다시 입력하시길 바랍니다.")
max_len = input_num * input_num #입력개수
result_list = mk_2ch(input_num) #배열크기 동적할당
w_count = input_num #입력 횟수
h_count = input_num -1
w_count2 = w_count-1
h_count2 = h_count-1
w_input = 0 #입력위치
h_input = input_num-1 #
w_input2 = input_num-1 #
h_input2 = 0 #
arrow = 0 #방향 구분자
count = 0 #입력값
range_while = 0
while (1):
if count == max_len: #탈출 구분자
break
elif arrow == 0: # 우측이동
for i in range(w_count):
result_list[w_input][i + (input_num - w_count - range_while)] = se(count)
count += 1
w_input += 1
w_count -= 2
arrow += 1
if arrow == 1: # 하향이동
for i in range(h_count):
result_list[i + (input_num - h_count - range_while) ][h_input] = se(count)
count += 1
h_input -= 1
h_count -= 2
arrow += 1
range_while += 1
if arrow == 2: # 좌측이동
reverse_list.clear()
for i in range(w_count2):
reverse_list.append(count)
count += 1
reverse_list.sort(reverse = True)
for i in range(w_count2):
result_list[w_input2][i + (input_num - w_count2 - range_while)] = se(reverse_list[i])
w_input2 -= 1
w_count2 -= 2
arrow += 1
if arrow == 3: #상향이동
reverse_list.clear()
for i in range(h_count2):
reverse_list.append(count)
count += 1
reverse_list.sort(reverse = True)
for i in range(h_count2):
result_list[i +(input_num - h_count2 - range_while)][h_input2] = se(reverse_list[i])
h_input2 += 1
h_count2 -= 2
arrow = 0
for x in result_list:
print(x)
#include <stdio.h>
#include <stdlib.h>
void input(int *y, int *x);
int **make_yx(int y, int x);
void fill_0(int **yx, int y, int x);
void fill_number(int **yx, int y, int x);
void print_yx(int **yx, int y, int x);
void free_memory(int **yx, int y);
void input(int *y, int *x)
{
scanf("%d%d", y, x);
}
int **make_yx(int y, int x)
{
int **yx = NULL;
int a = 0;
yx = (int **)malloc(sizeof(int *) * y);
for (a = 0; a < y; a++)
{
yx[a] = (int *)malloc(sizeof(int) * x);
}
return yx;
}
void fill_0(int **yx, int y, int x)
{
int a = 0;
int b = 0;
for (a = 0; a < y; a++)
{
for (b = 0; b < x; b++)
{
yx[a][b] = 0;
}
}
}
void fill_number(int **yx, int y, int x)
{
int yy = 0;
int xx = 0;
int minus = -1;
int zero = 0;
int start = 0;
int number = 0;
int number_end = y * x;
while (1)
{
while (1)
{
yx[yy][xx] = number;
xx++;
number++;
if (number == number_end)
{
goto end;
}
if (xx == x)
{
xx--;
yy++;
break;
}
}
while (1)
{
yx[yy][xx] = number;
yy++;
number++;
if (number == number_end)
{
goto end;
}
if (yy == y)
{
xx--;
yy--;
break;
}
}
while (1)
{
yx[yy][xx] = number;
xx--;
number++;
if (number == number_end)
{
goto end;
}
if (xx == minus)
{
xx++;
yy--;
break;
}
}
while (1)
{
yx[yy][xx] = number;
yy--;
number++;
if (number == number_end)
{
goto end;
}
if (yy == zero)
{
minus++;
zero++;
start++;
xx = start;
yy = start;
break;
}
}
y = y - 1;
x = x - 1;
}
end:
return;
}
void print_yx(int **yx, int y, int x)
{
int a = 0;
int b = 0;
printf("\n");
for (a = 0; a < y; a++)
{
for (b = 0; b < x; b++)
{
printf("%3d", yx[a][b]);
}
printf("\n");
}
}
void free_memory(int **yx, int y)
{
int a = 0;
for (a = 0; a < y; a++)
{
free(yx[a]);
}
free(yx);
}
int main(int argc, char *argv[])
{
int y = 0;
int x = 0;
int **yx = NULL;
input(&y, &x);
yx = make_yx(y, x);
fill_0(yx, y, x);
fill_number(yx, y, x);
print_yx(yx, y, x);
free_memory(yx, y);
return 0;
}
사용언어 : Kotlin
import java.util.*
/**
* spiral 만들기
* 1. m * n 2차원 배열 생성
* 2. 오른쪽 -> 아래 -> 왼쪽 -> 위 순으로 배열을 채워가며 이동
* 3. 배열에 값이 할당되어 있거나, 값 할당 횟수가 m * n을 넘어가는 경우 반복 중지
* 4. 배열 출력
*/
var m = 0
var n = 0
var spiralArray = Array(m) { IntArray(n) }
var flag = true
var count = 0
fun main() {
val sc = Scanner(System.`in`)
// m : 행의 수
m = sc.nextInt()
// n : 열의 수
n = sc.nextInt()
// spiralList 초기화
spiralArray = Array(m) { IntArray(n) }
//flag가 false : 모든 배열의 값이 채워질 때 까지 반복
while (flag) {
//시작점
goRight(0, 0)
}
// spiralArray 출력
for (row in spiralArray) {
for (i in row) {
print("$i ")
}
println()
}
}
//오른족으로 이동하는 함수
fun goRight(x: Int, y: Int) {
// 배열을 벗어나거나, 이미 채워진 값이 있는 경우
if (y > n - 1 || spiralArray[x][y] != 0) {
// 모든 배열의 값이 있는 경우
if (count >= m * n){
//멈춘다.
flag = false
}
// 배열이 비어있는 경우 아래로 이동
else goDown(x + 1, y - 1)
}
if (flag) {
// 반복횟수만큼 count 증가
count++
// 배열에 값 할당
spiralArray[x][y] = count
// 오른쪽으로 이동
goRight(x, y + 1)
}
}
fun goDown(x: Int, y: Int) {
// 배열을 벗어나거나, 이미 채워진 값이 있는 경우
if (x > m - 1 || spiralArray[x][y] != 0) {
// 모든 배열의 값이 있는 경우
if (count >= m * n){
//멈춘다.
flag = false
}
// 배열이 비어있는 경우 왼쪽으로 이동
else goLeft(x - 1, y - 1)
}
if (flag) {
// 반복횟수만큼 count 증가
count++
// 배열에 값 할당
spiralArray[x][y] = count
// 아래로 이동
goDown(x + 1, y)
}
}
fun goLeft(x: Int, y: Int) {
// 배열을 벗어나거나, 이미 채워진 값이 있는 경우
if (y < 0 || spiralArray[x][y] != 0) {
// 모든 배열의 값이 있는 경우
if (count >= m * n){
//멈춘다.
flag = false
}
// 배열이 비어있는 경우 위로 이동
else goUp(x - 1, y + 1)
}
if (flag) {
// 반복횟수만큼 count 증가
count++
// 배열에 값 할당
spiralArray[x][y] = count
// 왼쪽으로 이동
goLeft(x, y - 1)
}
}
fun goUp(x: Int, y: Int) {
// 배열을 벗어나거나, 이미 채워진 값이 있는 경우
if (x < 0 || spiralArray[x][y] != 0) {
// 모든 배열의 값이 있는 경우
if (count >= m * n){
//멈춘다.
flag = false
}
// 배열이 비어있는 경우 오른쪽으로 이동
else goRight(x + 1, y + 1)
}
if (flag) {
// 반복횟수만큼 count 증가
count++
// 배열에 값 할당
spiralArray[x][y] = count
// 위로 이동
goUp(x - 1, y)
}
}
import java.io.*
fun main() {
// val bf = FileReader("data.txt")
val bf = BufferedReader(InputStreamReader(System.`in`))
val (w, h) = bf.readText().split(" ").map{it.toInt()}
val spiral = Array(w){Array(h){-1}}
val direction = arrayOf(arrayOf(0,1), arrayOf(1,0), arrayOf(0,-1), arrayOf(-1,0))
var row = 0
var col = 0
var count = 1
var directionIdx = 0
while(spiral[row][col] == -1) {
spiral[row][col] = count
count++
val nextRow = row + direction[directionIdx][0]
val nextCol = col + direction[directionIdx][1]
if(nextRow >= spiral.size || nextRow < 0) directionIdx = (directionIdx + 1) % 4
else if(nextCol >= spiral[0].size || nextCol < 0) directionIdx = (directionIdx + 1) % 4
else if(spiral[nextRow][nextCol] != -1) directionIdx = (directionIdx + 1) % 4
row += direction[directionIdx][0]
col += direction[directionIdx][1]
}
var outputString = ""
spiral.forEach {
outputString += (it.joinToString(" ") + System.lineSeparator())
}
println(outputString.trim())
}
def generate_spiral_matrix(rows, cols):
matrix = [[0] * cols for _ in range(rows)]
num = 0
top, bottom, left, right = 0, rows - 1, 0, cols - 1
while num < rows * cols:
# 왼쪽 -> 오른쪽
for col in range(left, right + 1):
matrix[top][col] = num
num += 1
top += 1
# 위쪽 -> 아래쪽
for row in range(top, bottom + 1):
matrix[row][right] = num
num += 1
right -= 1
# 오른쪽 -> 왼쪽
for col in range(right, left - 1, -1):
matrix[bottom][col] = num
num += 1
bottom -= 1
# 아래쪽 -> 위쪽
for row in range(bottom, top - 1, -1):
matrix[row][left] = num
num += 1
left += 1
return matrix
def print_matrix(matrix):
for row in matrix:
for num in row:
print(f"{num:3}", end=" ")
print()
rows, cols = 6, 6
spiral_matrix = generate_spiral_matrix(rows, cols)
print_matrix(spiral_matrix)
row, col, r, c, d, inNum = 6, 6, 0, 0, 0, 0
mLen = row * col
matrix = [[-1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1]]
n = row
### r, c: 최근 좌표, inNum: 시작 수, n: 입력 갯수
def numfill(r, c, direction, inNum, n):
if direction == 0:
for j in range(inNum, inNum+n):
matrix[r][c] = j
c += 1
r += 1
c -= 1
elif direction == 1:
for j in range(inNum, inNum+n):
matrix[r][c] = j
r += 1
c -= 1
r -= 1
elif direction == 2:
for j in range(inNum, inNum+n):
matrix[r][c] = j
c -= 1
r -= 1
c += 1
elif direction == 3:
for j in range(inNum, inNum+n):
matrix[r][c] = j
r -= 1
c += 1
r += 1
return (inNum, r, c)
for i in range(mLen//2 -1):
direction = (d % 4) ### 0: 좌우, 1: 상하, 2: 우좌, 3: 하상
if i%2 == 1:
n -= 1
inNum, r, c = numfill(r, c, direction, inNum, n)
d += 1
inNum += n
print(matrix)
import numpy as np
h, w = input().split(' ')
h = int(h)
w = int(w)
ans = [[0 for j in range(w)] for i in range(h)]
ans = np.array(ans)
def spiral_fill(start_row, start_col, height, width, num_start):
if width == 1:
for i in range(height):
ans[start_row + i][start_col] = num_start + i
return True
if height == 1:
for i in range(width):
ans[start_row][start_col + i] = num_start + i
return True
else:
for i in range(width):
ans[start_row][start_col + i] = num_start + i
ans[start_row + height - 1][start_col + width - 1 - i] = num_start + width + height - 2 + i
for i in range(1, height - 1):
ans[start_row + i][start_col + width - 1] = num_start + width - 1 + i
ans[start_row + i][start_col] = num_start + width * 2 + height * 2 - 4 - i
if (height == 2) | (width == 2):
return True
else:
spiral_fill(start_row + 1, start_col + 1, height - 2, width - 2, num_start + 2 * width + 2 * height - 4)
return True
spiral_fill(0, 0, h, w, 0)
print(ans)
input_string = input('matrix : ')
input_matrix = input_string.split(' ')
x = int(input_matrix[0])
y = int(input_matrix[1])
output_matrix = [[0 for i in range(y)] for j in range(x)]
i = 0
j = 0
bound_left, bound_right, bound_up, bound_down = 0, y, 1, x
direction = 0
for k in range(x * y):
output_matrix[i][j] = k
if direction == 0:
j += 1
if j == bound_right - 1:
direction += 1
bound_right = j
elif direction == 1:
i += 1
if i == bound_down -1:
direction += 1
bound_down = i
elif direction == 2:
j -= 1
if j == bound_left:
direction += 1
bound_left = j + 1
else:
i -= 1
if i == bound_up:
direction += 1
bound_up = i + 1
direction = direction % 4
for i in range(x):
print(output_matrix[i])
import numpy as np
def maker(num1, num2):
num = list(range(num1 * num2))
# num1 * num2 행렬 만들기
array_empty = np.empty((num1, num2), int)
i = 0
z = 1
while num != 0:
# 오른쪽
array_empty[i][i:num2-i] = num[:num2-i*2]
del num[:num2-i*2]
if len(num) == 0:
break
# 밑으로
array_empty.T[num2 - (i+1)][i+1:num1-i] = num[:num1 - (i*2+1)]
del num[:num1 - (i*2+1)]
if len(num) == 0:
break
# 왼쪽으로
if i >= 1:
array_empty[num1-(i+1)][num2-(i+2):i-1:-1] = num[:num2 - (i*2+1)]
else:
array_empty[num1 - (1)][num2-2::-1] = num[:num2 - 1]
del num[:num2 - (i*2+1)]
if len(num) == 0:
break
# 위로
array_empty.T[i][num1-(i+2):i:-1] = num[:num1 - (i*2+2)]
del num[:num1 - (i*2+2)]
if len(num) == 0:
break
i+=1
return array_empty
num1, num2 = map(int,input().split())
print(maker(num1, num2))
제가 만든 코드지만.. 너무 더러워요 ;;ㅜㅜ
inp = input('>>').split()
r, c = int(inp[0]), int(inp[1])
map = [[-1 for _ in range(c)] for _ in range(r)]
direction = [[0,1],[1,0],[0,-1],[-1,0]]
d=0
mr, mc = 0, 0
cnt = 0
while cnt < r*c:
if 0<= mr<r and 0<=mc<c and map[mr][mc] == -1:
map[mr][mc] = cnt
cnt += 1
else:
mr, mc = mr-direction[d][0], mc-direction[d][1]
d = (d+1)%4
mr, mc = mr+direction[d][0], mc+direction[d][1]
for i in range(r):
for j in range(c):
print(' %2d'%map[i][j], end='')
print()
어찌저찌 만들긴 했는데 피드백 해주시면 감사하겠습니다 ㅠㅠ
package Algorithm;
import java.util.Scanner;
public class SpiralArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("크기 입력: ");
int num = scanner.nextInt();
int num2 = scanner.nextInt();
int cnt= 0;
int n=0;
int spiral[][] = new int[num][num2];
int totalCount = num*num2;
Loop: while(true) {
//오른
for(int i=0; i<(num2-(2*n)); i++) {
if(i+n <= num2-1 && n <= num-1) {
spiral[n][i+n] = cnt;
cnt++;
}
if(cnt == totalCount) break Loop;
}
//아래
for(int i=1; i<num-2*n; i++) {
spiral[i+n][num2-1-n] = cnt;
cnt++;
if(cnt == totalCount) break Loop;
}
//왼
for(int i=num2-1; i>=1+2*n ; i--) {
if(i-1-n >=0 && num-1-n>=0) {
spiral[num-1-n][i-1-n] = cnt;
cnt++;
if(cnt == totalCount) break Loop;
}
}
//위
for(int i=num-1; i>1+2*n; i--) {
spiral[i-1-n][0+n] = cnt;
cnt++;
if(cnt == totalCount) break Loop;
}
n++;
}
for(int i=0; i<spiral.length; i++) {
for(int j =0; j<spiral[0].length; j++) {
System.out.printf("%3d", spiral[i][j]);
}
System.out.println();
}
}
}
휴.. 풀었다는데 의의를 둡니다~ㅠㅠ
matrix_values = input()
i, j = matrix_values.split(' ')
i, j = int(i), int(j)
blank_list = []
for k in range(0,i):
blank_list.append([0]*j)
row = 0
col = 0
current_row_edge = i
current_col_edge = j
left_right = 1
up_down = 0
blank_list[row][col] = 0
current_num = 1
max_num = i*j
while current_num < max_num:
if left_right == 1 and up_down == 0:
try:
if col <= current_col_edge:
col += left_right
row += up_down
if blank_list[row][col] != 0:
raise
blank_list[row][col] = current_num
current_num += 1
except:
col = col - 1
left_right = 0
up_down = 1
if left_right == 0 and up_down == 1:
try:
if row <= current_row_edge:
col += left_right
row += up_down
if blank_list[row][col] != 0:
raise
blank_list[row][col] = current_num
current_num += 1
except:
row = row - 1
left_right = -1
up_down = 0
if left_right == -1 and up_down == 0:
try:
if col >= -1:
col += left_right
row += up_down
if blank_list[row][col] != 0:
raise
blank_list[row][col] = current_num
current_num += 1
except:
col = col + 1
left_right = 0
up_down = -1
if left_right == 0 and up_down == -1:
try:
if row >= -1:
col += left_right
row += up_down
if row ==0 and col == 0 and current_num > 0:
raise
elif blank_list[row][col] != 0:
raise
blank_list[row][col] = current_num
current_num += 1
except:
row = row + 1
left_right = 1
up_down = 0
for line in range(0,i):
print(blank_list[line])
방향 전환을 회전행렬을 응용하여 rotate 함수로 처리하였습니다. 방향 전환 시점은 칸의 경계를 벗어날 때 혹은 이미 채워진 칸에 도달할 때임을 이용하여, 채워지지 않은 칸을 -1로 처리하고 try-catch 문으로 경계를 벗어나는 경우를 걸러냈습니다.
가로, 세로 순으로 args에 입력한 후 실행하면 실행됩니다.
package spiralArray;
public class spiralArray {
//가로, 세로는 실제 화면과 동일
/* 좌표 예시
* (0, 0) (1, 0) (2, 0)
* (0, 1) (1, 1) (2, 1)
* (0, 2) (1, 2) (2, 2)
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final int[] size = {Integer.parseInt(args[0]), Integer.parseInt(args[1])}; //첫 번째가 가로, 두 번째가 세로
int[] lim = {0, size[0] - 1, 0, size[1] - 1}; //좌표의 한계(좌, 우, 상, 하)
int[] move = {1, 0}; //이동 방향, 첫 번째가 가로, 두 번째가 세로
int[][] map = new int[size[1]][size[0]]; //첫 번째가 세로, 두 번째가 가로
int[] coord = {0, 0};
for (int i = 0; i < size[0]; i++) {
for (int j = 0; j < size[1]; j++) {
map[j][i] = -1;
}
}
for (int i = 0; i < size[0]*size[1]; i++) {
System.out.println(coord[0] + ", " + coord[1]);
try {
if(map[coord[1] + move[1]][coord[0] + move[0]] != -1) {
move = rotate(move);
}
}
catch (ArrayIndexOutOfBoundsException e) {
// TODO: handle exception
move = rotate(move);
}
map[coord[1]][coord[0]] = i;
coord[0] += move[0];
coord[1] += move[1];
}
for (int[] row : map) {
for (int cell : row) {
System.out.print(cell + " ");
}
System.out.println("");
}
}
public static int[] rotate(int[] move) {
System.out.println("rotate");
return new int[] {-move[1], move[0]};
}
}
n,m=map(int,input().split())
lst=[]
for i in range(n+2):
row=[]
for j in range(m+2):
row.append(-2)
lst.append(row)
for i in range(n+2):
for j in range(m+2):
if i==0 or j==0 or i==n+1 or j==m+1:
lst[i][j]=-1
x=1
y=1
cnt=0
while True:
lst[y][x]=cnt
if lst[y-1][x]!=-2 and lst[y][x-1]!=-2 and lst[y][x+1]==-2:
x+=1
elif lst[y-1][x]!=-2 and lst[y][x-1]!=-2 and lst[y][x+1]!=-2 and lst[y+1][x]==-2:
y+=1
elif lst[y-1][x]!=-2 and lst[y][x+1]!=-2 and lst[y+1][x]==-2:
y+=1
elif lst[y-1][x]!=-2 and lst[y][x+1]!=-2 and lst[y+1][x]!=-2 and lst[y][x-1]==-2:
x-=1
elif lst[y][x+1]!=-2 and lst[y+1][x]!=-2 and lst[y][x-1]==-2:
x-=1
elif lst[y][x+1]!=-2 and lst[y+1][x]!=-2 and lst[y][x-1]!=-2 and lst[y-1][x]==-2:
y-=1
elif lst[y+1][x]!=-2 and lst[y][x-1]!=-2 and lst[y-1][x]==-2:
y-=1
elif lst[y+1][x]!=-2 and lst[y][x-1]!=-2 and lst[y-1][x]!=-2 and lst[y][x+1]==-2:
x+=1
else:
break
cnt+=1
for i in range(1,n+1):
for j in range(1,m+1):
print(f"{lst[i][j]:4}",end=' ')
print('')