[알고리즘 풀이_Lv0] 외계어 사전, 문자열 밀기, 컨트롤 제트, 등수 매기기
*제주코딩베이스캠프의 JavaScript 알고리즘 100일 챌린지를 참고로 정리하고 있습니다.*
외계어 사전_28번째
문제
https://school.programmers.co.kr/learn/courses/30/lessons/120869
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
PROGRAMMERS-962 행성에 불시착한 우주비행사 머쓱이는 외계행성의 언어를 공부하려고 합니다.
알파벳이 담긴 배열 spell과 외계어 사전 dic이 매개변수로 주어집니다.
spell에 담긴 알파벳을 한번씩만 모두 사용한 단어가 dic에 존재한다면 1,
존재하지 않는다면 2를 return하도록 solution 함수를 완성해주세요.

해결방안
이런 문제는 일반적으로 Set을 사용해서 풀지만
간혹 Set으로 풀 수 없는 문제가 발생한다.
그럴 때는 sort를 사용해서 풀어야 된다.
some은 조건을 만족할 경우 true 아닐 경우 false를 반환한다.
[1, 2, 3, 10, 20].some(v => v < -2) // false
[1, 2, 3, 10, 20].some(v => v === 2) // true
// every의 경우에는 모든 원소가 다 맞아야된다.
[1, 2, 3, 10, 20].every(v => v === 2) // false
function solution(spell, dic) {
// 배열만 sort가 된다. -> 문자열을 전개해야된다.
return dic.some((v) => [...v].sort() === [...spell].sort()) ? 1 : 2;
}
예#2에서는 true 1이 나와야 되지만, 이렇게만 쓰면 false가 나온다.
spell = ["z", "d", "x"], dic = ["def", "dww", "dzx", "loveaw"]
function solution(spell, dic) {
return dic.forEach(v => {
console.log([...v].sort() === [...spell].sort());
console.log([...v].sort());
console.log([...spell].sort());
})
}
// 출력 결과
false
[ 'd', 'e', 'f' ]
[ 'd', 'x', 'z' ]
false
[ 'd', 'w', 'w' ]
[ 'd', 'x', 'z' ]
false -> 원소가 같은데 false라고 출력이 된다.
[ 'd', 'x', 'z' ]
[ 'd', 'x', 'z' ]
false
[ 'a', 'e', 'l', 'o', 'v', 'w' ]
[ 'd', 'x', 'z' ]
배열을 비교하면 똑같이 생겨도 false가 나온다.
['d', 'x', 'z'] === ['d', 'x', 'z'] // false
[1, 2, 3] === [1, 2, 3] // false
이유. 주소값으로 비교하기 때문이다. (안에 원소 값이 같더라도)
해결. toString()을 사용해 주어 배열을 문자열로 바꾸고 비교해 준다.
function solution(spell, dic) {
// 배열만 sort가 된다. -> 문자열을 전개해야된다.
return dic.some((v) => [...v].sort().toString() === [...spell].sort().toString()) ? 1 : 2;
}
소스코드
function solution(spell, dic) {
return dic.some((v) => [...v].sort().toString() === [...spell].sort().toString()) ? 1 : 2;
}
문자열 밀기_29번째
문제
https://school.programmers.co.kr/learn/courses/30/lessons/120921
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문자열 "hello"에서 각 문자를 오른쪽으로 한 칸씩 밀고 마지막 문자는 맨 앞으로 이동시키면 "ohell"이 됩니다.
이것을 문자열을 민다고 정의한다면 문자열 A와 B가 매개변수로 주어질 때,
A를 밀어서 B가 될 수 있다면 밀어야 하는 최소 횟수를 return하고
밀어서 B가 될 수 없으면 -1을 return 하도록 solution 함수를 완성해보세요.

해결방안
"hello" "ohell" 1
"hello" "lohel" 2
"hello" "llohe" 3
hello를 2개를 엮으면 된다.
hellohello
"hello" "ohell" 1 => 4번째부터 있다. 5-4
"hello" "lohel" 2 => 3번째부터 있다. 5-3
"hello" "llohe" 3 => 2번째부터 있다. 5-2
hello의 길이 - 위치를 해주면 된다.
즉, A를 두 번 이어 주고 B의 위치를 찾아주고
A의 길이 - A를 2번 어이 준문자열에서 B가 시작하는 위치를 해주면 된다.
더 쉬운 방법
// B를 두번하고
ohellohell
// A를 비교
hello는 1번째부터 시작
lohellohel
hello는 2번째부터 시작
llohellohe
hello는 3번째부터 시작
B를 두 번 이어 주고 A의 위치를 찾는다.
function solution(A, B) {
return (B+B).indexOf(A);
}
indexOf에 해당되는 index가 없으면 -1을 반환한다.
소스코드
function solution(A, B) {
return (B+B).indexOf(A);
}
생각의 전환
[0, 0, 0, 0]
[0, 1, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
1이 주인공이라 했을 때 1을 아래칸으로 밀고 싶은 경우
순회하는 방법도 있지만 더 쉽게 하는 방법이 있다.
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
// [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 여기서
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0] 이만큼 이동해야됨
4칸 이후에 있는 index값을 1로 바꿔주면 된다. 나 자신을 0으로 만들어주고
컨트롤 제트_30번째
문제
https://school.programmers.co.kr/learn/courses/30/lessons/120853
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
숫자와 "Z"가 공백으로 구분되어 담긴 문자열이 주어집니다.
문자열에 있는 숫자를 차례대로 더하려고 합니다.
이 때 "Z"가 나오면 바로 전에 더했던 숫자를 뺀다는 뜻입니다.
숫자와 "Z"로 이루어진 문자열 s가 주어질 때, 머쓱이가 구한 값을 return 하도록 solution 함수를 완성해보세요.

소스코드
function solution(s) {
s = s.split(' ');
let result = [];
for(let i of s){
if(i==='Z'){
result.pop();
}else{
result.push(+i);
}
}
return result.reduce((a,c) => a+c, 0)
}
생각의 전환
"110Z3"
이렇게 주어지고 1~10까지의 숫자를 판단해야 되는 경우
정규식으로 1~10를 판단해 주거나
1 다음 0이 나오면 10이라는 것을 인식해 주면 된다.
지금 소스코드에서 if문은 더 추가하면 된다.
현재값이 1이고 다음값이 0일 경우 10으로 교체
등수 매기기_31번째
문제
https://school.programmers.co.kr/learn/courses/30/lessons/120882
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
영어 점수와 수학 점수의 평균 점수를 기준으로 학생들의 등수를 매기려고 합니다.
영어 점수와 수학 점수를 담은 2차원 정수 배열 score가 주어질 때,
영어 점수와 수학 점수의 평균을 기준으로 매긴 등수를 담은 배열을 return하도록 solution 함수를 완성해주세요.

해결방안
합(영어+수학)이나 평균((영어+수학)/2)이나 같다.
즉 영어수학의 합을 정렬하거나 영어수학의 평균을 정렬하면 같은 값이 나온다.
function solution(score) {
// 합(영어+수학)이나 평균((영어+수학)/2)이나 같다.
let 총합 = score.map(v => v[0] + v[1])
let 정렬된배열 = 총합.sort((a,b)=>b-a)
return 총합.map(v => 정렬된배열.indexOf(v));
}
이렇게 쓰면 실행결과가 엉망이 된다.

이유. sort (sort는 원본배열을 만지기 때문이다.)
해결. slice()사용하기 → 총합 !== 정렬된배열로 만들어야 된다.
function solution(score) {
// 합(영어+수학)이나 평균((영어+수학)/2)이나 같다.
let 총합 = score.map(v => v[0] + v[1])
let 정렬된배열 = 총합.slice().sort((a,b)=>b-a)
return 총합.map(v => 정렬된배열.indexOf(v)+1);
}
소스코드
function solution(score) {
let 총합 = score.map(v => v[0] + v[1])
let 정렬된배열 = 총합.slice().sort((a,b)=>b-a)
return 총합.map(v => 정렬된배열.indexOf(v)+1);
}