Last active
April 18, 2022 18:11
-
-
Save mununki/1baafc810643e846018edb472c574162 to your computer and use it in GitHub Desktop.
프로그래머스 코테 - 체스
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open Belt | |
module rec Board: { | |
type rec t | |
and coord = (row, col) | |
and size = int | |
and col | |
and row | |
let init: size => t | |
let postPieces: (t, list<string>) => t | |
let markMovesOf: (t, list<string>) => t | |
let countOfUnMarked: t => int | |
} = { | |
exception Invalid_Operation(string) | |
type rec coord = (row, col) | |
and row = int | |
and col = int | |
and size = int | |
and canGo = bool | |
and statusOfCoord = NotOccupied(canGo) | Occupied(Piece.t) | |
module CoordCmp = Belt.Id.MakeComparable({ | |
type t = coord | |
let cmp = (a, b) => Pervasives.compare(a, b) | |
}) | |
type rec t = Belt.Map.t<CoordCmp.t, statusOfCoord, CoordCmp.identity> | |
let init = size => { | |
let rows = Array.makeBy(size, x => x + 65) // "A" = 65 | |
let cols = Array.makeBy(size, x => x + 1) | |
let cells = | |
rows | |
->Array.map(r => cols->Array.map(c => (r, c))) | |
->Array.concatMany | |
->Array.map(c => (c, NotOccupied(false))) | |
cells->Map.fromArray(~id=module(CoordCmp)) | |
} | |
let genCoord = piece => | |
switch piece->Js.String2.split("") { | |
| [row, col] => { | |
let convertRow = row => { | |
let re = %re("/[ABCDEFGH]/") | |
let isValid = re->Js.Re.test_(row) | |
if isValid { | |
row->String.get(0)->Char.code->Some | |
} else { | |
None | |
} | |
} | |
switch (row->convertRow, col->Int.fromString) { | |
| (Some(row), Some(col)) => (row, col) | |
| _ => raise(Invalid_Operation(`Cann't generate the coord`)) | |
} | |
} | |
| _ => raise(Invalid_Operation(`Cann't generate the coord`)) | |
} | |
let postPiece: (t, coord, Piece.t) => t = (board, coord, piece) => | |
switch board->Map.get(coord) { | |
| None => raise(Invalid_Operation(`Cann't find the cell`)) | |
| Some(Occupied(_)) => raise(Invalid_Operation(`The position is taken`)) | |
| Some(NotOccupied(_)) => board->Map.set(coord, Occupied(piece)) | |
} | |
let rec postPieces = (board, pieces) => | |
switch pieces { | |
| list{} => board | |
| list{hd, ...tl} => { | |
let coord = genCoord(hd) | |
let newBoard = board->postPiece(coord, Piece.Bishop) | |
postPieces(newBoard, tl) | |
} | |
} | |
let markMoves: (t, coord, Piece.t) => t = (board, coord, piece) => { | |
let rec markMovesAuxInfinite = (board, coord, direction) => { | |
let (row, col) = coord | |
let (deltaOfRow, deltaOfCol) = direction | |
let newCoord = (row + deltaOfRow, col + deltaOfCol) | |
switch board->Map.get(newCoord) { | |
| None | |
| Some(Occupied(_)) => board | |
| Some(NotOccupied(_)) => { | |
let newBoard = board->Map.set(newCoord, NotOccupied(true)) | |
markMovesAuxInfinite(newBoard, newCoord, direction) | |
} | |
} | |
} | |
let rec markMovesAux = (board, coord, directions) => { | |
switch directions { | |
| list{} => board | |
| list{hd, ...tl} => | |
switch piece { | |
| Bishop => { | |
let newBoard = markMovesAuxInfinite(board, coord, hd) | |
markMovesAux(newBoard, coord, tl) | |
} | |
} | |
} | |
} | |
markMovesAux(board, coord, piece->Piece.directions) | |
} | |
let rec markMovesOf = (board, pieces) => | |
switch pieces { | |
| list{} => board | |
| list{hd, ...tl} => { | |
let coord = genCoord(hd) | |
let newBoard = board->markMoves(coord, Piece.Bishop) | |
markMovesOf(newBoard, tl) | |
} | |
} | |
let countOfUnMarked = board => | |
board->Map.reduce(0, (acc, _, v) => | |
switch v { | |
| Occupied(_) => acc | |
| NotOccupied(true) => acc | |
| NotOccupied(false) => acc + 1 | |
} | |
) | |
} | |
and Piece: { | |
type rec t = Bishop // 모든 기물을 추가하진 않고 비숍만 추가함 | |
and deltaOfCol = int | |
and deltaOfRow = int | |
and direction = (deltaOfRow, deltaOfCol) | |
and directions = list<direction> | |
let directions: t => directions | |
} = { | |
type rec t = Bishop | |
and deltaOfCol = int | |
and deltaOfRow = int | |
and direction = (deltaOfRow, deltaOfCol) | |
and directions = list<direction> | |
let directions = t => | |
switch t { | |
| Bishop => list{(1, 1), (1, -1), (-1, 1), (-1, -1)} | |
} | |
} | |
let solution = pieces => { | |
let board = Board.init(8) | |
let pieces = pieces->List.fromArray | |
board->Board.postPieces(pieces)->Board.markMovesOf(pieces)->Board.countOfUnMarked | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 8 x 8 체스 보드에 대각선으로 움직일 수 있는 비숍이 배열로 주어지는 경우 | |
// 비숍이 움직이지 못하는 보드 셀의 개수를 구하라. | |
// ["C6"] => 52 | |
// ["C6", "A4", "E5"] => 35 | |
module rec Board: { | |
type rec t | |
and coord = (row, col) | |
and size = int | |
and col | |
and row | |
let init: size => t | |
let postPieces: (t, list<string>) => t | |
let markMovesOf: (t, list<string>) => t | |
let countOfUnMarked: t => int | |
} | |
and Piece: { | |
type rec t = Bishop | |
and deltaOfCol = int | |
and deltaOfRow = int | |
and direction = (deltaOfRow, deltaOfCol) | |
and directions = list<direction> | |
let directions: t => directions | |
} | |
let solution: array<string> => int |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment