본문 바로가기

main/Algorithm

구름톤 챌린지 17일차 일기

예전에 제대로 못 풀었던 문제들(숙제..)을 몰아서 모두 처리하려고 했는데..

게임젬이 안 풀린다.(새벽에 겨우 풀었다...)

아...... 그래서 오늘 문제를 아직도 못 풀었다

 

 

문제 4. 완벽한 햄버거 만들기

// Run by Node.js
const readline = require('readline');

(async () => {
	let rl = readline.createInterface({ input: process.stdin });
	let n;
	let taste = [];
	let goodTaste = 0;
	let goodIndex = 0;
	let left, right;
	let result = 0;
	
	const main = (taste) => {
		taste.forEach((el, idx) => {
			if (goodTaste >= el) return;
			goodTaste = el;
			goodIndex = idx;
		})
		left = taste.slice(0, goodIndex).sort((a, b) => a-b);
		right = taste.slice(goodIndex).sort((a, b) => b-a);
		
		const sortedList = [...left, ...right];
		
		if (sortedList.length !== taste.length) {
			result = 0
			return;
		}
		for (let i=0; i<taste.length; i++) {
			if (taste[i] !== sortedList[i]) {
				result = 0
				return;
			} else {
				result += taste[i]
			}
		}
		return;
	}
	
	for await (const line of rl) {
		if (n === undefined) {
			n = Number(line);
		} else {
			taste = [line];
			main(taste[0].split(" ").map(Number));
			console.log(result)
		}
	}
	rl.close();
	process.exit();
})();

인풋을 좀 이상하게 받았어서 모든 로직이 main() 에 들어가있긴 하지만.. 어쨌든.

가장 맛이 좋은 값의 인덱스를 찾아서 그 양쪽 배열을 분리하고 정렬하여 값이 동일한지 체크하면 되는 문제였는데,

 

처음에는 배열 통째로 정렬하여 비교할 생각을 하지 않고

[4, 4, 3, 2, 1] 이거나, [1, 2, 3, 4, 4] 같은 테스트 케이스에서

인덱스 하나하나를 비교하려고 생각했더니 max idx 찾기도 힘들었고 로직을 어떻게 풀어나갈 지 방법이 떠오르지 않았었다.

 

그래서 문제를 못푼 채 묵혀뒀고...

오늘 정해 코드 보고 나서 배열로 해결하면 내가 고민한 것들은 고민할 필요도 없구나 라는 것을 깨달음.

 

 

문제 5. 이진수 정렬

const readline = require('readline');
let rl = readline.createInterface({
	input: process.stdin,
	output: process.stdout,
});
const input = []
rl.on('line', (line) => {
	input.push(line);
});

rl.on('close', () => {
	const [n, k] = input[0].split(" ").map(Number)
	const numbers = input.slice(1)[0].split(" ").map(Number)
	
	const oneCntList = numbers.map((el, idx) => {
		const binNum = el.toString(2)
		let cnt = 0;
		binNum.split("").forEach(bin => {
			if (bin === '1') cnt++;
		})
		return [cnt, numbers[idx]]
	})
	
	const sortedNumbers = oneCntList.sort((a, b) => {
		if (a[0] === b[0]) {
			return b[1] - a[1]
		}
		return b[0] - a[0]
	})
	console.log(sortedNumbers[k-1][1])
})

이 문제는 맞는데 계속 틀리는 거다.. 왜 맞냐면

지난 번 풀었을 때도 런타임 에러가 나서, 이상하네 로직은 맞는데 .. 너무 배열을 많이 돌렸나? 라고 생각했는데

오늘 일상이의 효율적인 코드를 보고 따라 풀고 제출했는데도 틀리는 것임.

???

뭐지 ..근데 정해 코드를 봤더니 내가 처음 푼 것처럼 그냥 배열을 돌리고 있음. 그래서 다시 그 로직으로 풀어봤는데 또 틀리는 것임.

???

인풋 문제다. 하고 인풋을 다시 받았더니 맞았음. ㅠ_ㅠ

 

어쨌든 내 로직은 무지성 for문 파티..

2진수로 바꾸고 1 갯수를 세고 원래 10진수와 함께 배열에 넣어준 뒤

정렬할 때 기준에 맞게 잘 해준다. sort함수 잘 쓰는 법을 배운 문제.

 

 

문제 10. GameJam

const readline = require('readline');
let rl = readline.createInterface({
	input: process.stdin,
	output: process.stdout,
});
const input = [];
rl.on('line', (line) => {
	input.push(line);
});

rl.on('close', () => {
	const n = Number(input[0]);
	const goormS = input[1].split(" ").map(el => Number(el-1));
	const playerS = input[2].split(" ").map(el => Number(el-1));
	const fields = input.slice(3).map(el => el.split(" "));
	const dir = {R: [0, 1], L: [0, -1], U: [-1, 0], D: [1, 0]}
	
	const play = (queue, memo) => {
		let moveCnt = 1;
		
		while (queue.length) {
			let [r, c] = queue.shift();
			memo[r][c] = 1;
			const cur = fields[r][c];
			const direction = cur.substr(-1);
			let playCnt = Number(cur.slice(0, -1));

			let nr = r, nc = c;
			while (playCnt > 0) {
				nr += dir[direction][0];
				nc += dir[direction][1];
				if (nr >= n) { nr = 0 }
				if (nr < 0) { nr = n-1 }
				if (nc >= n) { nc = 0 }
				if (nc < 0) { nc = n-1 };
				if (memo[nr][nc] === 1) {
					queue.length = 0;
					return moveCnt
				}
				memo[nr][nc] = 1;
				moveCnt++;
				playCnt--;
			}
			memo[nr][nc] = 1;
			queue.push([nr, nc]);
		}
		return moveCnt
	}
	
	const goormMemo = Array.from(Array(n), () => Array(n).fill(0));
	const goormResult = play([goormS], goormMemo)
	
	const playerMemo = Array.from(Array(n), () => Array(n).fill(0));
	const playerResult = play([playerS], playerMemo)
	
	if (goormResult > playerResult) {
		console.log("goorm", goormResult)
	} else {
		console.log("player", playerResult)	
	}
})

이 문제 시뮬레이션 이해를 잘 못하고 처음에 잘못 풀었다가 도저히 그 코드를 고칠 자신이 없어서

새로 풀었다.. 그런데 분명 이번엔 이해도 했고 로직도 맞는데 계속 틀리는 것..

결국 정해 코드를 봤는데도 내가 푼 거랑 로직상 별 다를 게 없어보였다.

 

어디가 잘못된 지 모르고 있는데 Number로 받아야 하는 변수를 String으로 받고 있는 것을 일상이가 찾아줌

일단 문제가 심각했는데 sprit()을 통해 문자열과 숫자를 구분해서

1R 의 경우 js의 타입 추론으로 Number가 되어 -- 연산자가 먹은 것 같은데 (어떻게 맞은지 모르겠지만 테케가 맞음)

12R 의 경우 sprit()을 통해 문자열과 숫자를 구분할 수 조차 없음

 

substr과 slice를 사용해서 다시 변수를 잘 설정하고..

제출하니 바로 맞았다. ㅠ_ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

따흑

 

 

문제 15. 과일 구매

let lines = [];
let N, K;
let P = [];
let C = [];

rl.on('line', (line) => {
	lines.push(line.trim());
});

rl.on('close', () => {
	[N, K] = lines[0].split(' ').map(Number);
	P[0] = 0;
	C[0] = 0;

	for (let i = 1; i <= N; i++) {
		[P[i], C[i]] = lines[i].split(' ').map(Number);
	}

	const slices = {}
	for (let i=1; i<=N; i++) {
		const sliceValue = C[i] / P[i]
		if (slices[sliceValue]) {
			slices[sliceValue].push(P[i])
		} else {
			slices[sliceValue] = [P[i]]
		}
	}
	
	let result = 0;
	const sortedFruits = Object.entries(slices).sort((a, b) => b[0] - a[0]);
	for (let i=0; i<sortedFruits.length; i++) {
		const fullness = sortedFruits[i][0]
		const prices = sortedFruits[i][1]
		const fruitPrices = prices.sort((a, b) => b-a);
		for (let j=0; j<fruitPrices.length; j++) {
			const canUse = fruitPrices[j]
			if (K < canUse) {
				result += fullness * K
				K -= K
				console.log(result)
				return;
			}
			result += fullness * canUse
			K -= canUse
		}
	}
	console.log(result)
});

모든 과일의 가격은 포만감 수치와 배수 관계에 있고 모든 과일은 쪼갤 수 있으므로

가장 가성비가 좋은(가격대비 포만감이 높은) 애들을 모아서 가성비 순서대로 정렬하고

그 가성비 중에서도 가장 가격이 비싼 애들이 앞으로 오게 정렬한다.

 

그리고나면 이 순서대로 과일을 하나씩 사면서 가진 돈을 깎은 뒤

가진 돈보다 과일의 값이 크면 과일을 쪼개서 남은 돈만큼 사버린다.

 

 

이제 지난주까지 밀린 문제 끝.. 하지만 이번 주 그래프 문제들도 왕창 밀려버림 ~