코딩 테스트/기타 : 인터넷 바다

[S2 - 릴레이 블로깅 챌린지 -] Daily Coding 오답 노트 정리

감귤밭호지차 2023. 4. 17. 21:01

데일리 코딩을 풀며 정확히 이해하지 못했거나 틀린 문제로 남겨두었던 문제들을 Section이 끝난 기념으로 총 정리 해보았습니다. 

** 13번 과 17번은 미해결 문제 입니다.. 

 

 

  Problem 04                                                                                                                                      

# 각 문자열의 첫 글자로 이루어진 문자열 리턴 
- Ex. 입력 : 'hello world" 출력 : "hw"
function firstCharacter(str){
	const answer = str.split(' ');
    let arr = [];
    let result = [];
    
    if( str.length === 0) {
    return '';
    }
    
    for( let i fo answer){ 
    	arr = i.split('');
        for( let j = 0 ; j <1; j++){ //맨 첫 글자만 필요함 
        	result.push(arr[j]);
        }
    }
    
    result = result.join(''); //배열을 다시 문자열로 합치기
    return result;
}​

# 1차 풀이 

입력 받은 문자열들을 이중 for문을 돌면서 각 문자열의 첫 번째 요소에 접근 후 새로운 배열에 넣어주었다. 그리고 join 메서드로 다시 문자열로 합치는 과정을 통해 테스트를 통과 


function firstCharacter(str) {
  if (str === '') {
    return '';
  }

  let words = str.split(' ');
  let result = '';
  for (let i = 0; i < words.length; i ++) {
    result += words[i][0];
  }
  return result;
}


# 2차 풀이 :
굳이 이중 for문을 돌릴 필요 없이 이차원 배열로 각 요소의 첫 번째 요소를 뽑아서 문자열 변수 result에 바로 넣어줄 수 있다.  

 

 

 

  Problem 10                                                                                                                                     

# 문자열을 입력 받아 연속된 한 자리 홀수 숫자 사이에 '-' 을 추가한 문자열을 리턴해야 한다. 
- EX  입력 : '454793'  출력 : 4547-9-3
function insertDash(str) {
 let result = str[0];

 for( let i = 1 ; i<str.length; i++){
   if( Number(str[i-1])%2 !== 0 && Number(str[i])%2 !== 0 ){
     result = result + '-';
   }
   result = result + str[i];
 }

 return result;
 
}

# 1차 풀이 :

문자열의 [0] 요소를 미리 result 변수 안에 선언을 해준 뒤, for문을 통해 문자열의 요소에 접근을 시도합니다. 
만약 이전 요소와 다음 요소가 모두 홀수라면 if문 에서 ' - ' 을 추가한 후 str[i]을 넣는 방식으로 진행합니다. 홀수가 아니라면 if문을 건너띄고 바로 str[i]를 집어넣습니다. 

** for문을 돌릴 때 이미 str[0]가 result 변수 안에 있으므로 str[1] 번재 요소부터 진행하는 것이 좋을 듯 합니다. 

 

 

  Problem 12                                                                                                                                     

# 이중 for문으로 각 행의 각 열 요소에 접근하기 
let arr = [
	['a', 'a', 'b'],
    ['a', 'a,' 'a'],
    ['a', 'a', 'a'],
];

for( let i = 0 ; i < arr.lenfth; i++){
	for( let j = 0; j < arr[i].length; j++)}{   // 1. 1차 실수
    	if( arr[i][j] === 'b'){                   // 2. 2차 실수
        	console.log( [i, j] );           // [0, 2]
        }
    }
}​

# 1차 실수
i 행을 돌면서 그 안에 요소에 접근하기 위해서 단순히 i.length  길이 만큼 돌려버렸으나, 이는 첫 번째 행의 경우 0 만큼 돌고 두번째 행은 1까지만 돌리는 결과가 되어버렸습니다. 
arr[i] 처럼 배열의 길이로 지정을 해주어야 우리가 원하는 결과를 얻을 수 있습니다. 

# 2차 실수 : 

단순히 arr[j] 만 원하는 값인 'b' 를 찾는 if문 을 조건으로 지정하였으나, 그렇게 되면 계속 'undefined ' 가 출력 됩니다. 
아마도, arr은 이차원 배열이기 때문에 i 행의 j 요소라는 정확한 위치를 지정하여 if문을 걸어야 하는 것 같습니다. 

참고 블로그 : 1,2차원 배열 선언 및 초기화

 

 

 

  Problem 13                                                                                                                                     

# 13번 readVertically
- 문자열을 요소로 갖는 배열을 입력 받아 문자열을 세로로 읽었을 때의 문자열을 리턴해야 합니다. 
- ex. 입력 : [ 'hello', 'world']  출력 : 'hweolllrod'


# 1차 풀이


function readVertically(arr) {
  let temp = [];
  for (let i = 0; i < arr.length; i++) {
    let str = arr[i];
    for (let j = 0; j < str.length; j++) {
      if (temp.length === j) {
        temp.push(str[j]);
      } else {
        temp[j] = temp[j] + str[j];
      }
    }
  }

  let result = '';
  for (let i = 0; i < temp.length; i++) {
    result = result + temp[i];
  }

  return result;
}​

# 2차 풀이 - 레퍼런스 

잘 모르겠다.

 

 

 

  Problem 17                                                                                                                                     

# 수를 입력 받아 제곱근 값을 소수점 두 자리까지 리턴
Ex. 입력 : 9 출력 : 3 ,   입력 : 6  출력 : 2.45 
function computeSquareRoot(num) {
  let answer = 0;
  for( let i = 1 ; i <= num/2; i++){
    if( i* i === num){
      answer = i;
    }
  }
  
  answer = (num/2).toFixed(2) // 1차 실수

  return answer;
}

# 1차 실수 : 

단순히 나눠서 소수점 2자리까지 출력하게 하면 안되었습니다.. 

function computeSquareRoot(num) {
  const diffs = [1, 0.1, 0.01, 0.001];
  let base = 1;
  for (let i = 0; i < diffs.length; i++) {
    while (base * base < num) {
      base = base + diffs[i];
    }

    if (base * base === num) {
      return base;
    } else {
      base = base - diffs[i];
    }
  }
  return Number(base.toFixed(2));
}​

# 2차 풀이 - 레퍼런스 -
잘 모르겠다.

** 바빌로니아 법 - 제곱근을 구하는 방법 중 하나 (바빌로니아 법의 점화식)

 

 

  Problem 18                                                                                                                                     

# 문자열을 입력받아 문자열에서 숫자를 모두 더한 뒤 해당 값을 문자열의 길이로 나눈 값을 정수로 반올림하여 리턴 
- Ex 입력 : 'Hello6' 출력 : 1  --> 문자 길이 6  / 문자열 내 숫자 6  :: 6 / 6 = 1

function numberSearch(str) {
  let sum = 0;
  let arr = [];
  const digits = '0123456789';
  let answer = 0; 
  let cnt = 0;

  if(str === ''){
    return 0;
  }

  arr = str.split('');
  for( let i = 0 ; i < arr.length; i++){
    if( digits.includes(arr[i])){
      sum += Number(arr[i]);
      cnt++;
    }
    if(arr[i] === ' '){
    cnt ++;
    }
  }

  return (Math.round(sum/(str.length-cnt)));
  
}​

# 1차 풀이 
digits 변수에 string 타입의 0 - 9 을 미리 선언을 한 뒤 includes 함수를 이용해서 각 for문의 요소가 digits 변수와 겹치는 부분이 있는지를 거른 뒤에 해당 요소를 Number() 로 타입을 변환하여 sum에 누적 덧셈을 해줍니다. 
* sum = 문자열 요소 내의 숫자 부분을 누적 더한 값 

같은 if 문 안에서 cnt 요소의 후위 증가를 해줌으로써 숫자를 찾을 때마다 카운트 , 그리고 바깥 if 문 조건에서 공백 부분을 찾을 때도 카운트를 해줌으로써 나중에 최종 str.length에서 공백과 숫자를 뺀 길이를 알 수 있습니다. 

마지막에 문제에서 원하는 조건에 맞추어 Math.round(반올림 )메소드를 사용하여 값을 return 해주었습니다. 



function numberSearch(str) {
  const digits = '0123456789';

  if (str === '') {
    return 0;
  }

  let sum = 0;
  let pureStr = '';
  for (let i = 0; i < str.length; i += 1) {
    if (digits.includes(str[i])) {
      // 숫자인 경우
      sum = sum + Number(str[i]);
    } else if (str[i] !== ' ') {
      // 숫자도 공백도 아닌 경우 *************
      pureStr = pureStr + str[i];
    }
  }

  // 결과를 반올림 한다.
  return Math.round(sum / pureStr.length);
}​

 


# 2차 풀이 - 레퍼런스
else if 문 조건으로 첫 번째 조건에서 숫자인 경우를 거르고 공백도 아닌 경우를 거름으로써 1차 풀이의 str.length - cnt 를 간편하게 pureStr 로 구할 수 있게 되었습니다. 

 

 

  Problem 19                                                                                                                                     

# 암호화된 문자열과 암호화 키를 입력 받아 복호화된 문자열을 리턴해야 합니다. 
** 카이사르 암호(Caesar cipher)는 평문(plaintext)을 암호화키 갯수만큼 오른쪽으로 평행 이동 시켜 암호화 합니다.
- Ex 입력 : 'hello'  / secret : 3  출력 : 'khoor'
   * h --> k       * e --> h       * l--> o   * o --> r  
function decryptCaesarCipher(str, secret) {
  str = str.toUpperCase();
  let newStr = '';

  for( let i = 0 ; i< str.length; i ++){
    if(str[i] === ' '){
      newStr += ' ';
    } else{
      newStr += String.fromCodePoint(str.charCodeAt(i)-secret);
    }
  }
  return newStr.toLowerCase();
}
# 1차 풀이 - 레퍼런스
문자를 아스키코드로 변환하는 charCodeAt ()과 반대인 String.fromCodePoint()메서드를 사용하려 하였으나 실패.
이유는 secret 에 할당 되는 숫자가 아스키코드 기준인  'A' 65 이하로 넘어가면 다른 문자나 기호로 변화되기 때문에 몇 예제들은 테스트를 통과하지 못합니다.



function decryptCaesarCipher(str, secret) {
  // 알파벳
  let alpha = 'abcdefghijklmnopqrstuvwxyz';

  let result = '';
  for (let i = 0; i < str.length; i++) {
    if (str[i] === ' ') {
      // 공백은 그대로 둔다.
      result = result + ' ';
    } else {
      // 현재 문자의 알파벳 순서를 구한다.
      let asis = alpha.indexOf(str[i]);
      // 복호화는 반대 방향으로 이루어기 때문에 seceret을 뺀다.
      let tobe = (asis - secret + alpha.length) % alpha.length;
      result = result + alpha[tobe];
    }
  }

  return result;
}​



# 2차 풀이 - 레퍼런스

첫 번째 조건문의 공백은 그대로 공백으로 넣어주는 것 까지는 동일하지만 두 번째 else 문에서부터 다릅니다. 
for문으로 순회하는 str[ i ] 가 미리 선언한 alpha 변수의 값과 일치하는 순서를 indexOf 메서드를 통해 asis 변수에 할당합니다. 예를 들어, str[ i ]가 ' b '라면 asis의 ' b '의 위치인 1 이 asis에 할당됩니다. 이를 가지고 - secret 을 통해 원래의 평문을 추측할 수 있습니다. 


[1] tobe 변수에서 1차 풀이에서 실패한 기준 문자열 이후로 넘어가는 문제를 ( asis - secret + alpha.length )를 통해 a 뒤로 숫자가 넘어가도 다시 알파벳의 끝에서부터 역순으로 원하는 값에 접근할 수 있게 되었습니다.

[2] 반대로 기준 a 를 넘어가지 않더라도 마지막에 % alpha.length를 통해 앞에서부터 원하는 값에 접근할 수도 있습니다. 


indexOf   [0] [1] [2] [3] [4]  ...  [23]  [24]  [25]
alpha         b    c      ...    x       y      z       ( 총 갯수 : 26개 )


>> str [ i ] = 'e' , secret = 3 일 때, 
asis = 4가 되고, tobe = ( 4 - 3 + 26) % 26;  = 1 이므로 alpha[ tobe = 1 ] 는 b 가 됩니다. 원하는 조건인 e 왼쪽으로 3칸 이동한 b 를 알맞게 찾은 것을 알 수 있죠. 


>> str[ i ] = 'a' , secret = 3 일 때, 
asis = 0 이 되고, tobe = ( 0 - 3 + 26 ) % 26; = 23 이므로 alpha [ tobe = 23 ] 는 x 가 됩니다. 원하는 조건인 a 왼쪽으로 3칸 이동한 x 를 알맞게 찾았습니다. 



최종적으로 result 에 alpha 변수에 저장 된 문자열들의 알맞은  순서들을 누적 하여 모든 테스트를 통과할 수 있습니다. 

 

 

  Problem 20                                                                                                                                     

# 문자열을 입력 받아 3개 이상 연속되는 문자가 있을 경우, 압축하여 리턴 해야 합니다. 
- Ex 입력 : 'wwwggoppopppp'  출력 : 3wggoppo4p

function compressString(str) {
  let count = 0;
  let arr = [];
  let w = str;

  if( str.length === 0){
    return ''
  }

  for (let i = 0; i < w.length; i++) {
    let j = w[0];
    if (j === w[i]) {
      count++;
      if (count >= 3) {
        w = w.substring(count);
        arr.push(`${count}${j}`);
        count = 0;
      }
    }
  }

  return arr.join('');
}​
# 1차 풀이 
자꾸 3w 무한 출력이 됩니다. 


function compressString(str) {
  //빈 문자열 처리
  if( str === ''){return ''};

  let check = str[0];
  let cnt = 1;
  let answer = ''; 

  // ** str의 마지막이 연속되는 숫자일 경우, 
  // 끊어주기 위해 공백 추가 
  str = str + ' ';
  for( let i = 1; i < str.length; i++){
    if(check === str[i]){
      cnt++;
    }else{
      //이전과 다른 문자일 경우, 
      if( cnt >= 3){
        answer += `${cnt}${check}`;
      } else {
        // cnt 3 미만은 cnt 갯수만큼 반복해서 집어 넣기 
        answer += check.repeat(cnt);
      }
      // 이전과 다른 문자이므로 값 초기화 및 새로운 check 할당
      check = str[i];
      cnt = 1;
    }
  }
  return answer;

}

# 2차 풀이 
우선 입력 받을 str의 마지막 부분이 연속되는 문자열일 경우, str 뒤에 공백을 추가해주지 않으면 마지막 연속되는 부분은 else 문에 걸러지지 않아 cnt ++만 수행되고 answer에는 누적되지 않아 반드시 공백으로 끊어주어야 합니다. 


** 연속되는 문자의 비교를 위해 check 변수에 문자열의 첫 번째 요소를 할당 합니다. check = str[ 0 ]; 


for문으로 문자열의 각 요소에 접근하며 check 의 값과 순차적으로 접근하는 문자열 요소의 값이 같으면 cnt ++를 수행합니다. 그러다 check와 다른 문자열을 만나게 되면 else 문으로 넘어가게 됩니다. 

이후 누적된 cnt의 값이 3개 이상일 경우 누적된 cnt 값과 해당 문자열인 check 를 함께 출력할 빈 문자열 answer 변수에 넣어줍니다. 반면에 cnt의 값이 3개 미만일 경우 repeat( ) 메소드를 사용하여 cnt의 갯수만큼 반복해서 answer 변수에 넣어줍니다. 


>> cnt = 2 일 때, check = 'o' 일 경우, 
repeat 메소드에 의하여 answer += ' oo ' 이 할당 됩니다. 


else 문 안의 if 조건문을 빠져나오며 모든 값을 초기화 해줌으로써 기존의 연속된 문자열 이후의 새로운 각 문자열들이 동일한 조건들을 순회 할 수 있게 해줍니다. 



 

 

20번 문제 1차 풀이에서 나온 무한 3w 슈슈슉 

피라미드를 이렇게 구현...?