Skip to content

Commit

Permalink
feature : 랜덤 스도쿠 맵 api 작성
Browse files Browse the repository at this point in the history
  • Loading branch information
lkoiescg2031 committed Mar 12, 2022
1 parent 52eb500 commit 0616fdc
Show file tree
Hide file tree
Showing 13 changed files with 292 additions and 0 deletions.
22 changes: 22 additions & 0 deletions sudoku-back/bin/main/io/sudoku/sudoku/math/Matrix.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.sudoku.sudoku.math

operator fun List<Int>.times(other: List<Int>): List<Int> {
assert(this.size == 9)
assert(this.size == other.size)

return Array(9) { it }.let {
it[0] = this[0] * other[0] + this[1] * other[3] + this[2] * other[6]
it[1] = this[0] * other[1] + this[1] * other[4] + this[2] * other[7]
it[2] = this[0] * other[2] + this[1] * other[5] + this[2] * other[8]

it[3] = this[3] * other[0] + this[4] * other[3] + this[5] * other[6]
it[4] = this[3] * other[1] + this[4] * other[4] + this[5] * other[7]
it[5] = this[3] * other[2] + this[4] * other[5] + this[5] * other[8]

it[6] = this[6] * other[0] + this[7] * other[3] + this[8] * other[6]
it[7] = this[6] * other[1] + this[7] * other[4] + this[8] * other[7]
it[8] = this[6] * other[2] + this[7] * other[5] + this[8] * other[8]

it.toList()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.sudoku.sudoku.sudoku.controller

import io.sudoku.sudoku.sudoku.model.Sudoku
import io.sudoku.sudoku.sudoku.model.SudokuRequest
import io.sudoku.sudoku.sudoku.service.SudokuService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/v1/sudoku")
class SudokuController {

@Autowired
private lateinit var sudokuService: SudokuService;

@GetMapping("/random")
fun getRandomMap(sudokuRequest: SudokuRequest): Sudoku
= sudokuService.getRandomMap(sudokuRequest)
}
21 changes: 21 additions & 0 deletions sudoku-back/bin/main/io/sudoku/sudoku/sudoku/model/Sudoku.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.sudoku.sudoku.sudoku.model

typealias Board = List<List<Int>>

data class Sudoku(val map: Board)

/**
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* */
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.sudoku.sudoku.sudoku.model

import org.hibernate.validator.constraints.Range

data class SudokuRequest(

val seed: Long? = null,

@Range(min = 18, max = 81) val showCount: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.sudoku.sudoku.sudoku.service

import io.sudoku.sudoku.sudoku.model.Sudoku
import io.sudoku.sudoku.sudoku.model.SudokuRequest

interface SudokuService {
fun getRandomMap(sudokuRequest: SudokuRequest): Sudoku
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.sudoku.sudoku.sudoku.service

import io.sudoku.sudoku.math.times
import io.sudoku.sudoku.sudoku.model.Sudoku
import io.sudoku.sudoku.sudoku.model.SudokuRequest
import org.springframework.stereotype.Service
import java.util.*

@Service
class SudokuServiceImpl : SudokuService {

override fun getRandomMap(sudokuRequest: SudokuRequest): Sudoku {
val s0 = sudokuRequest.seed?.let {
getLine(it)
} ?: getLine()

val map = getMap(s0)
val ret = filterMap(map, sudokuRequest.showCount)

return Sudoku(ret)
}

private fun getLine(): List<Int> = (1..9).toList().shuffled()

private fun getLine(seed: Long): List<Int> = (1..9).toList().shuffled(Random(seed))

private fun getMap(s0: List<Int>): List<List<Int>> {

val x1 = listOf(0, 0, 1, 1, 0, 0, 0, 1, 0)
val x2 = listOf(0, 1, 0, 0, 0, 1, 1, 0, 0)

val s1 = x2 * s0
val s2 = x1 * s0
val s3 = s0 * x1
val s4 = x2 * s0 * x1
val s5 = x1 * s0 * x1
val s6 = s0 * x2
val s7 = x2 * s0 * x2
val s8 = x1 * s0 * x2

return listOf(s0, s1, s2, s3, s4, s5, s6, s7, s8)
}

private fun filterMap(map: List<List<Int>>, showCount: Int): List<List<Int>> {
var random = Random()

var cnt = 0
var ret = Array(9) { Array(9) { 0 } }

while (true) {
var i = random.nextInt(8) + 1
var j = random.nextInt(8) + 1

if (ret[i][j] == 0 && random.nextBoolean()) {
ret[i][j] = map[i][j]
cnt++
if (cnt >= showCount) {
return ret.map { it.toList() }.toList()
}
}
}
}
}
2 changes: 2 additions & 0 deletions sudoku-back/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ dependencies {
// spring boot dependency 설정
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
// been validation
implementation("org.springframework.boot:spring-boot-starter-validation:2.6.4")

// kotlin dependency 설정
implementation("org.jetbrains.kotlin:kotlin-reflect")
Expand Down
22 changes: 22 additions & 0 deletions sudoku-back/src/main/kotlin/io/sudoku/sudoku/math/Matrix.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.sudoku.sudoku.math

operator fun List<Int>.times(other: List<Int>): List<Int> {
assert(this.size == 9)
assert(this.size == other.size)

return Array(9) { it }.let {
it[0] = this[0] * other[0] + this[1] * other[3] + this[2] * other[6]
it[1] = this[0] * other[1] + this[1] * other[4] + this[2] * other[7]
it[2] = this[0] * other[2] + this[1] * other[5] + this[2] * other[8]

it[3] = this[3] * other[0] + this[4] * other[3] + this[5] * other[6]
it[4] = this[3] * other[1] + this[4] * other[4] + this[5] * other[7]
it[5] = this[3] * other[2] + this[4] * other[5] + this[5] * other[8]

it[6] = this[6] * other[0] + this[7] * other[3] + this[8] * other[6]
it[7] = this[6] * other[1] + this[7] * other[4] + this[8] * other[7]
it[8] = this[6] * other[2] + this[7] * other[5] + this[8] * other[8]

it.toList()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.sudoku.sudoku.sudoku.controller

import io.sudoku.sudoku.sudoku.model.Sudoku
import io.sudoku.sudoku.sudoku.model.SudokuRequest
import io.sudoku.sudoku.sudoku.service.SudokuService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/v1/sudoku")
class SudokuController {

@Autowired
private lateinit var sudokuService: SudokuService;

@GetMapping("/random")
fun getRandomMap(sudokuRequest: SudokuRequest): Sudoku
= sudokuService.getRandomMap(sudokuRequest)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.sudoku.sudoku.sudoku.model

typealias Board = List<List<Int>>

data class Sudoku(val map: Board)

/**
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* | 1 2 3 | 1 2 3 | 1 2 3 |
* ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
* */
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.sudoku.sudoku.sudoku.model

import org.hibernate.validator.constraints.Range

data class SudokuRequest(

val seed: Long? = null,

@Range(min = 18, max = 81) val showCount: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.sudoku.sudoku.sudoku.service

import io.sudoku.sudoku.sudoku.model.Sudoku
import io.sudoku.sudoku.sudoku.model.SudokuRequest

interface SudokuService {
fun getRandomMap(sudokuRequest: SudokuRequest): Sudoku
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.sudoku.sudoku.sudoku.service

import io.sudoku.sudoku.math.times
import io.sudoku.sudoku.sudoku.model.Sudoku
import io.sudoku.sudoku.sudoku.model.SudokuRequest
import org.springframework.stereotype.Service
import java.util.*

@Service
class SudokuServiceImpl : SudokuService {

override fun getRandomMap(sudokuRequest: SudokuRequest): Sudoku {
val s0 = sudokuRequest.seed?.let {
getLine(it)
} ?: getLine()

val map = getMap(s0)
val ret = filterMap(map, sudokuRequest.showCount)

return Sudoku(ret)
}

private fun getLine(): List<Int> = (1..9).toList().shuffled()

private fun getLine(seed: Long): List<Int> = (1..9).toList().shuffled(Random(seed))

private fun getMap(s0: List<Int>): List<List<Int>> {

val x1 = listOf(0, 0, 1, 1, 0, 0, 0, 1, 0)
val x2 = listOf(0, 1, 0, 0, 0, 1, 1, 0, 0)

val s1 = x2 * s0
val s2 = x1 * s0
val s3 = s0 * x1
val s4 = x2 * s0 * x1
val s5 = x1 * s0 * x1
val s6 = s0 * x2
val s7 = x2 * s0 * x2
val s8 = x1 * s0 * x2

return listOf(s0, s1, s2, s3, s4, s5, s6, s7, s8)
}

private fun filterMap(map: List<List<Int>>, showCount: Int): List<List<Int>> {
var random = Random()

var cnt = 0
var ret = Array(9) { Array(9) { 0 } }

while (true) {
var i = random.nextInt(8) + 1
var j = random.nextInt(8) + 1

if (ret[i][j] == 0 && random.nextBoolean()) {
ret[i][j] = map[i][j]
cnt++
if (cnt >= showCount) {
return ret.map { it.toList() }.toList()
}
}
}
}
}

0 comments on commit 0616fdc

Please sign in to comment.