[Lv.1][1차] 다트 게임
문제 : https://programmers.co.kr/learn/courses/30/lessons/17682
🔶 내가 한 방법
function solution(dartResult) {
const result = [0, 0, 0];
const bonus = { S: 1, D: 2, T: 3 };
// 0. 점수|보너스|[옵션] 대로 각각 배열의 요소로 만든다.
const rx2 = /\d{1,2}[A-Z]["*"|"#"]?/g;
const arr = dartResult.match(rx2).map((el) => el); // ['1D', '2S#', '10S']
for (let i = 0; i < arr.length; i += 1) {
// arr의 각 요소를 돌면서 요소마다
// 1. 숫자만 찾아, result 배열에 담는다.
result[i] = +arr[i].match(/\d{1,2}/g); // 1, 2, 10
// 2. S,D,T를 찾아 제곱한다
const b = arr[i].match(/[A-Z]/g); // D, S, S
result[i] **= bonus[b[0]];
// 3.옵션 있으면, *(직전 점수와 해당점수에 2곱하고), #(해당점수 -1 곱한다)
const op = arr[i].match(/["*"|"#"]$/g); // null, # , null
if (op) {
// *
if (op[0] === '*') {
result[i] *= 2;
if (result[i - 1]) {
result[i - 1] *= 2;
}
}
// #
if (op[0] === '#') {
result[i] *= -1;
}
}
}
return result.reduce((acc, cur) => acc + cur);
}
// 실행코드
console.log('1:', solution('1S2D*3T')); // 37 ←11 * 2 + 22 * 2 + 33
console.log('2:', solution('1D2S#10S')); // 9 ←12 + 21 * (-1) + 101
console.log('3:', solution('1D2S0T')); // 3 ←12 + 21 + 03
console.log('4:', solution('1S*2T*3S')); // 23 ←-11 * 2 * 2 + 23 * 2 + 31
console.log('5:', solution('1D#2S*3S')); // 5 ←12 * (-1) * 2 + 21 * 2 + 31
console.log('6:', solution('1T2D3D#')); // -4 ←13 + 22 + 32 * (-1)
console.log('7:', solution('1D2S3T*')); // 59 ←12 + 21 * 2 + 33 * 2
🔶 다른 사람 풀이
function solution(dartResult) {
const bonus = { S: 1, D: 2, T: 3 };
const options = { '*': 2, '#': -1, '': 1 };
// 1.정규식으로 ['1S', '2D*', '3T'] 만들기
const darts = dartResult.match(/\d{1,}[SDT][*#]?/g); // 방법1 -\d{1,}(한자리 수 이상 숫자 추출함), [SDT](S,D,T 중 문자하나), [*#](*,# 중 문자하나), ?(있을수도 없을수도 있음)
// const darts = dartResult.match(/\d.\D?/g); // 방법2 - \d(0-9숫자 다 추출함), .(any sigle character), \D( 숫자가 아닌 문자), ?(있을수도 없을수도 있음)
for (let i = 0; i < darts.length; i += 1) {
// 2. 각 요소를 돌면서 숫자,문자,특수문자를 각각 변수로 만듦.
const [, digit, b, op] = darts[i].match(/(\d{1,})([SDT])([*#]?)/);
// ['1S', '1', 'S', '', index: 0, input: '1S', groups: undefined]
// console.log(digit, b, op); // digit :1, S / b :2 D * / op:3 T
const score = digit ** bonus[b] * options[op];
// 3. option이 *이면 직전 점수도 2곱해줌
if (op === '*' && darts[i - 1]) {
darts[i - 1] *= options['*'];
}
darts[i] = score;
}
return darts.reduce((a, b) => a + b);
}
function solution(dartResult) {
const reg = /[\d]+[SDT][*#]*/g;
// [\d](0-9중 숫자 한개), +(한개 이상), [SDT](S,D,T 중 한개) , [*#](*,#중 한개), *(0개 이상)
// +(1개 이상) *(0개 이상)
const darts = dartResult.match(reg); // ['1D', '2S#', '10S']
const result = [];
for (let i = 0; i < darts.length; i += 1) {
let number = darts[i].match(/[\d]+/g)[0];
const bonus = darts[i].match(/[SDT]/g)[0];
const option = darts[i].match(/[*#]/g);
switch (bonus) {
case 'S':
number **= 1;
break;
case 'D':
number **= 2;
break;
default:
number **= 3;
}
result[i] = number;
if (option) {
switch (option[0]) {
case '*':
result[i - 1] *= 2;
result[i] *= 2;
break;
default:
result[i] *= -1;
}
}
}
return result.reduce((acc, cur) => acc + cur);
}
🔶 피드백
1. 정규식, 문자 추출(캡쳐그룹) 잘 몰랐음.
-
캡쳐그룹 이란?
1) 정규식 또는 matches 배열 내의 ID로 나중에 참조될 전체 일치의 일부를 분리합니다.
2) ID는 1부터 시작합니다. ←[전체패턴, 1번그룹매치($1), 2번그룹 매치($2) ...] 이런 식으로 나옴
3) 정규식에 글로벌(/g) 플래그가 포함되어있지 않으면 캡쳐그룹이 안됨. -
설명
1)match는 유사배열로 반환됨(배열안에 내용의 자료형은 "문자"임 [""])
-첫 번째 요소는 정규식에 매치된 "전체 문자열", 두번째부터는 괄호로 "추출된 문자열"~이 나옴.
2)() 괄호는 String.prototype.match 호출 시 RegExpMatchArray로 유사배열로 "추출됨".
3)괄호를 추출하지 않고 싶다면 (?:...) 를 사용해서 무시할 수 있음.
const arr = "abcdef00".match(/ab(?:cd|ef)(e)(f)(00)/);
console.log(arr); // ["abcdef00", "e", "f", "00"] ← ?:를 붙여 cd또는 ef를 추출하지 않음.
4)global에서는 추출이 안됨.(mdn :캡처된 그룹은 반환되지 않습니다.)
:g쓰면 괄호 추출은 의미가 사라지고, 그냥 정규식 패턴에 맞는 텍스트를 모두 찾아
유사배열로 반환함(그냥 ()없이 쓰는거랑 똑같이 됨.)
console.log("a12bc3a1".match(/a(\d)/)); //["a1", "1"] ←() 지정된게 1개 추출됨
console.log("a12bc3a1".match(/a(\d)/g)); //["a1", "a1"] ←()가 추출되지 않음.★
2. 정규식으로 1D2S#10S → ['1D', '2S#', '10S'] 만드는 법 - 방법3개
// <방법1>
const dartResult = '1D2S#10S';
const darts = dartResult.match(/\d{1,}[SDT][*#]?/g);
// \d(0-9 중 한개), {1,}(한개 이상 숫자 추출함),
// [SDT](S,D,T 중 문자하나), [*#](*,# 중 문자하나), ?(있을수도 없을수도 있음)
// <방법2>
const dartResult = '1D2S#10S';
const darts = dartResult.match(/\d.\D?/g);
// \d(0-9 중 한개), .(문자 중 하나), <- 1D, 2S, 10 나옴
// \D('0' ~ '9'가 아닌 문자 즉,숫자가 아닌 문자), ?(있을수도 없을수도 있음) <- "", # , S
// <방법3>
const dartResult = '1D2S#10S';
const reg = /[\d]+[SDT][*#]*/g;
const darts = dartResult.match(reg);
// [\d](0-9중 숫자 한개), +(한개 이상), [SDT](S,D,T 중 한개) ,
// [*#](*,#중 한개), *(0개 이상)
// +(1개 이상) *(0개 이상)
3. 예제
- '880925-1184015' → '1988 남자'으로 반환하기
function jumin(str) {
let year = '';
let gender = '';
let [, second, third] = str.match(/(^\d{2})\d{4}-(\d)/); // ["880925-1", "88(추출)", "1(추출)"] ["940207-2", "94(추출)", "2(추출)"]
year = second[0] <= '2' ? `20${second}` : `19${second}`; // second는 88임, second[0]은 8
gender = third === '1' ? '남자' : '여자';
console.log(`${year} ${gender}`);
}
jumin('880925-1184015'); // 1988 남자;
jumin('100207-2188107'); // 1994 여자;
Author And Source
이 문제에 관하여([Lv.1][1차] 다트 게임), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jhplus13/Lv.11차-다트-게임저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)