[항해99] Week 2 [6.27 - 7.2]

Hajun Song·2022년 7월 2일
0

Weekly I Learned

목록 보기
2/7
post-thumbnail

[항해99] Week 2 [6.27 - 7.2]

0. ✅마무리 된 전투뜀걸음

달려보았다. 달려보았다는 경험을 얻었다.
주특기 시작 전 베이스 언어 기능 숙달이란 목표는 완료한듯 하다.
배운 기능들이 차차 쌓여가고 있다. indexing을 어떻게 하면 좋을지 고민이다.

🐱‍💻 NOTE
JS의 기본적인 기능 - [개념정리] javascript 모아보기 (velog)
└ 나눌 수록 커졌던 걷기반과의 알고리즘 여행 - 알고리즘 모아보기 (Github)

0-0. ✅크레인! 강해져서 돌아왔다!

40+α개의 문제들을 조원들과 풀면서 가장 기억에 남는 문제를 꼽으라면 프로그래머스 64061번 문제 크레인 인형뽑기 게임이라고 할 수 있다. 이 문제는 작년 이맘때 쯤 찍먹으로 하던 파이썬에서 아는게 없어서 포기했던 문제였다. board 하나만 찍어보고 처참히 무너졌었다.

그렇게 JS를 익히고 돌아왔다.

1단계지만 아는 것은 다 썼다. 내장 기능, 수학적 이론, step by step. 과거의 나를 가볍게 짓밟으니 아 그래도 성장했구나 체감할 수 있었다.

function Exercise_64061(board, moves) { 
    let clon = []
    let array = []
    let tong = ''
    
    //step-0
    //보다 쓰기 좋은 2차원 전치행렬 만들기
    //|0,0,0,0,0|        |0,0,0,4,3| 1번 줄
    //|0,0,1,0,3|        |0,0,2,2,5| 2번 줄
    //|0,2,5,0,1|   =>   |0,1,5,4,1| 3번 줄
    //|4,2,4,4,2|        |0,0,0,4,3| 4번 줄
    //|3,5,1,3,1|        |0,3,1,2,1| 5번 줄
    
    //step-1
    //reverse를 이용해 뒤집은 후
    //filter을 통해서 0 없애기, pop으로 쉽게 뽑기 위함.
    //|0,0,0,4,3|        |3,4      | 1번 줄
    //|0,0,2,2,5|        |5,2,2    | 2번 줄
    //|0,1,5,4,1|   =>   |1,4,5,1  | 3번 줄
    //|0,0,0,4,3|        |3,4      | 4번 줄
    //|0,3,1,2,1|        |1,2,1,3  | 5번 줄
    
    for (i=0; i<board.length;i++) {             
        for (j=0; j<board.length;j++){              
            clon.splice(j,0,board[j][i])
        }
        array.splice(i,0,clon.reverse())
        array[i]=array[i].filter((a)=> a!=0 )
        clon = []
    }
    // board의 전치결과 :
    console.log(array)
    
    //step-2
    //pop을 이용해 k번째 moves에 해당하는 줄에서 뽑아 tong에 담기
  	//비어있는 통에서 나오는 undefined는 제거하기.
    
    //|3,4      |                          |3        |       | |
    //|5,2,2    |                          |5,2,2    |       | |
    //|1,4,5,1  |   =>   moves[k]=1   =>   |1,4,5,1  |   +   | |
    //|3,4      |     pick * in line 1     |3,4      |       | |
    //|1,2,1,3  |                          |1,2,1,3  |       |4| tong
    
    //step-3
    //같은 수가 나오면 2개 지우고 2점 올리기
    //뒤에 붙어서 쌓이니까 2연속 스코어링을 놓치지 않기 위해 (i=tong.length i--)를 이용함. 아래참고.

    //i=0부터 위로 탐색시 i가 증가함에 따라 탐색 제한 발생
    //   i           i          i          i
    //|3|4        | |4       | |4       | |4
    //|1|3        | |        | |        | |
    //|1|2   =>   |3|   =>   |3|   =>   |3|<제거 불가
    //|3|1        |3|        |3|        |3|
    //|4|0        |4|score:2 |4|        |4|score:2

    //i=4부터 아래로 탐색시 탐색 제한 없음
    //   i           i          i          i
    //|3|4        | |        | |        | |
    //|1|3        | |3       | |        | |
    //|1|2   =>   |3|2   =>  |3|2   =>  | |
    //|3|1        |3|1       |3|1       | |1
    //|4|0        |4|score:2 |4|0       |4|0 score:2
    
    let score = 0;  
    for (k in moves) {  // for(k=0; k< moves.length;k++) 과 동일 통체우기
        tong = tong.concat(array[moves[k]-1].pop(),'!').replace(/undefined+!/g,'')
      //빈 통에서 뽑으면 undefined라 뺀 숫자 옆의 !와 함께 제거
    }
    tong=tong.split('!')
    for (i=tong.length; i>0;i--) {
        if (tong[i]==tong[i-1]){
            tong.splice(i-1,2)
            score+=2
        }
    }

    return score;
}

트러블 슈팅 #0

step-1 filter을 통해서 0 없애기
0을 없애기 위해 arraysplice() 시 정규표현식을 이용해서 (join('').replace(/0/g,'').split(''))과 같이 0을 모두 제거하는 방법을 썼었으나
자릿수가 2개 이상인 수에서 20도 2가 되고 901도 91이 되는 상황이 발생했다.
그 결정적인 이유는 clon에서 splice()시 수만 가져오기 때문.
정규표현식을 위해 합치는 순간 13234058305이 되어 숫자를 구분할 수 없기 때문이었다.

clonsplice()!,숫자,!를 제공하고 !0!를 만나면 !로 변환해도 가능할 것 같다.
1!3!23!4!0!5!8!30!5!0! => 1!3!23!4!5!8!30!5!

하지만 배열 [0] 요소를 제거하는게 더 읽기에 깔끔했다.
그래서 배열 [0] 요소를 제거하는 filter()를 사용했다.

트러블 슈팅 #1

step-2 비어있는 통에서 나오는 undefined는 제거하기
<제한사항>
만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는
아무런 일도 일어나지 않습니다.

배열에 요소가 없어서 pop() 불가시 undefined가 도출되어 제거해야 한다.

배열로 받아서 tong.filter((a)=>a!=undefined))를 사용해도 되었을 것 같다.
하지만 filter()를 사용하려면 tong이 완성되어 있어야 한다.

tong에 담으며 undefined를 제거하는 과정 속에서 빈 배열이 남지 않도록 문자열로 받았다.

트러블 슈팅 #2

step-3 같은 수가 나오면 2개 지우고 2점 올리기
각 숫자별 정규표현식 10개를 반복할지 0-9 로 찾으면 연속된 같은 수가 안되어서 고민했다.
애초에 인형이 최대 1000가지였으니 이 방법은 무리였다.

완성된 통에서 한번만에 다 찾기에는 무리가 있었다.
12442가 122로 122에서 1로 총 임의의 n번이 필요했다.
순차적으로 터뜨리는걸로 설계했으면 문제가 없었을텐데.
하지만 마지막 for문을 내부에 넣으면 문제없이 순차적으로 작동하니 차이는 없었다.
다만 반복이 많아져 다 쌓고 터뜨리는 것으로 수정했다.

이때 뒤에 붙으며 쌓이니까 k연속 스코어링을 놓치지 않기 위해 (i=tong.length i--)를 이용했다.

🐱‍💻 NOTE
복수를 위해 칼을 가는 것이 게으름에 칼을 갈지 않는 것 보단 좋다.
나 자신을 좌절시킨 무언가가 있을 때 그것을 기억에 남겨두는 것도 좋지 싶다. 뛰어넘는 기쁨은 막혀본 사람만 느낄 수 있다.

0-1. ✅JS 알고리즘 마라톤 회고

🐱‍💻 NOTE
푸는덴 10분 설명하는덴 1시간
알려주고 설명하는 실력은 여전히 부족했다. 각자의 시선에서 바라보고 객관적인 배경에서 바라보는 연습이 더디다. 아무래도 러버덕이 필요하다.


1. 🔍Javascript

짧은 시간동안 Javascript 하나만 다루었다. 한눈팔지 않고 그렇게 달렸다. 그러는 와중에 어 이게 되네? 어 이게 안되네? 싶은 것들도 있었고 파이썬에만 있고 없는 기능인 줄 알았던 것들도 JS에 많이 있었다.

🐱‍💻 NOTE
나. 너 좋아하냐..?
도전하지 않은 것에 겁먹지 않는 것 만큼이나 중요한 것이 모르면서 판단하지 않는 것이다. 배움과 겸손함으로 잘 배워보자. JS, 생각보다 마음에 든다.

시작전 JS 개념정복 - React 입문주차 SA (velog)

1-0. 🔍ECMAScript(ES)

javascript 이후로 우후죽순 생겨났던 스크립팅 언어의 표준 ECMAScript. 언어가 아무리 10일만에 뚝딱 만들어졌다고 한들 계속해서 표준에 맞춰 javascript는 발전해왔다. 지금 오늘 쓴 문법이 과거에는 없었고 미래에는 또 어떤 문법이 생길 줄 모른다.

1-1. 🔍ES5와 ES6

아무리 모든 ES의 변천사를 다룰 수는 없어도 ES6에서 나타난 엄청난 변화와 발전들은 몇가지라도 짚어볼 필요가 있었다. ES6는 2009년의 ES5이후로 6년만(2015년)에 출판된 표준안이다.

ES6에서 등장한 기능

0. 화살표 함수
대표적으로 알고리즘을 풀며 정말 많이 사용한 기능이 있었다. 바로 화살표 함수.

화살표 함수 () =>

화살표 함수는 기본 함수식에서 function{} 그리고 결과값 도출을 위한 return을 생략한 함수 표기법이다. 함수가 필요한 기능들에 넣어 (매개변수) => 식의 표현으로 짧게 표현하기에 용이하다. 예로 아래의 1번2번이 서로 같은 기능의 함수이다.

//1번 (기존 ES5)
function filterByID(item) {
  if (item.id !== 0) {
    return true;
  }
  return false;
}
//2번 (ES6 지원)
(item) => item.id!==0

물론 정해진 함수명이 없는 익명함수라 여러번 호출해서 사용이 불가능 하다는 제한사항이 있다. 여러번 쓰지 않는, 다른 메서드를 위해 매번 커스터마이징이 필요한 함수에 대해 사용하는 것이 좋다.

var arr = [{ id: 15 },{ id: -1 },{ id: 0 },{ id: 3 },{ id: 12.2 }]
var arrByID = arr.filter((item) => item.id!==0);
// 0. arr로 부터 filter의 매개변수(arr의 i번째 값)를 item 이라는 변수로 함수에 전달한다.
// 1. item.id!==0 가 true이면 arrByID에 저장, false가 나오면 버려진다.
// 2. i를 arr의 배열 길이만큼 반복한다.
console.log(arrByID)
//결과 : [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]

💖 삼항연산자처럼 짧고 조아..

.filter(),.reduce(),.map() 등과 같이 함수가 필요한 기능들은 화살표 함수와 함께 사용하면 짧고 간결하게 운용할 수 있다.

1. 템플릿 리터럴
프로젝트를 만들며 temp_html을 이용해 html 구문을 만든게 얼마나 많았던가. 문자열 안에 표현식을 사용할 수 있는 고마운 기능이다.

템플릿 리터럴 `안녕${userName}`

템플릿 리터럴은 백틱을 이용해 표현하는 문자열이다. 백틱 내부에 플레이스 홀더 ${변수명}을 사용하여 문자열과 변수를 함께 사용할 수 있다.

//1번 (기존 ES5)
var name = 'hajun'
console.log('hello' +name +'good morning')	// 결과 : hello hajun good morning
//2번 (ES6 지원)
let name = 'hajun'
console.log(`hello ${name} good morning`)	// 결과 : hello hajun good morning

💖 이제 안녕 나의 작은 아기따옴표. 변수 선언할때 보자.

2. 변수 선언 let, const
ES5까지는 변수 선언 방식이 var밖에 존재하지 않았다고 한다. 재할당과 재선언에 자유로운 var만의 장점도 있겠지만 새로 추가된 재선언 불가능한 let재할당할 수 없는 const만의 장점도 있다. 약간의 느슨함을 쪼여 효율을 얻는 변화가 아니었나 싶다.

var, let, const

var은 재할당과 재선언에 굉장히 자유롭다.
let은 재할당은 가능하지만 재선언은 불가능하다.
const는 재할당도 재선언도 불가능하다.

//1번 (var)
var name = 'hajun'
var name = 'jhon'
console.log(name)	// 결과 : 'jhon'
//2번 (let)
let name = 'hajun'
let name = 'daeun'	// 결과 : 에러 name은 이미 선언되어 있습니다. 재선언 불가
//3번 (const)
const name = 'hajun'
name = 'Peter'		// 결과 : const는 바꿀 수 없습니다.

💖 재선언 재할당 가능여부를 제외한 후의 가장 큰 차이는 var은 블록 스코프에 한해 외부에서 내부 참조가 가능하고, let과 const는 접근이 제한된다는 점이다.

// var
if (false) { 
    var i = 0;
}
console.log(i); // 결과 : undefined (선언문 접근)
//let
if (false) { 
    let k = 0;
}
console.log(k); // 결과 : 에러 k...?몰..루..

🐱‍💻 NOTE
언어도 자라는데...
여러 메서드, 구조분해 할당, 객체 지향언어로의 출발 Class 등을 제외하고 정말 극히 일부를 알아보았지만 그래도 많다. 언어의 성장보단 나의 성장이 빨라야 언젠가 그 끝을 만나지 않을까.


2. ✅시작 된 주특기 입문주차

마라톤. 얼얼했다. 마라탕. 먹고싶다.
충전 잘 하고 시작하는 3주차.

🐱‍👤 TODO
자세 바르게 앉기 : 다 얻고 척추 잃으면 말짱 꽝
├ 도움 많이 받고, 도움 많이 주기. 나눌 수록 커진다. - React 연습 모아보기 (Github)
└ 알고리즘 멈추지 않기. - 알고리즘 모아보기 (Github)

profile
일단 똥을 싸라, 그리고 박수칠 때 까지 닦아라.

0개의 댓글