이 페이지는 코딩도장 데이터의 읽기 전용 정적 보관본입니다.

Random Walk

'술취한 바퀴벌레' 문제라고도 한다. 다음과 같은 격자에 술취한 바퀴벌레가 있다고 해 보자

. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .

바퀴벌레는 임의의 한 점에서 시작하여서 임의의 방향으로 움직이게 된다. 이미 지나갔던 자리에 다시 갈 수 있으며 프로그램은 바퀴벌레가 각 위치에 몇번 갔는지 기억하여야 한다. 프로그램은 바퀴벌레가 모든 지점에 적어도 한번 이상 도달하였을 경우 끝난다. 바퀴벌레는 가로, 세로, 대각선으로 한칸 씩만 움직일수 있으며, 바퀴벌레가 움직이는 방향을 랜덤하게 만드는 것은 각자가 생각해 보도록 한다.

입력

격자의 가로, 세로 크기, 바퀴벌레의 초기 위치

출력

각 칸에 바퀴벌레가 멈추었던 횟수, 바퀴벌레가 움직인 횟수.

심화문제

격자의 가로, 세로의 크기를 입력받을때. 엄청나게 큰 크기를 입력하면 어떻게 할 것인가?


참고

출처: 위키백과

무작위 행보(無作爲行步, random walk, 랜덤 워크)는 수학, 컴퓨터 과학, 물리학 분야에서 임의 방향으로 향하는 연속적인 걸음을 나타내는 수학적 개념이다. 무작위 행보(random walk)라는 개념은 1905년 Karl Pearson이 처음 소개하였으며 생태학, 수학, 컴퓨터 과학, 물리학, 화학 등의 분야에서 광범위하게 사용되고 있다.

랜덤 워크는 시간에 따른 편차의 평균이 0이지만 분산은 시간에 비례하여 증가하게 된다. 따라서, 앞 뒤로 움직일 확률이 동일하다고 해도 시간이 흐름에 따라 평균에서 점차 벗어나는 경향을 보인다.

대표적인 예로는 브라운 운동이 있으며, "술고래의 걸음"이라고도 한다.

2014/03/09 16:59

pahkey

저 질문있어요^^; 출력에서 바퀴벌레가 움직인 횟수는 무엇을 말하는 것인가요?;ㅋㅋㅋ 혹시 바퀴벌레가 일직선으로 움직일때(들어온방향과 나간방향이 같을때) 바퀴벌레가 그 칸을 움직인거고, 그 칸에서 방향을 바꿨다면 그 칸에서 멈춘건가요? 각 칸에 바퀴벌레가 지나간 횟수가 최소화된다 뭐 이런 조건 없이 마음대로 랜덤하게 짜면 되는건가요? - Katherine, 2014/03/10 10:02
@Katherine님, 바퀴벌레가 움직인 횟수는 바퀴벌레가 칸을 이동한 총 횟수이구요, 각 칸에 바퀴벌레가 멈추었던 횟수는 바퀴벌레가 몇번 그 칸에 들렀는지라고 보면 될것 같습니다. 네, 최소화 조건은 없구요, 바퀴벌레 자유의지에 의해서 랜덤하게 만드시면 됩니다. ^^ - pahkey, 2014/03/10 10:35
@길가의풀 네 알겠어요^^ 감사합니다^^ - Katherine, 2014/03/10 11:05
+1 Programming Challenge 자체가 현재 판매중인 프로그래밍 문제 책이고 사이트는 그 책의 문제들을 채점해볼 수 있는 공간을 제공하기 위한 것 아닌가요? 저작권 문제가 되지 않을지? - Kim Jaeju, 2014/03/10 13:55
@Kim Jaeju 님, 아.. 저작권 문제가 될 수도 있을것 같네요, 생각도 못 해 봤는데요.. 저작권에 대해서는 잘 검토 해 보도록 하겠습니다. 알려주셔서 감사합니다. - pahkey, 2014/03/10 14:04
@Kim Jaeju 님, Programming Challenge 저자(Miguel A. Revilla Ramos씨)에게 문의한 결과, Academic한 사용으로는 제한없이 사용할 수 있다는 답장을 받았네요 ^^. - pahkey, 2014/03/10 19:52
제가 푼 방식이 맞는지는 모르겠으나, 재미있게 풀었습니다 ^^ - Buckshot, 2020/05/15 14:02

67개의 풀이가 있습니다.

Python 3.4 입니다. 좌표값을 사전으로 처리하는 방법을 사용하였습니다. 100*100 수행시 제 컴퓨터에서 약 1초 정도 소요되네요(36만번 이동)

import random
import itertools
import time

DIRECTION = list(itertools.product((-1, 0, 1), repeat=2))
DIRECTION.remove((0, 0))


def roach(xsize, ysize, xpos, ypos):
    matrix = {}
    pos = (xpos, ypos)
    count = 0
    while len(matrix) < xsize * ysize:
        matrix[pos] = matrix.get(pos, 0) + 1
        count += 1
        while True:
            tempdir = random.choice(DIRECTION)
            temppos = (pos[0] + tempdir[0], pos[1] + tempdir[1])
            if -1 < temppos[0] < xsize and -1 < temppos[1] < ysize: break
        pos = temppos
    return count, matrix

if __name__ == '__main__':
    t=time.time()
    xsize, ysize, xpos, ypos = 100, 100, 0, 0
    r= roach(xsize,ysize,xpos,ypos)
    print(r[0])
    print(time.time()-t)
    for i in range(ysize):
        print(' '.join(['{0:3}'.format(str(r[1][(j,i)])) for j in range(xsize)]))

2015/01/17 00:22

투플러스

C# 입니다.

const int X = 100, Y = 100;
const int BOUNDX = X - 1, BOUNDY = Y - 1;        

bool[,] isPassPos = new bool[X, Y];
int[,] numPassPos = new int[X, Y];
int remainPosCount = X * Y;

Random rnd = new Random();
int posX = rnd.Next(0, X);
int posY = rnd.Next(0, Y);                        
double moveCount = 0;

while (true)
{
    moveCount++;
    numPassPos[posX, posY]++;

    if (!isPassPos[posX, posY])
    {
        isPassPos[posX, posY] = true;
        if (--remainPosCount == 0) break;
    }

    switch (posX)
    {
        case 0: posX += rnd.Next(0, 2); break;
        case BOUNDX: posX += rnd.Next(-1, 1); break;
        default: posX += rnd.Next(-1, 2); break;
    }
    switch (posY)
    {
        case 0: posY += rnd.Next(0, 2); break;
        case BOUNDY: posY += rnd.Next(-1, 1); break;
        default: posY += rnd.Next(-1, 2); break;
    }
}

Console.WriteLine("MoveCount : " + moveCount);

C#의 경우는 100 x 100을 실행하는데에는 20밀리초 정도가 걸립니다.C#의 기본 난수 발생은 Donald E. Knuth의 감산 알고리즘, 파이썬은 메르센 트위스터가 기본 알고리즘이라고 하네요. 아마 랜덤의 생성에서 대부분의 시간이 차이나는걸로 보입니다. 저도 단순 무식한 방법으로 했구요, 남아있는 위치의 카운트 변수를 추가적으로 만들어 마지막을 체크했습니다. 문제엔 꼭 다음 스텝에 이동을 해야한다는 조건이 없기때문에, 방향 백터가 0,0이 나오는 경우도 있습니다. 그래서 그 자리에 그대로 머물러 있는 경우도 카운트에 포함됩니다. 총 이동 카운트는 20 ~ 50만까지 다양하게 찍힙니다.

2015/12/19 19:22

이 우람

제 PC에서는 100X100 크기일 때 약 2~4초대에 결과가 나옵니다. (시작위치는 랜덤으로 했습니다.)

다음 위치를 고를 때 딱 한 번의 랜덤연산을 하기위해서 현 위치에서 갈 수 있는 위치를 모두 뽑은 다음, 그 중 하나를 랜덤으로 선택합니다. (3 ~7 개 중에서 하나를 고릅니다.) 한 번도 방문하지 않은 칸의 수를 별도 변수로 두고, 최초 방문하는 방이 있을 때마다 이 값을 감소시켜서 이 값이 0보다 큰 동안만 루프를 돌게 했습니다.

그런데 1000 X 1000 크기일 때는 너무 느려서 뭔가 다른 방법이 필요할 듯 합니다.

from random import randrange

def nextPos(i, _w, _h):
    _x = i % _w
    _y = i // _w
    ofs = [(_x + x, _y + y) for x in (-1, 0, 1) for y in (-1, 0, 1)
           if x*2 + y != 0 and 0 <= (_x + x) < w and 0 <= (_y + y) < _h]
    rx, ry = ofs[randrange(len(ofs))]
    return ry * w + rx

w = 100
h = 100
sx = randrange(w)
sy = randrange(h)

def main():
    data = [0] * (h * w)
    s = h * w
    m = 0
    p = sy * w + sx

    while s > 0:
        if data[p] is 0:
            s -= 1
        data[p] += 1
        p = nextPos(p, w, h)
        m += 1

    # print result
    print('move: ', m)
    print('\n'.join([' '.join(["{:03d}".format(data[x + y * w]) for x in range(w)]) for y in range(h)]))

main()

2016/03/24 16:30

룰루랄라

파이썬 3.4 입니다. 심화문제는 나중에 생각해 봐야겠습니다. 100*100 격자만 되어도 많이 느려지네요. 많이 부족하지만 올려봅니다.

예를 들어, 격자의 가로는 3, 세로는 4 이고 초기 위치가 (2, 1) 라고 가정해 봅니다. 각 격자의 각 셀의 위치를 x,y 좌표를 기반으로 표시합니다. 각 위치에 해당하는 방문횟수를 stop_count 라는 리스트 형태로 작성해 보았습니다.

첫째로, 현재의 위치 정보 (2, 1) 을 받아들여 stop_count[1][0] 에 +1 을 합니다.

둘째로, 임의로 한칸 움직일 방향을 정합니다 (아래 코드의 __get_direction 함수). random 모듈의 randrange 를 이용하였고, x / y 축에 대해 각각 (-1, 0, 1) 사이의 값을 고르도록 했습니다. 단 위치에 따라 움직임에 제약생기는 부분을 고려하면, 위치 값이 1 인 경우는 (0, 1) 중에서, 최대값 ( x=3, or y=4 ) 이면 (-1, 0) 중에서 선택하도록 했습니다. 그리고, 선택한 값이 (0, 0) 이 되면 다시 선택하도록 했습니다.

셋째로, 움직임 방향이 정해지면 실제로 움직여서 새로운 위치정보를 얻습니다. 이때 움직인 횟수를 하나 더해줍니다. 그리고 다시 현재 위치 정보를 받아들여서 stop_count 리스트에 반영합니다.

이제, stop_count 리스트의 모든 값이 0 이 아닌지 확인합니다 (아래 코드의 __check_stop_by 함수). 만약 0이 있으면 전체 과정을 반복합니다.

아래는 Output 의 한 예 입니다.

The number of total movement is 36.

The matrix below is the number of visit to each cell.

1 3 3
2 4 3
1 5 5
2 4 4

from random import randrange

class RoachMatrix:
    def __init__(self,matrix_size,position):
        self.matrix_size = matrix_size
        self.x = self.matrix_size[0]; self.y =self.matrix_size[1]
        self.position = position
        self.stop_count = []
        for i in range(self.x):
            y_array = [0]*self.y
            self.stop_count.append(y_array)
        x = self.position[0]-1; y = self.position[1]-1
        self.stop_count[x][y] = 1
        self.all_stop_by = False
        self.total_move = 0

    def __get_direction(self):
        direction = [0,0]
        while direction == [0,0]:
            for i in range(2):
                if self.position[i] == 1: direction[i] = randrange(0,2)
                elif self.position[i] == self.matrix_size[i]: direction[i] = randrange(-1,1)
                else: direction[i] = randrange(-1,2)
        return direction

    def __check_stop_by(self):
        result = True
        for i in self.stop_count:
            if all(j for j in i) == False:
                result = False
                return result
        return result

    def record_move(self):
        while self.all_stop_by == False:
            direction = self.__get_direction()
            for i in range (2):
                self.position[i] = self.position[i] + direction[i]
            self.total_move += 1
            x = self.position[0]-1; y = self.position[1]-1
            self.stop_count[x][y] = self.stop_count[x][y] + 1
            self.all_stop_by = self.__check_stop_by()
        print("The number of total movement is %d.\n"%self.total_move)

    def print_stop_count(self):
        print("The matrix below is the number of visit to each cell.\n")  
        for i in range(self.y-1,-1,-1):
            line = ''
            for j in range(self.x):
                temp_count = str(self.stop_count[j][i])+'\t'
                line = line + temp_count
            print(line)            

matrix_size = [3,4]
start_pos = [2,1]

a = RoachMatrix(matrix_size,start_pos)
a.record_move()
a.print_stop_count()

2014/10/11 17:00

돌구늬ㅋ~썬

public class RandomWalk {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int width = Integer.parseInt(sc.nextLine());
        int height = Integer.parseInt(sc.nextLine());
        int[][] map = new int[width][height];
        int count = 0;
        int remained = width * height;

        int curX = Integer.parseInt(sc.nextLine());
        int curY = Integer.parseInt(sc.nextLine());
        sc.close();

        long startTime = System.currentTimeMillis();
        while(true) {
            map[curX][curY]++;
            if(map[curX][curY] == 1) {
                remained--;
                if(remained == 0) {
                    break;
                }
            }

            Random random = new Random();
            while(true) {
                int preX = curX, preY = curY;
                int rand = random.nextInt(9);
                switch(rand) {
                case 1: preX--; preY--; break;
                case 2: preY--;         break;
                case 3: preX++; preY--; break;
                case 4: preX--;         break;
                case 5: preX++;         break;
                case 6: preX--; preY++; break;
                case 7: preY++;         break;
                case 8: preX++; preY++; break;
                }

                if(0 <= preX && preX < width && 0 <= preY && preY < height) {
                    curX = preX;
                    curY = preY;
                    break;
                }
            }

            count++;
        }
        long endTime = System.currentTimeMillis();

        System.out.println("elapsed time: " + (endTime - startTime));
        System.out.println("count: " + count);

        for(int i = 0; i < height; i++) {
            for(int j = 0; j < width; j++) {
                System.out.printf("%6d ", map[j][i]);
            }
            System.out.println();
        }
    }
}

2015/08/03 10:44

고영감

walk = function(mat, row, col, n){
  mat[row,col]=mat[row,col]+1
  if(row>1 && row<nrow(mat)){    v.row=(row-1):(row+1)
  } else if(row>1) { v.row=(row-1):row
  } else if(row<nrow(mat)) { v.row=row:(row+1)
  } else {v.row=row}
  if(col>1 && col<ncol(mat)){ v.col=(col-1):(col+1)
  } else if(col>1) { v.col=(col-1):col
  } else if(col<ncol(mat)) { v.col=col:(col+1)
  } else {v.col=col}
  repeat{
    sample.row=sample(v.row, 1)
    sample.col=sample(v.col, 1)
    if(!((sample.row==row) && (sample.col==col))) {row<<-sample.row; col<<-sample.col; break} 
  }
  return(mat)
}
row=1
col=1
matt=matrix(0, 100, 100)
system.time(repeat{
    matt=walk(matt, row, col)
    if(all(matt>0)==T) {cat("완료\n") ; print(matt) ; print(sum(matt)); break}
  }
)

R로 무식하게 짜봤습니다.

모든 값이 0인 행렬을 생성하고 해당 위치에 바퀴벌레가 올 경우 +1을 해주며 모든 값이 0보다 클 경우 현재 행렬과 움직인 회수를 출력합니다. 바퀴벌레의 이동은 각 행과 열에 대해 if문으로 범위를 정하고 임의로 정하며 제자리에 있는 경우는 제외했습니다. 마지막으로 재귀함수를 통해 모든 칸이 채워질 때까지 반복했습니다.

만일 격자가 매우 클 경우 바퀴벌레의 이동횟수는 격자 크기에 대해서 기하급수적으로 증가하기 때문에 계산이 오래 걸리고 컴퓨터 사양에 많이 의존할 것 같네요.. 실제로 R 코드에서는 재귀 호출에 한계가 있는지 10x10 정도의 격자가 한계더군요.

수정: 코드가 지저분해 졌지만 재귀 호출을 하지 않도록 해보았습니다. 100x100격자에 34만번 이동이 90초 정도 걸리는 듯 합니다

system.time(repeat{
    matt=walk(matt, row, col)
    if(all(matt>0)==T) {cat("완료\n") ; print(matt) ; print(sum(matt)); break}
  }
)
[1] 346112
 사용자  시스템 elapsed 
  90.90    0.03   92.29 

2014/03/10 17:59

한 성탁

지뢰찾기랑 거의 동일하게 만들었습니다.

바퀴를 스타트 지점에 위치시킨 후 0~7 까지의 랜덤한 수를 받아서 그 수에 해당되는 방향으로 계속 이동시키고 이동시킬 때마다 카운트를 올립니다. 그리고 카운트가 0 인 위치(Square)가 없을 때까지 계속 이동시킵니다. 바퀴가 모든 위치를 거쳤다면 그 결과를 출력시킵니다.

100 x 100 인 경우, 경우에 따라서 다르지만 제 PC에서는 421,503번 이동에 50초가량 걸리네요. 술취한 바퀴벌레는 무조건 랜덤이기 때문에 어떤식으로 최적화가 가능할지는 생각해 봐야겠습니다.


파이썬입니다.

# -*- coding: utf-8 -*-
import unittest
import random


class Square:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.value = 0

    def __str__(self):
        return "%s\t" % self.value


class Matrix:
    direction = [
        (-1,-1),(0,-1),(1,-1),
        (-1,0),(+1, 0),
        (-1,+1),(0,+1),(1,+1),
    ]
    def __init__(self, m, n):
        self.map = []
        for y in range(n):
            cols = []
            for x in range(m):
                square = Square(x, y)
                cols.append(square)
            self.map.append(cols)

    def getSquare(self, x, y):
        if 0 <= x < len(self.map[0]) and 0 <= y < len(self.map):
            return self.map[y][x]
        else:
            return None

    def isWalkAll(self):
        for row in self.map:
            for square in row:
                if square.value == 0: return False
        return True

    def getNextSquare(self, square):
        d = self.direction[random.randint(0,7)]
        next = self.getSquare(square.x+d[0], square.y+d[1])
        if not next: return self.getNextSquare(square)
        else: return next

    def start(self, x, y):
        square = self.getSquare(x, y)
        square.value += 1
        next = square
        while not self.isWalkAll():
            next = self.getNextSquare(next)
            next.value += 1

    def reveal(self):
        total = 0
        result = []
        for row in self.map:
            for square in row:
                result.append(str(square))
                total += square.value
            result.append("\n")
        return "".join(result).strip(), total


class RoachTest(unittest.TestCase):
    def test1(self):
        matrix = Matrix(4, 7)
        matrix.start(0, 0)
        m, total = matrix.reveal()
        print m
        print '-' * 70
        print "Total movement: %s" % total


if __name__ == "__main__":
    unittest.main()

2014/03/10 18:02

pahkey

Python 2.7.6

프래그래밍 초보입니다. 어떠한 피드백도 환영합니다.

# -*- coding: cp949 -*-

import random

class Result: # 결과 객체용 클래스
    tile = [] # 각 타일별 벌레가 멈추었던 횟수를 저장하는 2차원 배열
    count = 0 # 바퀴벌레가 총 움직인 횟수

def bug_run(m, n, cood):
    tile = [[0 for i in xrange(n)] for j in xrange(m)] # 타일별 멈춘 횟수 초기값 0으로 세팅하여 생성
    tile[cood[0]][cood[1]] = 1 # 일단 시작 위치에도 멈춘 횟수 1을 줌
    new_cood = [] # 편의상 임시 변수(벌레의 이동 후의 새로운 좌표를 나타냄)
    count = 0 # 총 이동 횟수 저장용 변수

    while 1:

        while 1:
            random_dx = random.choice((-1, 0, 1,))
            random_dy = random.choice((-1, 0, 1,))
            new_cood = [cood[0]+random_dx, cood[1]+random_dy] # 벌레를 랜덤 이동시킴

            if not(random_dx == 0 and random_dy == 0): # 랜덤 이동의 유효성을 평가
                if new_cood[0] > -1 and new_cood[0] < m and new_cood[1] > -1 and new_cood[1] < n:
                    count = count + 1
                    break # 유효한 이동이 나오면 랜덤화 중단

        cood = [new_cood[0], new_cood[1]] # 실제로 벌레를 이동 시킴
        tile[cood[0]][cood[1]] = tile[cood[0]][cood[1]] + 1 # 이동한 타일에 대하여 멈춘 횟수를 업데이트

        trigger = True # 루프 종료 조건용 변수

        for i in xrange(m):
            if 0 in tile[i]:
                trigger = False # 각 타일에 멈춘 횟수 0이 하나라도 있으면 종료 불가

        if trigger:
            break

    result = Result()
    result.tile = tile
    result.count = count

    return result

# 테스트

bug_test = bug_run(6, 6, [3, 3])

for i in bug_test.tile:
    print i

print "Total Count: %d" % (bug_test.count)

2014/03/13 17:07

deukey

파이썬입니다~ 바퀴벌레의 위치는 랜덤으로 입력되도록 했습니다. 바퀴벌레 위치는 cock_map에 바퀴벌레가 이동하면서 머문 횟수는 stack_map에 기록했습니다. cnt는 바퀴벌레가 이동한 횟수입니다~

class Roach:
    def __init__(self,a,b):
        self.mp = [[0 for i in range(b)] for x in range(a)]
        self.a = a
        self.b = b # a,b,mp을 글로벌 변수로 지정

    def start(self):
        from random import choice
        from random import randrange
        import copy

        cock_map = self.mp
        stack_map = copy.deepcopy(cock_map) # 딥카피로 리스트 내부까지 카피
        cnt = 0  

        pin_a = randrange(0,self.a)
        pin_b = randrange(0,self.b)
        cock_map[pin_a][pin_b] = "*"
        stack_map[pin_a][pin_b] += 1

        cont = True
        while cont:
            lst = [-1,0,1]
            temp_a = 0
            temp_b = 0
            temp_a = pin_a + choice(lst)
            temp_b = pin_b + choice(lst)
            if temp_a < 0 or temp_a >= self.a or temp_b < 0 or temp_b >= self.b:
                continue
            else:
                cock_map[pin_a][pin_b] = 0
                pin_a = temp_a
                pin_b = temp_b
                cock_map[pin_a][pin_b] = "*"
                stack_map[pin_a][pin_b] += 1
                cnt += 1

            check = True
            for i in range(self.a):
                for j in range(self.b):
                    if stack_map[i][j] == 0: check = False
            if check == True: cont = False
        print cnt
        print stack_map # 기존의 a,b를 모두 글로벌 변수 self.a, self.b로 변환

ck = Roach(4,4)
ck.start()

2014/11/15 21:31

jo dong hyun

제 PC에서 100*100 기준시 빠를때는 4~5초 정도 소요되고, 느릴때에는 100초 정도가 걸렸습니다.
매번 소요시간이 일정치 않은걸로 봤을때, 파이썬 기본 랜덤 모듈의 난수생성 방식과 다른
방법을 사용해야 할것같은데 아직 대안은 찾지 못했습니다. 파이썬의 기본 난수 생성 알고리즘이
Mersenne Twister 인걸로 알고있는데 다른 방식의 난수생성 알고리즘을 적용하면
좀더 빨라질지 모르겠습니다.

coding by python beginner

import random
import time

startTime = time.time()

w = 100; h = 100; pos = [0, 0]; moveCnt = 0
posCounter = [[0 for x in range(w)] for y in range(h)]
posCounter[pos[0]][pos[1]] += 1

def getMovablePos():
    movablePos = [
        [[-1, -1], [-1, 0], [-1, 1]],
        [[0, -1], False, [0, 1]],
        [[1, -1], [1, 0], [1, 1]]
    ]

    if pos[0] == 0:
        movablePos[0] = list([False])*3
    elif pos[0] == h-1:         
        movablePos[2] = list([False])*3

    if pos[1] == 0:
        for p in movablePos: p[0] = False
    elif pos[1] == w-1:
        for p in movablePos: p[2] = False

    rs = []
    for line in movablePos:
        for p in line:
            if p is not False: rs.append(p) 
    return rs


def randomWalk():
    movablePos = getMovablePos()
    movePos = movablePos[random.randrange(0, len(movablePos))]

    for i in range(2): pos[i] += movePos[i]
    posCounter[pos[0]][pos[1]] += 1 


def chkEnd():
    for i in range(len(posCounter)):
        for j in range(len(posCounter[0])):
            if posCounter[i][j] == 0: return False          
    return True

while True:
    if chkEnd(): break      
    randomWalk()
    moveCnt += 1

endTime = time.time()
print(posCounter, moveCnt, endTime - startTime)

2015/02/03 12:48

vegan

% MATLAB
function [map, cnt] = solution(r, c, ini)

    % map : 각지점에서 바퀴벌레가 멈추었던 횟수
    % cnt : 총 움직인 횟수 (초기 자리는 제외)

    map = zeros(r,c);
    indexmap = reshape(1:r*c, size(map));
    map(ini) = 1;
    cnt = 0;
    H = ones(3,3); % conv kernel
    currPos = ini;

    while inf
        cnt = cnt+1; % 움직임을 카운팅

        % 한위치에서 움직일수있는 가능성 공간(가로 세로 대각)
        t = false(r,c);
        t(currPos) = true;
        possible = logical(conv2(double(t), H, 'same'));
        possible(currPos) = false;  % 제자리에 있는것은 불가능하다고 가정
        ind = indexmap(possible);
        % 랜덤으로 이동
        currPos = ind(randi([1,length(ind)],1));
        map(currPos) = map(currPos)+1; % 각위치에 몇번 지나간지에 대한 카운팅

        % 모든 칸을 지나가면 while문 종료
        if all(map(:) ~= 0)
            break;
        end
    end
end

2015/05/12 14:27

EiGeN

    Sub Main()
        Dim input() As Integer = Array.ConvertAll(Split(Console.ReadLine, " "), Function(d As String) CInt(Val(d)))

        Dim size As New Size(input(0), input(1))
        Dim pt As New Point(input(2), input(3))

        Dim map(size.Width - 1)() As Integer

        For x As Integer = 0 To size.Width - 1
            map(x) = New Integer(size.Height - 1) {}
        Next

        Dim cnt As Integer = 0
        Do
            cnt += 1
            map(pt.X)(pt.Y) += 1

r:
            Randomize()
            Dim direc As Integer = CInt(Rnd() * 8)

            Select Case direc
                Case 0, 3, 5
                    If pt.X > 0 Then : pt.X -= 1 : Else : GoTo r : End If
                Case 1, 6

                Case 2, 4, 7
                    If pt.X < size.Width - 1 Then : pt.X += 1 : Else : GoTo r : End If
            End Select

            Select Case direc
                Case 0 To 2
                    If pt.Y > 0 Then : pt.Y -= 1 : Else : GoTo r : End If
                Case 3 To 4

                Case 5 To 7
                    If pt.Y < size.Height - 1 Then : pt.Y += 1 : Else : GoTo r : End If
            End Select

            If map.Where(Function(n() As Integer) n.Contains(0)).Count = 0 Then
                Exit Do
            End If
        Loop

        For y As Integer = 0 To size.Height - 1
            For x As Integer = 0 To size.Width - 1
                Console.Write(map(x)(y) & vbTab)
            Next
            Console.WriteLine()
        Next

        Console.WriteLine("이동 횟수: " & cnt)

        Console.ReadLine()
    End Sub

2015/06/19 19:24

Steal

    static void exce38()
    {
        int x = 1000, y = 1000, cnt = 0,walk = 0; 
        Random rand = new Random();
        int[] roach = { rand.nextInt(x), rand.nextInt(y) };
        int[][] stage = new int[x][y];

        for(int i=0;i<x;i++)
        {
            for(int j=0;j<y;j++)
            {
                stage[i][j] = 0;
            }
            System.out.println();
        }

        stage[roach[0]][roach[1]]++;
        cnt++;

        while (cnt != x * y)
        {
            int direc = rand.nextInt(8);


            /*for (int i = 0; i < x; i++)
            {
                for (int j = 0; j < y; j++)
                {
                    if (i == roach[0] && j == roach[1])
                        System.out.printf("@");
                    else
                    {
                        if (stage[i][j] == 0)
                            System.out.printf("□");
                        else
                            System.out.printf("■");
                    }
                }
                System.out.println();
            }
            System.out.println();
            System.out.println("--------------------");*/

            switch (direc)
            {
                case 0:
                    if (roach[0] < x - 1 && roach[1] > 0)
                    {
                        roach[0]++;
                        roach[1]--;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
                case 1:
                    if (roach[0] < x - 1)
                    {
                        roach[0]++;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
                case 2:
                    if (roach[0] < x - 1 && roach[1] < y - 1)
                    {
                        roach[0]++;
                        roach[1]++;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
                case 3:
                    if (roach[1] < y - 1)
                    {
                        roach[1]++;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
                case 4:
                    if (roach[0] > 0 && roach[1] < y - 1)
                    {
                        roach[0]--;
                        roach[1]++;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
                case 5:
                    if (roach[0] > 0)
                    {
                        roach[0]--;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
                case 6:
                    if (roach[0] > 0 && roach[1] > 0)
                    {
                        roach[0]--;
                        roach[1]--;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
                case 7:
                    if (roach[1] > 0)
                    {
                        roach[1]--;
                        walk++;
                        if (stage[roach[0]][roach[1]] == 0)
                            cnt++;
                        stage[roach[0]][roach[1]]++;
                    }
                    break;
            }
        }
        System.out.printf("움직인 횟수 : %d번\n",walk);
        for(int i=0;i<x;i++)
        {
            System.out.printf("%3d : ",i);
            for(int j=0;j<y;j++)
            {
                System.out.printf("(%3d)",stage[i][j]);
            }
            System.out.println();
        }

    }

모든 구역을 다 순회하였는가 판정을 2차원구역배열을 전부 체크하게되면 저거만 해도 O(n^2)가 되서... 처음 구역에 도착한 횟수를 세는 변수를 하나 지정해서 해당 변수가 구역 가로x세로 만큼 되면 전부 순회한것으로 판단하였습니다. 100x100은 0.5초 미만이고 1000x1000은 2~3초 정도 걸리긴 한데 출력에 시간이 한참 걸리네요. 주석 안은 바퀴의 움직임을 가시적으로 표시하기 위해서 사용했던 코드입니다.

2015/08/25 10:05

조서현

느려용.. ㅠㅠ

from random import randint
import operator

def randommove():
    while True:
        p = (randint(-1,1),randint(-1,1))
        if p != (0,0):
            return p;

def roachmove(curpos,width,height):
    while True:
        m = randommove()
        nextpos = tuple(map(operator.add, curpos, m))
        if (nextpos[0] < 0 or nextpos[0] >= width or nextpos[1] < 0 or nextpos[1] >= height) is False:
            return nextpos

def drinkroach(width,height,curpos):
    area = width * height
    areacount = 0
    movecount = 0
    Matrix = [[0 for x in range(width)] for x in range(height)] 

    while True:
        x = curpos[0]
        y = curpos[1]

        if Matrix[y][x] == 0:
            areacount += 1

        Matrix[y][x] += 1
        movecount += 1

        if areacount == area:
            print 'movecount:',movecount
            # print Matrix
            break

        curpos = roachmove(curpos,width,height)

drinkroach(1000,1000,(0,0))

2015/10/07 17:40

우주미아홍구

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

void RandomMove(int ** matrix, int * x, int * y, int m, int n, long long * remaining_boxes);
void printMatrix(int ** matrix, int m, int n);
void moveMatrix(int ** matrix, int x, int y, int m, int n, long long * remaining_boxes);

int main(int argc, char* argv[])
{
    int m =0, n=0, x =0, y =0;
    int ** matrix;
    int i=0;
    long long total = 0, remaining_boxes=0, loop_count=0, loop_loop_count = 0;
    int temp_count = 0, remaining_change = 0, temp_rem = 0;
    time_t start,end; 
    double diff;
    double ratio;

    if (argc!=5) {
        printf("ERROR: Input argument missing. Usage: main 5 4 1 1");
        return 0;
    }

    m = atoi(argv[1]);
    n = atoi(argv[2]);
    x = atoi(argv[3]);
    y = atoi(argv[4]);

    if (x >= m){
        printf("ERROR: x muse be smaller than m value. x:%d, m:%d\n", x, m);
        return 0;
    }
    if (y >= n){
        printf("ERROR: y muse be smaller than n value. y:%d, n:%d\n", y, n);
        return 0;
    }
    remaining_boxes = m * n;
    total = remaining_boxes;    

    srand((unsigned)time(NULL)+(unsigned)getpid());
    if ((matrix = (int **)calloc(m, sizeof(int))) == NULL ) {
        printf("Array allocation of size of %d has failed.\n", m*n);

        return 0;
    }

    for (i=0; i<m; i++){
        if ((matrix[i] = (int *)calloc(n, sizeof(int))) == NULL ) {
            printf("Array allocation of size of %d has failed.\n", m*n);
            return 0;
        }
    }   
    matrix[x][y]=1;
    remaining_boxes--;
//  Initialization has been finished.

    time (&start);
    while (remaining_boxes > 0) {
        temp_rem = remaining_boxes;
        RandomMove(matrix, &x, &y, m, n, &remaining_boxes);
        if (temp_rem == remaining_boxes)
            temp_count++;
        else
            temp_count=0;
        if (loop_count == 100000000) {
            loop_loop_count++;
            loop_count=0;
        }
        else 
            loop_count++;
        if (temp_count > 50000) {
            temp_count = 0;
            srand((unsigned)time(NULL)+(unsigned)getpid());
        }
    }
    time (&end);
//  Random walk has been finished.

//  printMatrix(matrix, m, n)
    printf("Random walk simulation has finished.\n");
    printf("Last location of mouse is (%d, %d).\n", x, y);
    if (loop_loop_count > 0){
        printf("Total number of move is  %lld * 100,000,000 + ", loop_loop_count);  
        printf("%lld\n", loop_count);
    }
    else {  
        printf("Total number of move is  %lld.\n+", loop_count);  
    }
    diff = difftime (end,start); 
    printf ("Elasped time : %.2lf seconds.", diff ); 


//  Finilization begins
    for(i=0; i<m; i++){
        free(matrix[i]);
    }
    free(matrix);

    return 0;
}   

void RandomMove(int ** matrix, int * x, int * y, int m, int n, long long * remaining_boxes)
{
    int r = 0, done = 0;

    while (done == 0) {
        r = rand()%8;
        switch(r) {
            case 0 :
                if(*x>=1 && *y>=1) {
                    moveMatrix(matrix, *x-1, *y-1, m, n, remaining_boxes);
                    *x=*x-1;
                    *y=*y-1;
                    done = 1;
                    break;
                }
                else    
                    break;
            case 1 : 
                if(*x>=1) {
                    moveMatrix(matrix, *x-1, *y, m, n, remaining_boxes);
                    *x=*x-1;
                    done = 1;
                    break;
                }
                else    
                    break;
            case 2 : 
                if(*x>=1 && *y <=n-2 ) {
                    moveMatrix(matrix, *x-1, *y+1, m, n, remaining_boxes);
                    *x=*x-1;
                    *y=*y+1;
                    done = 1;
                    break;
                }
                else    
                    break;  
            case 3 : 
                if(*y >=1 ) {
                    moveMatrix(matrix, *x, *y-1, m, n, remaining_boxes);
                    *y=*y-1;
                    done = 1;
                    break;
                }
                else    
                    break;
            case 4 : 
                if(*y <=n-2 ) {
                    moveMatrix(matrix, *x, *y+1, m, n, remaining_boxes);
                    *y=*y+1;
                    done = 1;
                    break;
                }
                else    
                    break;
            case 5 :
                if(*x<=m-2 && *y>=1) {
                    moveMatrix(matrix, *x+1, *y-1, m, n, remaining_boxes);
                    *x=*x+1;
                    *y=*y-1;
                    done = 1;
                    break;
                }
                else    
                    break;
            case 6 : 
                if(*x<=m-2) {
                    moveMatrix(matrix, *x+1, *y, m, n, remaining_boxes);
                    *x=*x+1;
                    done = 1;
                    break;
                }
                else    
                    break;
            case 7 : 
                if(*x<=m-2 && *y <= n-2) {
                    moveMatrix(matrix, *x+1, *y+1, m, n, remaining_boxes);
                    *x=*x+1;
                    *y=*y+1;
                    done = 1;
                    break;
                }
                else    
                    break;
            default :
                break;
        }
    }
}

void moveMatrix(int ** matrix, int x, int y, int m, int n, long long * remaining_boxes)
{
    if (matrix[x][y]==0) {
        matrix[x][y]++;
        (*remaining_boxes)--;
    }
    else {
        matrix[x][y]++;
    }
}

void printMatrix(int ** matrix, int m, int n)
{
    int i, j;

    for (i=0; i<m; i++){
        for(j=0; j<n; j++){
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

  • 처음 작성해봤습니다. 동적으로 matrix를 생성하고, 초기 위치는 입력받는 걸로 해봤습니다.
  • 총 이동 횟수가 수십억이 넘어가니 자릿수를 벗어나네요.. Big Number를 구현하기 보다는, 그냥 되는데로 자릿수 나눠서 카운트해봤습니다.
  • 100x100은 1초도 안걸리고, 2,000x2,000은 1,347초 걸리네요..

D:\Codes\RandomWalk>main 100 100 0 0 Random walk simulation has finished. Last location of mouse is (7, 0). Total number of move is 214380. +Elasped time : 0.00 seconds.

D:\Codes\RandomWalk>main 2000 2000 0 0 Random walk simulation has finished. Last location of mouse is (943, 745). Total number of move is 420 * 100,000,000 +21472115 Elasped time : 1347.00 seconds.

2016/01/04 13:28

노형석

알고리즘은 다들 쓰신거랑 같구요, 사이즈가 커지면 꽤 오래 걸리네요.심화문제는 더 생각해봐야겠어요

from random import choice
x_size = 100
y_size = 100
visited_aim = x_size*y_size
initx, inity = 5,5

def roach(x_size,y_size,initx,inity):
    (x,y)=(initx,inity)
    land=[[0]*x_size for i in range(y_size)]
    land[y][x] = 1; move=0; visited = 1
    while True:
        land[y][x] += 1
        dx,dy = choice([(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)])
        if not x+dx in range(x_size) or not y+dy in range(y_size):continue
        x+=dx;y+=dy
        land[y][x] += 1; move+=1
        if land[y][x] == 1:
            visited+=1
            if visited==visited_aim : break
    for line in land:
        for point in line:
            print "%4d"%point,
        print
    print "Total move: %d"%move

roach(x_size,y_size,initx,inity)

2016/01/27 14:55

상파

Ruby

require 'set'

def random_walk(x, y, pos, g=[*1..y].product([*1..x]))
  rest, grid = g.to_set, g.map {|k| [k, 0]}.to_h
  move = ->c,r { p=[rand(c-1..c+1),rand(r-1..r+1)] until p!=[c,r] && grid[p]; p}
  (pos = move[*pos]; grid[pos] += 1; rest.delete pos) until rest.empty?
  puts grid.values.each_slice(x).map {|_|_.map{|c|"%3d "%c}*""}, grid.values.sum
end

성능

# 100 x 100 화면출력 포함 : 1.5초. +-0.5초
Rehearsal -----------------------------------------------------
random walk :       1.200000   0.000000   1.200000 (  1.207901)
out to console :    0.010000   0.000000   0.010000 (  0.003795)
-------------------------------------------- total: 1.210000sec

                        user     system      total        real
random walk :       0.000000   0.000000   0.000000 (  0.000008)
out to console :    0.010000   0.000000   0.010000 (  0.003654)

Output

# 10x10 case
random_walk(10, 10, [5,5]) 
 1   2   2   6   5   9   6   4   9   4
 2   5   7   4  13   8  10   4   5   5
 2  10   5  11  10   9   7   4   4   3
 2   8   7   9  20  13   8   3   8   5
 4   8   7   8  21  13   9   7   5   5
 4  13  10  19  12  12  10   8   4   3
 8   9  14  11   9   6  10   8   6   3
 3   5   4   8  18  14  11  10   5   9
 2   9   9  19  16  20  16  18   9   7
 2   4   8  11  15  16  20  12  11   5
841

2016/03/06 20:23

rk

Python 2.7

100*100은 약 1초 소요됩니다.

import random
d = zip([-1,-1,-1,0,0,1,1,1], [-1,0,1,-1,1,-1,0,1])
def walk(m, n, start=(0,0)):
    walkmat = [[0]*m for i in xrange(n)]
    posx = start[0]
    posy = start[1]
    unvisited = {(x,y) for x in xrange(m) for y in xrange(n)}-{(posx,posy)}
    walkmat[posy][posx]+= 1
    count = 0
    while unvisited:
        try:
            dx, dy = random.choice(d)
            assert 0 <= posx+dx < m
            assert 0 <= posy+dy < n
        except:
            continue
        posx+= dx
        posy+= dy
        walkmat[posy][posx]+= 1
        unvisited-= {(posx,posy)}
        count+= 1
    for y in xrange(n):
        for x in xrange(m):
            print walkmat[y][x],
        print
    print count

2016/03/24 11:37

최 재민

파이썬3.4입니다. 알고리즘이나 성능은 생각조차 못하고, 일단 출력되는데까지 했습니다.
제 컴이 문제인지(아니라면 더 비극ㅜ) maximum recursion depth exceeded 에러가 뜨길래, sys.setrecursionlimit를 늘려주면 된다고해서 일단 import해봤구요.
100x100이 뭔가요? 50x50만 해도 뻗어버리네요 ㅜㅜ
차후 실력이 늘거나 생각좀 해보고 수정해봐야겠네요..

from random import *
from pprint import *
import sys
sys.setrecursionlimit(10000000)
def f(x, y, walk = 0):
    global mtx
    def chk():
        for i in range(col):
            for j in range(row):
                if mtx[i][j] == 0:
                    return False
        return True
    if chk():
        return walk
    else:
        mtx[x][y] += 1
        a = randrange(-1, 2)
        b = randrange(-1, 2)
        while  x + a < 0 or x + a >= len(mtx) or y + b <0 or y + b >= len(mtx[0]):
            a = randrange(-1, 2)
            b = randrange(-1, 2)
        return f(x + a, y + b, walk + 1)
col, row = 30, 30 
x, y = 2, 3
mtx = [[0 for i in range(col)] for j in range(row)]
walk = f(x, y)
pprint(mtx)
print('walk', walk)

혹시 리스트가 느릴까봐, 모두 튜플로 바꿨고, 매트릭스는 좌표값을 키로, 방문횟수는 값으로 하여 딕셔너리로 했어요
매트릭스 딕셔너리를 셋으로 복사하여 방문한 곳은 셋에서 제거를 하면서 셋이 모두 비워질때까지 순환합니다.
100 x 100은 대략 2초 내외로 나오고, 300 x 300 이상도 많이 느리네요

'''
매트릭스를 딕셔너리로 구현. 혹시 리스트보다 빠를까봐
매트릭스의 키를 셋으로 복사하여, 한번 방문한 곳은 셋에서 제거함
모든 구역을 다 갔다면 셋이 {} 비어있음
'''
from random import randrange
from time import time

def make_matrix(col, row):
    matrix = {}
    for i in range(row):
        for j in range(col):
            matrix.update({(i, j): 0})
    return matrix

def walk(x, y):
    global matrix, matrix_set
    matrix[x, y] += 1
    matrix_set -= {(x, y)} #색인
    while True:
        dir_sel = DIR[randrange(8)]
        dir_sel_x, dir_sel_y = dir_sel[0], dir_sel[1]
        new_x, new_y = x + dir_sel_x, y + dir_sel_y
        if new_x < 0 or new_x >= col or new_y < 0 or new_y >= row:
            continue
        else:
            break
    return new_x, new_y

def start(x, y):
    a = time()
    chk = 0 #움직인 횟수
    while True:
        x, y = walk(x, y) 
        chk += 1
        if not matrix_set: #모두 방문하였으면
            break
    print(chk)
    print(matrix)
    b = time()
    print('time: %.2f' % (b - a))


col, row = 100, 100 
matrix = make_matrix(col, row)
matrix_set = set(matrix.keys())
DIR = (
    (-1, -1), (0, -1), (1, -1),
    (-1, 0), (1, 0),
    (-1, 1), (0, 1), (1, 1),
)

x, y = randrange(col), randrange(row)
start(x, y)

2016/03/25 18:27

디디

import random as rd
class cursor():
    def __init__(self, li, y, x):
        self.li, self.y, self.x = li, y, x
        self.li[y][x] += 1
        self.total = 0
    def get_movable(self):
        result = {'up':0, 'left':0, 'right':0, 'down':0}
        if self.y + 1 <= len(self.li) - 1:
            result['up'] = 1
        if self.x - 1 >= 0:
            result['left'] = 1
        if self.x + 1 <= len(self.li[0]) - 1:
            result['right'] = 1
        if self.y - 1 >= 0:
            result['down'] = 1
        return result
    def __next__(self):
        while 1:
            moves = self.get_movable()
            dy = rd.randint(-moves['down'],moves['up'])
            dx = rd.randint(-moves['left'],moves['right'])
            if dy == dx == 0: continue
            self.y += dy
            self.x += dx
            self.li[self.y][self.x] += 1
            self.total += 1
            if any(any(x == 0 for x in y) for y in self.li):
                continue
            else:
                break
        return self.li, self.total
    def print(self):
        for y in self.li:
            for x in y:
                print(x, end = ' ')
            print()
        print('\ntotal : '+str(self.total))
while __name__ == '__main__':
    m, n = list(map(int, input('>>>').split()))
    x, y = list(map(int, input('>>>>>>').split()))
    mp = list(list(0 for x in range(m)) for y in range(n))
    c = cursor(mp, y, x)
    next(c)
    c.print()

100*100에서 꽤 걸리네요. 파이썬 3.5.1

2016/04/15 12:26

Flair Sizz

# 파이썬 3.5.1

from random import *

def do(xl,yl,x,y):
    c = 0
    mat = [[0 for i in range(xl)] for i in range(yl)]
    direc = {0:(0,-1),1:(1,-1),2:(1,0),3:(1,1),4:(0,1),5:(-1,1),6:(-1,0),7:(-1,-1)}
    while True:
        matstr = ''
        matstt = ''
        for i in mat:
            i = list(map(str,i))
            matstt += ' ' + ' '.join(i) + ' \n'
            matstr += ' '.join(i) + '\n'
        if x == 1:
            if y == 1:
                di = choice([2,3,4])
            elif y == yl:
                di = choice([0,1,2])
            else:
                di = choice([0,1,2,3,4])
        elif x == xl:
            if y == 1:
                di = choice([4,5,6])
            elif y == yl:
                di = choice([6,7,0])
            else:
                di = choice([4,5,6,7,0])
        else:
            if y == 1:
                di = choice([2,3,4,5,6])
            elif y == yl:
                di = choice([0,1,2,6,7])
            else:
                di = choice([0,1,2,3,4,5,6,7])
        mat[x-1][y-1] += 1
        x += direc[di][0]
        y += direc[di][1]
        if matstt.count(' 0 ') == 0:
            return matstr,c
        c += 1

xM,yM,x,y = map(int,input().split())
s,c = do(xM,yM,x,y)
print(s)
print(c)

2016/04/22 23:08

차우정

C#으로 작성했습니다. 위의 이우람 님의 코드를 도움 받아 작성했습니다. Random Walk가 아직도 이해하기 어렵네요. 추후에 다시 작성해서 올리겠습니다.

        public double CountRandomWalk(int m, int n)
        {

            var count = 0d;
            var enabled = new bool[m, n];
            var matrix = new int[m, n];
            var maxX = m - 1;
            var maxY = n - 1;
            var left = m*n;
            var random = new Random();
            var positionX = random.Next(0, m);
            var positionY = random.Next(0, n);

            while (true)
            {

                count++;
                matrix[positionX, positionY]++;
                if (!enabled[positionX, positionY])
                {
                    enabled[positionX, positionY] = true;
                    if (--left == 0) break;
                }

                if (positionX == 0) positionX += random.Next(0, 2);
                else if (positionX == maxX) positionX += random.Next(-1, 1);
                else positionX += random.Next(-1, 2);

                if (positionY == 0) positionY += random.Next(0, 2);
                else if (positionY == maxY) positionY += random.Next(-1, 1);
                else positionY += random.Next(-1, 2);

            }

            return count;
        }

2016/05/31 14:25

Straß Böhm Jäger

늅늅입니다. 자바로 풀어봤습니다.

public static int sizeX;
    public static int sizeY;
    public static int mapCount;
    public static int moveCount;
    public static boolean[][] mapCheck;
    public static Random rand;
    public static int[] movePos;
    public static void main(String args[])
    {
        CreateMap(2000, 2000);
        Start();
    }

    public static void CreateMap(int x, int y)
    {
        sizeX = x; sizeY = y;

        mapCheck = new boolean[x][y];
        mapCount = x*y;
        moveCount = 0;
        movePos = new int[2];
        rand = new Random();

        for(int i = 0; i < x; i++) for(int j = 0; j <y; j++)
        {
            mapCheck[i][j] = false;
        }
    }

    public static void Start()
    {
        int moveX, moveY;

        moveX = 6; moveY = 5;

        mapCheck[moveX][moveY] = true;
        mapCount--;

        do 
        {
            movePos = RandMove(moveX, moveY);
            moveCount++;

            if(mapCheck[moveX][moveY] == false)
            {
                mapCheck[moveX][moveY] = true;
                mapCount--;
            }

            moveX = movePos[0];
            moveY = movePos[1];

            //System.out.println("바퀴가 " + moveX + ":" + moveY + "로 움직입니다." + " " + moveCount + " " + "아직 가보지 않은 방은 " + mapCount +"개 남았습니다."  );

        } while (mapCount != 0);

        Result();
    }

    public static int[] RandMove(int x, int y)
    {
        int moveTargetX, moveTargetY;

        moveTargetX = x;
        moveTargetY = y;

        int tempnum = rand.nextInt(3);
        switch(tempnum)
        {
        case 0:
            if(moveTargetX > 0)
                moveTargetX--;
            break;
        case 1:
            break;
        case 2:
            if(moveTargetX < sizeX-1)
                moveTargetX++;
            break;
        }

        tempnum = rand.nextInt(3);
        switch(tempnum)
        {
        case 0:
            if(moveTargetY > 0)
                moveTargetY--;
            break;
        case 1:
            break;
        case 2:
            if(moveTargetY < sizeY-1)
                moveTargetY++;
            break;
        }

        int[] targetPos = {moveTargetX, moveTargetY};

        movePos = targetPos;

        return movePos;
    }

    public static void Result()
    {
        System.out.println("바퀴가 움직인 횟수는 " + moveCount +"회 입니다.");
    }

제 컴퓨터에선 2000*2000 이 약 8~11초 정도 소요됩니다. 동선을 보기위해 주석을 푸니... ( ..)...

2016/08/03 18:39

여우와향신료

심화는 .... 어렵워서 ㅠㅠ .... 100 * 100하는데 꾀 걸림 ㅠㅠ.

stay : 108 , move : 287

Board

17 38 35 13 1

27 19 15 7 2

28 13 11 3 1

11 14 4 4 2

1 4 4 1 3 계속하려면 아무 키나 누르십시오 . . .

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


void move(int* x, int* y);
bool verdict(int** arr);

int h, w;
int stay;
void main() { 
    srand(time(NULL));

    int init_x =0, init_y = 0;
    int x, y;
    x = init_x;
    y = init_y;
    h=5;
    w=5;
    stay = 0;
    //arr[y][x];
    int** arr = (int**) malloc (sizeof(int*) * h);
    for(int i=0;i<h;i++)
        arr[i] = (int*) malloc (sizeof(int*) * w);

    for(int i=0;i<h;i++)
        for(int j=0;j<h;j++)
            arr[i][j] = 0;

    while(!verdict(arr)) {
        move(&x, &y);
        arr[y][x]++;
    }
    int sum = 9;
    for(int i=0;i<h;i++)
        for(int j=0;j<h;j++)
            sum = sum + arr[i][j];
    printf("stay : %d , sum : %d\n", stay, sum);

    printf("\n\nBoard\n");
    for(int i=0;i<h;i++){
        for(int j=0;j<h;j++) {
            printf("%d\t", arr[i][j]);
        }
        printf("\n");
    }

}

bool verdict(int** arr) {
    for(int i=0;i<h;i++)
        for(int j=0;j<h;j++)
            if(arr[i][j]==0)
                return false;
    return true;
}

void move(int* x, int* y) {
    int d = rand()%8;
    int sx = *x, sy = *y;
    switch(d) {
        case 1:
            if(*y-1 >=0 && *x-1>=0) {
                (*y)--;
                (*x)--;
            }
            break;
        case 2:
            if(*y-1 >=0) 
                (*y)--;
            break;
        case 3:
            if(*y-1 >=0 && *x+1<w) { 
                (*y)--;
                (*x)++;
            }
            break;
        case 4:
            if(*x-1 >=0) 
                (*x)--;
            break;
        case 5:
            if(*x+1<w)
                (*x)++;
            break;
        case 6:
            if(*x-1 >=0  && *y+1 < h) {
                (*y)++;
                (*x)--;
            }
            break;
        case 7:
            if(*y+1 < h)
                (*y)++;
            break;
        case 8:
            if(*y+1 < h && *x+1 < w) {
                (*y)++;
                (*x)++;
            }
            break;
    }
    if(sx==*x && sy==*y)
        stay++;
}

2017/01/11 15:04

코딩초보

import random

x, y, gps = input().split(' ')
x, y, gps = int(x), int(y), list(map(int,gps.split('.')))
_map = [0 for z in range(x*y)]
_list = [[a,b] for a in range(x) for b in range(y)]

while 0 in _map:
    a = random.randint(-1,1)
    b = random.randint(-1,1)
    if gps[0]+a == x or gps[0]+a < 0 or \
       gps[1]+b == y or gps[1]+b < 0:
        continue
    gps = [gps[0]+a,gps[1]+b]
    _map[_list.index(gps)] += 1
for a in [_map[a:a+x] for a in range(0,x*y,x)][::-1]:
    print(a)
print('총 움직인 횟수 : %d' % sum(_map))

#### 2017.01.27 D-391 ####

2017/01/27 23:23

GunBang

```{.java} import java.util.Random;

public class Random_Walk { int size_x,size_y = 0; int ori_x,ori_y = 0; int count = 0; int[][] matrix; public Random_Walk(int a, int b,int x, int y){ size_x = a; size_y = b; ori_x = x; ori_y = y; matrix = new int[size_x][size_y]; } public void random_walk(){ Random random = new Random();

    while(count < size_x * size_y){
        switch(random.nextInt(8)){
            case 0 : 
                if(!check_this(ori_x, ori_y+1))
                    break;
                ori_y++; break;
            case 1:
                if(!check_this(ori_x+1, ori_y+1))
                    break;
                ori_x++;ori_y++; break;
            case 2: 
                if(!check_this(ori_x+1, ori_y))
                    break;
                ori_x++; break;
            case 3: 
                if(!check_this(ori_x+1, ori_y-1))
                    break;
                ori_x++;ori_y--; break;
            case 4: 
                if(!check_this(ori_x, ori_y-1))
                    break;
                ori_y--; break;
            case 5: 
                if(!check_this(ori_x-1, ori_y-1))
                    break;
                ori_x--;ori_y--; break;
            case 6: 
                if(!check_this(ori_x-1, ori_y))
                    break;
                ori_x--; break;
            case 7: 
                if(!check_this(ori_x-1, ori_y+1))
                    break;
                ori_x--;ori_y++; break;
        }
    }
}

public boolean check_this(int x, int y){
    if(0 > x | x >= size_x)
        return false;
    if(0 > y | y >= size_y)
        return false;

    if(matrix[x][y] == 0)
            count++;
    matrix[x][y]++;

    return true;

}

public void print_matrix(){
    for(int i = 0; i < size_x; i++){
        for(int j = 0; j < size_y; j++)
            System.out.print(matrix[i][j]+" ");
    System.out.println();
    }
}

}

```> 다른분들 풀이를 보니 저도 비슷하게 풀었더군요. matrix의 배열 하나하나를 0으로 체크하고 다 돌았나 확인하는 방법은 너무 느린거 같아서 count 변수를 따로 만들어 다 회전했나 확인하게 했습니다. 랜덤하게 움직이는 것은 Random class를 이용했습니다.

2017/03/03 20:00

KimSeonbin

#-*- coding:utf-8 -*-
import numpy as np
import time
##입력 : 격자의 가로, 세로 크기, 바퀴벌레의 초기 위치            ##
##출력 : 각 칸에 바퀴벌레가 멈추었던 횟수, 바퀴벌레가 움직인 횟수. ##

def f_cocka(h,v,i,j):
    array = np.zeros((v,h),dtype=int)
    count = 0
    switch_case = {
        1: (0, -1), 2: (1, -1),
        3: (1,  0), 4: (1,  1),
        5: (0,  1), 6: (-1, 1),
        7: (-1, 0), 8: (-1,-1)
    }
    while len(array[array==0]) != 0:
        #랜덤으로 방향을 움직이고 그 전에 장소에 1를 더함
        direction = np.random.randint(1, 9)
        d_x = switch_case[direction][0]
        d_y = switch_case[direction][1]
        if ((i+d_x < 0)|(i+d_x >= v)|(j+d_y < 0)|(j+d_y >= h)):
            continue
        else :
            count += 1
            array[i, j] += 1
            i += d_x
            j += d_y
    return array,count

startTime = time.time()
print f_cocka(100,100,2,3)
endTime = time.time()
print "걸린 시간은 %.2f 초" % (endTime - startTime)

2017/04/26 13:24

daybreak

  1. 파이썬 3.x입니다.
  2. 매회 방향을 구할 때, 현재 위치에 따라서 움직일 수 있는 방향을 제한하였습니다. 속도저하가 있다면 여기에 있지 않을까 생각이 듭니다.
  3. 바퀴의 머문 횟수는 dictionary로 구현하였습니다. 가독성은 떨어지지만 좌표를 나타내었습니다.
# Random walk

import random

length = int(input('너비 입력 :'))
height = int(input('길이 입력 :'))
(x_n , y_n) = (int(input('초기위치(x좌표) :')), int(input('초기위치(y좌표) :')))
board = {(i,j):0 for i in range(length) for j in range(height)}
move = ()
num_of_moves = 0

def proper_directions(x_n,y_n): #네모 밖으로 나가면 안되니까
    directions = set([(-1,1),(-1,0),(-1,-1),(0,1),(0,-1),(1,1),(1,0),(1,-1)])
    if x_n == 0:
        directions = directions - set([(-1,1),(-1,0),(-1,-1)])
    elif x_n == length -1:
        directions = directions - set([(1,1),(1,0),(1,-1)])
    if y_n == 0:
        directions = directions - set([(-1,-1),(0,-1),(1,-1)])
    elif y_n == height -1:
        directions = directions - set([(-1,1),(0,1),(1,1)])
    return list(directions)

board[(x_n,y_n)]=1 #초기위치
while list(board.values()).count(0)>0: #모든칸에 바퀴가 한번 이상 갈 때까지

    move = random.choice(proper_directions(x_n,y_n)) 
    x_n += move[0]
    y_n += move[1]
    board[(x_n,y_n)] += 1
    num_of_moves += 1

print('바퀴의 이동 횟수 : {}'.format(num_of_moves))
print('각 칸에 바퀴가 머물렀던 횟수 : {}'.format(board))

2017/05/01 22:42

고든

// 바퀴벌레 - C#
using System;
namespace Roach
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Ready>>>");
            string input = Console.ReadLine();
            int x = int.Parse(input.Split(' ')[0]);
            int y = int.Parse(input.Split(' ')[1]);
            int inix = int.Parse(input.Split(' ')[2]);
            int iniy = int.Parse(input.Split(' ')[3]);
            long[,] board = new long[x, y];
            int posx = inix - 1, posy = iniy - 1;
            board[posx, posy]++;
            Random r = new Random();
            long counter = 0;
            while(true)
            {
                bool check = true;
                int tempx = r.Next(-1, 2);
                int tempy = r.Next(-1, 2);
                if (tempx + posx < 0 || tempx + posx >= x || tempy + posy < 0 || tempy + posy >= x)
                    continue;
                else
                    posx += tempx; posy += tempy;
                board[posx, posy]++; counter++;
                for (int i = 0; i < x; i++)
                    for (int j = 0; j < y; j++)
                        if (board[i, j] == 0)
                            check = false;
                if (check)
                    break;
            }
            for (int i = 0; i < y; i++)
            {
                for (int j = 0; j < x; j++)
                    Console.Write("{0} ", board[j, i]);
                Console.WriteLine();
            }
            Console.WriteLine("Move Rate = {0}", counter);
        }
    }
}

2017/06/30 22:45

Jeong Hoon Lee

Python3

1차원으로 만들어 봤습니다. 딱히 더 빠르진 않은 거 같네요.

from random import choice
import time

X, Y, cx, cy = tuple(map(int, input().split()))  # zero-base
roach = cx * X + cy
visits = [0 for x in range(X * Y)]
dir = [-X-1, -X, -X+1, -1, 0, 1, X-1, X, X+1]
stime = time.time()

visits[roach] = 1
vcnt = X*Y - 1
nmove = 0
while vcnt:
    next = list(filter(lambda x: 0 <= x < X*Y, [roach+d for d in dir]))
    roach = choice(next)

    if not visits[roach]: vcnt -= 1
    visits[roach] += 1
    nmove += 1

for i in range(X): print(visits[i*X:(i+1)*X])
print(nmove)
print('%.2f sec' % (time.time() - stime))

2017/08/05 04:51

Noname

import random
import numpy as np

def RW(A,B,pos):
    grid = []
    for b in range(B):
        grid.append([0 for a in range(A)])
    D = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]]
    a = pos[0]
    b = pos[1]

    while np.prod(grid) == 0:
        grid[b][a] += 1
        candid = []
        for d in D:
            if 0<=a+d[1]<A and 0<=b+d[0]<B:
                candid.append(d)
        c = candid[int(np.random.choice(len(candid)))]
        a += c[1]
        b += c[0]
    print(grid, np.sum(grid)-1)

A = 4
B = 8
pos = (int(np.random.choice(A,1)),int(np.random.choice(B,1)))

RW(A,B,pos)

2017/08/19 15:50

이현우

package codingdojang;

import java.util.Random; import java.util.Scanner;

public class ex38 {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt(); // 세로 길이
    int m = sc.nextInt(); // 가로 길이
    int map[][] = new int[n][m];
    int x = sc.nextInt(); // 벌레의 x
    int y = sc.nextInt(); sc.nextLine(); // 벌레의 y

    roach r = new roach(x,y,n,m);
    map[x][y] = 1;
    int remain = n*m -1; // 한번도 안지나간 좌표의 수
    Random rd = new Random();

    System.out.println(remain);


    while(remain>0) {
    r.move(rd.nextInt(8));
    map[r.getX()][r.getY()]++;
        if(map[r.getX()][r.getY()] == 1) {
            remain--;
        }
    }

    System.out.println(remain);
    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++) {
            System.out.print(map[i][j]+ " "); // 각 좌표별 지나간 횟수 출력
        }
        System.out.println();
    }
}

}

class roach{ private int x; private int y; private int maxX; private int maxY;

public roach(int x,int y,int maxX,int maxY) {
    this.x = x;
    this.y = y;
    this.maxX = maxX;
    this.maxY = maxY;
}

public void move(int sw) {
    switch(sw) {
    case 0:
        if(x>0)
        x = x-1;
        break;
    case 1:
        if(x<maxX-1)
        x = x+1;
        break;
    case 2:
        if(y>0)
        y = y-1;
        break;
    case 3:
        if(y<maxY-1)
        y = y+1;
        break;
    case 4:
        if(x>0&&y>0) {
        x = x-1;
        y = y-1;
        }
        break;
    case 5:
        if(x>0&&y<maxY-1) {
        x = x-1;
        y = y+1;
        }
        break;
    case 6:
        if(x<maxX-1&&y>0) {
        x = x+1;
        y = y-1;
        }
        break;
    case 7:
        if(x<maxX-1&&y<maxY-1) {
        x = x+1;
        y = y+1;
        }
        break;          
    default:
        break;
    }
}

public int getX() {
    return x;
}
public int getY() {
    return y;
}

}

2017/10/08 14:34

이병호

투플러스님꺼 참고해서 풀었어요. 랜덤으로 방향을 정하는것 보다 iter을 사용한 랜덤 방향전환이 확실이 속도면에서 빠른거 같아요

import random
import time
import itertools
t = time.time()
r = 100
c = 100

board = dict()
total = 0

direction = list(itertools.product((-1, 0, 1), repeat=2))
direction.remove((0, 0))

# random starting point
x = random.randint(0, r - 1)
y = random.randint(0, c - 1)
board[(x, y)] = 1
while len(board) < r*c:
    tempx, tempy = random.choice(direction)
    x += tempx
    y += tempy
    if x < 0:
        x = 0
    elif x > c-1:
        x = c-1
    if y < 0:
        y = 0
    elif y > r-1:
        y = r-1

    board[(x,y)] = board.get((x, y), 0) + 1
    total += 1

print(time.time() - t)
print(total)
print(board)

2017/12/06 00:05

Sung Kim

Java 입니다.

import java.util.Random;

public class level_3_drunken_cockroach {

public static void main(String[] args) {

    int xmin = 0;
    int xmax = 4; // 최대 가로 길이.
    int ymin = 0;
    int ymax = 7; // 최대 세로 길이.
    int count = 0;

    int[][] box = new int[ymax][xmax]; // 2차원 배열 생성. (현재는 가로 4칸, 세로 7칸, 총 28칸.)

    Random randomGenerator = new Random(); // 랜덤 한 수 생성하는 명렁.
    int randomY = randomGenerator.nextInt(ymax); // 0 부터 6 까지 랜덤 수.
    int randomX = randomGenerator.nextInt(xmax); // 0 부터 3 까지 랜덤 수.

    for(int i = 0; i < ymax; i++) // 모든 칸에 0 을 입력함.
    {
        for(int j = 0; j < xmax; j++)
        {
            box[i][j] = 0;
        }
    }
    box[randomY][randomX] = 1; // 시작. 랜덤 위치에 바퀴벌레 뿅.

    while(true) // 무한 반복.
    {
        if(randomY == ymin && randomX == xmin) // 시작점이 (최솟값, 최솟값) 이면.
        {
            randomY = randomGenerator.nextInt(2); // y 값이 0 이면, 0 ~ 1 까지 랜덤 수.
            randomX = randomGenerator.nextInt(2); // x 값이 0 이면, 0 ~ 1 까지 랜덤 수.
            box[randomY][randomX]++;
            count++;
        }
        else if(randomY == ymax - 1 && randomX == xmax - 1) // 시작점이 (최댓값, 최댓값) 이면.
        {
            randomY = randomGenerator.nextInt(2) + randomY - 1;
            randomX = randomGenerator.nextInt(2) + randomX - 1;
            box[randomY][randomX]++;
            count++;
        }
        else if(randomY == ymin && randomX == xmax - 1) // 시작점이 오른쪽 위 꼭지점 이면.
        {
            randomY = randomGenerator.nextInt(2) + randomY;
            randomX = randomGenerator.nextInt(2) + randomX - 1;
            box[randomY][randomX]++;
            count++;
        }
        else if(randomY == ymax - 1 && randomX == xmin) // 시작점이 왼쪽 아래 꼭지점 이면.
        {
            randomY = randomGenerator.nextInt(2) + randomY - 1;
            randomX = randomGenerator.nextInt(2) + randomX;
            box[randomY][randomX]++;
            count++;
        }
        else if(randomY == ymin && (randomX > xmin && randomX < xmax)) // 꼭지점을 제외한, 위 모서리.
        {
            randomY = randomGenerator.nextInt(2);
            randomX = randomGenerator.nextInt(3) + randomX - 1;
            box[randomY][randomX]++;
            count++;
        }
        else if(randomY == ymax - 1 && (randomX > xmin && randomX < xmax)) // 꼭지점을 제외한, 아래 모서리.
        {
            randomY = randomGenerator.nextInt(2) + randomY - 1;
            randomX = randomGenerator.nextInt(3) + randomX - 1;
            box[randomY][randomX]++;
            count++;
        }
        else if((randomY > ymin && randomY < ymax) && randomX == xmin) // 꼭지점을 제외한, 왼쪽 모서리.
        {
            randomY = randomGenerator.nextInt(3) + randomY - 1;
            randomX = randomGenerator.nextInt(2);
            box[randomY][randomX]++;
            count++;
        }
        else if((randomY > ymin && randomY < ymax) && randomX == xmax - 1) // 꼭지점을 제외한, 오른쪽 모서리.
        {
            randomY = randomGenerator.nextInt(3) + randomY - 1;
            randomX = randomGenerator.nextInt(2) + randomX - 1;
            box[randomY][randomX]++;
            count++;
        }
        else // 모서리 부분을 제외한 부분이면.
        {
            randomY = randomGenerator.nextInt(3) + randomX - 1;
            randomX = randomGenerator.nextInt(3) + randomX - 1;
            box[randomY][randomX]++;
            count++;
        }
        int judge = box[randomY][randomX]; // 모든 배열 요소 값이 1 이상일 경우 무한루프를 멈추게 할때 쓰일 변수.
        for(int i = 0; i < ymax; i++) // 모든 값들이 곱해준다.
        {
            for(int j = 0; j < xmax; j++)
            {
                judge = judge * box[i][j];
            }
        }
        if(judge != 0) // 모든 값들을 곱했을때 0이 아니면 무한루프 종료.
        {
            break;
        }
    }       
    for(int j = 0; j < ymax; j++) // o
    {
        System.out.println();
        for(int h = 0; h < xmax; h++)
        {
            System.out.print(box[j][h] + "  ");
        }
    }
    System.out.println();
    System.out.println("바퀴벌레가 돌아다닌 횟수 : " + count);
}

}

5일차만에 바퀴벌레를 잡긴했는데... 바퀴벌레 움직임이 이상하네요. 사각형 격자의 왼쪽위 꼭지점에서 오른쪽 아래 꼭지점으로 거의 이렇게 대각선 모양으로 움직이네요. 자바 초보라서 왜이러는지 잘 모르겠어요 검색해도 안나오고, 시드문제는 아닌거같고. 혹시 댓글로 조언해주시면 매우 감사하겠습니다. 애착가는 문제네요.

범위지정 난수로 문제를 풀었습니다.

2018/01/24 10:42

Byam_Gyu

파이썬 3.6

"""
아이디어>
 1. [column][row] 크기의 격자를 모든 요소값을 0으로 대입하여 만들고,
 2. 바퀴벌레 위치에 따른 이동 가능 방향 =>[좌상,상,우상,좌,우,좌하,하,우하]
 3. 현재 위치에서 위의 방향 리스트의 좌표값을 임의로 선택합니다. 이때 좌표값이 0<= x <= row-1, 0 <= y < column-1 범위 안에 있을때까지 임의 선택을 반복합니다. 
 4. 조건을 만족하는 자표값 이 선택되면 이동하고, 최초 시작위치에서 이동시 마다 이동횟수와 해당 좌표의 요소값을 1씩 증가 시킵니다.
 5. 매 이동시 모든 요소값에 대해 0 이 있는지 확인하여, 0 이 없을 때까지 이동을 계속합니다.
"""

import random

def random_walk(m,n,p):
    move,chk,tmp,x,y = 0, 0,[],p[0],p[1]
    matrix = [[0 for h in range(m)] for i in range(n)]
    while True:
        chk = 0
        direction = [[x-1,y-1],[x,y-1],[x+1,y-1],[x-1,y],[x+1,y],[x-1,y+1],[x,y+1],[x+1,y+1]]
        while True:
            tmp = random.choice(direction)
            if 0 <= tmp[1] <= n-1 and 0 <= tmp[0] <= m-1:
                break
        matrix[tmp[1]][tmp[0]] += 1
        move += 1        
        for arr in matrix:
            if 0 in arr:
                chk += 1
        if chk == 0:
            break
        x,y = tmp[0],tmp[1]        
    for i in matrix:
        print(''.join([str("{0:^4}".format(h)) for h in i]))
    print("\n""☞이동한 횟수 = %d"% move)

if __name__ == "__main__":
    m = int(input("row = "))
    n = int(input("column = "))
    p = [int(input("x(0 <= y <= row-1) = ")),int(input("y(0 <= y <= column-1) = "))]
    print("\n")
    random_walk(m,n,p)

*결과값

row = 4
column = 2
x(0 <= y <= row-1) = 1
y(0 <= y <= column-1) = 1


 3   8   7   1  
 2   5   2   1  

☞이동한 횟수 = 29

row = 9
column = 5
x(0 <= y <= row-1) = 3
y(0 <= y <= column-1) = 3


 5   2   3   9   13  16  11  6   3  
 8   9   8   18  25  20  11  9   6  
 7   8   7   12  13  14  9   12  4  
 4   6   5   8   8   12  11  7   5  
 1   3   6   4   5   7   6   5   3  

☞이동한 횟수 = 374

2018/01/31 21:04

justbegin

import random
def randomwalk(m,n,a,b):
    l = [[0 for i in range(m)] for j in range(n)]
    l[b][a] = 1
    notpassed = m*n-1
    while notpassed:
        if a == 0 and b == 0:
            x = random.choice([(1,0), (1,1), (0, 1)])
        elif a == 0 and b == n-1:
            x = random.choice([(0, -1), (1, -1), (1, 0)])
        elif a == m-1 and b == 0:
            x = random.choice([(0, 1), (-1, 1), (-1, 0)])
        elif a == m-1 and b == n-1:
            x = random.choice([(0, -1), (-1, 0), (-1, -1)])
        elif  a == 0:
            x = random.choice([(0, -1), (1, -1), (1, 0), (1, 1), (0, 1)])
        elif a == m-1:
            x = random.choice([(0, -1), (0, 1), (-1, 1), (-1, 0), (-1, -1)])
        elif b == 0:
            x = random.choice([(1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0)])
        elif b == n-1:
            x = random.choice([(0, -1), (1, -1), (1, 0), (-1, 0), (-1, -1)])
        else:
            x = random.choice([(0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)])
        a += x[0]
        b += x[1]
        if l[b][a] == 0:
            notpassed -= 1
        l[b][a] += 1
    return l
a = list(map(int, input().split(' ')))
b = randomwalk(a[0], a[1], a[2], a[3])
result = 0
for i in b:
    print(i)
    result += sum(i)
print(result - 1)

2018/02/18 10:02

김동하

생각보다 좀 많이 움직이네요. 그래도 모두 채웠을때 출력이 됩니다.

using System;

namespace CSharp_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            int width;
            int height;

            int pos_x, pos_y; //바퀴벌래 위치
            int[,] arr;

            Console.Write("width : "); width = int.Parse(Console.ReadLine());
            Console.Write("height : "); height = int.Parse(Console.ReadLine());
            Console.Write("pos_x : "); pos_x = int.Parse(Console.ReadLine());
            Console.Write("pos_y : "); pos_y = int.Parse(Console.ReadLine());

            arr = new int[height, width];

            arr[pos_y, pos_x]++;
            bool flag = true;

            int moveCount = 0; //바퀴벌레 이동횟수

            //처음 배열(위치)
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Console.Write("{0} ", arr[i, j]);
                }
                Console.WriteLine();
            }

            while (true)
            {
                int count = 0;

                //바퀴벌레 이동
                moveCount++;
                Random r = new Random();

                int randomNum;

                while(true)
                {
                    bool s = false; //움직여도 되는 위치로 선정되면 true로 빠져나간다.

                    randomNum = r.Next(1, 5);

                    if (width - 1 == pos_x && randomNum == 1)//x마지막에 있는경우
                        continue;
                    if (pos_x == 0 && randomNum == 2)          //x맨앞에 있는 경우
                        continue;
                    if (height - 1 == pos_y && randomNum == 3) //y마지막에 있는 경우
                        continue;
                    if (pos_y == 0 && randomNum == 4)//y맨앞에 있는 경우
                        continue;
                    break;
                }

                switch (randomNum)
                {
                    case 1://우
                        pos_x++;
                        arr[pos_y, pos_x]++;
                        break;
                    case 2://좌
                        pos_x--;
                        arr[pos_y, pos_x]++;
                        break;
                    case 3://상
                        pos_y++;
                        arr[pos_y, pos_x]++;
                        break;
                    case 4://하
                        pos_y--;
                        arr[pos_y, pos_x]++;
                        break;
                }

                //검사
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        if (arr[i, j] == 0)
                        {
                            count++;
                        }
                    }
                }
                //모든 지역을 들렀다면 끝
                if (count == 0)
                    break;
            }
            Console.WriteLine("moveCount : {0}", moveCount);
            Console.WriteLine();

            //배열출력 (지역마다 들럿던 횟수)
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Console.Write("{0} ", arr[i, j]);
                }
                Console.WriteLine();
            }
        }
    }
}

2018/02/23 22:46

와디더

import java.util.Random;
import java.util.Scanner;

public class Table {


    static int verticals = 0;

    static int rows = 0;

    public static void execute(int[][] table, int count, int row, int vertical){
        if(table[row][vertical] == 0){
            count--;
            table[row][vertical]++;
        }else{
            table[row][vertical]++;
        }
        if(count == 0){
            return ;
        }

        Random random = new Random();

        boolean flag = false;

        while(!flag){
            int direction = random.nextInt(4);

            if(direction == 0){
                if(row-1 >= 0){
                    row--;
                    flag = true;
                }
            }else if(direction == 1){
                if(vertical+1 < verticals){
                    vertical++;
                    flag = true;
                }

            }else if(direction == 2){
                if(row +1 < rows){
                    row++;
                    flag = true;
                }


            }else{
                if(vertical-1 >= 0){
                    vertical--;
                    flag = true;
                }

            }

        }
        execute(table, count, row, vertical);

    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner sc = new Scanner(System.in);

        verticals = sc.nextInt();
        rows = sc.nextInt();
        int startRow = sc.nextInt();
        int startVertical = sc.nextInt();

        int[][] table = new int[rows][verticals];

        int count = rows * verticals; // 모든 칸수

        execute(table, count, startRow, startVertical);


        int sum = 0;
        for(int i=0; i< table.length; i++){
            for(int j=0; j < table[i].length; j++){
                System.out.printf("%3d" , table[i][j]);
                sum += table[i][j];

            }
            System.out.println();
        }
        System.out.println("sum :: " + sum);


    }

}

2018/04/03 21:00

김태훈

Swift입니다.

무작위로 이동하며, 최초 방문 타일의 갯수가 전체 타일 갯수와 같아지면 종료합니다. 엄청나게 큰 지도의 경우, 무작위라는 조건이 달려 있을 때 무엇을 할 수 있는지는 잘 모르겠습니다.

지도 크기가 1000x1000인 경우 약 40초에 방문한 타일 갯수는 약 7천만개입니다.

// Random Walk
import Foundation

let width = 100     // <-- Change this!!
let height = 100    // <-- Change this!!

let totalTileCount = width * height
var map = Array(repeating: Array(repeating: 0, count: width), count: height)
var foundNewTileCount = 0
var x = 0
var y = 0

while true {
    if map[y][x] == 0 {
        foundNewTileCount += 1
        print("Found tile count -> \(foundNewTileCount)")
    }
    map[y][x] += 1

    if foundNewTileCount < totalTileCount {
        let direction = Int(arc4random_uniform(8))
        if direction == 0 || direction == 1 || direction == 7 { // y - UP
            y = y > 0 ? (y - 1) : (y + 1)
        }
        if direction == 3 || direction == 4 || direction == 5 { // y - Down
            y = y < (height - 1) ? (y + 1) : (y - 1)
        }
        if direction == 1 || direction == 2 || direction == 3 { // x - Right
            x = x < (width - 1) ? (x + 1) : (x - 1)
        }
        if direction == 5 || direction == 6 || direction == 7 { // x - Left
            x = x > 0 ? (x - 1) : (x + 1)
        }
    } else {
        break
    }
}

var total = 0
for line in map {
    total += line.reduce(0, +)
}
print("Total move count -> \(total)")

2018/04/05 02:20

졸린하마

파이썬입니다. 100*100 크기 실행이 1초정도 걸리네요

from random import *

w=int(input('가로길이 입력:'))
h=int(input('세로길이 입력:'))
loc=list(int(input('바퀴벌레의 초기위치 입력:')) for i in range(2))
mylist=[ [0 for n in range(w)] for m in range(h)]
mylist[loc[0]][loc[1]]+=1
count=0
zero=1
while True:
    i,j=randint(-1,1),randint(-1,1)
    if loc[0]+i<0 or loc[1]+j<0 or loc[0]+i>h-1 or loc[1]+j>w-1:
        continue
    loc[0]+=i
    loc[1]+=j
    if mylist[loc[0]][loc[1]]==0:
        zero+=1
    mylist[loc[0]][loc[1]]+=1
    count+=1
    if zero==w*h:
        break
for myli in mylist:
    print(myli)
print(count)

2018/05/10 16:12

박종범

def random_walk(x, y, startx, starty):
    import random
    board = [[0 for xa in range(x)] for ya in range(y)]
    board[starty][startx] = 1
    xaxis = startx - 1
    yaxis = starty - 1
    direction = 0
    check = 0
    dilist = list(range(1, 9))
    moving = 0
    while not check:
        direction = dilist.pop(dilist.index(random.choice(dilist)))
        if direction == 1: xaxis -= 1; yaxis -= 1
        elif direction == 2: yaxis -= 1
        elif direction == 3: xaxis += 1; yaxis -= 1
        elif direction == 4: xaxis -= 1
        elif direction == 5: xaxis += 1
        elif direction == 6: xaxis -= 1; yaxis += 1
        elif direction == 7: yaxis += 1
        else: xaxis += 1; yaxis += 1
        try: board[yaxis][xaxis] += 1
        except: continue
        else:
            dilist = list(range(1, 9))
            moving += 1
            for i in board:
                if 0 in i:
                    break
                check += 1
            if check != len(board):
                check = 0
    board.append(moving)
    return board
for run in random_walk(100, 100, 2, 3):
    print(run)

Python 3입니다

board변수는 이름 그대로 바퀴벌레가 움직이는 판이며

xaxis변수로 x좌표를, yaxis변수로 y좌표를 컨트롤합니다

direction변수로 좌상, 상, 우상, 좌, 우, 좌하, 하, 우하 8가지의 움직이는 경우 중 하나를 택한 뒤

board리스트를 벗어나면 방향을 다시 설정하여 움직이는 방식입니다

2018/05/21 01:37

myyh2357

짧게 짜봤습니다. 잘 돌아가네요 ㅎㅎ

import numpy as np
import random as rd

n, m = list(map(int, input('n, m = :').split()))
field = np.zeros((n, m))
start = divmod(rd.choice(range(n * m)), m)
count = -1
while True:
    point = start
    px, py = point
    field[start] += 1
    count += 1
    if 0 not in field: break
    while True:
        dx = rd.choice([-1, 0, 1])
        dy = rd.choice([-1, 0, 1])
        if (dx, dy) != (0, 0) and 0 <= px + dx < m and 0 <= py + dy < n: break
    next_point = (px+dx, py+dy)
    start = next_point

print(field, '\n\n', count)

결과

n, m = : 100 100
[[ 4. 10.  9. ... 17. 10.  5.]
 [11. 13. 14. ... 30. 12.  8.]
 [14. 16. 14. ... 22. 19.  4.]
 ...
 [20. 37. 45. ... 39. 39. 28.]
 [35. 51. 52. ... 38. 31. 24.]
 [19. 43. 37. ... 24. 24. 11.]] 

 292178

2018/06/02 00:19

Hyuk

파이썬 3

  • numpy 사용하였습니다.

  • 바퀴벌레가 움질일 수 있는 옵션을 계산하는 부분은 다른 코드들과 차별됩니다.

import numpy as np
import random

row, col, (r0,c0) = 7, 4, (3,0) #입력값: 행, 열, 시작 좌표
grid = np.zeros((row,col))
grid[r0,c0] = 1
print(grid)

count = 0
r, c = r0, c0
while True:
    rc_options = [(i, j) for i in range(max(r-1, 0), min(r+1, row-1) + 1) for j in range(max(c-1, 0), min(c+1, col-1) + 1)]
    r_temp, c_temp = random.choice(rc_options)
    if r_temp == r and c_temp == c: #움직이지 않은 경우
        continue
    else:
        r, c = r_temp, c_temp
    count += 1
    grid[r, c] += 1

    if np.count_nonzero(grid==0) == 0: #모든 곳을 다 가봤다면
        break

print("이동횟수: {}".format(count))
print(grid)

결과

이동횟수: 204
[[ 4.  1.  1.  1.]
 [ 6.  4.  3.  3.]
 [ 5. 13.  7.  9.]
 [13. 10. 11. 11.]
 [11. 16.  8.  5.]
 [ 4. 10. 15.  4.]
 [ 6. 14.  7.  3.]]

2018/07/12 05:57

WJ K

'''
매번 zero 가 아닌 것을 모두 체크할 필요는 없고, 1 이 되는 순간 done_count 를 하나씩 올리면
이 갯수가 가로x세로 값과 같은 순간이 모두 1 이상이 되는 시점이겠죠.
'''

import random as rd
import numpy as np

h,v = map(int,input().split())

m = np.zeros((h,v),dtype=int)
x = rd.randint(1,h)
y = rd.randint(1,v)

walk_count = 0
done_count = 0

while 1:
    if x == 0: movex = rd.randint(0,1)
    elif x == (h-1): movex = rd.randint(-1,0)
    else: movex = rd.randint(-1,1)

    if y == 0: movey = rd.randint(0,1)
    elif y == (v-1): movey = rd.randint(-1,0)
    else: movey = rd.randint(-1,1)

    if (movex,movey) == (0,0):
        continue

    x = x + movex
    y = y + movey

    m[x,y] += 1
    walk_count += 1

    if m[x,y] == 1:
        done_count += 1
    if done_count == (h*v):
        break

print(walk_count)

2018/07/20 20:06

구름과비

from random import *

row,clm = map(int,input().split())

board = [0 for i in range(row*clm)]
dirc = ((-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1))

start = randint(0,row*clm-1)
board[start],cnt,cnt2 = 1,0,1

curps = start
while cnt2 < row*clm:
    d = dirc[randint(0,7)]
    if not(0<=curps//clm+d[0]<row and 0<=curps%clm+d[1]<clm): continue
    curps = (curps//clm+d[0])*clm+curps%clm+d[1]
    board[curps] += 1
    if board[curps] == 1: cnt2 += 1
    cnt += 1

for i in range(row*clm):
    print('{:{}}'.format(board[i],len(str(row*clm))),end=' ')
    if (i+1)%clm == 0: print()
print('\n',cnt)

2018/07/20 23:47

Creator

import java.util.Random;
import java.util.Scanner;

public class main3 {
    public static void main(String[] args) {
        Scanner scn = new Scanner(System.in);
        int count = 0;
        int check = 0;
        Random random = new Random();
        int move = 0;

        try {
            System.out.println("가로크기를 입력해 주세요.");
            int x = scn.nextInt();
            int bugX = x / 2;
            System.out.println("세로크기를 입력해 주세요.");
            int y = scn.nextInt();
            int bugY = y / 2;

            int[][] map = new int[x][y];
            map[bugX][bugY]++;

            while(true){
                move = random.nextInt(8);

                switch (move) {
                case 0:
                    bugX--;
                    bugY--;
                    break;
                case 1:
                    bugX--;
                    break;
                case 2:
                    bugX--;
                    bugY++;
                    break;
                case 3:
                    bugX--;
                    break;
                case 4:
                    bugX++;
                    break;
                case 5:
                    bugX--;
                    bugY++;
                    break;
                case 6:
                    bugY++;
                    break;
                case 7:
                    bugX++;
                    bugY++;
                    break;
                default:
                    break;
                }

                if(bugX < 0){
                    bugX++;
                }
                if(bugX >= x){
                    bugX--;
                }

                if(bugY < 0){
                    bugY++;
                }
                if(bugY >= y){
                    bugY--;
                }

                map[bugX][bugY]++;

                check = 0;
                for(int i = 0; i < x; i++){
                    for(int j = 0; j < y; j++){
                        if(map[i][j] > 0){
                            check++;
                        }
                    }
                }

                if(check >= (x * y)){
                    break;
                }
                count++;
            }
            for(int i = 0; i < x; i++){
                for(int j = 0; j < y; j++){
                    System.out.print("[" + map[i][j] + "] ");
                }
                System.out.println("");
            }
            System.out.println(count + "번 움직였습니다.");
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }

    }
}

2018/07/26 11:46

PuTa

씨 언어 로 풀었습니다. 바퀴벌레가 움직이지 않은 부분은 0. 움직이면 1로 고정. 멈추는 부분 마다 + 시켜서 얼마나 멈추는지 확인 바퀴벌레가 움직이는 방향을 -1, 0, 1 로 설정. 0 0 이 나오면 안움직이고 가만히 멍때린다고 가정. 임의의 자리도 그냥 랜덤 상수로 주었습니다.

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

int movingX()
{
    int moveX = (rand() % 3) -1;            //create -1 ~ 1;
    return moveX;
}

int movingY()
{
    int moveY = (rand() % 3) -1;            //create -1 ~ 1;
    return moveY;
}

int main()
{
    int x, y;
    scanf("%d %d", &x, &y);

    //Origin two dimesional array
    int **ptr = malloc(sizeof(int *)*x);

    for(int i = 0; i < x; i++)
    {
        ptr[i] = malloc(sizeof(int)*y);
    }

    //initialize
    for(int i = 0; i < x; i++)
    {
        for(int j = 0; j < y; j++)
        {
            ptr[i][j] = 0;
        }
    }

    //Temporary one
    int **Tptr = malloc(sizeof(int *)*x);

    for(int i = 0; i < x; i++)
    {
        Tptr[i] = malloc(sizeof(int)*y);
    }

    //initialize
    for(int i = 0; i < x; i++)
    {
        for(int j = 0; j < y; j++)
        {
            Tptr[i][j] = 0;
        }
    }



    srand(time(NULL));          //여러 난수로 나오게끔

    int tmpX = rand() % x ;     //0~x-1 create random num
    int tmpY = rand() % y ;     //0~y-1 create random num

    ptr[tmpX][tmpY] = 1;            //Create CockRoach

    printf("first C R location : %d %d\n", tmpX, tmpY);

    // moving there 

    int exitCount = 1;
    int moveCount = 0;
    int moveX = tmpX, moveY = tmpY;     //시작위치 임의의점에서 새로 시작
    int i = 0;                                      //얼마나 움직이는 지 확인 

    while( exitCount != x*y )
    {
        moveX += movingX();
        moveY += movingY();
        i++;

        //num X check
        if( moveX < 0)
        {
            ++moveX;
        }
        else if( moveX > x-1)
        {
            --moveX;
        }
        //num Y check
        if( moveY < 0 )
        {
            ++moveY;
        }
        else if( moveY > y-1)
        {
            --moveY;
        }

        Tptr[moveX][moveY] += 1;

        //moving check
        if( ptr[moveX][moveY] == 0)
        {
            printf("%d location %d , %d\n", ++moveCount, moveX, moveY);
            ptr[moveX][moveY] = 1;
            exitCount ++;
        }
    }

    printf("times C.R moved : %d\n", i);

    for(int v = 0; v < x; v++)
    {
        for(int k = 0; k < y; k++)
        {
            printf("%4d", Tptr[v][k]);
        }
        printf("\n");
    }
   free 해주세요 전 귀찮;
}
6 4
first C R location : 3 2
1 location 4 , 3
2 location 3 , 3
3 location 2 , 3
4 location 1 , 3
5 location 0 , 3
6 location 1 , 2
7 location 0 , 2
8 location 1 , 1
9 location 2 , 1
10 location 3 , 0
11 location 2 , 0
12 location 3 , 1
13 location 5 , 3
14 location 5 , 2
15 location 2 , 2
16 location 0 , 0
17 location 0 , 1
18 location 4 , 2
19 location 4 , 1
20 location 4 , 0
21 location 5 , 1
22 location 5 , 0
23 location 1 , 0
times C.R moved : 140
   9   6   3   2
   1   6   5   3
   3   8   7   5
   8   7   4   7
   6   3   4  12

2018/08/26 02:38

Jaeju An

import random as rd
def move(y,x,y_length,x_length):
    direction_t =  set([1,2,3,4,5,6,7,8])
    if y <= 0:
        direction_t -= set([1,2,3])
    if y >= (y_length-1):
        direction_t -= set([6,7,8])
    if x <= 0:
        direction_t -= set([1,4,6])
    if x >= (x_length-1):
        direction_t -= set([3,5,8])
    rnd=rd.sample(direction_t,1)
    t_y,t_x = y,x
    if rnd[0] in [1,4,6]:
        t_x-=1
    if rnd[0] in [3,5,8]:
        t_x+=1
    if rnd[0] in [1,2,3]:
        t_y-=1
    if rnd[0] in [6,7,8]:
        t_y+=1
    return [t_y,t_x]

def check_arr(y_l,arr_t):
    for i in range(y_l):
        if 0 in arr_t[i]:
            return True
    return False

def drunken_bug():
    xlength,ylength,xspot,yspot = map(int,input().split(','))
    arr=[[0]*xlength for i in range(ylength)]
    circle=0
    arr[yspot][xspot]=1
    while check_arr(ylength,arr):
        tempxy = move(yspot,xspot,ylength,xlength)
        yspot =tempxy[0]
        xspot =tempxy[1]
        arr[yspot][xspot]+=1
        circle+=1
    for i in range(ylength):
        print(arr[i])
    print('반복횟수 : {0}'.format(circle))
drunken_bug()

2018/09/03 14:22

JaehakChoi

C#

  • 문제 해결을 위한 Roach 클래스 생성
  • 모든 셀을 방문했는지 확인: 남은 셀 카운트
  • 반드시 한 칸은 이동하는 것으로 가정 (제자리에 있을 경우도 카운트 할 경우 45라인 조건 삭제)
using System;
using System.Linq;

namespace CD038
{
    class Program
    {
        static void Main(string[] args)
        {
            Roach roach = new Roach(20, 20, 5, 5);
            roach.LetMeMove();
            roach.DisplayResult();
        }
    }

    class Roach
    {
        private int scaleY, scaleX; // 매트릭스 크기
        private int[,] matrix; // 매트릭스 방문횟수
        private int remainCount; // 방문하지 않은 셀 갯수
        private int moveCount = 0; // 바퀴벌레 이동 횟수
        private int posY, posX; // 바퀴벌레 현재 위치

        // constructor
        public Roach(int scaleY, int scaleX, int posY, int posX)
        {
            this.scaleY = scaleY; this.scaleX = scaleX;
            remainCount = scaleY * scaleX;
            matrix = new int[scaleY, scaleX];
            this.posY = posY; this.posX = posX;
        }

        // 바퀴벌레 이동
        public void LetMeMove()
        {
            matrix[posY, posX] += 1; remainCount--; // 초기 위치
            Random rnd = new Random();
            while (remainCount > 0)
            {
                int nextY, nextX; // 다음 이동 예상 위치
                do
                {
                    int dy = rnd.Next(-1, 2), dx = rnd.Next(-1, 2);
                    nextY = posY + dy; nextX = posX + dx;
                } while ((nextY == posY && nextX == posX) || // 반드시 이동하는 것으로 가정
                        nextY < 0 || nextY >= scaleY || nextX < 0 || nextX >= scaleX);

                posY = nextY; posX = nextX;
                if (matrix[posY, posX] == 0) { remainCount--; }
                matrix[posY, posX] += 1;
                moveCount++;
            }
        }

        // 결과 출력
        public void DisplayResult()
        {
            // 움직인 횟수 최대값의 길이 -> 셀 출력 길이 설정
            int maxLength = (from int count in matrix select count).Max().ToString().Length;

            for (int row = 0; row < scaleY; row++)
            {
                for (int col = 0; col < scaleX; col++)
                {
                    Console.Write(matrix[row, col].ToString().PadLeft(maxLength + 1));
                }
                Console.WriteLine();
            }
            Console.WriteLine($"Move count: {moveCount}");
        }
    }
}

2018/09/06 15:12

mohenjo

from random import randint

def cockroach(m,n,x,y):
    lis = [[0]*m for i in range(n)]
    lis[y][x] = 1

    while list(lis[y][x] for y in range(n) for x in range(m)).count(0) != 0:

        rs = randint(-1,1),randint(-1,1)

        if -1<x+rs[0]<m and -1<y+rs[1]<n:
            x,y = x+rs[0],y+rs[1]
            lis[y][x] += 1

    for x in lis:
        print(x)

    print(sum(list(lis[y][x] for y in range(n) for x in range(m))))

2019/01/27 15:14

김영성

import java.util.Random;
import java.util.Scanner;

public class RandomWalk {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        Random random = new Random();

        System.out.println("배열의 행, 열 크기를 입력하세요 : ");
        int array [][] = null;
        int x = scanner.nextInt();
        int y = scanner.nextInt();
        int count1, count2;

        System.out.println("시작 지점 입력 : ");
        int p, q;
        while(true) {
            p = scanner.nextInt();
            q = scanner.nextInt();
            if(p < x && p >= 0 && q < y && q >= 0) break;
            System.out.println("다시 입력하세요.");
        }

        array = new int [x][];
        for(int i=0; i < x; i++) {
            array[i] = new int[y];
        }

        array[p][q] = 1;
        while(true) {
            count1 = random.nextInt(3) - 1;
            count2 = random.nextInt(3) - 1;
            p += count1;
            q += count2;
            if(p < 0 || q < 0 || p >= x || q >= y) {
                p -= count1;
                q -= count2;
                continue;
            } else {
                array[p][q]++;
            }
            int sum = 0;
            out:
                for(int i = 0; i < x; i++) {
                    for(int j = 0; j < y; j++) {
                        if(array[i][j] == 0) {
                            break out;
                        } else sum++;
                    }

                }
                if(sum == x * y) break;
        }
        int total = 0;
        for(int i = 0; i< x; i++) {
            for(int j = 0; j < y; j++) {
                total += array[i][j];
                System.out.printf("%2d ", array[i][j]);
            }
            System.out.println();
        }
        System.out.println("총 움직인 횟수 : " + (total - 1));
    }
}

2019/04/03 15:06

김동혁

import random
import math
from copy import copy

direction = ((-1,-1), (-1,0), (-1,1), (0,-1), (0,1), (1,-1), (1,0), (1,1))

def is_finished(L):
    for a in L:
        for b in a:
            if b == 0: return False
    return True

def showWalks(L):
    Q = [list(map(str, a)) for a in L]        
    return '\n'.join(list(map(lambda x : ' '.join(x), Q)))

def RandomWalk(m, n, x, y):
    L = [[0]*n for i in range(m)]
    L[x][y] = 1
    is_out = lambda x, y : True if x<0 or y<0 or x>=m or y>=n else False
    walks = 0
    while not is_finished(L): #전부 다 밟았는지
        while True: #밖에 안 나가도록
            dx, dy = direction[math.floor(8*random.random())]
            if is_out(x+dx, y+dy):
                continue
            else:
                x += dx
                y += dy
                L[x][y] += 1
                walks += 1
                break
    return [L, walks]
>>> T = RandomWalk(5,4, 0,0)

>>> print("각 칸에 바퀴벌레가 멈추었던 횟수 :\n" + showWalks(T[0]))

각 칸에 바퀴벌레가 멈추었던 횟수 :
2 1 1 1
5 4 1 2
1 3 7 3
1 3 6 1
2 3 3 1
>>> print("바퀴벌레가 움직인 횟수 :", T[1])

바퀴벌레가 움직인 횟수 : 50

2019/04/05 08:58

messi

from random import randint, choice

r, c, x, y = input().split()

r, c = int(r), int(c)
size, size_index = [], []
start = [int(x), int(y)]

for a in range(int(r)):
    size.append([])
    for b in range(int(c)):
        size[a].append(0)
        size_index.append([a, b])


def list_sum(l1, l2):
    result = []
    for d in range(len(l2)):
        result.append(l1[d] + l2[d])

    return result


def random_walk(row, column, start_l):
    next_p = [start_l[0] + randint(-1, 1), start_l[1] + randint(-1, 1)]
    if next_p[0] > row or next_p[1] > column or next_p[0] < 0 or next_p[1] < 0 or next_p == start_l:
        while 1:
            next_p = [start_l[0] + randint(-1, 1), start_l[1] + randint(-1, 1)]
            if 0 <= next_p[0] < row and 0 <= next_p[1] < column and next_p != start_l:
                break

    return next_p


size[start[0]][start[1]] += 1
size_index.remove([start[0], start[1]])

move_count = 0

while len(size_index) > 0:
    position = random_walk(int(r)-1, int(c)-1, start)
    size[position[0]][position[1]] += 1
    if position in size_index:
        size_index.remove(position)
    move_count += 1
    start = position

print(move_count)

2020/01/20 03:44

농창

파이썬 3입니다.

numpy의 randint를 이용하여 무작위적으로 좌표를 움직이는 함수를 정의하고 문제를 해결했습니다.

from numpy.random import randint

col, row, i_col, i_row = tuple(map(int, input().split()))  # 가로 크기, 세로 크기, 초기 위치 (가로, 세로)

# 격자 생성
grid = [[0 for _ in range(col)] for _ in range(row)]


def r_dir(r, c, i0, j0):  # (행, 열, 현재 행, 현재 열): 랜덤으로 좌표 변경
    if i0 == j0 == 0:
        d = randint(3)
        return i0 + (d in (1, 2)), j0 + (d in (0, 2))
    elif i0 == 0 and j0 == c - 1:
        d = randint(3)
        return i0 + (d in (1, 2)), j0 - (d in (0, 1))
    elif i0 == r - 1 and j0 == 0:
        d = randint(3)
        return i0 - (d in (1, 2)), j0 + (d in (0, 1))
    elif i0 == r - 1 and j0 == c - 1:
        d = randint(3)
        return i0 - (d in (0, 1)), j0 - (d in (1, 2))
    elif i0 == 0 and j0 not in (0, c - 1):
        d = randint(5)
        return i0 + (d in (2, 3, 4)), j0 + (d in (0, 4)) - (d in (1, 2))
    elif i0 == r - 1 and j0 not in (0, c - 1):
        d = randint(5)
        return i0 - (d in (1, 2, 3)), j0 + (d in (0, 1)) - (d in (3, 4))
    elif i0 not in (0, r - 1) and j0 == 0:
        d = randint(5)
        return i0 + (d in (0, 1)) - (d in (3, 4)), j0 + (d in (1, 2, 3))
    elif i0 not in (0, r - 1) and j0 == c - 1:
        d = randint(5)
        return i0 + (d in (0, 1)) - (d in (3, 4)), j0 - (d in (1, 2, 3))
    else:
        d = randint(8)
        return i0 + (d in (5, 6, 7)) - (d in (1, 2, 3)), j0 + (d in (0, 1, 7)) - (d in (3, 4, 5))


def end_cond(gr):  # 메인 코드의 종료 조건
    for r1 in range(len(gr)):
        if 0 in gr[r1]:
            return False
    return True


i1, j1 = i_row, i_col  # 좌표에 초기값 입력
N = 0  # 바퀴벌레가 이동한 횟수

while True:
    if end_cond(grid):
        break
    grid[i1][j1] += 1
    i1, j1 = r_dir(row, col, i1, j1)
    N += 1

# 출력

print('각 칸에 바퀴벌레가 멈추었던 횟수:')

for i in range(row):
    for j in range(col):
        print('{:3d}'.format(grid[i][j]), end=' ')
    print()

print('\n 바퀴 벌레는 총 {}만큼 움직였다'.format(N))

2020/01/21 20:49

우재용

import random
a=10
b=10
d={}
c=0
n=0

for i in range(a):
    for k in range(b):
        d[(i,k)]=0

m=''
for i in range(b):
    m+='\n\n'
    for k in range(a):
        m+=str(d[(k,b-1-i)])+'   '
print(m)
print('<<격자 모양>>')

ox=random.choice(list(range(a)))
oy=random.choice(list(range(b)))
l=[ox,oy]
t=(l[0],l[1])
d[t]+=1

m=''
for i in range(b):
    m+='\n\n'
    for k in range(a):
        m+=str(d[(k,b-1-i)])+'   '
print(m)
print(str(t)+'에서부터 시작.')
while c==0:    
    while True:
        x=random.choice([-1,0,1])
        y=random.choice([-1,0,1])
        if x!=0 or y!=0:
            l[0]+=x
            l[1]+=y
            if 0<=l[0]<a and 0<=l[1]<b:
                if x>0 and y>0:
                    print('이동 방향은 '+'↗'+'방향')
                elif x>0 and y==0:
                    print('이동 방향은 '+'→'+'방향')
                elif x>0 and y<0:
                    print('이동 방향은 '+'↘'+'방향')
                elif x==0 and y>0:
                    print('이동 방향은 '+'↑'+'방향')
                elif x==0 and y<0:
                    print('이동 방향은 '+'↓'+'방향')
                elif x<0 and y<0:
                    print('이동 방향은 '+'↙'+'방향')
                elif x<0 and y>0:
                    print('이동 방향은 '+'↖'+'방향')
                else:
                    print('이동 방향은 '+'←'+'방향')
                break
            else:
                l[0]-=x
                l[1]-=y                
                continue
        else:
            continue
    t=(l[0],l[1])
    print('이동할 좌표'+str(t))
    d[t]+=1
    g=d[t]
    d[t]='['+str(d[t])+']'
    n+=1
    m=''
    for i in range(b):
        m+='\n\n'
        for k in range(a):
            m+=str(d[(k,b-1-i)])+'   '
    print(m)
    d[t]=g    
    v=1
    for i in range(a):
        for k in range(b):
            v*=d[(i,k)]
    c=v
print('\n\n결과:')
print('초기값:' +str([ox,oy]))
print('이동한 총 횟수 '+str(n))

파이썬 입니다. 격자를 문자열로 표현하려 해 보았습니다. 격자에서 멈춘 횟수의 자릿수가 바뀌거나 현재 위치를 표기하면 같은 줄의 문자들의 위치가 조금씩 밀려나는 현상이 나타났는데, 상황에 무관하게 문자 위치가 유지되는 코드를 짤 수 있도록 앞으로 더 노력해야 할 것 같습니다. 재미있고 유익한 문제 올려주셔서 감사합니다. ^^

2020/03/30 03:33

di figo

#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
/*
'술취한 바퀴벌레' 문제라고도 한다. 다음과 같은 격자에 술취한 바퀴벌레가 있다고 해 보자

.   .   .   .
.   .   .   .
.   .   .   .
.   .   .   .
.   .   .   .
.   .   .   .
.   .   .   .

바퀴벌레는 임의의 한 점에서 시작하여서 임의의 방향으로 움직이게 된다. 
이미 지나갔던 자리에 다시 갈 수 있으며 프로그램은 바퀴벌레가 각 위치에 몇번 갔는지 기억하여야 한다. 
프로그램은 바퀴벌레가 모든 지점에 적어도 한번 이상 도달하였을 경우 끝난다. 
바퀴벌레는 가로, 세로, 대각선으로 한칸 씩만 움직일수 있으며, 바퀴벌레가 움직이는 방향을 랜덤하게 만드는 것은 각자가 생각해 보도록 한다.

입력
격자의 가로, 세로 크기

출력
각 칸에 바퀴벌레가 멈추었던 횟수, 바퀴벌레가 움직인 횟수.
*/

bool CheckIdx(int n, int m, int cn, int cm) {
    if (cn < n && cn >= 0) {
        if (cm < m && cm >= 0) { return true; }
        else { return false; }
    }
    else { return false; }
}

void Func(int n, int m) {
    int **arr;
    arr = new int*[n];
    for (int i = 0; i < n; i++)
        arr[i] = new int[m];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            arr[i][j] = 0;

    int sn, sm; //바퀴 벌레 시작 위치
    sn = rand() % n;
    sm = rand() % m;

    vector<pair<int, int>> v;
    v.reserve(8);
    int num;
    int count = -1;
    bool check;
    while (1) {
        arr[sn][sm] += 1;
        count++;

        //바퀴벌레의 이동을 하나하나 다 살펴 볼수있음
        /*for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cout << arr[i][j] << "\t";
            }
            cout << endl;
        }
        cout << "현재 바퀴벌레 위치: arr[" << sn << "][" << sm << "]" << endl;
        cout << "현재까지 이동 횟수: " << count << "회" << endl;
        system("pause");
        cout << endl;
        */

        if (CheckIdx(n, m, sn - 1, sm - 1)) { v.push_back(make_pair(sn - 1, sm - 1)); }
        if (CheckIdx(n, m, sn - 1, sm)) { v.push_back(make_pair(sn - 1, sm)); }
        if (CheckIdx(n, m, sn - 1, sm + 1)) { v.push_back(make_pair(sn - 1, sm + 1)); }
        if (CheckIdx(n, m, sn, sm - 1)) { v.push_back(make_pair(sn, sm - 1)); }
        if (CheckIdx(n, m, sn, sm + 1)) { v.push_back(make_pair(sn, sm + 1)); }
        if (CheckIdx(n, m, sn + 1, sm - 1)) { v.push_back(make_pair(sn + 1, sm - 1)); }
        if (CheckIdx(n, m, sn + 1, sm)) { v.push_back(make_pair(sn + 1, sm)); }
        if (CheckIdx(n, m, sn + 1, sm + 1)) { v.push_back(make_pair(sn + 1, sm + 1)); }

        num = rand() % v.size();
        sn = v[num].first;
        sm = v[num].second;
        v.clear();

        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; }
    }
    cout << "===================끝====================" << endl;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cout << arr[i][j] << "\t";
        }
        cout << endl;
    }
    cout << "바퀴 벌레 총 이동횟수: " << count << "회" << endl;

    for (int i = 0; i < n; i++)
        delete[] arr[i];
    delete[] arr;
}

int main() {
    srand((unsigned int)time(NULL));
    Func(10, 10);
}

2020/04/17 18:50

++C

from random import *
import os

def show_map(m):                #맵을 출력해주는 함수
    for j in range (0,y):   
        for i in range (0,x):
            if m[j][i]>0:
                if i==xx and j==yy:   # 방금 이동한 위치는 빨간색으로 표시
                    print ("\x1b[31m"+"%5d" %m[j][i]+"\x1b[0m",end=' ')
                else:                 # 한번 이상 이동한 곳은 빨간색으로 표시
                    print ("\x1b[34m"+"%5d" %m[j][i]+"\x1b[0m",end=' ')
            else:                      #한번도 가지 않은곳은 흰색으로 표시
                print ("\x1b[37m"+"%5d" %m[j][i]+"\x1b[0m",end=' ')                    
        print ()

def find_0(m):              #맵에 0이 포함되어 있으면 True 반환
    for j in range (0,y):   
        if 0 in m[j]:
            return True            

temp=str(input('x(가로길이) y(세로길이) z(처음위치)...')).split(' ')
x,y,z=int(temp[0]),int(temp[1]),int(temp[2])
yy,xx=z//y,z%x      #xx,yy는 현재위치를 위미하며, 처음위치를 나타냄

m=[]
for j in range (0,y):           #맵m을 모두 0으로 초기화 함
    temp=[]
    for i in range (0,x):
        temp.append(0)
    m.append(temp)

m[yy][xx]+=1
show_map(m)

while(1):
    if find_0(m) !=True:    #맵에 0에 포함되어 있지 않으면 프로그램 루프 종료
        break

    direction=randint(0,7)
    if direction==0:     #위로 이동
        if yy!=0:
            yy-=1
        else:
            m[yy][xx]-=1

    elif direction==1:     #아래로 이동
        if yy!=(y-1):
            yy+=1
        else:
            m[yy][xx]-=1

    elif direction==2:     #오른쪽으로 이동
        if xx!=(x-1):
            xx+=1
        else:
            m[yy][xx]-=1

    elif direction==3:     #왼쪽으로 이동
        if xx!=0:
            xx-=1
        else:
            m[yy][xx]-=1

    elif direction==4:     #오른쪽 위
        if xx!=(x-1) and yy!=0:
            xx+=1
            yy-=1
        else:
            m[yy][xx]-=1

    elif direction==5:     #오른쪽 아래
        if xx!=(x-1) and yy!=(y-1):
            xx+=1
            yy+=1
        else:
            m[yy][xx]-=1

    elif direction==6:     #왼쪽 위
        if xx!=0 and yy!=0:
            xx-=1
            yy-=1
        else:
            m[yy][xx]-=1

    elif direction==7:     #왼쪽 아래
        if xx!=0 and yy!=(y-1):
            xx-=1
            yy+=1   
        else:
            m[yy][xx]-=1     

    os.system('CLS')
    m[yy][xx]+=1
    print('바퀴벌레의 현재위치 xx=',xx,'yy=',yy,'\n')
    show_map(m)

sum=0
for j in range (0,y):   
    for i in range (0,x):
        sum+=m[j][i]
print ('\n바퀴벌레의 총 이동거리 : ',sum)

2020/05/15 14:02

Buckshot

x(가로길이) y(세로길이) z(처음위치)...3 3 0 바퀴벌레의 현재위치 xx= 2 yy= 0 4 1 1 3 4 2 2 3 3 바퀴벌레의 총 이동거리 : 23 x(가로길이) y(세로길이) z(처음위치)...5 5 10 바퀴벌레의 현재위치 xx= 4 yy= 0 7 9 6 2 1 8 8 6 1 2 6 13 6 6 2 8 13 6 4 1 4 6 6 2 1 바퀴벌레의 총 이동거리 : 134 x(가로길이) y(세로길이) z(처음위치)...10 10 50 바퀴벌레의 현재위치 xx= 9 yy= 0 13 20 23 18 12 11 6 4 5 1 26 45 22 21 29 13 17 19 13 2 34 50 37 40 25 21 18 17 15 11 27 35 36 37 33 27 19 13 17 10 17 33 37 35 26 31 31 22 24 13 26 30 38 35 36 31 21 25 26 17 27 34 37 39 33 39 30 25 33 20 18 36 38 33 38 36 34 29 32 25 25 35 30 22 43 33 39 37 44 25 19 26 20 21 16 21 17 14 26 16 바퀴벌레의 총 이동거리 : 2561 x(가로길이) y(세로길이) z(처음위치)...15 15 150 바퀴벌레의 현재위치 xx= 14 yy= 0 8 6 5 7 8 9 9 6 6 6 5 6 5 3 1 10 14 9 9 9 19 20 16 10 16 18 15 15 7 2 13 19 19 10 18 15 26 18 24 16 14 16 14 9 4 11 23 12 18 20 14 21 23 14 14 10 12 13 14 5 10 20 17 24 18 16 21 20 23 17 12 14 16 12 10 10 21 14 20 21 22 13 21 20 12 21 16 13 8 9 11 25 20 24 22 19 17 18 22 19 10 14 13 19 12 9 14 21 18 15 21 15 21 21 18 15 9 17 17 10 13 22 15 12 19 22 26 22 19 20 22 20 18 19 8 11 24 21 22 15 21 20 16 19 17 22 22 16 16 15 12 18 23 26 18 19 18 18 14 18 18 17 19 15 13 12 25 12 15 16 23 22 22 14 13 22 20 23 21 12 18 27 19 13 25 23 29 21 15 15 19 25 20 24 18 13 17 21 20 28 19 24 22 16 11 19 27 29 25 17 8 8 10 18 13 16 12 9 8 14 13 17 27 16 7 바퀴벌레의 총 이동거리 : 3642 - Buckshot, 2020/05/15 14:11
이건 5*5 크기로만 테스트를 해봤는데 이동거리가 많이 차이게 나네요. x(가로길이) y(세로길이) z(처음위치)...5 5 12 2 8 10 12 5 1 12 21 22 14 6 8 22 19 13 7 17 20 18 11 7 7 8 6 5 바퀴벌레의 총 이동거리 : 281 1 2 3 9 10 3 7 12 21 12 13 10 26 22 12 18 27 26 26 21 9 15 17 17 10 바퀴벌레의 총 이동거리 : 349 2 4 9 4 1 5 7 14 7 5 7 10 11 18 4 9 15 18 16 5 4 11 16 10 3 바퀴벌레의 총 이동거리 : 215 6 15 6 2 1 18 14 7 3 1 9 20 9 7 1 8 12 19 10 2 3 8 12 5 2 바퀴벌레의 총 이동거리 : 200 - Buckshot, 2020/05/15 14:16
import random
def random_work(rlim, clim, row, col):
    grid = [[0]*clim for _ in range(rlim)]
    grid[row][col] = 1
    cnt = 0
    while not all([all(grid[i]) for i in range(rlim)]):
        while 1:
            direction = [random.randint(-1, 1) for _ in range(2)]
            if not all(direction) and (0 <= row+direction[0] < len(grid)) and (0 <= col+direction[1] < len(grid[0])):
                row += direction[0]
                col += direction[1]
                break

        cnt += 1
        grid[row][col] += 1
    print('각 칸에 바퀴벌레가 멈추었던 횟수:\n {}\n바퀴벌레가 움직인 횟수: {}'.format(grid, cnt))

if __name__ == '__main__':
    rlim, clim = 100, 100
    row, col = 2, 2
    random_work(rlim, clim, row, col)

2020/06/15 11:19

Hwaseong Nam

import random

def sol(x_size, y_size) :
    d_list, m, position = [-1, 0, 1], [0 for i in range(x_size*y_size)], (random.randint(0, x_size-1), random.randint(0, y_size-1))
    counter = 0
    m[(position[1]*x_size)+position[0]] += 1
    print("Initial point : ", position)
    while True :
        d_position = (d_list[random.randint(0, 2)], d_list[random.randint(0, 2)]) # 이동 방향 결정
        if d_position == (0, 0) : continue
        if 0 <= (position[0]+d_position[0]) < x_size and 0<=(position[1]+d_position[1]) < y_size :
            position = (position[0]+d_position[0], position[1]+d_position[1]) # 위치 갱신
            m[(position[1]*x_size)+position[0]] += 1 # 갱신된 위치 카운트
            counter += 1
        else : continue

        if not 0 in m : #모든 좌표를 방문한 경우 결과 출력
            justSize = len(str(max(m)))+1
            for r in range(0, y_size) :
                r_txt = ""
                for c in range(0, x_size) :
                    r_txt += str(m[r*x_size+c]).rjust(justSize)
                print(r_txt)

            return "count : "+str(counter)
    return counter

if __name__ == "__main__" :
    print(sol(20, 20))

결과

Initial point :  (1, 8)
 14 28 29 29 16 13 20 15 12 11 11 18 21 19 19 19 17 12 16 13
 24 41 37 35 25 28 31 24 22 24 21 21 31 42 34 29 23 19 22 17
 29 33 27 23 23 23 21 15 27 28 25 20 22 32 33 27 22 24 26 15
 22 40 26 20 23 20 11 26 13 18 17 25 21 25 25 20 21 18 26  9
 21 28 26 30 31 19 18 20 21 19 25 17 23 24 16 18 19 28 16 10
 14 26 26 30 34 19 27 22 23 21 23 24 27 23 23 22 31 25 13  6
 17 30 30 29 28 34 27 30 25 23 24 24 36 28 21 19 23 21 14  7
 14 34 33 17 30 32 29 24 19 18 21 22 21 16 12 15 13 15 20 15
 24 29 30 21 24 28 18 20 24 17 14 19 18 14  9 12 13 12 16 11
 24 28 18 32 24 24 19 18 18 11 15 15 23 16  6  7  8 18 13  4
 16 26 25 23 30 35 22 19 10 19  9  9 14 10  7  6  8 17 13  3
 12 27 23 23 25 32 26 14 12  9  7  6  5  9 12  8 12 10  9  4
 18 15 24 17 24 24 27 15  9 11  8  6 14 11 12 11 13 14  1  1
 13 17 23 18 23 29 27 12 17  7  6 11 12 12 17 15 15 11  8  1
  7 24 21 14 17 27 20 25 12 10 17 18 14 16 18 13 16 18  9  3
 10 28 17 16 27 12 34 23 22 20 18 17 17 15 21 20 18 18 17 12
 16 24 25 16 18 24 26 33 20 18 19 20 11 12 19 21  9 18 19 14
  7 25 23 22 24 32 30 24 24 16 22 20 13 12 17 16 13 21 27 13
 11 25 32 20 16 25 31 29 32 16 15 22 29 11 11 14 13 20 20 15
 12 19 11 10 11 13 21 21 12 13 10 14 17 10  2  4 10 10  9  8
count : 7637

100 x 100 정도의 사이즈라면 '인내할만한' 시간 안에 결과가 나오지만 1000 단위 이상은 확실히 오래걸립니다.

2020/08/21 10:57

GG

public class DrunkBaTeacher {
    private static int[][] MAP;
    public static void main(String[] args) {
        int x = 0, y = 0, moveCNT = 0, checkCNT = 0;
        int baX = 0, baY = 0;
        int way_FLAG = 0;
        boolean sr_FLAG = true;
        boolean flag = true;
        // Straight / Reverse
        System.out.print("가로의 길이 : ");
        x = KunheeUtil.scanIntData(x);
        System.out.print("세로의 길이 : ");
        y = KunheeUtil.scanIntData(y);
        MAP = new int[x][y];

        baX = new Random().nextInt(x);
        baY = new Random().nextInt(y);

        MAP[baX][baY] = 1;

        while(flag) {
            way_FLAG = new Random().nextInt(3);
            sr_FLAG = new Random().nextBoolean();
            checkCNT = 0;
            /* way_FLAG
             *  0: 직선, 1: 세로, 2: 대각선
             * sr_FLAG
             *  TRUE: 직진(+), FALSE: 후진(-)
             */
            if(way_FLAG == 0) {
                baY = sr_FLAG ? baY+1 : baY-1;
            }else if(way_FLAG == 1) {
                baX = sr_FLAG ? baX+1 : baX-1;
            }else {
                if(sr_FLAG) {
                    baX++;
                    baY++;
                }else {
                    baX--;
                    baY--;
                }
            }

            baX = (baX == x) ? 0 : baX;
            baY = (baY == y) ? 0 : baY;
            baX = (baX == -1) ? x-1 : baX;
            baY = (baY == -1) ? y-1 : baY;

            MAP[baX][baY]++;
            moveCNT++;

            for (int i = 0; i < MAP.length; i++) {
                for (int j = 0; j < MAP[i].length; j++) {
                    if(MAP[i][j] == 0) checkCNT++;
                }
            }
            flag =  checkCNT > 0 ? true : false;
        }

        System.out.println("- 움직인 횟수: " + moveCNT);
        System.out.println("- 마지막 위치: " + (baX+1) + " 행  " + (baY+1) + " 열");
        System.out.println("\n< MAP >\n");
        for (int i = 0; i < MAP.length; i++) {
            for (int j = 0; j < MAP[i].length; j++) {
                if(i == baX && j == baY) {
                    System.out.print("['" + MAP[i][j] + "']");
                }else {
                    System.out.print("[ " + MAP[i][j] + " ]");
                }

            }
            System.out.println();
        }
    }
}

2020/09/22 09:34

gunhee0323

import random
import numpy as np

def Sheet():
    count=0
    A=int(input("격자의 가로길이 : "))
    B=int(input("격자의 세로길이 : "))
    a = np.zeros((A,B))
    c = int(input("행 입력 : "))-1  # 시작위치지정
    d = int(input("열 입력 : "))-1
    print(a)
    while True:
        total=0 
        if (c==0 and d==0):  # 좌측 위 아래 끝
            q = random.randrange(0,3)
            if q==0:
                c+=1
            elif q==1:
                c+=1
                d+=1
            elif q==2:
                d+=1
            a[c,d]+=1          # 랜덤의 수가 나온이후 랜덤자리에 1을 넣어줘서 지나갔다는 흔적을 남김
        elif  (c==A-1 and d==0):
            w= random.randrange(0,3)
            if w==0:
                c-=1
            elif w==1:
                c-=1
                d+=1
            elif w==2:
                d+=1
            a[c,d]+=1
        elif (c==0 and d==B-1):  # 우측 위 아래 끝
            z=random.randrange(0,3)
            if z==0:
                d-=1
            elif z==1:
                c+=1
                d-=1
            elif z==2:
                c+=1
            a[c,d]+=1
        elif (c==A-1 and d==B-1):
            r=random.randrange(0,3)
            if r==0:
                c-=1
            elif r==1:
                d-=1
            elif r==2:
                c-=1
                d-=1
            a[c,d]+=1
        elif c==0:     #0번째 줄 
            t = random.randrange(0,5)
            if t==0:
                d-=1
            elif t==1:
                d+=1
            elif t==2:
                c+=1
                d-=1
            elif t==3:
                c+=1
            elif t==4:
                d+=1
                c+=1
            a[c,d]+=1
        elif c==A-1:     # 6번째 줄
            t = random.randrange(0,5)
            if t==0:
                d-=1
            elif t==1:
                d+=1
            elif t==2:
                c-=1
                d-=1
            elif t==3:
                c-=1
            elif t==4:
                d+=1
                c-=1
            a[c,d]+=1
        elif d==0:
            y=random.randrange(0,5)
            if y==0:
                c-=1
            elif y==1:
                c-=1
                d+=1
            elif y==2:
                d+=1
            elif y==3:
                c+=1
            elif y==4:
                c+=1
                d+=1
            a[c,d]+=1
        elif d==B-1:
            y=random.randrange(0,5)
            if y==0:
                c-=1
            elif y==1:
                c-=1
                d-=1
            elif y==2:
                d-=1
            elif y==3:
                c+=1
            elif y==4:
                c+=1
                d-=1
            a[c,d]+=1
        else:
            y=random.randrange(0,8)
            if y==0:
                c-=1
                d-=1
            elif y==1:
                c-=1
            elif y==2:
                c-=1
                d+=1
            elif y==3:
                d-=1
            elif y==4:
                d+=1
            elif y==5:
                c+=1
                d-=1
            elif y==6:
                c+=1
            elif y==7:
                c+=1
                d+=1
            a[c,d]+=1
        count+=1
        for i in range(A):    # 반복문을 통해서 시트안의 자취흔적 조사 
            for j in range(B):
                if a[i,j]>0:
                    total+=1
                    if total==A*B:
                        break
            if total==A*B:
                break
        if total==A*B:
            break
    print(a)
    print(count)
Sheet()

고수분들 풀이보니까 제가 너무 허접한거같네요,,

2021/03/23 21:18

fox.j

시간이 많이 드네요..

import random

#가로,세로,초기위치
n,m,s = 10,10,[5,5]

#필드생성
room = [[0]*n for _ in range(m)]

#이동방향
move_list = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,0),(0,1),(1,-1),(1,0),(1,-1)]

#좌표이동 후 횟수측정
count = 0
countdown = n*m
while countdown>0:
    move = move_list[random.randint(0,len(move_list)-1)]
    if 0<=s[0]+move[0]<n and 0<=s[1]+move[1]<m:
        if room[s[0]+move[0]][s[1]+move[1]] == 0: countdown -=1
        room[s[0]+move[0]][s[1]+move[1]]+=1
        count+=1
        s[0]+=move[0]
        s[1]+=move[1]
    else : continue

print('=='*11,' 칸마다 방문수 ','=='*11)
for i in room:
    for j in i:
        print(f'{j:5d}',end=' ')
    print()
print(f'\n바퀴벌래의 이동수 : {count}칸')

2021/06/29 13:20

약사의혼자말

from random import *

#arr 원소에 0을 포함하는지 여부 판단 함수
def fun (arr):
    f=[]
    for i in arr:
        if 0 not in i:
            f.append(0)
    if len(f) == len(arr):
        return False
    else:
        return True

inp = list(map(int,input('격자의 가로,세로 크기 입력').split(',')))
start = list(map(int,input('초기위치 row,column :').split(',')))
arr=[[0 for _ in range(inp[1])] for _ in range(inp[0])]

r=start[0]
c=start[1]
n=0
arr[r][c]=1 #초기값을 1로 둘지 말지는 선택 가능

print(arr)
#배열의 0이 없어질때 까지 바퀴벌레 랜덤 이동 함수
while fun(arr):
    row=r+randint(-1,1)
    col=c+randint(-1,1)
    if (row>=0 and row<inp[0]) and (col>=0 and col<inp[1]):
        if not (r==row and c==col):
            r=row
            c=col
    arr[r][c] +=1
    n+=1

print('이동횟수는',n,'회 입니다')
for k in arr:
    for i in k:
        print(i,end=' ')
    print('')

주석이 부실하긴한데, random함수를 이용해서 바퀴벌레의 랜덤한 이동칸수를 정했어요 row와 column성분을 각각 무작위로 뽑았고, 만일 row 와 col 성분 모두 0칸을 움직이는경우는 움직임이 없다고 판단하여, 이동횟수를 카운트 하지 않도록 했습니다.

2022/02/12 16:33

양캠부부

import random
import numpy as np
import matplotlib.pyplot as plt
import networkx as nx
from matplotlib.animation import FuncAnimation, PillowWriter 

N = 700
X,Y = [],[]

col, row = 30,30
cnt = [[0 for value in range(col)] for value in range(row)]
np_cnt = np.array(cnt)
cnt_fla = cnt_flatten = np_cnt.flatten()

x = random.randint(0,col-1)
y = random.randint(0,row-1)

while sum(cnt_fla) <N:
    x_max = min(x+1, col-1)
    x_min = max(x-1, 0)

    y_max = min(y+1, row-1)
    y_min = max(y-1, 0)

    x=random.randint(x_min, x_max)
    y=random.randint(y_min, y_max)

    cnt[y][x] += 1
    np_cnt = np.array(cnt)
    cnt_fla = cnt_flatten = np_cnt.flatten()
    X.append(x)
    Y.append(y)

plt.plot(X,Y)
plt.show()

2022/03/02 15:52

로만가

import random
import numpy as np

class Action:
  def __init__(self, grid_x, grid_y, initial_x, initial_y):
    self.grid = np.zeros((grid_x, grid_y))
    self.x, self.y = initial_x, initial_y
    #return self.x, self.y        

  def action(self,x, y):
    self.x = x
    self.y = y
    self.x_temp = self.x
    self.y_temp = self.y
    action = random.randint(1,8)

    if action == 1:
      self.x_temp-=1
    if action == 2:
      self.x_temp-=1; self.y_temp-=1
    if action == 3:
      self.y_temp+=1
    if action == 4:
      self.x_temp+=1; self.y_temp+=1
    if action == 5:
      self.x_temp += 1
    if action == 6:
      self.x_temp+=1; self.y_temp-=1
    if action == 7:
      self.y_temp-=1
    if action == 8:
      self.x_temp-=1; self.y_temp-=1

    if self.x_temp==-1 or self.x_temp == self.grid.shape[0]:
      self.x = self.x
    else:
      self.x = self.x_temp

    if self.y_temp==-1 or self.y_temp == self.grid.shape[1]:
      self.y = self.y
    else:
      self.y = self.y_temp

    #self.grid[self.x,self.y] += 1 
    return self.x, self.y 

  def grid_update(self, x, y):
    self.x = x; self.y = y
    if self.x>=0 and self.x<self.grid.shape[0] and self.y>=0 and self.y<self.grid.shape[1]:
      #print(x,y)
      self.grid[x,y]+=1

grid_x, grid_y, initial_x, initial_y =input().split(" ")
grid_x, grid_y, initial_x, initial_y = int(grid_x), int(grid_y), int(initial_x), int(initial_y)

drunken = Action(grid_x, grid_y, initial_x, initial_y)
x, y = initial_x, initial_y

count = 0
while True:
  x_new, y_new = drunken.action(x,y)
  drunken.grid_update(x_new, y_new)
  if x_new != x or y_new != y:
    count+=1
  if np.count_nonzero(drunken.grid)==grid_x*grid_y:
    print("각 칸에 바퀴벌레가 멈추었던 횟수:\n", count)
    print("바퀴벌레가 움직인 횟수:\n",drunken.grid)
    break
  x, y = x_new, y_new

2023/07/18 12:37

스탠리

import random

def mapPrint(C, R, mapW):
    for r in range(R):
        for c in range(C):
            print('%3d' %(mapW[(r,c)]), end='')
        print()


def randomWalk(C, R, iniPos):
    dr = [-1,-1,0,1,1,1,0,-1]
    dc = [0,1,1,1,0,-1,-1,-1]
    mapW = {}
    pos = (iniPos[0],iniPos[1])
    mapW[pos] = 1
    move = 0
    while len(mapW) < C*R:
        move += 1        
        while True:
            i = random.randint(0,7)
            r, c = pos[0]+dc[i], pos[1]+dr[i]
            if 0<=c<C and 0<=r<R:
                pos=(r,c)
                break
        if pos not in mapW:
            mapW[pos]=0
        mapW[pos] += 1
    print('각 칸에 바퀴벌레가 멈추었던 횟수')
    mapPrint(C, R, mapW)
    print('바퀴벌레가 움직인 횟수: ', move)

c=int(input("가로: "))
r=int(input("세로: "))
iniPos = list(map(int, input("바퀴벌레의 초기 위치: ").split()))
print(' ='*10)
randomWalk(c,r,iniPos)

2024/01/12 19:29

insperChoi

JAVA입니다. 각 칸의 좌표를 해시 테이블에 등록하고 바퀴벌레가 그 칸을 지날 때마다 그 칸을 해시 테이블에서 제거하여 해시 테이블의 크기가 0인지 확인하는 방법을 이용하였습니다. 100X100 격자의 경우 약 100ms 정도, 1000X1000 격자의 경우 약 6000ms정도 소요됩니다.

package question3.random_walk;

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int xSize = sc.nextInt();
        int ySize = sc.nextInt();
        int roachX = sc.nextInt();
        int roachY = sc.nextInt();

        Grid grid = new Grid(xSize, ySize, roachX, roachY);

        long startTime = System.currentTimeMillis();

        while(true) {
            grid.randomWalk();

            if(grid.hasVisitedAll()) {
                break;
            }
        }

        for (int[] is : grid.grid) {
            for (int i : is) {
                System.out.print(i + ", ");
            }
            System.out.println("");
        }
        System.out.println("움직인 횟수: " + grid.moveCount);

        long endTime = System.currentTimeMillis();

        long elapsedTime = endTime - startTime;
        System.out.println("소요 시간: " + elapsedTime);

        sc.close();
    }

}

package question3.random_walk;

import java.util.Hashtable;
import java.util.Random;

public class Grid {

    public class Coord {
        int x;
        int y;

        public Coord(int x, int y) {
            this.x = x;
            this.y = y;
        }

        //hashTable을 쓰기 위해 equals, hashCode 오버라이드
        @Override
        public boolean equals(Object o) {
            if(o instanceof Coord) {
                Coord other = (Coord) o;
                return (this.x == other.x && this.y == other.y);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return x*xSize*ySize + y;
            //hashCode가 중복되지 않도록 해시를 설정
        }
    }

    int xSize;
    int ySize;
    int[][] grid;
    Coord roach;
    int moveCount;
    Hashtable<Coord, Boolean> notVisited;

    public Grid(int xSize, int ySize, int roachX, int roachY) {
        this.xSize = xSize;
        this.ySize = ySize;
        this.roach = new Coord(roachX, roachY);
        this.grid = new int[ySize][xSize]; //y좌표, x좌표 순
        this.moveCount = 0;
        notVisited = new Hashtable<Grid.Coord, Boolean>();

        for (int i = 0; i < ySize; i++) {
            for (int j = 0; j < xSize; j++) {
                notVisited.put(new Coord(j, i), true);
            }
        }

        notVisited.remove(roach);
        //현재 위치는 이미 방문했으므로
    }

    void randomWalk() {
        Random random = new Random();
        int rand = random.nextInt(0, 8);

        Coord move = new Coord(0, 0);

        switch (rand) {
        case 0:
            move = new Coord(1, 0);
            break;
        case 1:
            move = new Coord(0, 1);
            break;
        case 2:
            move = new Coord(1, 1);
            break;
        case 3:
            move = new Coord(-1, 0);
            break;
        case 4:
            move = new Coord(0, -1);
            break;
        case 5:
            move = new Coord(-1, -1);
            break;
        case 6:
            move = new Coord(1, -1);
            break;
        default:
            move = new Coord(-1, 1);
            break;
        }

        moveRoach(move);
    }

    void moveRoach(Coord move) {
        int newX = roach.x + move.x;
        int newY = roach.y + move.y;

        if((newX >= 0 && newX < xSize) && (newY >= 0 && newY < ySize)) {
            grid[newY][newX] += 1;
            roach = new Coord(newX, newY);
            moveCount++;
            notVisited.remove(roach);
        }
    }

    boolean hasVisitedAll() {
        return notVisited.isEmpty();
    }
}

2025/02/19 21:03

박준우

목록으로