TIL: 2022-05-14 알고리즘 day 2

김하연·2022년 5월 15일
0

TIL: Today I Leaned

목록 보기
5/27

1. 내적

길이가 같은 두 1차원 정수 배열 a, b가 매개변수로 주어집니다. a와 b의 내적을 return 하도록 solution 함수를 완성해주세요.

이때, a와 b의 내적은 a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의 길이)

예시

입출력 예

a			  b				  result
[1,2,3,4]	  [-3,-1,0,2]	  3
[-1,0,1]	  [1,0,-1]		  -2

입출력 예 #1
a와 b의 내적은 1*(-3) + 2*(-1) + 3*0 + 4*2 = 3 입니다.
입출력 예 #2
a와 b의 내적은 (-1)*1 + 0*0 + 1*(-1) = -2 입니다.

내가 작성한 solution.js

function solution(a, b) {
    var answer = 1234567890;
    return answer = a.reduce((acc,cur,idx) => acc = acc + cur*b[idx], 0);
}

이 문제는.. 문제를 이해는 것 부터가 문제였다..ㅋㅋㅋㅋㅋ 내적?? 내적이 대체 뭐야...???
나의 내적 갈등을 일으킨 문제...^^
수포자인 나한테는 자연수, 정수, 유리수, 실수 이해는것조차 힘든데.. 아무튼 내적이 뭔지 몰라서 당황좀 했는데 입출력 예시에 대충 공식이 나와있어서 참고해서 풀었다.
어제 팀원분들이랑 같이 문제 해설 하면서 reduce 함수의 강력한 힘을 실감하고 오늘 응용해보고 싶었다. 나름 화살표 함수까지 사용해서 최대한 간결하게!
reduce함수 관련 링크는 어제 팀원분께서 reduce 학습을 추천하며 보내주신건데, 아래 표현이 너무 재밌었다 ㅋㅋㅋㅋ

이와 같이 sort, every, some, find, findIndex, includes도 다 reduce로 구현 가능합니다. reduce가 이들 모두의 아버지였던 것입니다. ㅠㅠ



2. 문자열 내 p와 y의 개수

대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.

예를 들어 s가 "pPoooyY"면 true를 return하고 "Pyy"라면 false를 return합니다.


내가 작성한 solution.js

function solution(s){
    var answer = true;
    let sArr = s.split('');
    let obj = {};
    sArr.reduce((acc,cur)=>{
        obj[cur.toUpperCase()] = obj[cur.toUpperCase()] === undefined ? 1 : obj[cur.toUpperCase()]+=1;
    },0)
    return answer = obj['P'] === 0 && obj['Y'] === 0 ? true : obj['P'] === obj['Y'] ? true : false;
}

reduce의 유용성을 깨달은 뒤로 일단 문제를 보면 이건 reduce로 활용이 가능할까? 부터 생각하고있다..ㅋㅋ 이걸 이렇게 남발(?)해도 되나 싶어서 for, foreach, filter, map, reduce등 반복문들의 성능을 찾아봤다.

검색해보니 for문 다음으로 reduce의 처리 속도가 앞서는걸 확인했고 그렇다면 앞으로 조금 더 reduce 함수를 남발해도 될 것 같다는 결론을 얻었다..ㅎㅎㅋ
근데 가장 원시적인 느낌의 for문이 가장 앞서는걸 보니 기본은 역시 무시할 수 없나보다 하는 생각도..?!

아무튼, 이번 문제는 reduce도 사용하고 삼항연산자까지 사용해서 다른 고수들이 코드 줄이는 방법을 좀 따라해보려고 했는데.. 길이는 줄었을지 몰라도 가독성이 떨어져서 별로인 것 같다. 코드 형태도 가로방향으로 길어졌을 뿐 간결한 코드인가..? 라고 생각해보면 그것도 아닌 것 같고?!

간결함 + 가독성 두마리 토끼를 잡으려면 정말 많은 공부가 필요할 것 같다.😓

그러고 발견한 어느 고수의 코드...

function numPY(s){
  //함수를 완성하세요
    return s.toUpperCase().split("P").length === s.toUpperCase().split("Y").length;
}

다른사람들의 코드를 참고하면 정말 좋은게, 함수들의 다양한 응용 방법을 학습할 수 있어서 좋은 것 같다. split은 그냥 배열이 아닌 애들을 배열로 만들어주는 명령어일 뿐이라고 생각했는데, 이렇게 활용을 할 수가 있다니..????
P, Y를 기준으로 잘라서 만들어지는 배열의 length값을 비교하는 방법.
P랑 Y의 갯수가 같으면 당연히 새로 생성된 배열의 length값도 같을테니 진짜 신박한 방법인 것 같다.




3. 서울에서 김서방 찾기

String형 배열 seoul의 element중 "Kim"의 위치 x를 찾아, "김서방은 x에 있다"는 String을 반환하는 함수, solution을 완성하세요. seoul에 "Kim"은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다.

이때, a와 b의 내적은 a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의 길이)

예시

입출력 예

seoul				return
["Jane", "Kim"]		"김서방은 1에 있다"

내가 작성한 solution.js

function solution(seoul) {
    var answer = '';
    let idx;
    for(let i=0; i<seoul.length; i++){
        if(seoul[i] === 'Kim'){
            idx = i;
        }
    }
    return answer = `김서방은 ${idx}에 있다`;
}

이건 비교적 쉬운 문제였던 것 같다. 'Kim'은 반드시 Seoul안에 있고, 한 번만 들어있다고 하니까 'Kim'의 인덱스만 찾으면 되는 문제라서 그냥 for문으로 해결했다.

function findKim(seoul){
  var idx = seoul.indexOf('Kim');
  return "김서방은 " + idx + "에 있다";
}

근데 역시나 고수들은 다르다...^^ indexOf() 로 바로 index 찾아버리기~~~
보는 순간 띠용 했다. 나 스스로도 '오 index만 찾으면 되잖아?' 라고 생각해놓고는 바로 index를 찾는 방법을 제쳐두고 for문을 돌려버림..
indexOf 를 아예 몰랐으면 우와 이런것도 있구나 하고 넘어갔을텐데, 알면서도 사용하지 못한게 더 아쉽다ㅠㅠ 배열만 보면 for문 돌릴 생각부터 하는 습관이 있는 것 같다.
명령어나 함수를 다양하게 활용하려고 생각해보자!!!!!!




4. 수박수박수박수박수박수?

길이가 n이고, "수박수박수박수...."와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 "수박수박"을 리턴하고 3이라면 "수박수"를 리턴하면 됩니다.

이때, a와 b의 내적은 a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의 길이)

예시

입출력 예

n	return
3	"수박수"
4	"수박수박"

내가 작성한 solution.js

function solution(n) {
    var answer = '';
    for(var i=1; i<n+1; i++){
        answer = answer + ((i%2) ? '박' : '수');
    }
    return answer;
}

n의 숫자만큼 for문을 돌려서 '수'와 '박'이라는 텍스트를 교차로 집어넣으면 될 것 같다고 생각했다.
1은 true, 0은 false와도 같다고 배워서 삼항연산자 조건에 (1%2)를 사용했고, (i%2)의 나머지가 1일 경우에는 true이니까 '수'를 집어넣고, 나머지 경우에는 '박'이 들어가도록 작성했다.

참고로, 1 == true, false == 0 이라는 조건은 정상 작동하지만,
=== 연산자는 보다 더 엄격하게 변수의 유형까지 고려하기 때문에 1 === true, 0 === false를 작성하면 1과 0은 유형이 number, true와 false는 boolean이라서 두 조건 모두 false값을 리턴한다.

1 == true // true
0 == false // true
1 === true // false (typeof 1은 'number', typeof true는 'boolean')
0 === false // false (typeof 0은 'number', typeof false는 'boolean')



5. 완주하지 못한 선수

길이가 n이고, "수박수박수박수...."와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 "수박수박"을 리턴하고 3이라면 "수박수"를 리턴하면 됩니다.

이때, a와 b의 내적은 a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의 길이)

예시

입출력 예

n	return
3	"수박수"
4	"수박수박"

내가 작성한 solution.js

function solution(participant, completion) {
    var answer = '';
    var obj = {};
    
for(var i=0; i<participant.length; i++){
	obj[participant[i]] = 0;
}
for(var i=0; i<participant.length; i++){
	obj[participant[i]] += 1;
}

for (var i=0; i<completion.length; i++){
	obj[completion[i]] -= 1;
}

for(var i=0; i<participant.length; i++){
	if(obj[participant[i]] !== 0){
		answer = participant[i]
	}
} 
    return answer;
}
function solution(n) {
    var answer = '';
    for(var i=1; i<n+1; i++){
        answer = answer + ((i%2) ? '박' : '수');
    }
    return answer;
}

n의 숫자만큼 for문을 돌려서 '수'와 '박'이라는 텍스트를 교차로 집어넣으면 될 것 같다고 생각했다.
1은 true, 0은 false와도 같다고 배워서 삼항연산자 조건에 (1%2)를 사용했고, (i%2)의 나머지가 1일 경우에는 true이니까 '수'를 집어넣고, 나머지 경우에는 '박'이 들어가도록 작성했다.

참고로, 1 == true, false == 0 이라는 조건은 정상 작동하지만,
=== 연산자는 보다 더 엄격하게 변수의 유형까지 고려하기 때문에 1 === true, 0 === false를 작성하면 1과 0은 유형이 number, true와 false는 boolean이라서 두 조건 모두 false값을 리턴한다.

1 == true // true
0 == false // true
1 === true // false (typeof 1은 'number', typeof true는 'boolean')
0 === false // false (typeof 0은 'number', typeof false는 'boolean')

0개의 댓글