Print a random maze

높이와 폭의 길이를 입력받아 임의의 미로를 출력하는 프로그램 입니다.
미로는 프로그램을 실행할 때마다 다르게 출력되어야 하며 코너는 + 로, 수직벽은 | 를 사용하여야 합니다.
출구는 벽면이 없는 형태로 출력하고, 현재위치는 # 로 표기합니다. 단 현재위치와 출구는 반드시 연결되어야 합니다.

Sample Input

4 5

Sample Output

+-+-+
  |#|
|   |
+---+
maze ascii-art
"가로벽을 `-`로 표시 한다"는 내용이 들어가면 더 낫겠네요. - Han Jooyung, 2016/11/24 22:25 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

8개의 풀이가 있습니다.

결과물(160x160) : https://www.dropbox.com/s/ub9km51j7utbbau/maze.txt?dl=0

import random
import time

class maze:
    maze_makingTime=0
    maze_size=0
    maze_map=None
    maze_mapList=None
    maze_exitWay=None
    startPoint_x=1
    startPoint_y=0
    endPoint_x=0
    endPoint_y=0

    def __init__(self,input_size):
        list_maze=list()
        for i in range(input_size):
            list_maze.append(list())
            for j in range(input_size):
                list_maze[i].append(1)
        self.maze_map=list_maze
        self.maze_size=int(input_size)

        t_start=time.time()
        self.design_mazeOut()
        t_end=time.time()
        self.maze_makingTime=t_end-t_start
        self.duplicate_MazeToList()

    #사용하지 말것,__init__에서 자동으로 호출한다
    def design_mazeOut(self):
        #나가는 법을 기록
        temp_way=list()
        self.maze_map[self.startPoint_y][self.startPoint_x]=0
        temp_x,temp_y=self.startPoint_x,self.startPoint_y+1
        temp_prevDir=4
        temp_way.append(temp_prevDir)
        self.maze_map[temp_y][temp_x]=0

        while True:
            int_exit_select=random.randint(1,4)
            if temp_x==0 or temp_y==0 or temp_x==self.maze_size-1 or temp_y==self.maze_size-1:
                break
            elif temp_prevDir==3:
                if int_exit_select<3:
                    temp_x+=1
                    temp_prevDir=3
                    temp_way.append(temp_prevDir)
                    self.maze_map[temp_y][temp_x]=0
                else:
                    temp_y+=1
                    temp_prevDir=4
                    temp_way.append(temp_prevDir)
                    self.maze_map[temp_y][temp_x]=0

            elif temp_prevDir==4:
                if int_exit_select<3:
                    temp_y+=1
                    temp_prevDir=4
                    temp_way.append(temp_prevDir)
                    self.maze_map[temp_y][temp_x]=0
                else:
                    temp_x+=1
                    temp_prevDir=3
                    temp_way.append(temp_prevDir)
                    self.maze_map[temp_y][temp_x]=0
        #나가는 경로 지정 완료

        #나가는 법 저장 객체에 저장
        self.maze_exitWay=temp_way
        self.endPoint_x,self.endPoint_y=temp_x,temp_y
        temp_x,temp_y=self.startPoint_x,self.startPoint_y

        #이 부분은 나가는 길을 만든 후 가짜 길을 만들기 위한 부분이다.
        for temp_prev in temp_way:
            if temp_prev==4:
                self.randomspace(temp_x-1,temp_y,1)
                self.randomspace(temp_x+1,temp_y,3)
                temp_y+=1
            else:
                self.randomspace(temp_x,temp_y-1,2)
                self.randomspace(temp_x,temp_y+1,4)
                temp_x+=1

    def duplicate_MazeToList(self):
        self.maze_mapList=list()
        for i,line in enumerate(self.maze_map):
            self.maze_mapList.append(list())
            for line_ele in line:
                self.maze_mapList[i].append(line_ele)


    #이 메소드를 호출하면 길을 랜덤하게 만들어준다 design_mazeOut에서 자동 호출한다.
    def randomspace(self,point_x,point_y,prev):
        if  point_x==0 or point_y==0 or point_x==self.maze_size-1 or point_y==self.maze_size-1:
            return

        int_select=random.randint(1,10)

        if prev==1:
            if self.maze_map[point_y-1][point_x]==1 and self.maze_map[point_y+1][point_x]==1 and self.maze_map[point_y][point_x-1]==1:
                if int_select<8:
                    self.maze_map[point_y][point_x]=0
                    self.randomspace(point_x-1,point_y,1)
                    self.randomspace(point_x,point_y-1,2)
                    self.randomspace(point_x,point_y+1,4)
        elif prev==2:
            if self.maze_map[point_y-1][point_x]==1 and self.maze_map[point_y][point_x-1]==1 and self.maze_map[point_y][point_x+1]==1:
                if int_select<8:
                    self.maze_map[point_y][point_x]=0
                    self.randomspace(point_x-1,point_y,1)
                    self.randomspace(point_x,point_y-1,2)
                    self.randomspace(point_x+1,point_y,3)
        elif prev==3:
            if self.maze_map[point_y-1][point_x]==1 and self.maze_map[point_y+1][point_x]==1 and self.maze_map[point_y][point_x+1]==1:
                if int_select<8:
                    self.maze_map[point_y][point_x]=0
                    self.randomspace(point_x+1,point_y,3)
                    self.randomspace(point_x,point_y-1,2)
                    self.randomspace(point_x,point_y+1,4)
        else:
            if self.maze_map[point_y+1][point_x]==1 and self.maze_map[point_y][point_x-1]==1 and self.maze_map[point_y][point_x+1]==1:
                if int_select<8:
                    self.maze_map[point_y][point_x]=0
                    self.randomspace(point_x-1,point_y,1)
                    self.randomspace(point_x+1,point_y,3)
                    self.randomspace(point_x,point_y+1,4)

    #미궁을 어떤 식으로 출력할지 결정
    def set_mazeLine(self):
        #x좌표가 0일때 공백으로 전환
        for temp_x in range(self.maze_size):
            for temp_y in range(self.maze_size):
                if self.maze_mapList[temp_y][temp_x]==0:
                    self.maze_map[temp_y][temp_x]=" "

        for temp_x in range(self.maze_size):
            for temp_y in range(self.maze_size):
                if temp_x==0:
                    if self.maze_mapList[temp_y][temp_x+1]==0:
                        self.maze_map[temp_y][temp_x]="|"
                    else:
                        self.maze_map[temp_y][temp_x]="+"

                elif temp_x==self.maze_size-1:
                    if self.maze_mapList[temp_y][temp_x-1]==0:
                        self.maze_map[temp_y][temp_x]="|"
                    else:
                        self.maze_map[temp_y][temp_x]="+"
                elif temp_y==0:
                    if self.maze_mapList[temp_y+1][temp_x]==0:
                        self.maze_map[temp_y][temp_x]="-"
                    else:
                        self.maze_map[temp_y][temp_x]="+"
                elif temp_y==self.maze_size-1:
                    if self.maze_mapList[temp_y-1][temp_x]==0:
                        self.maze_map[temp_y][temp_x]="-"
                    else:
                        self.maze_map[temp_y][temp_x]="+"
                else:
                    if self.maze_mapList[temp_y][temp_x]==0:
                        pass
                    elif self.maze_mapList[temp_y][temp_x-1]==0 and self.maze_mapList[temp_y][temp_x+1]==0 and self.maze_mapList[temp_y-1][temp_x]==0 and self.maze_mapList[temp_y+1][temp_x]==0:
                        self.maze_map[temp_y][temp_x]="+"
                    elif self.maze_mapList[temp_y][temp_x-1]==0 and self.maze_mapList[temp_y][temp_x+1]==0:
                        self.maze_map[temp_y][temp_x]="|"
                    elif self.maze_mapList[temp_y-1][temp_x]==0 and self.maze_mapList[temp_y+1][temp_x]==0:
                        self.maze_map[temp_y][temp_x]="-"
                    else:
                        self.maze_map[temp_y][temp_x]="+"
            self.maze_map[self.startPoint_y][self.startPoint_x]="#"
            self.maze_map[self.endPoint_y][self.endPoint_x]=" "

    def set_mazeSquare(self):
        for temp_x in range(self.maze_size):
            for temp_y in range(self.maze_size):
                if self.maze_mapList[temp_y][temp_x]==0:
                    self.maze_map[temp_y][temp_x]=" "
                else:
                    self.maze_map[temp_y][temp_x]="◼︎"
        self.maze_map[self.startPoint_y][self.startPoint_x]="#︎"

    def print_maze(self,mode=0):
        t_start=time.time()
        if mode==0:
            self.set_mazeLine()
        else:
            self.set_mazeSquare()
        t_end=time.time()
        for line in self.maze_map:
            for temp_char in line:
                print(temp_char,end="")
            print("")
        return t_end-t_start

    def save_txtMaze(self,mode=0):
        if mode==0:
            self.set_mazeLine()
        else:
            self.set_mazeSquare()
        f_maze=open("maze.txt","w")
        for line in self.maze_map:
            for temp_char in line:
                f_maze.write(temp_char)
            f_maze.write("\n")

...네 더럽게 깁니다. 물론 출력용이나 그런 쓸데없는 코드도 있지만 코드자체가 좀 길더군요;;

코드에 대해 설명하자면

maze 객체의 변수는 총9개가 있지만 가장 중요한 것은 maze_map. maze_mapList. maze_exitWay. startPoint_x. * startPoint_y. 이렇게 5가지입니다. map과 mapList는 사실 같은 내용이지만 두개가 있는 이유는 객체의 print_maze 또는 save_maze메소드를 호출할 때 Set_MazeLine 혹은 set_mazeSquare를 통해 1과0으로 구성된 MapList 가 사각벽 미로나, 선 미로로 변환되고 이것이 map에 저장됩니다. 한마디로 같은 내용을 생긴것만 다르게 만들었다는 뜻인데 이게 사실 하나만 있어도 되는데 따로 있는 이유는 사실 제가 print를 할때하고 save를 할때 따른 방식으로(square방식과 line 방식) 미궁을 저장해서 그렇습니다. startPoint와 exitWay는 시작점과 나가는 법을 나타내는 것입니다.

maze_size : len함수로 크기를 얻어도 되지만 계산시간을 고려해서 그냥 변수로 선언했습니다. maze_makingTime : 미궁 리스트(1,0)을 만드는 시간이 궁금해서 넣었습니다. endPoint : exitWay와 startPoint를 사용하면 얻을 수 있지만 따로 함수를 하나 더 만들기 그래서 넣었습니다.

이 객체에서 가장 중요한 메소드는 design_maze하고 randomspaze 입니다.

객체를 생성할 때 init에서 design_maze를 호출하고 이 메소드에서 randomspace를 호출하는 형식인데.

design 메소드는 2가지의 작업으로 나뉩니다. 첫째는 나가는 길을 만드는 것이고 둘째는 가짜 통로를 만드는 것입니다. 이 메소드는 1,0(좌표)에서 시작해 아래, 혹은 우측으로 움직이며 길을 만들고 이를 exitWay변수에 저장하는 것이 첫째 단계입니다. 여기서 왜 시작점은 고정되고 이동방향은 우,하밖에 없느냐는 질문에는 여러번 이 함수를 반복할 때 출구까지의 거리를 일정하게 유지시키기 위해서라고 말하겠습니다. 처음에는 design_out이란 함수가 나가는 길을 만들어 주는 방식이였는데 가끔식 바로 옆으로(0,1)나가는 길을 뚫어버리는 통에 아얘 가장 쉬운 방법으로 나가는 길을 만들게 되었습니다.

design 메소드의 두번째 작업은 exitWay와 startPoint로 나가는 길을 그대로 따라가면서 가짜 통로를 만드는 것입니다. 나가는 길을 따라가면서 좌우 좌표를 randomspace함수의 변수로 넘기는게 바로 그것인데, randomspace는 재귀식으로 자신을 호출한 방향 메소드가 있었던 방향을 제외한 나머지 방향으로 나아가면서 길을 만듭니다. 이때 자신 전의 함수가 나아간 방향으로 다시 나아갈 확률을 랜덤으로 만들기 위해 random.randint()함수를 사용했습니다. 사실 이전에 나아갔던 방향으로 나아갈 확률이 압도적으로 높은데 이는 미로가 너무 구불구불해지면 randomspace함수 특성상 쉽게 길을 가로막힐 가능성이 있기에 이런 방법을 사용했습니다.

design메소드가 호출되면 이렇게 미로만들기가 모두 종료됩니다.

이후print나 save 메소드들이 호출되면 set 메소드가 호출되면서 mapList변수를 이용해서 map변수의 각 요소를 문자형으로 변환합니다.

maze_size=160

m_test=maze(maze_size)
time_changing=m_test.print_maze()

print("\n"+str(m_test.maze_makingTime)+"초 걸림(제작)")
print("\n"+str(time_changing)+"초 걸림(변환)")
m_test.save_txtMaze(2)

이게 실제로 160X160칸 미로를 만드는 과정인데 실제 진행하면 .

0.19153094291687012초 걸림(제작). 0.028708934783935547초 걸림(변환).

총 0.21초 정도 걸립니다.(저장과정 제외,시간이 적게 걸리는 부분 제외 걸린시간). 160칸이 넘어가면 maximum recursion depth exceeded 오류가 일어나서 이 이상은 몇초정도 걸리는지 잘 모르겠습니다. 재귀부분을 수정하기는 어려운데;;. ps. macPro 2015년형 pypy3.2에서 동작함 pss.이 문제 이런식으로 푸는게 맞나??

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define xsize 10
#define ysize 10

//001000 => LEFT  //000100 => RIGHT //000010 => TOP //000001 => BOTTOM
//010000 => BLOCK //100000 => NOW
enum direction {
    NONE = 0, 
    LEFT = 8, RIGHT = 4, TOP = 2, BOTTOM = 1, 
    BLOCK = 16, NOW = 32
};

int getRandDirection() {
    int d = rand() % 4;
    switch(d){
        case 0:
            return LEFT;
        case 1:
            return RIGHT;
        case 2:
            return BOTTOM;
        case 3:
            return TOP;
    }
}

void getDirectionChar(int left, int me, int top, int row, char* c) {
    if(row == 0){
        c[0] = '+'; 
        if((me >> 1) & 1 || top & 1){
            c[1] = ' '; 
            c[2] = ' '; 
        }
        else{
            c[1] = '-'; 
            c[2] = '-'; 
        }
    }
    if(row == 1){
        if((me >> 3) & 1 || (left >> 2) & 1) {
            c[0] = ' ';
        }else{
            c[0] = '|';
        }       
        switch(me){
            case NOW:
                c[1] = '#';
                c[2] = ' ';
                break;
            case NONE:
                c[1] = '.';
                c[2] = '.';
                break;          
            default:
                c[1] = ' ';
                c[2] = ' ';
                    break;
        }
    }
}

void printMaze(int a[xsize][ysize], int x, int y) {
    system("cls");
    for(int j = 0; j < ysize; j++) {
        for(int k = 0; k < 2; k++) {
            for(int i = 0; i < xsize; i++) {                
                int left, me, top;      

                left = i > 0 ? a[i - 1][j] : (j == 0 ? RIGHT : BLOCK);
                me = i ==x && j == y ? NOW : a[i][j];               
                top = j > 0 ? a[i][j - 1] : BLOCK;              

                char c[3] = { ' ', ' ', ' ' }; 
                getDirectionChar(left, me, top, k , c);
                printf("%c%c%c", c[0], c[1], c[2]);
            }
            printf(k == 0 ? "+\n" : "|\n");
        };
    }
    for(int i = 0; i < xsize; i++) {
        printf("+--");
    }
    printf("+\n");
}

int goForward(int a[xsize][ysize], int x, int y){
    printMaze(a, x, y);
    int d = 0;
    while(1) {
        if((x == 0 || a[x - 1][y] != NONE) && //LEFT is disable
            (x == xsize - 1 || a[x + 1][y] != NONE) && //RIGHT is disable
            (y == 0 || a[x][y - 1] != NONE) && //TOP is diable
            (y == ysize - 1 || a[x][y + 1] != NONE)) { //BOTTOM is diable
                return 0;
        }
        d = getRandDirection();
        switch(d){
            case LEFT:
                if(x > 0 && a[x - 1][y] == NONE) {
                    a[x][y] += LEFT;
                    x--;
                    goForward(a, x, y);
                    a[x][y] += RIGHT;
                }
                break;
            case RIGHT:
                if(x < xsize - 1 && a[x + 1][y] == NONE) {
                    a[x][y] += RIGHT;
                    x++;
                    goForward(a, x, y);
                    a[x][y] += LEFT;
                }
                break;
            case TOP:
                if(y > 0 && a[x][y - 1] == NONE) {
                    a[x][y] += TOP;
                    y--;
                    goForward(a, x, y);
                    a[x][y] += BOTTOM;
                }
                break;
            case BOTTOM:
                if(y < ysize - 1 && a[x][y + 1] == NONE) {
                    a[x][y] += BOTTOM;
                    y++;
                    goForward(a, x, y);
                    a[x][y] += TOP;
                }
                break;
        }
    }
}

int main(){
    srand(time(NULL));
    int a[xsize][ysize];
    for(int i = 0; i < xsize; i++) {
        for(int j = 0; j < ysize; j++) {
            a[i][j] = NONE;
        }
    }
    a[0][0] = LEFT;
    goForward(a, 0, 0);
    printMaze(a, xsize - 1, ysize - 1);
}
- => -- 로 결과를 변형함. 보기더 나음.
+--+--+--+--+--+--+--+--+--+--+
   |              |        |  |
+  +--+--+--+  +  +  +--+  +  +
|              |     |     |  |
+--+--+--+--+--+--+--+  +--+  +
|  |           |        |     |
+  +  +--+--+  +  +--+--+  +  +
|     |        |  |        |  |
+--+--+  +--+--+  +--+--+  +  +
|     |  |        |     |  |  |
+  +  +  +  +--+--+  +  +--+  +
|  |     |  |        |  |     |
+  +--+--+  +  +--+--+  +  +--+
|           |        |  |     |
+  +--+--+--+--+--+  +  +--+  +
|  |              |  |        |
+  +--+--+  +--+  +  +--+--+  +
|        |     |  |     |     |
+--+--+  +--+  +  +--+  +  +--+
|              |        |   # |
+--+--+--+--+--+--+--+--+--+--+

D:\16.minGW>

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
from random import randint
K=lambda x: (x-1)/2
top=[]; walls=[]; bot=[]; start='#'
X,Y=0,0

def show():
    topLine=botLine=''; wall=''  #top,bot as one string
    for i in top:
        topLine+=i
    for i in bot:
        botLine+=i
    for i in walls:
        for j in i:
            wall+=j
        wall+='\n'
    print topLine+'\n'+wall[:-1]+'\n'+botLine   

def breakingPrison():
    left,right=[],[]
    for i in range(Y-2):
        left.append(walls[i][0])
        right.append(walls[i][X])
    if ' ' not in top or bot or left or right:
        return True

def prison(x,y):         #가로를 x, 세로를 y로 했고 모양세를 위해 x는 홀수만 입력가능
    if x%2==0:
        print 'x should be an odd number';return 0
    X,Y=x,y
    row = randint(0,Y-3)
    col = randint(1,K(X)) *2-1

    for i in range(y-2):
        walls.append([])
        for j in range(x):
            walls[i].append('|' if j%2==0 else ' ')
            if j==col and i==row:
                walls[i][j]= start
    for i in range(x):                     #top,bot list
        top.append('-'); bot.append('-') 

    while breakingPrison():
        count=0
        direction=randint(1,10) #up, down, left,  right
        up,down, left,right = [1,2],[3,4],[5,6,7],[8,9,10]
        if direction in up:
            if row!=0:
                row-=1; count+=1
            else:
                if count<3:          #넘 빨리 끝나지 않게 대충 카운트 걸어줬어요.
                    continue
                top[col]=' '; break
        elif direction in down:
            if row != Y-3:
                row+=1; count+=1
            else:
                if count<3:
                    continue
                bot[col]=' '; break
        elif direction in left:
            if col!=1:
                walls[row][col-1]=' '; col-=2; count+=1
            else:
                walls[row][0]=' '; break
        elif direction in right:
            if col!= X-2:
                walls[row][col+1]=' '; col+=2; count+=1
            else:
                walls[row][X-1]=' '; break
    for i in range(x):                             
        if walls[0][i]=='|':           #최외곽 벽이 깨졌을때 맨 위벽 바로아래 수직벽이 없으면 코너로 변경
            top[i]='+'
        if walls[-1][i]=='|':          #최외곽 벽이 깨졌을떄 맨 아래벽 바로위 수직벽이 없으면 코너로 변경
            bot[i]=('+')
    show()
prison(23,10)

음 문제 출력 예시 보고 코너만 +로 나오고 세로벽 위아래로는 세로벽만 나온다고 이해하고 풀었습니다. 일단 전부 세로벽으로 채운 뒤, 출발위치에서 상,하,좌,우 랜덤으로 탈옥을 시도하며 가장 바깥쪽 벽을 깨면 그 결과를 출력하게 짰습니다. 일명 PrisonBreak ㅋㅋ

+---+-+-+-+-+-+-+-+-+-+ 23 x 10 예시
|   | | | | | | | | | |
|   | | | | | | | | | |
|#    | | | | | | | | |
| | | |   | | |       |
| | |   |           | |
| | | | | |       | | |
| | | | | | | | |      
| | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

Python 2.7 모든 칸이 뚫릴 때까지 길을 만드는 방법을 사용했습니다. 다만 염두에 두고 만든 미로의 형태는 가로, 세로가 모두 홀수일 때만 가능합니다. 예시 출력같은 형태는 좀 더 생각해 봐야 겠네요...

import random

x = input()
y = input()
assert x%2==1 and y%2==1

uncovered = {(a,b) for a in xrange(1,x,2) for b in xrange(1,y,2)}
unfinished = set()
maze = [[' ']*x for i in xrange(y)]

#Initialization
for a in xrange(x):
    for b in xrange(y):
        if a%2==0:
            if b%2==0:
                maze[b][a] = '+'
            else:
                maze[b][a] = '|'
        elif b%2==0:
            maze[b][a] = '-'
start = random.choice([(1,b) for b in xrange(1,y,2)])
maze[start[1]][start[0]] = '#'
uncovered-= {start}
unfinished.add(start)

#Digging
def nextspot(c):
    return {(c[0]+x[0], c[1]+x[1]) for x in zip([-2,0,0,2],[0,-2,2,0])}.intersection(uncovered)

while uncovered:
    c = random.sample(unfinished,1)[0]
    d = nextspot(c)
    if len(d) == 0:
        unfinished-= {c}
        continue
    dig = random.sample(d,1)[0]
    maze[(c[1]+dig[1])/2][(c[0]+dig[0])/2] = ' '
    uncovered.remove(dig)
    if len(nextspot(dig)) > 0:
        unfinished.add(dig)

#Exit setting
exit = random.choice([(x-1,b) for b in xrange(1,y,2)])
maze[exit[1]][exit[0]] = ' '

#'+' Removal
def get(L, x, y):
    if not 0<=x<len(L[0]) or not 0<=y<len(L):
        return
    return L[y][x]

for a in xrange(0,x,2):
    for b in xrange(0,y,2):
        vertical = False
        horizontal = False
        if get(maze,a-1,b) == '-' or get(maze,a+1,b) == '-':
            horizontal = True
        if get(maze,a,b+1) == '|' or get(maze,a,b-1) == '|':
            vertical = True
        if vertical and not horizontal:
            maze[b][a] = '|'
        elif horizontal and not vertical:
            maze[b][a] = '-'

#Print
for a in maze:
    print ''.join(a)

''' Example
25
11
+---+-------------+-----+
|#  |             |     |
| --+ --+ +---+ --+ | | |
|       | |   |     | | |
| --+ --+-+ | | ----+-+-+
|   |   |   | |     |    
| | | | | --+-+---+-+ --+
| | | |           |     |
| +-+-+-- --------+-- --+
|     |                 |
+-----+-----------------+
'''
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

일단 미로의 구조를 짠 다음에 - (벽, 코너가 있는 좌표를 변수 a에 저장) <무한루프 시작> 현재 위치를 읽어들이는 함수를 사용해서 #을 출력하고 키보드 입력이 들어올 때까지 대기하고 있다가 누르면 (if 문을 사용해서 a와 비교 후 일치하면 continue) 이동시키고 나서 전에건 지우는 방식으로 코딩하는건 어떨까요? o v o

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

프림알고리즘을 이용한 미로 만들기

결과 1 결과 2 결과 3

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void init();
void display();
int up(int x, int y);
int down(int x, int y);
int left(int x, int y);
int right(int x, int y);
void randomMaze(int x, int y);
bool verdict(int x, int y);

int w = 51;
int h = 21;
char** board;

void main() {
    int x =1, y =1;
    init();
    board[y][x] = 'x';
    board[y][x+2] = 'o';
    board[y+2][x] = 'o';
    randomMaze(x, y);
    display();
}
void randomMaze(int x, int y) {
    int dir = rand()%4;
    while(verdict(x, y)) {
        switch(dir) {
            case 0:
                y = up(x, y);
                randomMaze(x, y);
                break;
            case 1:
                y = down(x, y);
                randomMaze(x, y);
                break;
            case 2:
                x = left(x, y);
                randomMaze(x, y);
                break;
            case 3:
                x = right(x, y);
                randomMaze(x, y);
                break;
        }
    }
}

void init() {
    srand(time(NULL));
    board = (char**) malloc (sizeof(char*) * h);
    for(int i = 0 ; i<h ; i++)
        board[i] = (char*) malloc (sizeof(char) * w);

    for(int i = 0 ; i<h ; i++) {
        for(int j = 0 ; j<w ; j++) {
            board[i][j] = ' ';
            if(i==0) 
                board[i][j] = '-';
            if(i== h-1) 
                board[i][j] = '-';
            if(j==0) 
                board[i][j] = '|';
            if(j==w-1) 
                board[i][j] = '|';

            if( (i==0 && j==0)  ||  (i==0 && j==w-1)  ||  (i==h-1 && j==0)  ||  (i==h-1 && j==w-1)) 
                board[i][j] = '+';
        }
    }

    for(int i = 1 ; i<h-1 ; i++) {
        for(int j = 1 ; j<w-1 ; j++) {
            if(i%2 == 0 && j%2 != 0)
                board[i][j] = '-';
            if(i%2 != 0 && j%2 == 0)
                board[i][j] = '|';
            if(i%2 == 0 && j%2 == 0)
                board[i][j] = '+';
        }
    }
}


void display() {
    for(int i = 1 ; i<h-1 ; i++) {
        for(int j = 1 ; j<w-1 ; j++) {
            if(board[i][j] == '+') {
                if(board[i+1][j] == ' '  && board[i-1][j] == ' '  && board[i][j+1] == ' '  && board[i][j-1] == ' ')
                    board[i][j] = ' ';
            }
            if(board[i][j] == 'x') {
                board[i][j] = ' ';
            }
            if(board[i][j] == 'o') {
                board[i][j] = ' ';
            }
        }
    }
    for(int i = 0 ; i<h ; i++) {
        for(int j = 0 ; j<w ; j++) {
            if(i==1 && j==1) {
                printf("#");
                continue;
            }
            if(i==h-2 && j==w-1) {
                printf(" ");
                continue;
            }
            printf("%c", board[i][j]);
        }
        printf("\n");
    }

}
int up(int x, int y) {
    if((y-2) < 0)
        return y;
    if(board[y-2][x] == 'x')
        return y;
    board[y-1][x] = ' ';
    y-=2;
    board[y][x] = 'x';

    if(y-2 > 0 && board[y-2][x]== ' ')
        board[y-2][x] = 'o';
    if(x-2 > 0 && board[y][x-2]== ' ')
        board[y][x-2] = 'o';
    if(y+2 < h && board[y+2][x]== ' ')
        board[y+2][x] = 'o';
    if(x+2 < w && board[y][x+2]== ' ')
        board[y][x+2] = 'o';

    return y;
}
int down(int x, int y) {
    if(h<=(y+2))
        return y;
    if(board[y+2][x] == 'x')
        return y;

    board[y+1][x] = ' ';
    y+=2;
    board[y][x] = 'x';

    if(y-2 > 0 && board[y-2][x]== ' ')
        board[y-2][x] = 'o';
    if(x-2 > 0 && board[y][x-2]== ' ')
        board[y][x-2] = 'o';
    if(y+2 < h && board[y+2][x]== ' ')
        board[y+2][x] = 'o';
    if(x+2 < w && board[y][x+2]== ' ')
        board[y][x+2] = 'o';

    return y;
}
int left(int x, int y) {
    if((x-2) < 0)
        return x;
    if(board[y][x-2] == 'x')
        return x;

    board[y][x-1] = ' ';
    x-=2;
    board[y][x] = 'x';

    if(y-2 > 0 && board[y-2][x]== ' ')
        board[y-2][x] = 'o';
    if(x-2 > 0 && board[y][x-2]== ' ')
        board[y][x-2] = 'o';
    if(y+2 < h && board[y+2][x]== ' ')
        board[y+2][x] = 'o';
    if(x+2 < w && board[y][x+2]== ' ')
        board[y][x+2] = 'o';

    return x;
}
int right(int x, int y) {
    if(w<=(x+2))
        return x;
    if(board[y][x+2] == 'x')
        return x;

    board[y][x+1] = ' ';
    x+=2;
    board[y][x] = 'x';

    if(y-2 > 0 && board[y-2][x]== ' ')
        board[y-2][x] = 'o';
    if(x-2 > 0 && board[y][x-2]== ' ')
        board[y][x-2] = 'o';
    if(y+2 < h && board[y+2][x]== ' ')
        board[y+2][x] = 'o';
    if(x+2 < w && board[y][x+2]== ' ')
        board[y][x+2] = 'o';

    return x;
}

bool verdict(int x, int y) { // false 면 끝~
    if(y-2 > 0 && board[y-2][x]== 'o')
        return true;
    if(x-2 > 0 && board[y][x-2]== 'o')
        return true;
    if(y+2 < h && board[y+2][x]== 'o')
        return true;
    if(x+2 < w && board[y][x+2]== 'o')
        return true;
    return false;
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
int main(int argc, const char * argv[]) {
    srand((unsigned int)time(NULL));
    int width = 30, height = 15;
    maze* m = make_maze(width, height);
    print_maze(m);
    free_maze(m);
    return 0;
}

maze는 2차원 배열에 벽과 복도를 1과 0으로 표시하고, 시작점/출구를 기억.

typedef struct maze maze;
struct maze {
    int width;
    int height;
    char** cells;
    int startx;
    int starty;
    int goalx;
    int goaly;
};

이제 미로를 만들어보자.

maze* make_maze(int width, int height) {
    maze* m = (maze*)malloc(sizeof(maze));
    m->width = width;
    m->height = height;

    // allocate 2D array
    m->cells = (char**)calloc(width, sizeof(char*));
    for (int x=0; x<width; x++)
        m->cells[x] = (char*)calloc(height, sizeof(char));

시작점은 내부에 있어야 한다.

    // starting point is not on the boundary
    m->startx = uniform(1, width-1);
    m->starty = uniform(1, height-1);

출구는 외부, 하지만 네 귀퉁이는 될 수 없다.

    // goal is on the boundary, but not on the corner
    int side = uniform(0,4);
    switch (side) {
        case 0:
            m->goalx = uniform(1, width-1);
            m->goaly = 0;
            break;
        case 1:
            m->goalx = 0;
            m->goaly = uniform(1, height-1);
            break;
        case 2:
            m->goalx = uniform(1, width-1);
            m->goaly = height-1;
            break;
        default: //3
            m->goalx = width-1;
            m->goaly = uniform(1, height-1);
            break;
    }

기본 아이디어는 외부벽을 만든다음 랜덤하게 벽을 키워나가되 길을 끊지 않는 것이다.

먼저 외부벽을 만든다.

    // draw boundary
    for (int i=0; i<width; i++) {
        m->cells[i][0] = 1;
        m->cells[i][height-1] = 1;
    }
    for (int i=0; i<height; i++) {
        m->cells[0][i] = 1;
        m->cells[width-1][i] = 1;
    }
    m->cells[m->goalx][m->goaly] = 0;

외부벽을 키워나가려면.. (좀 무식하게.. ㅠ.ㅠ) 빈칸 중에서 벽에 연결되면서 연결방향의 전방에 다른 벽이 있으면 안된다. (길을 막지 않아야..) 이런 조건에 해당하는 빈칸 중에서 랜덤하게 하나를 골라서 벽을 만든다!

    // for each empty cell, find a cell to be connected to the wall with only one side
    // and not close the road
    int* candidate = (int*)calloc(width * height, sizeof(int));
    int  size = 0;
    while (1) {
        for (int y=1; y<m->height-1; y++) {
            for (int x=1; x<m->width-1; x++) {
                if (m->cells[x][y] || (x == m->startx && y == m->starty))
                    continue;
                if (is_candidate(m->cells, x, y))
                    candidate[size++] = y * width + x;
            }
        }
        if (size == 0)
            break;
        int pos = candidate[rand() % size];
        m->cells[pos % width][pos / width] = 1;
        size = 0;
    }
    free(candidate);

    return m;
}

연결 조건을 확인하는 코드는 아래..

int is_candidate(char** cells, int x, int y) {
    if (cells[x-1][y]) {
        return cells[x+1][y-1] == 0
        && cells[x+1][y] == 0
        && cells[x+1][y+1] == 0
        && cells[x][y-1] == 0
        && cells[x][y+1] == 0;
    }
    if (cells[x+1][y]) {
        return cells[x-1][y-1] == 0
        && cells[x-1][y] == 0
        && cells[x-1][y+1] == 0
        && cells[x][y-1] == 0
        && cells[x][y+1] == 0;
    }
    if (cells[x][y-1]) {
        return cells[x-1][y] == 0
        && cells[x+1][y] == 0
        && cells[x-1][y+1] == 0
        && cells[x][y+1] == 0
        && cells[x+1][y+1] == 0;
    }
    if (cells[x][y+1]) {
        return cells[x-1][y] == 0
        && cells[x+1][y] == 0
        && cells[x-1][y-1] == 0
        && cells[x][y-1] == 0
        && cells[x+1][y-1] == 0;
    }
    return 0;
}

출력하는 건 간단하다.

void print_maze(maze* m) {
    for (int y=0; y<m->height; y++) {
        for (int x=0; x<m->width; x++)
            printf("%c", cell(m, x, y));
        printf("\n");
    }
}

char cell(maze* m, int x, int y) {
    if (x==m->startx && y==m->starty)
        return '#';
    if (m->cells[x][y] == 0)
        return ' ';

    int h = (x > 0 && m->cells[x-1][y]) || (x < m->width-1 && m->cells[x+1][y]);
    int v = (y > 0 && m->cells[x][y-1]) || (y < m->height-1 && m->cells[x][y+1]);
    int corner = (x == 0 || x == m->width -1) && (y == 0 || y == m->height - 1);

    if (corner || (h && v))
        return '+';
    if (h)
        return '-';
    return '|';
}

남은 함수는 메모리 해제와 랜덤 선택

int uniform(int a, int b) {
    return a + rand() % (b - a);
}

void free_maze(maze* m) {
    for (int x=0; x<m->width; x++)
        free(m->cells[x]);
    free(m->cells);
    free(m);
}

아래는 결과 예제

+-+-+-+-+-+-+-+-+-+--+--+-+--+
| | | | | | | | | |  |  | |  |
|     | | | | | | ++ |    +- |
+--- ++ | | | | |  | ++ +-+  |
|    |  |     | | -+  | | | -+
+--- |  +-+-+   |  |         |
|    | -+ | | --+- | -+  -+--+
+---        |         +-  |  |
     +--+--   --+- ---+     -+
| |  |  |   |   |     ++  |  |
+-+-   ++ | +- ++ -+   | ++ -+
|  # | |  +-+  |   | --+-+   |
| +- | ++ |   -+ | |   | | --+
| |  |  | | |  | | | | |     |
+-+--+--+-+-+--+-+-+-+-+-----+
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
from random import randint
from time import time

MOVEMAP = {"UP":0, "DOWN":1, "LEFT":2, "RIGHT":3, "CURRENT":4}

class maze:
    BLOCK = '+'
    ENTRANCE = '#'
    def __init__(self, height = 5, width = 5):
        self.__height, self.__width = height, width
        self.init_array(height, width)
        self.make_maze()

    def init_array(self, height, width):
        self.__array = self.make_array(height, width)
        self.make_wall()

    def make_wall(self):
        for y in range(self.__height):
            if y%2 == 0:
                for x in range(self.__width):
                    self.set_item(y, x, maze.BLOCK)
            for x in range(self.__width):
                if x%2 == 0:
                    self.set_item(y, x, maze.BLOCK)

    def make_array(self, height, width):
        return [*([*(0 for x in range(width))] for y in range(height))]

    def make_maze(self):
        y_list, x_list = [*(y for y in range(1, self.__height, 2))], [*(x for x in range(1, self.__width, 2))]
        ry, rx = randint(0, len(y_list)-1), randint(0, len(x_list)-1)
        y, x = y_list[ry], x_list[rx]
        self.set_item(y, x, maze.ENTRANCE)
        P = maze_pointer(self, y, x)
        P.make_maze()

    def get_maze(self):
        return self.__array

    def get_item(self, y, x):
        return self.get_maze()[y][x]

    def set_item(self, y, x, new_value):
        self.get_maze()[y][x] = new_value

    def calc_char(self, y, x):
        p = maze_pointer(self, y, x)
        BLOCK = maze.BLOCK
        up = down = left = right = current = 0
        try:
            up = self.get_item(*p.get_location_by_direction(0)) == BLOCK
        except TypeError:
            pass
        try:
            down = self.get_item(*p.get_location_by_direction(1)) == BLOCK
        except TypeError:
            pass
        try:
            left = self.get_item(*p.get_location_by_direction(2)) == BLOCK
        except TypeError:
            pass
        try:
            right = self.get_item(*p.get_location_by_direction(3)) == BLOCK
        except TypeError:
            pass
        try:
            current = self.get_item(*p.get_location_by_direction(4))
        except TypeError:
            pass
        v = up or down
        h = left or right
        if current == maze.ENTRANCE:
            return maze.ENTRANCE
        elif current != BLOCK:
            return ' '
        elif v and h:
            return '+'
        elif v:
            return '|'
        elif h:
            return '-'
        else:
            return ' '

    def __repr__(self):
        result = ''
        for j in range(self.__height-1, -1, -1):
            for i in range(self.__width):
                result += self.calc_char(j, i) + ' '
            result += '\n'
        return result

class maze_pointer:
    def __init__(self, _maze:maze, y = 1, x = 1):
        self.__height, self.__width = len(_maze.get_maze()), len(_maze.get_maze()[0])
        self.__maze = _maze
        self.__y, self.__x = y, x
        self.__history = [(y, x)]
        self.__all = self.make_all()
        self.__escape = None

    def make_all(self):
        return [*(((j, i) for i in range(0, self.__width, 2)) for j in range(0, self.__height, 2))]

    def get_location(self):
        return self.__y, self.__x

    def get_location_by_direction(self, direction:MOVEMAP, times = 1):
        y, x = self.get_location()
        if direction == MOVEMAP['UP']:
            y += times
        elif direction == MOVEMAP['DOWN']:
            y -= times
        elif direction == MOVEMAP['LEFT']:
            x -= times
        elif direction == MOVEMAP['RIGHT']:
            x += times

        if self.is_out_of_bound(y, x):
            return 'ERROR'
        else:
            return y, x

    def set_location(self, y, x):
        if y%2 == 1 and x%2 == 1 and not self.is_out_of_bound(y, x):
            self.__y = y
            self.__x = x
            self.__history.append((y, x))
            return True
        else:
            return False

    def move(self, direction:MOVEMAP):
        y, x = self.get_location()
        if direction == MOVEMAP['UP']:
            y += 2
        elif direction == MOVEMAP['DOWN']:
            y -= 2
        elif direction == MOVEMAP['LEFT']:
            x -= 2
        elif direction == MOVEMAP['RIGHT']:
            x += 2
        if self.set_location(y, x):
            wall_location = ((self.get_history()[-2][0] + y)//2, (self.get_history()[-2][1] + x)//2)
            self.__maze.set_item(*wall_location, 0)
            return True
        else:
            return False

    #constraint variable's value
    def clamp(self, _min, _max, target):
        return max(_min, min(_max, target))

    #constraint location by height and width
    def get_clamped_location(self, y, x):
        return self.clamp(0, self.__height-1, y), self.clamp(0, self.__width-1, x)

    #check location is out of array size
    def is_out_of_bound(self, y, x):
        if self.get_clamped_location(y, x) != (y, x):
            return True
        else:
            return False

    def __repr__(self):
        return str(self.get_location())

    def get_movable_directions(self):
        result = []
        for x in range(4):
            temp = self.get_location_by_direction(x, 2)
            if temp != 'ERROR' and temp not in self.__history:
                result.append(x)
        return result

    def random_move(self):
        while True:
            directions = self.get_movable_directions()
            if len(directions) == 0:
                if self.__escape:
                    return
                y, x = self.get_location()
                if y == 1:
                    y -= 1
                elif y == self.__height-2:
                    y += 1
                elif x == 1:
                    x -= 1
                elif x == self.__width-2:
                    x += 1
                if (y, x) != self.get_location():
                    self.__maze.set_item(y, x, 0)
                    self.__escape = (y, x)
            else:
                random_int = randint(0, len(directions)-1)
                self.move(directions[random_int])
#recursion can be dangerous, because of recursion limit
#        directions = self.get_movable_directions()
#        if len(directions) == 0:
#            return
#        else:
#            random_int = randint(0, len(directions)-1)
#            self.move(directions[random_int])
#            self.random_move()

    def get_left_blocks(self)->set:
        return set(self.__all) - set(self.__history)

    def is_movable_block(self, location:"2DVector"):
        y, x = location
        temp_pointer = maze_pointer(self.__maze, y, x)
        temp_pointer.set_history(self.get_history())
        if temp_pointer.get_movable_directions() != []:
            return True
        else:
            return False

    def make_maze(self):
        while True:
            self.random_move()
            new_locations = [*filter(self.is_movable_block, self.get_history())]
            if not len(new_locations) > 0:
                break
            else:
                random_int = randint(0, len(new_locations)-1)
                self.set_location(*new_locations[random_int])

    def get_history(self):
        return self.__history

    def set_history(self, history_to_copy, do_copy = True):
        if do_copy:
            self.__history = history_to_copy[:]
        else:
            self.__history = history_to_copy
while __name__ == '__main__':
    print('Both height and width must be odd numbers')
    h = int(input('Height : '))
    w = int(input('Width : '))
    t = time()
    M = maze(h, w)
    print(M)
    print("Elapsed time : " + str(time() - t))

파이썬 3.6.0 64bit

설명:

maze 객체 -> 넓이, 높이를 받아 배열을 생성한다. 또 배열의 값으로부터 출력할 문자열을 계산한다.

maze_pointer 객체 -> 미로 위를 움직이면서 길을 만든다. (Hunt-and-Kill 알고리즘 사용)

21 정도에서는 금방 나오지만 100 넘어가면 한참 걸립니다. 최적화는 생략합니다. 객체지향 연습도 할 겸 캡슐화도 적극적으로 사용했습니다.

출력(h 51, w 53)

Both height and width must be odd numbers
Height : 51
Width : 53
+ - - - + - - - + - - - + - - - -   + - - - - - - - - - - - + - - - + - - - - - - - - - + - - - - - - - + 
|       |     # |       |           |                       |       |                   |               | 
+ - -   |   - - +   |   |   - - - - +   + - - - - - -   |   + - +   |   + - +   |   |   |   - - + - - - + 
|       |           |   |               |               |       |       |   |   |   |   |       |       | 
|   + - + - + - - - +   + - - - - - + - +   - - + - - - + - +   + - - - +   |   |   |   + - +   |   |   | 
|   |       |                       |           |           |               |   |   |       |   |   |   | 
|   + - -   |   + - + - - - +   - - +   + - - - +   |   |   + - +   |   + - +   |   + - +   |   |   |   | 
|           |   |   |       |           |       |   |   |       |   |   |       |       |   |   |   |   | 
+ - - - +   |   |   |   - - + - - - - - +   |   |   + - + - +   |   + - +   + - + - +   + - +   |   |   | 
|       |   |       |                       |       |       |   |           |       |               |   | 
|   |   |   |   + - + - + - - - - - -   + - + - - - +   |   |   + - + - -   |   + - +   + - + - - - +   | 
|   |       |   |       |               |           |   |           |           |       |   |           | 
+ - +   + - + - +   |   |   + - - - -   + - - - +   + - + - -   |   |   - - + - +   - - +   |   |   + - + 
|       |           |       |           |       |       |       |   |       |           |       |   |   | 
|   - - +   + - +   + - + - + - + - - - +   |   + - -   |   - - +   + - +   |   - - +   + - - - +   |   | 
|           |   |       |       |       |   |           |       |       |   |       |           |       | 
|   - - + - +   + - +   + - +   |   |   |   + - - - + - + - +   + - +   |   |   |   + - - - +   + - -   | 
|       |           |       |       |   |           |       |       |       |   |   |       |   |       | 
+ - -   + - - - +   + - +   |   + - +   + - + - -   |   - - + - +   + - - - + - +   |   |   |   |   + - + 
|       |       |       |   |   |   |       |       |           |   |       |       |   |       |   |   | 
|   + - +   |   |   - - +   |   |   + - +   |   |   + - - - +   |   + - -   |   - - + - + - -   |   |   | 
|   |       |           |   |   |       |       |   |       |       |       |       |           |   |   | 
+ - +   - - + - - - +   |   |   + - +   |   - - + - +   - - + - - - +   + - + - - - +   + - - - +   |   | 
|           |       |       |       |   |                   |       |   |               |       |   |   | 
|   + - - - +   + - + - - - + - +   |   + - - - - - - - +   |   |   |   |   |   + - - - + - +   |   |   | 
|   |           |               |   |                   |       |   |   |   |   |           |   |       | 
|   |   + - - - +   + - + - -   |   |   + - - - + - - - + - +   |   |   |   + - +   + - -   |   |   |   | 
|   |   |           |   |       |       |       |           |   |   |   |   |       |           |   |   | 
|   |   |   + - -   |   |   - - + - - - +   - - +   |   |   |   |   |   + - +   + - +   |   - - +   |   | 
|   |   |   |       |   |       |                   |   |       |   |           |       |           |   | 
|   |   |   |   - - +   + - +   |   - - + - - - - - + - + - -   |   + - + - - - +   + - + - -   + - +   | 
|       |   |           |   |           |           |           |   |   |       |   |           |       | 
|   |   |   + - - - - - +   + - - - - - +   - - + - +   - - + - +   |   |   |   + - +   + - - - +   + - + 
|   |   |                   |           |       |           |   |       |   |   |       |           |   | 
|   |   + - - - - - - - -   + - -   |   |   |   |   - - +   |   + - + - +   + - +   |   + - - - +   |   | 
|   |                       |       |   |   |   |       |   |       |       |       |           |       | 
+ - + - - - - - - - - - - - +   - - + - +   + - + - -   |   |   |   |   - - +   + - +   + - +   + - - - + 
|                           |           |               |   |   |   |           |       |   |           | 
|   - - + - +   + - - - -   |   - - +   + - - - - - +   |   + - +   + - - - - - + - + - +   + - -   |   | 
|       |   |   |           |       |   |           |   |                           |       |       |   | 
+ - -   |   |   + - - - - - + - +   + - +   |   |   + - + - - - - - - - - - + - +   |   |   |   - - + - + 
|       |                       |   |       |   |       |                   |   |       |   |           | 
|   + - + - - - - - - - - - +   |   |   + - +   + - -   |   |   - - - - +   |   + - - - + - + - - - +   | 
|   |                       |       |   |       |       |   |           |   |                       |   | 
|   |   - - +   + - - - +   |   - - +   |   |   |   |   |   + - - - - - +   + - - - -   |   - - +   |   | 
|   |       |   |       |   |       |   |   |   |   |   |               |   |           |       |       | 
|   + - +   + - +   |   |   + - -   |   + - +   |   + - + - - - - - -   |   |   - - + - +   - - + - -   | 
|       |       |   |       |       |       |   |   |                   |   |       |   |       |       | 
+ - -   + - -   |   + - - - + - - - + - -   |   |   |   - - - - +   - - +   + - -   |   + - -   |   - - + 
|               |                           |   |               |       |           |           |       | 
+ - - - - - - - + - - - - - - - - - - - - - + - + - - - - - - - + - - - + - - - - - + - - - - - + - - - + 

Elapsed time : 3.2903761863708496
높이 101, 넓이 103에서 102초 걸립니다. - Flair Sizz, 2017/04/17 12:32 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.

ascii-art x 2
maze x 1
연관 문제
genius.choi, 2017/03/19 16:58

언어별 풀이 현황
전 체 x 8
python x 4
cpp x 1
기 타 x 3