주사위 네개

문제

언어

  • JavaScript

순서도

  1. 각 조건에 맞게 상금 계산
  2. 계산한 상금들 중에서 최댓값 구하기

문제 풀이 step 1

  • 1 에서부터 6 까지의 눈을 가진 4 개의 주사위를 던져서 다음과 같은 규칙에 따라 상금을 받는 게임이 있습니다.
    • 같은 눈이 4 개가 나오면 50,000원 + (같은 눈) × 5,000원 의 상금을 받게 된다.
    • 같은 눈이 3 개만 나오면 10,000원 + (3 개가 나온 눈) × 1,000원 의 상금을 받게 된다.
    • 같은 눈이 2 개씩 두 쌍이 나오는 경우에는 2,000원 + (2 개가 나온 눈) × 500원 + (또 다른 2 개가 나온 눈) × 500원 의 상금을 받게 된다.
    • 같은 눈이 2 개만 나오는 경우에는 1,000원 + (같은 눈) × 100원 의 상금을 받게 된다.
    • 모두 다른 눈이 나오는 경우에는 (그 중 가장 큰 눈) × 100원 의 상금을 받게 된다.
  • N (1 ~ 1000) 명이 주사위 게임에 참여하였을 때, 가장 많은 상금을 받은 사람의 상금을 구하는 문제입니다.

문제 풀이 step 2

  • 위에서 주어지는 조건에 맞게 상금을 계산하면 되기 때문에 크게 어려운 부분은 없습니다.
  • 하지만, 창의적인 방법이 여러 가지 있어서 한 번 소개해보려고 합니다.
  • 첫 번째, 단순하게 조건으로 분기하는 방법
    • 모든 조건을 하나씩 나열하며 분기하는 방법으로, 하드 코딩에 가까운 아주 단순한 방법입니다.
  • 두 번째, 정렬을 이용하는 방법
    • 내림차순 혹은 오름차순으로 정렬 후, 조건에 맞게 분기하는 방법입니다.
    • 정렬을 하게 되면, 조건을 분기하는 부분이 상당히 간결해집니다.
  • 세 번째, 계수 정렬처럼 각 주사위의 눈을 세는 방법
    • 계수 정렬처럼 각 주사위의 눈을 세서 같은 눈의 개수에 따라서 조건을 분기하는 방법입니다.
    • 이 또한, 조건을 분기하는 부분이 상당히 간결해집니다.
  • 네 번째, SET 자료구조와 정렬을 이용하는 방법
    • SET 을 이용해서 중복된 주사위 눈을 제거하고, SET 의 원소의 개수에 따라서 조건을 분기하는 방법입니다.
    • 이 또한, 조건을 분기하는 부분이 상당히 간결해집니다.
  • 위의 방법 중에서 원하는 방법을 선택한 후에 상금의 최댓값을 구해서 출력하면 정답입니다.
  • 추가 설명은 주석으로 작성하겠습니다.

후기

  • 저는 첫 번째 방법으로 구현을 했는데, 이렇게 다양한 방법이 있을 줄은 몰랐습니다.
  • 정렬을 이용하는 방법이 제일 간단하고 빨랐던 것 같습니다.
  • 그리고 SET 자료구조와 정렬을 이용하는 방법이 가장 창의적인 방법인 것 같습니다.
  • 어려운 문제는 아니지만, 문제를 풀기 위한 다양한 경로가 있다는 것이 너무 재미있어서 포스트하게 되었습니다.

소스 코드

const input = require("fs")
	.readFileSync("/dev/stdin")
	.toString()
	.trim()
	.split("\n");

const check4 = (a, b, c, d) => {
	if (a === b && b === c && c === d) return 50000 + a * 5000;
	return -1;
};

const check3 = (a, b, c, d) => {
	if (a === b && b === c && c !== d) return 10000 + a * 1000;
	if (b === c && c === d && a !== b) return 10000 + b * 1000;
	if (a === c && c === d && a !== b) return 10000 + a * 1000;
	if (a === b && b === d && a !== c) return 10000 + a * 1000;
	return -1;
};

const check2 = (a, b, c, d) => {
	if (a === b && c === d) return 2000 + a * 500 + c * 500;
	if (a === c && b === d) return 2000 + a * 500 + b * 500;
	if (a === d && b === c) return 2000 + a * 500 + b * 500;
	return -1;
};

const check1 = (a, b, c, d) => {
	if (a === b && a !== c && a !== d) return 1000 + a * 100;
	if (a === c && a !== b && a !== d) return 1000 + a * 100;
	if (a === d && a !== b && a !== c) return 1000 + a * 100;
	if (b === c && b !== a && b !== d) return 1000 + b * 100;
	if (b === d && b !== a && b !== c) return 1000 + b * 100;
	if (c === d && c !== a && c !== b) return 1000 + c * 100;
	return -1;
};

const solution = (input) => {
	let n = Number(input[0]);

	let max = 0;
	let index = 1;
	while (n-- > 0) {
		const [a, b, c, d] = input[index++].split(" ").map(Number);

		if (check4(a, b, c, d) !== -1) {
			max = Math.max(max, check4(a, b, c, d));
		} else if (check3(a, b, c, d) !== -1) {
			max = Math.max(max, check3(a, b, c, d));
		} else if (check2(a, b, c, d) !== -1) {
			max = Math.max(max, check2(a, b, c, d));
		} else if (check1(a, b, c, d) !== -1) {
			max = Math.max(max, check1(a, b, c, d));
		} else {
			max = Math.max(max, Math.max(a, b, c, d) * 100);
		}
	}

	return max;
};

console.log(solution(input));