-
항해 99 5기 TIL_46항해 99 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/
https://yeolco.tistory.com/157
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
https://geometery-programing.tistory.com/23
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
https://curryyou.tistory.com/234
https://junghyeonsu.tistory.com/260
'항해 99' 카테고리의 다른 글
항해 99 5기 TIL_48 (0) 2022.02.27 항해 99 5기 TIL_47 (0) 2022.02.26 항해 99 5기 TIL_45 (0) 2022.02.24 항해 99 5기 TIL_44 (0) 2022.02.23 항해 99 5기 TIL_43 (0) 2022.02.22