
N * M 크기의 지도 숫자가 써 있고 모든면이 0인 주사위가 지도 위에 놓여져 있다.
주사위가 명령에 따라 동서남북으로 굴러갈 때, 아래와 같은 작업을 수행한다.
주사위를 굴렸을 때, 이동한 칸에 쓰여 있는 수가 0이면, 주사위의 바닥면에 쓰여 있는 수가 칸에 복사된다.
0이 아닌 경우에는 칸에 쓰여 있는 수가 주사위의 바닥면으로 복사되며, 칸에 쓰여 있는 수는 0이 된다.
큐브에게 동서남북으로 이동시키는 명령이 주어졌을 때, 명령 후 큐브 상단에 적혀있는 숫자를 출력하는 문제이다.
단, 큐브는 지도 밖으로 나갈 수 없고 지도 밖으로 나가는 명령은 무시한다.
나는 Dice 클래스를 만들어서 주사위의 6면의 숫자를 저장하기로 했다.
그 후 메서드를 이용하여 주사위 이동을 구현했다.
주사위 이동 메서드 Go### 로직
Dice 클래스
class Dice {
constructor(nowX, nowY) {
// 주사위 6면
this.up = 0;
this.down = 0;
this.left = 0;
this.right = 0;
this.front = 0;
this.back = 0;
// 지도상 주사위 위치.
this.x = nowX;
this.y = nowY;
}
GoDown() {
// 다음 위치
const [nextX, nextY] = [this.x + 1, this.y];
// 다음 위치가 지도 내부라면.
if (this.CheckOut(nextX, nextY)) {
// 이동 후 숫자 변경.
[this.up, this.down, this.front, this.back] = [this.back, this.front, this.up, this.down];
this.x = nextX;
// 지도 숫자에 따른 주사위 숫자 변경.
this.ChangeValue();
// 주사위 상단 리턴.
return this.up;
} else {
// 만약 지도 밖으로 나간다면 -1 리턴.
return -1;
}
}
GoUp() {
const [nextX, nextY] = [this.x - 1, this.y];
if (this.CheckOut(nextX, nextY)) {
[this.up, this.down, this.front, this.back] = [this.front, this.back, this.down, this.up];
this.x = nextX;
this.ChangeValue();
return this.up;
}else {
return -1;
}
}
GoLeft() {
const [nextX, nextY] = [this.x, this.y - 1];
if (this.CheckOut(nextX, nextY)) {
[this.up, this.down, this.left, this.right] = [this.left, this.right, this.down, this.up];
this.y = nextY;
this.ChangeValue();
return this.up;
}else {
return -1;
}
}
GoRight() {
const [nextX, nextY] = [this.x, this.y + 1];
if (this.CheckOut(nextX, nextY)) {
[this.up, this.down, this.left, this.right] = [this.right, this.left, this.up, this.down];
this.y = nextY;
this.ChangeValue();
return this.up;
}else {
return -1;
}
}
// 지도 숫자에 따른 주사위 숫자 변경
ChangeValue() {
// 지도 숫자.
const MapValue = map[this.x][this.y];
// 지도 숫자가 0이 아니라면.
if (MapValue) {
// 주사위 바닥면에 숫자 복사.
this.down = MapValue;
// 지도 숫자 0으로 변경.
map[this.x][this.y] = 0;
} else {
// 만약 지도 숫자가 0이라면.
// 지도에 주사위 숫자 복사.
map[this.x][this.y] = this.down;
}
}
// 지도를 벗어나는지 확인.
CheckOut(nextX, nextY) {
return !(nextX < 0 || nextX >= N || nextY < 0 || nextY >= M);
}
}
이제 명령에 따라 주사위 이동을 명령 할 solution() 로직만 추가하면 된다.
전체 코드
let fs = require("fs");
let input = fs.readFileSync("./input.text").toString().trim().split('\n');
// let input = fs.readFileSync("/dev/stdin").toString().trim().split("\n");
let [N, M, X, Y, OrderCount] = input.shift().split(' ').map(Number);
let map = input.splice(0, N).map(v => v.split(' ').map(Number));
const Orders = input.shift().split(' ').map(Number);
class Dice {
constructor(nowX, nowY) {
// 주사위 6면
this.up = 0;
this.down = 0;
this.left = 0;
this.right = 0;
this.front = 0;
this.back = 0;
// 지도상 주사위 위치.
this.x = nowX;
this.y = nowY;
}
GoDown() {
// 다음 위치
const [nextX, nextY] = [this.x + 1, this.y];
// 다음 위치가 지도 내부라면.
if (this.CheckOut(nextX, nextY)) {
// 이동 후 숫자 변경.
[this.up, this.down, this.front, this.back] = [this.back, this.front, this.up, this.down];
this.x = nextX;
// 지도 숫자에 따른 주사위 숫자 변경.
this.ChangeValue();
// 주사위 상단 리턴.
return this.up;
} else {
// 만약 지도 밖으로 나간다면 -1 리턴.
return -1;
}
}
GoUp() {
const [nextX, nextY] = [this.x - 1, this.y];
if (this.CheckOut(nextX, nextY)) {
[this.up, this.down, this.front, this.back] = [this.front, this.back, this.down, this.up];
this.x = nextX;
this.ChangeValue();
return this.up;
}else {
return -1;
}
}
GoLeft() {
const [nextX, nextY] = [this.x, this.y - 1];
if (this.CheckOut(nextX, nextY)) {
[this.up, this.down, this.left, this.right] = [this.left, this.right, this.down, this.up];
this.y = nextY;
this.ChangeValue();
return this.up;
}else {
return -1;
}
}
GoRight() {
const [nextX, nextY] = [this.x, this.y + 1];
if (this.CheckOut(nextX, nextY)) {
[this.up, this.down, this.left, this.right] = [this.right, this.left, this.up, this.down];
this.y = nextY;
this.ChangeValue();
return this.up;
}else {
return -1;
}
}
// 지도 숫자에 따른 주사위 숫자 변경
ChangeValue() {
// 지도 숫자.
const MapValue = map[this.x][this.y];
// 지도 숫자가 0이 아니라면.
if (MapValue) {
// 주사위 바닥면에 숫자 복사.
this.down = MapValue;
// 지도 숫자 0으로 변경.
map[this.x][this.y] = 0;
} else {
// 만약 지도 숫자가 0이라면.
// 지도에 주사위 숫자 복사.
map[this.x][this.y] = this.down;
}
}
// 지도를 벗어나는지 확인.
CheckOut(nextX, nextY) {
return !(nextX < 0 || nextX >= N || nextY < 0 || nextY >= M);
}
}
const solution = () => {
const MyDice = new Dice(X, Y);
let answer = [];
for (const order of Orders) {
// 주사위 윗면 숫자를 저장할 변수.
let goDice = -1;
if (order === 1) {
goDice = MyDice.GoRight();
} else if (order === 2) {
goDice = MyDice.GoLeft();
} else if (order === 3) {
goDice = MyDice.GoUp();
} else if (order === 4) {
goDice = MyDice.GoDown();
}
if (goDice !== -1) {
answer.push(goDice);
}
}
console.log(answer.join('\n'));
};
solution();
주사위를 어떻게 저장할지 고민이 되었던 문제였다. 막상 주사위를 어떻게 저장할지 정하니 그 후에는 쉽게 풀렸다.