
Problem
์ฝ๋ฉํ ์คํธ ์ฐ์ต - 3์ฃผ์ฐจ
[[1,1,0,0,1,0],[0,0,1,0,1,0],[0,1,1,0,0,1],[1,1,0,1,1,1],[1,0,0,0,1,0],[0,1,1,1,0,0]] [[1,0,0,1,1,0],[1,0,1,0,1,0],[0,1,1,0,1,1],[0,0,1,0,0,0],[1,1,0,1,1,0],[0,1,0,0,0,0]] 14 [[0,0,0],[1,1,0],[1,1,1]] [[1,1,1],[1,0,0],[0,0,0]] 0
programmers.co.kr
Solution
1. ๊ฒ์๋ณด๋์ ํ ์ด๋ธ์ ํผ์ฆ ์กฐ๊ฐ๋ค์ ์ฐพ๋๋ค.
๊ฒ์๋ณด๋์ ํ ์ด๋ธ์ ํผ์ฆ ์กฐ๊ฐ๋ค์ ์ฐพ๊ธฐ ์ํด์ BFS ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด์ผ ๋ฉ๋๋ค.
๊ฒ์๋ณด๋๋ฅผ ํ์ํ ๋ ๋ง์ฝ 0์ ๋ง๋๊ฒ ๋์๋ค๋ฉด ๊ทธ ์ฃผ๋ณ ์ผ์ชฝ,์ค๋ฅธ์ชฝ,์,์๋๊ฐ 0์ธ์ง๋ฅผ ํ์ ํฉ๋๋ค.
๋ง์ฝ 0์ด๋ผ๋ฉด ํ์ ํด๋น ์์น๋ฅผ ๋ฃ๊ณ ๋ฐ๋ณตํด์ค์ ํผ์ฆ์ ์กฐ๊ฐ์ ์์ฑํฉ๋๋ค.
func makePuzzle(x:Int,y:Int,isEmpty:Bool) {
var queue:[(Int,Int)] = [(x,y)]
while !queue.isEmpty {
let first = queue.removeFirst()
let new = [(first.0-1,first.1),(first.0+1,first.1),(first.0,first.1-1),(first.0,first.1+1)]
for d in new {
if 0..<boardCopy.count ~= d.0 && 0..<boardCopy.count ~= d.1 {
if boardCopy[d.1][d.0] == 0 {
boardCopy[d.1][d.0] = 1
if isEmpty {
emptyBlocks[emptyBlocks.count-1].append(d)
}else {
blocks[blocks.count-1].append(d)
}
queue.append(d)
}
}
}
}
}
2. ํ ์ด๋ธ์ ํผ์ฆ ์กฐ๊ฐ์ ํ์ ํด์ค๋ค.
๊ฒ์๋ณด๋์ ํ ์ด๋ธ์ ํผ์ฆ ์กฐ๊ฐ์ด ๊ฐ์์ง ํ์ธํ๊ธฐ ์ํด์ ํ ์ด๋ธ์ ๊ฐ 0,90,180,270๋๋ก ํ์ ๋ ํผ์ฆ ์กฐ๊ฐ๋ค์ ๋น๊ตํด์ฃผ์ด์ผ ํฉ๋๋ค.
90๋ ์๊ณ๋ฐฉํฅ์ผ๋ก ํ์ ํ๋ ๊ณต์์ (x,y) -> (y,-x)์ ๋๋ค.
func rotateBlocks(block:[(Int,Int)]) -> [[(Int,Int)]] {
var newBlock = block
var rotateBlocks:[[(Int,Int)]] = [block]
for _ in 0..<3 {
var rotateBlock:[(Int,Int)] = []
for b in newBlock {
rotateBlock.append((b.1,-b.0))
}
newBlock = rotateBlock
rotateBlocks.append(rotateBlock)
}
return rotateBlocks
}
3. ๊ฒ์๋ณด๋์ ํ ์ด๋ธ์ ํผ์ฆ ์กฐ๊ฐ์ ๋ชจ๋ ๋น๊ตํด์ค๋๋ค.
๊ฒ์๋ณด๋์ ํ ์ด๋ธ์ ํผ์ฆ ์กฐ๊ฐ์ด ๊ฐ์ ๊ฒ์ธ์ง ํ์ธํ๊ธฐ ์ํด์ ์ ๋ ๋ค์๊ณผ ๊ฐ์ด ๋น๊ตํด์ฃผ์์ต๋๋ค.
1. ๋จผ์ ํผ์ฆ ์กฐ๊ฐ์ ๋ชจ๋ ์์น๋ฅผ x๊ฐ ์์ ๊ฒ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํ๊ณ ๋ง์ฝ ๊ฐ๋ค๋ฉด y๊ฐ ์์ ๊ฒ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌํด์ฃผ์์ต๋๋ค.
2. ์ ๋ ฌ๋ ํผ์ฆ ์กฐ๊ฐ์ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ ์์น๋ฅผ ์๋ก ๋น๊ตํ์ฌ ๊ทธ ์ฐจ์ด๋ฅผ ๋ํด์ฃผ๊ณ ๋น๊ตํ์ต๋๋ค.
๋ง์ฝ ์๋์ ๊ฐ์ ๋ ํผ์ฆ์ด ์๋ค๊ณ ๊ฐ์ ํ๋ฉด ์ ๋ ฌ์ ํด์ฃผ๋ฉด 1. [00,10,20,21] 2. [11,21,31,32] ๊ฐ ๋ ๊ฒ ์ ๋๋ค.
ex) 1. 00 10 20 2. 11 21 31
21 32
๋ ํผ์ฆ์ ๊ฐ์ฅ ์ฒซ ๋ฒ์งธ ์ฆ 00๊ณผ 11์ ์ฐจ์ด๋ 0 - 1 = -1 0 - 1 = -1 -1,-1์ด๋ฏ๋ก
๋๋ฒ์งธ ํผ์ฆ์ x์ y์ -1,-1์ ๋ํด์ฃผ๋ฉด ์ฒซ ๋ฒ์งธ ํผ์ฆ๊ณผ ๊ฐ์ด ๋ ๊ฒ ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณค ๋ชจ๋ ํผ์ฆ์ ์์น๋ฅผ ๋น๊ตํด์ค๋๋ค.
func checkEqualPuzzleCount() -> Int {
var answer:Int = 0
while !emptyBlocks.isEmpty {
let empty = emptyBlocks.removeFirst()
outer:for (i,block) in blocks.enumerated() {
if block.count != empty.count { continue }
let emptySort = sortBlock(block: empty)
second:for rotateBlock in rotateBlocks(block: block) {
var rotateSort = sortBlock(block: rotateBlock)
let x = emptySort.first!.0 - rotateSort.first!.0
let y = emptySort.first!.1 - rotateSort.first!.1
rotateSort = rotateSort.map{($0.0+x,$0.1+y)}
for i in 0..<emptySort.count {
if emptySort[i] != rotateSort[i] {
continue second
}
}
blocks.remove(at: i)
answer += empty.count
break outer
}
}
}
return answer
}
4. ๊ฐ์ ํผ์ฆ์ ์กฐ๊ฐ๋ค์ ์ธ์ด ๋ฐํํฉ๋๋ค.
return checkEqualPuzzleCount()
Source Code
import Foundation | |
var boardCopy:[[Int]] = [] | |
var emptyBlocks:[[(Int,Int)]] = [] | |
var blocks:[[(Int,Int)]] = [] | |
func solution(_ game_board:[[Int]], _ table:[[Int]]) -> Int { | |
boardCopy = game_board | |
findBlocks(isEmpty:true) | |
boardCopy = table.map{$0.map{abs($0-1)}} | |
findBlocks(isEmpty:false) | |
return checkEqualPuzzleCount() | |
} | |
func findBlocks(isEmpty:Bool) { | |
var check:Bool = true | |
while check { | |
check = false | |
outer:for (y,board) in boardCopy.enumerated() { | |
for (x,n) in board.enumerated() { | |
if n == 0 { | |
if isEmpty { | |
emptyBlocks.append([(x,y)]) | |
}else { | |
blocks.append([(x,y)]) | |
} | |
boardCopy[y][x] = 1 | |
makePuzzle(x: x, y: y,isEmpty: isEmpty) | |
check = true | |
break outer | |
} | |
} | |
} | |
} | |
} | |
func makePuzzle(x:Int,y:Int,isEmpty:Bool) { | |
var queue:[(Int,Int)] = [(x,y)] | |
while !queue.isEmpty { | |
let first = queue.removeFirst() | |
let new = [(first.0-1,first.1),(first.0+1,first.1),(first.0,first.1-1),(first.0,first.1+1)] | |
for d in new { | |
if 0..<boardCopy.count ~= d.0 && 0..<boardCopy.count ~= d.1 { | |
if boardCopy[d.1][d.0] == 0 { | |
boardCopy[d.1][d.0] = 1 | |
if isEmpty { | |
emptyBlocks[emptyBlocks.count-1].append(d) | |
}else { | |
blocks[blocks.count-1].append(d) | |
} | |
queue.append(d) | |
} | |
} | |
} | |
} | |
} | |
func checkEqualPuzzleCount() -> Int { | |
var answer:Int = 0 | |
while !emptyBlocks.isEmpty { | |
let empty = emptyBlocks.removeFirst() | |
outer:for (i,block) in blocks.enumerated() { | |
if block.count != empty.count { continue } | |
let emptySort = sortBlock(block: empty) | |
second:for rotateBlock in rotateBlocks(block: block) { | |
var rotateSort = sortBlock(block: rotateBlock) | |
let x = emptySort.first!.0 - rotateSort.first!.0 | |
let y = emptySort.first!.1 - rotateSort.first!.1 | |
rotateSort = rotateSort.map{($0.0+x,$0.1+y)} | |
for i in 0..<emptySort.count { | |
if emptySort[i] != rotateSort[i] { | |
continue second | |
} | |
} | |
blocks.remove(at: i) | |
answer += empty.count | |
break outer | |
} | |
} | |
} | |
return answer | |
} | |
func rotateBlocks(block:[(Int,Int)]) -> [[(Int,Int)]] { | |
var newBlock = block | |
var rotateBlocks:[[(Int,Int)]] = [block] | |
for _ in 0..<3 { | |
var rotateBlock:[(Int,Int)] = [] | |
for b in newBlock { | |
rotateBlock.append((b.1,-b.0)) | |
} | |
newBlock = rotateBlock | |
rotateBlocks.append(rotateBlock) | |
} | |
return rotateBlocks | |
} | |
func sortBlock(block:[(Int,Int)]) -> [(Int,Int)] { | |
let sort:[(Int,Int)] = block.sorted{$0.0 == $1.0 ? $0.1 < $1.1 : $0.0 < $1.0 } | |
return sort | |
} |
'๐ Problem Solution > Programmers' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] ํ๋ก๊ทธ๋๋จธ์ค ์ํด๋ฆฌ ์ฑ๋ฆฐ์ง 4์ฃผ์ฐจ ์ง์ ๊ตฐ ์ถ์ฒํ๊ธฐ (0) | 2021.08.28 |
---|---|
[Swift] ํ๋ก๊ทธ๋๋จธ์ค N-Queen (0) | 2021.08.28 |
[Swift] 2020 KAKAO BLIND RECRUITMENT ๊ธฐ๋ฅ๊ณผ ๋ณด ์ค์นํ๊ธฐ (0) | 2021.08.13 |
[Swift] ํ๋ก๊ทธ๋๋จธ์ค ์ํด๋ฆฌ ์ฑ๋ฆฐ์ง 2์ฃผ์ฐจ ์ํธ ํ๊ฐ (0) | 2021.08.10 |
[Swift] 2021 KAKAO INTERNSHIP ๊ฑฐ๋ฆฌ๋๊ธฐ ํ์ธํ๊ธฐ (0) | 2021.08.07 |
๋๊ธ