DNA

문제

언어

  • JavaScript

순서도

  1. 주어진 DNA 들의 각 자리별로 각 문자의 개수를 세고, 가장 개수가 많은 문자로 그 자리를 결정
  2. 만약, 개수가 동일하다면 사전 순으로 먼저 오는 문자로 그 자리를 결정
  3. 그와 동시에 Hamming Distance 구하기
  4. 모든 자리에 대해서 위의 1, 2, 3 번 과정을 수행 후 만들어진 문자열을 출력

문제 풀이 step 1

  • DNA 는 서로 다른 4 가지의 뉴클레오티드로 이루어져 있습니다. (Adenine, Thymine, Guanine, Cytosine)
  • 우리는 어떤 DNA 를 표현할 때, 이 DNA 를 이루는 뉴클레오티드의 첫 글자를 따서 표현합니다. (TAACTGCCGAT)
  • 그리고 Hamming Distance 란 길이가 같은 두 DNA 가 있을 때, 각 위치의 뉴클레오티드 문자가 다른 것의 개수입니다.
    • 만약에 “AGCAT” 와 “GGAATT” 는 첫 번째 글자와 세 번째 글자가 다르므로 Hamming Distance 는 2 입니다.
  • 본 문제에서 원하는 것은 N 개의 길이가 M 인 DNA s1, s2, … sn 이 주어질 때, Hamming Distance 의 합이 가장 작은 DNA s 를 구하는 것입니다.
    • 즉, (s 와 s1 의 Hamming Distance) + (s 와 s2 의 Hamming Distance) + (s 와 s3 의 Hamming Distance) + … 의 합이 최소가 되는 경우의 s 를 구하는 것입니다.

문제 풀이 step 2

  • 주어진 DNA 들에 대해서 각 자리별로 각 문자의 개수를 셉니다.
  • 그 중에서 가장 개수가 많은 문자로 그 자리를 결정합니다.
  • 만약, 개수가 동일하다면 사전 순으로 먼저 오는 문자로 그 자리를 결정합니다.
  • 그리고 그 자리에 결정된 문자와 다른 문자의 개수인 Hamming Distance 를 갱신합니다.
  • 위의 과정을 모두 수행하면, Hamming Distance 의 합이 가장 작은 DNA s 가 나오게 되고, Hamming Distance 의 총합을 구할 수 있게 됩니다.
  • 추가 설명은 주석으로 작성하겠습니다.

후기

  • 영화 GATTACA 가 생각나서, 재미있게 풀 수 있었던 문제입니다.

소스 코드

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

const solution = (input) => {
	const [n, m] = input[0].split(" ").map(Number);

	let dna = "";
	let hammingDistance = 0;

	const arr = input.slice(1);
	for (let i = 0; i < m; i++) {
		let cnts = [
			["A", 0],
			["C", 0],
			["G", 0],
			["T", 0],
		];

		// 각 자리 별로 각 문자의 개수가 몇 개인지 세기
		for (let j = 0; j < n; j++) {
			if (arr[j][i] === "A") cnts[0][1] += 1;
			else if (arr[j][i] === "C") cnts[1][1] += 1;
			else if (arr[j][i] === "G") cnts[2][1] += 1;
			else cnts[3][1] += 1;
		}

		// 가장 많이 겹치는 문자 순으로 정렬하고, 만약 겹치는 개수가 동일하다면 사전순으로 정렬
		cnts.sort((a, b) => {
			const [ch1, cnt1] = a;
			const [ch2, cnt2] = b;

			if (cnt1 === cnt2) {
				if (ch1 < ch2) return -1;
				return 1;
			}
			return cnt2 - cnt1;
		});

		// 가장 많이 겹치며 사전순으로 앞서는 문자로 그 자리를 결정
		dna += cnts[0][0];

		// Hamming Distance 값 갱신
		hammingDistance += n - cnts[0][1];
	}

	return dna + "\n" + hammingDistance;
};

console.log(solution(input));