본문 바로가기
VBA

[VBA] 스토쿠를 풀어보자(Feat. 앳마)

by 일등미노왕국 2022. 5. 16.

https://1stminokingdom.tistory.com/74

 

[VBA]스토쿠를 풀어보자

VBA를 처음배우면서 언젠가 꼭 해보고 싶다하고 한게 스토쿠였다. 그때는 막연하게 꿈일것만 같았던 일이 VBA를 배운지 2년 정도되니 구현을 할 수 있게 되었다. 물론 정말 잘하는 분들이 풀어놓

1stminokingdom.tistory.com

이전 스토쿠1 버전에서는 본인이 직접 푸는 방식으로 풀다가 경우의 수가 너무 많아질때는 그냥 1부터 9까지 하나씩 넣어보는 방식으로 풀었다고 하면 이번 공개할 코드는 그냥 처음부터 1부터 9까지 경우의 수를 넣어서 푸는 방식으로 구현하였다.

 

코드의 가이드 라인은 앳마님 블로그에서 참고를 하였다.  

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=atmyhome&logNo=90182310003 

 

(엑셀vba)엑셀로 스도쿠문제 풀기

인터넷상에서 스도쿠문제를 푸는 엑셀관련 자료를 몇개 찾아서 실행해보니 해답을 잘 못찾는 경우가 많은 ...

blog.naver.com

이분께서 2013에 이 구문을 게시하였으니..지금은 얼마나 더 멋진 코드를 만들고 계실지 한없는 부러움과 동시대를 지내면서 난 뭘했나 싶은 반성이 앞선다. 앳마님도 재미있는(?) 주제로 코드들을 많이 올려주시니 구독하셔서 더 많은 정보를 가져가시기를 바란다.

 

기존 1버전보다는 코드도 깔끔해지고 완성시간도 어마어마하게 줄일 수 있는 시간이 되었다.

 

코드 진행은 이렇다.

1. 전체영역을 Vall 배열에 담는다.

 

2. 전체영역에서 빈셀의 위치값을 Vb 배열에 담는다.

 

3. Vall 배열중 Empty 한 공간을 순환하면서 후보값들을 해당공간에 +1을 한다.(1번째 핵심구문이다.)

1부터 순서대로 들어가는게 아니라 해당영역값에 +1 이다. 이렇게 해야 순차적으로 1부터 9까지 후보값을 넣어보다가

후보값이 9보다 크면 이전 빈셀 배열로 이동하여 해당값이 +1 해야 하기 때문이다.

예를 들면 이전셀이 4이고 지금 셀이 9까지 했는데도 마땅한 값이 없을때는 이전셀 4를 +1하고 현재셀은 Empty 상태로 변경하여 1부터 9까지 후보값들을 순차적으로 넣어보는 작업을 다시 해야 하기에 단순히 1부터가 아닌 영역에 +1임을 기억해야 한다.

 

4. 후보값이 검증이 끝나서 배열에 적용이 되었다면 무한 Loop를 벗어나서 빈셀이 더 있는지 아니면 빈셀을 알맞은 값들로 대체했는지 묻는 구문이 나온다. 빈셀이 없다면 종료하게 되고 빈셀이 있다면 두가지로 나눌 수 있는데 정상적인 숫자이면 다음 빈셀 배열을 검증하면 되고 후보값이 9보다 큰 경우에는 그 후보군을 지우고 이전 셀값을 +1하여 계속 알맞은 값들을 구문을 반복하게 된다.

 

5.  핵심구문 2번째는 3X3 안의 중복값 검증이다.

스토쿠는 크게는 3X3구문이 총 9개 영역으로 구성되어 있다. 값들은 3X3 구문의 총 9개 영역에 들어가게 되는데 

(1,1) 은 (1,1).resize(3,3)  을 하게 되면 1번째 영역값들을 대상으로 할 수 있는데

(1,2) 을 (1,2).resize(3,3) 을 하게되면 1번째영역과 2번째 영역까지 영역이 확대되게 된다.

이문제를 풀려면 결국에는 1번 영역에는 시작값이 (1,1) 어야 하고 2번 영역은 (1,4)  3번영역은 (1,7)로 해당 영역의 모든값들은 시작점이 같아야 한다.

 

약간의 트릭이 필요한다.

 

가령 셀(2,3)라고 하자 이는 1번 영역이다. 기준점은 (1,1)인데 (2,3)을 (1,1)로 만드는 방법을 알려드리면 약간의 산수가 필요하다.

 

2는 2 - ((2+2) mod 3) (mod 3 : 어떤 수를 3으로 나누었을 때 나머지) = 2- (4 mod 3) = 2 - 1 = 1

3은 3-((3+2) mod 3) = 3 - 2 = 1

 따라서 (1,1)

 

(5,8)은 6영역이다. 6영역의 기준점은 (4,7) 이다.

5는 5 - ((5 + 2) mod 3) = 5 - 1 = 4

8은 8 - ((8 + 2) mod 3) = 8 - 1 = 7

 

6. 3번째 핵심구문은 

    가로 전체 행과 세로 전체 열의 검증이다.

    여기에 사용된 구문은 이부분이다.

    https://1stminokingdom.tistory.com/83

 

[VBA] 배열내 중복된 값들을 도출하고 중복값을 구해라

배열 또는 셀의 영역 데이터 중 고유값을 구하고 중복된 값을 구하는 것은 보통 딕셔너리로 구한다. 또는 어레이리스트나 컬렉션으로 구하는게 대부분이다. 본인의 VBA 뮤즈인 준빠님께서 질문

1stminokingdom.tistory.com

 

이렇게 해서 본인의 5개월동안의 스토쿠 여정을 마무리 하려고 한다.

스토쿠완성(22.05.15).xlsm
0.03MB

댓글