[TIL] 2021.03.15

승아·2021년 3월 15일
0

👩🏻‍💻 오늘 공부한 내용

스도쿠 생성하기 ( 참고 사이트1 , 참고사이트 2 )

기본적인 스도쿠 완성하기


1. S0 구하기

  • 1 ~ 9 까지의 숫자가 랜덤으로 들어간 3 x 3 배열을 만들어준다.
var sudoku: [[[Int]]] = []
var S : [[Int]] = [[1, 2, 3],
                   [4, 5, 6],
                   [7, 8, 9]]
                   
for _ in 0...9{ // 무작위로 수를 생성하여 10번 자리를 바꿔주었다.
    let randNum1 = Int(arc4random_uniform(3))
    let randNum2 = Int(arc4random_uniform(3))
    let randNum3 = Int(arc4random_uniform(3))
    let randNum4 = Int(arc4random_uniform(3))
    
    let temp = S[randNum1][randNum2]
    S[randNum1][randNum2] = S[randNum3][randNum4]
    S[randNum3][randNum4] = temp
}                   
  1. S1 구하기
  • 행렬 X1과 행렬 S0를 곱한다.
  • X1을 곱하면 1행 -> 2행, 2행 -> 3행, 3행 -> 1행으로 변경된다.
  • S를 기준으로 한 행씩 밑으로 내려가는 셈이다.
let X1 = [[0,0,1],
         [1,0,0],
         [0,1,0]]
         
// S1 = X1 * S
var S1: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += X1[k][j] * S[j][i]
        }
        arr.append(sum)
    }
    S1.append(arr)
}
  1. S2 구하기
  • 행렬 X2와 행렬 S0을 곱한다.
  • X2를 곱하면 1행 -> 3행, 2행 -> 1행, 3행 -> 2행으로 변경된다.
  • S를 기준으로 두 행씩 밑으로 내려가는 셈이다.
let X2 = [[0,1,0],
          [0,0,1],
          [1,0,0]]
// S2 = X2 * S
var S2: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += X2[k][j] * S[j][i]
        }
        arr.append(sum)
    }
    S2.append(arr)
}

sudoku.append(S2)
  1. S3 구하기
  • 행렬 S와 행렬 X1을 곱해준다.
  • S에 X1을 곱해주면 3열 -> 2열, 2열 -> 1열, 1열 -> 3열로 변경된다.
  • S를 기준으로 1열씩 왼쪽으로 이동한 셈이다.
// S3 = S * X1
var S3: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += S[k][j] * X1[j][i]
        }
        arr.append(sum)
    }
    S3.append(arr)
}

sudoku.append(S3)
  1. S4 구하기
  • 행렬 S1와 행렬 X1을 곱해준다.
  • 현재는 S1을 기준으로 곱해주었지만 S3를 기준으로 곱해준다면 X1 * S3를 하면 된다.
// S4 = X1 * S * X1
var S4: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += S1[k][j] * X1[j][i]
        }
        arr.append(sum)
    }
    S4.append(arr)
}

sudoku.append(S4)
  1. S5 구하기
  • 행렬 S2와 행렬 X1을 곱해준다.
// S5 = X2 * S * X1
var S5: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += S2[k][j] * X1[j][i]
        }
        arr.append(sum)
    }
    S5.append(arr)
}

sudoku.append(S5)
  1. S6 구하기
  • 행렬 S와 행렬 X2을 곱해준다.
// S6 = S * X2
var S6: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += S[k][j] * X2[j][i]
        }
        arr.append(sum)
    }
    S6.append(arr)
}

sudoku.append(S6)
  1. S7 구하기
  • 행렬 S1과 행렬 X2을 곱해준다.
// S7 = X1 * S * X2
var S7: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += S1[k][j] * X2[j][i]
        }
        arr.append(sum)
    }
    S7.append(arr)
}

sudoku.append(S7)
  1. S8 구하기
  • 행렬 S2와 행렬 X2을 곱해준다.
// S8 = X2 * S * X2
var S8: [[Int]] = []
for k in 0...2{
    var arr: [Int] = []
    for i in 0...2{
        var sum = 0
        for j in 0...2{
          sum += S2[k][j] * X2[j][i]
        }
        arr.append(sum)
    }
    S8.append(arr)
}

sudoku.append(S8)

스도쿠 변형하기

  • 1단계만 거치면 패턴이 반복되어 풀기 쉬우니 변형을 통해 난이도를 높여주자.
  1. 같은 3 x 3 영역에 있는 전체 세로줄과 전체 가로줄은 교환이 가능하다.
// 가로줄 교환
var horizonNum = 0
for _ in 0...2{
    let randNum1 = Int(arc4random_uniform(3)) + horizonNum
    let randNum2 = Int(arc4random_uniform(3)) + horizonNum
    
    if randNum1 != randNum2 {
        let temp = sudoku2Arr[randNum1]
        sudoku2Arr[randNum1] = sudoku2Arr[randNum2]
        sudoku2Arr[randNum2] = temp
    }
    horizonNum += 3
}

// 세로줄 교환
var verticalNum = 0
for _ in 0...2{
    let randNum1 = Int(arc4random_uniform(3)) + verticalNum
    let randNum2 = Int(arc4random_uniform(3)) + verticalNum
    
    if randNum1 != randNum2{
        for i in 0...8{
            let temp = sudoku2Arr[i][randNum1]
            sudoku2Arr[i][randNum1] = sudoku2Arr[i][randNum2]
            sudoku2Arr[i][randNum2] = temp
        }
    }
    
    verticalNum += 3
}
  1. 3 x 3 영역 전체를 잇는 3개의 가로 영역(3 x 9)끼리 or 세로 영역(9 x 3)끼리 교환이 가능하다.
// 가로 영역
let randNum1 = Int(arc4random_uniform(3)) * 3
let randNum2 = Int(arc4random_uniform(3)) * 3

if randNum1 != randNum2{
    for i in 0...2{
        let temp = sudoku2Arr[randNum1 + i]
        sudoku2Arr[randNum1 + i] = sudoku2Arr[randNum2 + i]
        sudoku2Arr[randNum2 + i] = temp
    }
}

// 세로 영역
let randNum3 = Int(arc4random_uniform(3)) * 3
let randNum4 = Int(arc4random_uniform(3)) * 3

if randNum3 != randNum4{
    for i in 0...2{
        for j in 0...8{
            let temp = sudoku2Arr[j][i + randNum3]
            sudoku2Arr[j][i + randNum3] = sudoku2Arr[j][i + randNum4]
            sudoku2Arr[j][i + randNum4] = temp
        }
    }
}
  1. 숫자끼리의 교환이 가능하다. (1 ~ 9 까지 전체 1:1 교환 및 재배열 가능)
for _ in 1...10{ // 무작위로 10번 교환 
    let randNum1 = Int(arc4random_uniform(9)) + 1
    let randNum2 = Int(arc4random_uniform(9)) + 1
    
    if randNum1 != randNum2{
        var xyArr: [[Int]] = []
        for i in 0...8{
            var cnt = 0
            for j in 0...8{
                if sudoku2Arr[i][j] == randNum1{
                    xyArr.append([i,j,randNum2])
                    cnt += 1
                } else if sudoku2Arr[i][j] == randNum2{
                    xyArr.append([i,j,randNum1])
                    cnt += 1
                }
                
                if cnt == 2{
                    break
                }
            }
        }
        
        for i in xyArr{
            sudoku2Arr[i[0]][i[1]] = i[2]
        }
    }
}
  1. 9 x 9 스도쿠의 회전이 가능하다.
  2. 9 x 9 스도쿠의 거울 대칭이 가능하다. (좌우, 상하 외에 대각선 대칭도 가능)

0개의 댓글