항해 99

항해 99 5기 TIL_46

Dream Herb 2022. 2. 25. 04:06

▶ Today I Learned

 

<알고리즘>

 

[폴리오미노]

 

소요시간: 40분

해결 여부: 해결

 

https://www.acmicpc.net/problem/1343

 

 

/*
폴리오미노

민식이는 다음과 같은 폴리오미노 2개를 무한개만큼 가지고 있다. AAAA와 BB

이제 '.'와 'X'로 이루어진 보드판이 주어졌을 때, 민식이는 겹침없이 'X'를 모두 폴리오미노로 덮으려고 한다. 이때, '.'는 폴리오미노로 덮으면 안 된다.

폴리오미노로 모두 덮은 보드판을 출력하는 프로그램을 작성하시오.
*/


let a = 'AAAA'
let b = 'BB'

let board = 'XX.XX'

// split('.') 을 했을 때 X가 모두 짝수이기만 하면 될까?
// 그렇다 4나 2로 나눠버리면 되니까
// 하지만 짝수인 걸 구한 다음 그걸 출력해주어야 한다.
// 게다가 짝수인게 아니라 xxx.xxx의 경우는 홀수인데도 x 길이의 합은 짝수라는 모순이 생긴다.

console.log(board.split('.'))

let arr = board.split('.')

// // 짝수가 아니면 애초에 덮을 수가 없다.
if (!arr.join('').length%2 === 0) {
  console.log(-1)
} else {
  
}

 

문제를 해결하기 위해 스택을 이용해 반복문을 돌리고 X를 넣다가 .를 넣는 구간 앞을 AAAA나 BB로 바꿔넣자는 의견도 있었다.

물론 이도 좋은 방법이겠지만 사실 더 간단한 방법이 있었다.

그건 바로 다음과 같다.

const path = process.platform === 'linux' ? '/dev/stdin' : 'input.txt'
const input = require("fs").readFileSync(path).toString().trim().split('\n')

const board = input[0]

function replaceString (board) {

  board = board.replace(/XXXX/g, 'AAAA'); // 사전 순으로 먼저 하므로 AAAA부터 시작
  board = board.replace(/XX/g, 'BB');

  return board
}

let answer = replaceString(board).split('').includes("X")? -1 : replaceString(board)

console.log(answer)

 

 

<클론코딩>

 

// 로그인 정보 저장 + 토큰 발급
router.post("/users/loginKakao", async (req, res) => {
    const { email, nickname } = req.body;

    const existsUsers = await User.findOne({ email });
    if (existsUsers) {
        // 이미 해당 이메일이 DB에 있는 경우 DB에 new User로 새로 테이블을 만들어주지 않고 토큰만 보내준다.
        res.send({
            result: true,
            token: jwt.sign({ email: existsUsers.email }, JWT_SECRET_KEY),
        });
        return;
    }

    const user = new User({ email, nickname });
    await user.save();

    res.send({
        result: true,
        token: jwt.sign({ email: user.email }, JWT_SECRET_KEY),
    });
});

 

카카오 소셜 로그인을 구현하는 와중 비밀번호가 해쉬화 되지 않는 것을 발견했다.

 

// 사전 hook , save 시 password 암호화 해서 저장
UserSchema.pre("save", function (next) {
    let user = this;

    if (user.password) {
        // 저장할 때 user로 받아오는 값 중 password가 있는 경우만 실행! 즉, 카카오는 받아오는 비밀번호가 없으므로 실행되지 않음
        bcrypt.genSalt(10, (err, salt) => {
            if (err) return next(err);
            bcrypt.hash(user.password, salt, (err, hash) => {
                if (err) return next(err);
                user.password = hash;
            });
        });
}
       next();
});

이것이 문제의 코드였다. 곰곰이 분석하기도 하고 콘솔을 찍어보았는데

해쉬화 자체는 잘 이뤄지고 있었다.

그렇게 원인을 찾지못하다가 다른 분들과 함께 고민하던 중 next()라는 함수가 if문과 동시에 실행된다는 것을 발견했다.

해쉬화가 이뤄지고 다음으로 넘어가야 하는 것이다.

 

그래서 다음과 같이 바꾸었다.

// 사전 hook , save 시 password 암호화 해서 저장
UserSchema.pre("save", function (next) {
    let user = this;

    if (user.password) {
        // 저장할 때 user로 받아오는 값 중 password가 있는 경우만 실행! 즉, 카카오는 받아오는 비밀번호가 없으므로 실행되지 않음
        bcrypt.genSalt(10, (err, salt) => {
            if (err) return next(err);
            bcrypt.hash(user.password, salt, (err, hash) => {
                if (err) return next(err);
                user.password = hash;
                next();
            });
        });
    } else {
        next();
    }
});

 

그렇게 if문 안에 next()가 들어가게 되면서 해쉬화 다음으로 잘 실행되었다.

자바스크립트의 비동기식 처리라는 특성을 좀 더 신경써서 다음엔 이런 문제를 금방해결해보도록 하자 :)

 

 

▶ 느낀 점

 

드디어 세 번째 프로젝트인 클론 코딩 프로젝트가 끝이 났다.

첫 주차 때와 달리 꽤 완성도있는 사이트가 만들어졌고 1주일 만에 이 정도의 사이트를 구축할 수 있다는 게 놀라웠다.

물론 내가 다 구현한 것은 아니지만 일조했다는 생각에 뿌듯했다.

더 많이 일조하기 위해 더 공부하고 싶어졌다.

 

오늘 하루는 간만에 좀 기쁜 마음으로 잘 수 있겠다.

앞으로도 열심히 해서 잘 해보자 :)

 

 

▶ 공부 시 참고 링크들

 

 

https://docs.mongodb.com/manual/reference/operator/query/elemMatch/

 

$elemMatch (query) — MongoDB Manual

Docs Home → MongoDB Manual$elemMatchThe $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.{ : { $elemMatch: { , , ... } } }If you specify only a single condition in t

docs.mongodb.com

 

https://yeolco.tistory.com/157

 

자바스크립트 객체 배열에서 indexOf 사용방법

기본적인 배열은 일반 변수들이 나열된 모양이다. var arr = [ "사과", "딸기", "복숭아 ]; var arr2 = [ 5, 3, 0.5, 7, 2, 9]; 이런 일반적인 배열에서 인덱스를 통해 배열의 값을 구할수있다. console.log(arr[0..

yeolco.tistory.com

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

 

Array.prototype.findIndex() - JavaScript | MDN

The findIndex() method returns the index of the first element in the array that satisfies the provided testing function. Otherwise, it returns -1, indicating that no element passed the test.

developer.mozilla.org

https://geometery-programing.tistory.com/23

 

[Object] Object 다루기 - map, filter 로 값 추출하기

Object(객체) 다루기 Object(객체) 란 무엇인가? 1. key: value 쌍을 가지는 자료구조입니다. 2. value 에 문자, 숫자, 배열, 객체, 함수를 할당할 수 있습니다. 1. 오브젝트 데이터 생성 const objPersons = { pe..

geometery-programing.tistory.com

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

 

String.prototype.replace() - JavaScript | MDN

The replace() method returns a new string with some or all matches of a pattern replaced by a replacement. The pattern can be a string or a RegExp, and the replacement can be a string or a function to be called for each match. If pattern is a string, only

developer.mozilla.org

 

https://curryyou.tistory.com/234

 

[자바스크립트] 정규표현식(Regular Expression) 기초/기본 쉽고 상세한 사용 방법 정리(샘플 예제 코

# 정규표현식이란?(Regular Expression: Regex) 정규표현식은 "특정 패턴의 문자열"을 찾기 위한 표현 방식입니다. (이런걸 형식 언어, formal languange라고 합니다.) 정규표현식을 이용하면, 특정 패턴에 매

curryyou.tistory.com

 

https://junghyeonsu.tistory.com/260

 

[백준] 1343번: 폴리오미노 (JavaScript, NodeJS)

문제 민식이는 다음과 같은 폴리오미노 2개를 무한개만큼 가지고 있다. AAAA와 BB 이제 '.'와 'X'로 이루어진 보드판이 주어졌을 때, 민식이는 겹침없이 'X'를 모두 폴리오미노로 덮으려고 한다. 이

junghyeonsu.tistory.com