회고

[Main-Project 개발일지]-23

Happy Programmer 2022. 9. 30. 23:50

오늘은 시작하자마자 어제 바빠서(6시 50분까지 계속해서 백엔드분들과 수정작업을 했다) 넘어간 issue 추가를 한 다음 작업하지 않은 나머지 부분의 server와 소통(delete, update)하는 작업을 시작했다.

중간에 Recommendation의 css도 깨지는 부분(작은 화면에서)을 발견해 수정했고
mypage 부분 글자가 깨지는 부분도 수정했으며 Jay 대신 받아온 닉네임을 넣게 수정했다.
보인 김에 냉장고, 냉동실, 냉장실의 Jay부분도 서버에서 nickname을 준다면 그 부분을 넣게 수정했다.

로그인 화면에서 window를 조작해 이동하는 것이 아닌 방식이 필요함을 확인하고 찾아보다가
프론트팀원분이 저번에 작업했던 방법은 괜찮았던 것 같아서 질문드려고 보니 자리를 비우신 상태였다. 

history에 답이 있을 것 같은데 답이 없는 상태였고 대부분의 결과는 link to를 이용하라는 단순한 수준의 내용밖에 없었다.
그 중 history.push()라는 글을 봤는데 당연히 적용되지 않았고 
history의 공식문서에 들어가니 pushState라는 기능이 있는데 앞 두개는 무시한 채 window.history.pushState("", "", "http://localhost:3000/");라는 명령으로 메인을 띄우려고 했는데 주소창의 글자만 바뀌고 페이지 이동은 되지 않았다.
곰곰히 생각해보다가 강제 변경은 새로고침처리가 되므로 push를 두번 밀어넣어 이전기록에도 메인페이지가 찍히게 한 다음 window.history.back()으로 처리하니 새로고침 없이 페이지 이동을 할 수 있었다.
같은 원리로 pushState, back, go를 통해 해보려고 했으나 go는 강제이동이라 새로고침 처리가 되었고 forward가 맞는 동작인 것 같다고 생각되서 push, back, forward를 사용했지만 이동이 없다. 씨스타 push push가 생각나는 push push back으로만 가능한 것을 확인하고 넘어갔다.

모든 기능을 axios로 server와 소통할 수 있게 처리한 다음 
백엔드분들의 요청으로 이런저런 테스트와 데이터 변경등을 체크하고 
회원 아이디들이 달라도 냉장고의 재료 데이터베이스는 분할되지 않고 하나로 잡혀있어
아이디1로 작성해둔 내용을 처음 생성한 아이디2로도 볼 수 있고 수정할 수 있으며
수정된 내용을 아이디3으로 접속해도 볼 수 있는 난장판 상태였다.
프론트엔드쪽에서 가능한 부분은 다 했기 때문에 테스트를 할 수 있는 환경만 마련해드리고
전체 회의에서 기능들에 대해 한번 시연한 다음 일정에 대해 이야기를 나누다가

발표자료 제출 때문에 수요일까지는 뭔가 해결해야 할 것 같다는 의견이 모였다.
시작할 때 부터 언급됐던 것 처럼 프론트 팀원분이 발표는 맡아주시기로 했지만
개인발표 2분씩 들어있는 부분 때문에 각자 프레젠테이션 느낌으로 뭔가를 해야 한다고 한다.
그 부분에 대해서는 전혀 고려하지 않고 있었는데 질문에 대한 답변은 잘 할 수 있곘지만
겨우 crud와 로그인, 회원가입, 로컬스토리지 등의 단순한 기능구현에 어떤 어필을 할 수 있을지 의아함이 든다.

토론을 끝낸 다음 프론트 팀원분과 담당할 부분에 대한 정리를 나누고
팀원분은 아직 완성되지 않은 crud(메모)부분의 axios와
클라이언트 배포를 aws로 도전해본다고 하셨기 때문에
나는 재료의 crud 구현, 프로필화면, 로그인, 회원가입, 로컬스토리지로 로그인 유지 및 로그아웃시 로컬스토리지 토큰 삭제 등을 소개할 예정이다.

swr에 대한 부분을 조금 봤는데 매력적이기는 하지만
react-query가 조금 더 react hook과 유사한 방식이라 빠르게 학습할 수 있을 것 같다.
이번 주는 리액트 강의를 들으며 hook에 대한 부분을 더 자세히 보고
react-query를 알아봐야겠다.


CT(1).배열 탈출이라는 문제는 현재 위치의 값보다 낮은 값으로만 갈 수 있으며
현재 위치의 값을 1 올릴 때 마다 1원씩 지불해야하는 특이한 조건으로
0,0(문제는 1,1이라고 표기)에서 n-1,n-1(문제는 n,n)까지 이동해야 하는 문제였다.
현재 위치에서 갈 수 있는 방향들의 dp를 Math.min을 통해 모두 조정하는 방식을 선택했다.
최대 222, 2222칸이기 때문에 98만정도의 최대값을 가질 수 있어 100만의 임시값을 배정하고 출발지점의 지불요금은 0원으로 시작했다.

let input = `5
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1`.split('\n') //경로별 지정 값

let n = Number(input[0]) //size (NxN)
let arr = input.slice(1) //arr(요금계산용)
for(let i = 0 ; i < n ; i++){ //arr Number type 만들기
    arr[i] = arr[i].split(' ').map(Number)
}
let dp = [] 
for(let i = 0 ; i < n ; i++){ // NxN size 배열 만들기(최대값초과인 100만 세팅)
    dp.push(new Array(n).fill(1000000))
}
dp[0][0]=0 //시작위치 요금 0원

for(let i = 0 ; i < n ; i++){
    for(let j = 0 ; j < n ; j++){
        if(i === n-1 && j === n-1){//도착지점인 경우 아무것도 하지 않는다.
        }
        else if(i === n-1){ //i만 벽에 도달한 경우 j쪽으로만 이동
            if(arr[i][j] > arr[i][j+1]){ //현재값이 큰 경우 그냥 Math.min
                dp[i][j+1] = Math.min(dp[i][j+1], dp[i][j])
            }
            else{ //현재값이 작은 경우 차액만큼 더한 다음 Math.min
                dp[i][j+1] = Math.min(dp[i][j+1], dp[i][j]+arr[i][j+1]+1-arr[i][j])
            }
        }
        else if( j === n-1){ //j만 벽인 경우 i쪽 이동
            if(arr[i][j] > arr[i+1][j]){
                dp[i+1][j] = Math.min(dp[i+1][j], dp[i][j])
            }
            else{
                dp[i+1][j] = Math.min(dp[i+1][j], dp[i][j]+arr[i+1][j]+1-arr[i][j])
            }
            
        }
        else{//i, j 모두 벽이 아닌 경우 위의 조건체크 세분화
            if(arr[i][j] > arr[i][j+1] && arr[i][j] > arr[i+1][j]){
                dp[i][j+1] = Math.min(dp[i][j+1], dp[i][j])
                dp[i+1][j] = Math.min(dp[i+1][j], dp[i][j])
            }
            else if(arr[i][j] > arr[i][j+1]){
                dp[i][j+1] = Math.min(dp[i][j+1], dp[i][j])
                dp[i+1][j] = Math.min(dp[i+1][j], dp[i][j]+arr[i+1][j]+1-arr[i][j])
            }
            else if(arr[i][j] > arr[i+1][j]){
                dp[i][j+1] = Math.min(dp[i][j+1], dp[i][j]+arr[i][j+1]+1-arr[i][j])
                dp[i+1][j] = Math.min(dp[i+1][j], dp[i][j])
            }
            else{
                dp[i][j+1] = Math.min(dp[i][j+1], dp[i][j]+arr[i][j+1]+1-arr[i][j])
                dp[i+1][j] = Math.min(dp[i+1][j], dp[i][j]+arr[i+1][j]+1-arr[i][j])
            }
        }
    }
}
console.log(dp[n-1][n-1])//목적지에서 누적 지출요금 출력



CT(2).게임 맵 최단거리라는 문제는 열심히 재귀로 도전해봤지만
모든 정확성은 맞고 시간도 0.3ms정도로 양호했지만 효율성에서 call stack 초과로 런타임 에러 및 일부 시간초과가 걸려버렸다.
해결은 가능하고 효율성 중 하나도 0.027초(27.2ms)만에 해결했다는 것을 보면 실제 사용에는 지장없는 코드라고 생각한다.. 지나치게 낮은 단위의 효율성이 밉다.

function solution(maps) {
    var answer = 0;
    let ap = maps.length
    let bp = maps[0].length
    let dp = []
    for(let i = 0 ; i < ap ; i++){
        dp.push(new Array(bp).fill(10000))
    }
    dp[0][0] = 1
    
    if(ap === 1){
        return (maps[0].indexOf(0) === -1 ? bp : -1)
    }
    else if(bp === 1){
        let sum = 0
        for(let i = 0 ; i < ap ; i++){
            sum += maps[i][0]
        }
        return (sum === ap ? ap : -1)
    }
    
    function recurtion(a,b){
        if(a === 0){
            if(b === 0){//아래 오른쪽 
                if(dp[a][b]+1 < dp[a+1][b] && maps[a+1][b]){ //아래
                    dp[a+1][b] = dp[a][b]+1
                    recurtion(a+1,b)
                }
                if(dp[a][b]+1 < dp[a][b+1] && maps[a][b+1]){ //오른쪽
                    dp[a][b+1] = dp[a][b]+1
                    recurtion(a,b+1)
                }
            }
            else if(b > 0 && b < bp-1){ // 아래 왼쪽 오른쪽  
                if(dp[a][b]+1 < dp[a+1][b] && maps[a+1][b]){ //아래
                    dp[a+1][b] = dp[a][b]+1
                    recurtion(a+1,b)
                }
                if(dp[a][b]+1 < dp[a][b+1] && maps[a][b+1]){ //오른쪽
                    dp[a][b+1] = dp[a][b]+1
                    recurtion(a,b+1)
                }
                if(dp[a][b]+1 < dp[a][b-1] && maps[a][b-1]){ //왼쪽
                    dp[a][b-1] = dp[a][b]+1
                    recurtion(a,b-1)
                }
            }
            else if(b === bp-1){//아래 왼쪽
                if(dp[a][b]+1 < dp[a+1][b] && maps[a+1][b]){ //아래
                    dp[a+1][b] = dp[a][b]+1
                    recurtion(a+1,b)
                }
                if(dp[a][b]+1 < dp[a][b-1] && maps[a][b-1]){ //왼쪽
                    dp[a][b-1] = dp[a][b]+1
                    recurtion(a,b-1)
                }
            }
        }
        else if(a > 0 && a < ap-1){
            if(b === 0){//위,아래,오른쪽
                if(dp[a][b]+1 < dp[a-1][b] && maps[a-1][b]){ //위
                    dp[a-1][b] = dp[a][b]+1
                    recurtion(a-1,b)
                }
                if(dp[a][b]+1 < dp[a+1][b] && maps[a+1][b]){ //아래
                    dp[a+1][b] = dp[a][b]+1
                    recurtion(a+1,b)
                }
                if(dp[a][b]+1 < dp[a][b+1] && maps[a][b+1]){ //오른쪽
                    dp[a][b+1] = dp[a][b]+1
                    recurtion(a,b+1)
                }
            }
            else if(b > 0 && b < bp-1){//위,아래,왼쪽,오른쪽
                if(dp[a][b]+1 < dp[a-1][b] && maps[a-1][b]){ //위
                    dp[a-1][b] = dp[a][b]+1
                    recurtion(a-1,b)
                }
                if(dp[a][b]+1 < dp[a+1][b] && maps[a+1][b]){ //아래
                    dp[a+1][b] = dp[a][b]+1
                    recurtion(a+1,b)
                }
                if(dp[a][b]+1 < dp[a][b+1] && maps[a][b+1]){ //오른쪽
                    dp[a][b+1] = dp[a][b]+1
                    recurtion(a,b+1)
                }
                if(dp[a][b]+1 < dp[a][b-1] && maps[a][b-1]){ //왼쪽
                    dp[a][b-1] = dp[a][b]+1
                    recurtion(a,b-1)
                }
            }
            else if(b === bp-1){//위,아래,왼쪽
                if(dp[a][b]+1 < dp[a-1][b] && maps[a-1][b]){ //위
                    dp[a-1][b] = dp[a][b]+1
                    recurtion(a-1,b)
                }
                if(dp[a][b]+1 < dp[a+1][b] && maps[a+1][b]){ //아래
                    dp[a+1][b] = dp[a][b]+1
                    recurtion(a+1,b)
                }
                if(dp[a][b]+1 < dp[a][b-1] && maps[a][b-1]){ //왼쪽
                    dp[a][b-1] = dp[a][b]+1
                    recurtion(a,b-1)
                }
            }
            
        }
        else if(a === ap-1){
            if(b === 0){//위,오른쪽
                if(dp[a][b]+1 < dp[a-1][b] && maps[a-1][b]){ //위
                    dp[a-1][b] = dp[a][b]+1
                    recurtion(a-1,b)
                }
                if(dp[a][b]+1 < dp[a][b+1] && maps[a][b+1]){ //오른쪽
                    dp[a][b+1] = dp[a][b]+1
                    recurtion(a,b+1)
                }
            }
            else if(b > 0 && b < bp-1){//위,왼쪽,오른쪽
                if(dp[a][b]+1 < dp[a-1][b] && maps[a-1][b]){ //위
                    dp[a-1][b] = dp[a][b]+1
                    recurtion(a-1,b)
                }
                if(dp[a][b]+1 < dp[a][b+1] && maps[a][b+1]){ //오른쪽
                    dp[a][b+1] = dp[a][b]+1
                    recurtion(a,b+1)
                }
                if(dp[a][b]+1 < dp[a][b-1] && maps[a][b-1]){ //왼쪽
                    dp[a][b-1] = dp[a][b]+1
                    recurtion(a,b-1)
                }
            }
            else if(b === bp-1){//도착지
                return
            }
            
        }
    }
    recurtion(0,0)
    return (dp[ap-1][bp-1] === 10000 ? -1 : dp[ap-1][bp-1]);
}