[Main-Project 개발일지]-27
오늘은 오전에 사람이 모이자마자 바로 프론트,백엔드 통합테스트에 들어갔다.
로그인, 회원가입, 로그인유지상태에서 다른 사람의 정보 보이지 않기 등은 잘 해결되었고
메모장 crud까지도 확인할 수 있었다.
다만 메모장 crud부분은 백엔드부분에서 합쳐지지 않고 구현되었기 때문에 다시 합치는 작업을 진행했고 그 사이에 프론트엔드에서도 기능을 수정하기로 했다.
id는 결국 처음에 언급했던 email이 대체하고 id를 삭제하기로 했고 로고, title, title img 부분은 프론트 팀원님께서 맡기로 하고
나는 기존에 확인할 수 없었던 링크들의 방문 전 색이 파란색으로 나오는 부분을 모두 수정하고 백엔드에서 요청했던 id 데이터 제거하는 부분을 처리했으며 회원가입 후 로그인페이지로 이동할 때 새로고침이 되어 netlify에서 튕기는 오류가 있는데 로그인페이지 이동 또한 로그인->메인페이지 이동처럼 매끄럽게 바꿔주는 일을 처리했다.
netlify의 배포에 대해 프론트엔드끼리 조금 더 보는 시간을 가지고
페이지 주소를 특정할 수 있는 방법을 적용해 링크 이동시 해당 주소값에서 넘어가는
방식을 사용할 수 있게 되었다.
완료된 페이지들의 주석등을 완전히 지우고(비완료 페이지는 수정을 감안해 주석을 살려뒀다)
Reccomand부분에 사용자 이름이 아닌 임시명칭이 들어있는 부분도 데이터를 받아와 할 수 있게 적용했다.
다만 새로고침을 해도 튕기지 않는 부분은 긍정적이라고 생각했지만
비동기적으로 데이터를 받아오다보니 재료를 추가하거나 변경하는 등의 행동이 있지 않으면
사용자명칭이 제대로 추가되어있지 않은 모습을 볼 수 있었다.
이 부분은 로그인을 할 때 백엔드측에서 nickname을 body로 반환해주면 가능하기 때문에
오늘 저녁 멘토링에서 질문한다고 하셔서 보류했다.
로고 생성페이지나 기술스택 생성 페이지 등을 같이 찾아보기도 하고
실시간으로 계속 재배포하며 테스트하는 재미도 있었다.
다만 git을 통해 배포하는 방식이 아닌 npm run build를 사용해서 배포했는데
netlify에서 왜 자동적으로 배포가 진행되지 않는지는 잘 모르겠다.
api를 통해 요리할 수 있는 음식들을 추천해주는 페이지도 만들고 싶은데
백엔드측에서 오늘 진행해보고 내일 추가된 api를 제공할 수 있을 것 같다고 해서
일차적으로 마무리했다.
-현재 부족한점
1.로그인 후 즉각적인 사용자 nickname 적용 안됨
2.재료추천 안됨
3.유통기한 관리시간에 따른 색 변경 아이디어만 나오고 적용 안됨
4.netlify의 문제점인지는 모르겠지만 페이지 내 새로고침 지원 안됨(..프론트에서는 지원)
CT(1).백준 17845 수강과목은 일반적 배낭문제와 유사한 패턴을 가지고 있었으며
벼락치기라는 문제와도 거의 동일한 패턴을 가지고 있다.
let input = `80 3
650 40
700 60
60 40`.split('\n')
for(let i = 0 ; i < input.length ; i++){ //입력 number type 만들기
input[i] = input[i].split(' ').map(Number)
}
let time = input[0][0]
let unit = input[0][1]
let dp = new Array(time+1).fill(0) //dp 초기화
for(let i = 1 ; i <= unit ; i++){
let [a,b] = input[i] //포인트,시간 구조분해할당
for(let j = time ; j > 0 ; j--){
if(j >= b){ //입력값보다 큰 경우 역으로 내려가기(1개씩만 적용하기 위해)
dp[j] = Math.max(dp[j],dp[j-b]+a) //최대값만 저장
}
}
}
console.log(dp[time])
CT(2).프로그래머스 이진수 더하기는 10진법 변환 후 이진법으로 교체하는 방식으로 진행했다.
(parseInt(bin1, 2) + parseInt(bin2,2)).toString(2)
CT(3).프로그래머스 공 던지기는 2칸씩 이동하고 1번째는 index 0이기 때문에 k+2 -2를 참여자 숫자로 나눴다.
numbers[(k*2 -2)%numbers.length]
CT(4).프로그래머스 한 번만 등장한 문자는 객체에 각 글자의 등장횟수를 적은 다음 1인 키를 모아 정렬한 다음 출력했다.
function solution(s) {
let answer = []
let obj = {}
for(let i = 0 ; i < s.length ; i++){
if(obj[s[i]]){
obj[s[i]]++
}
else{
obj[s[i]] = 1
}
}
for(let key in obj){
if(obj[key] === 1){
answer.push(key)
}
}
return answer.sort().join('')
}
CT(5).프로그래머스 외계어 사전은 단 한번씩만 글자를 사용한다는 조건이었기 때문에 정렬해서 만든 문자열이 같은지 비교하면 되는 문제였다.
function solution(spell, dic) {
let spellStr = spell.sort().join('')
for(let i = 0 ; i < dic.length ; i++){
if(dic[i].split('').sort().join('') === spellStr){
return 1
}
}
return 2;
}
CT(6).프로그래머스 문자열 밀기는 문자열을 몇번 밀어야 해당 문자열로 돌아오는지를 판별하는 문제로 작은 함정이 있다면 0번째를 체크하는 것 정도가 있다.
function solution(A, B) {
let str = A.split('')
let num = 0
for(let i = 0 ; i < A.length ; i++){
if(str.join('') === B){
return num
}
str.unshift(str.pop())
num++
}
return -1;
}
CT(7).프로그래머스 모스부호(1)은 다른 나쁜 문제들과는 다르게 객체형태로 key, value쌍을 만들어 제공했기 때문에 간단하게 split한 letter을 key값으로 넣어 value를 더해주는 방식으로 해결했다.
function solution(letter) {
let answer = '';
let morse = {
'.-':'a','-...':'b','-.-.':'c','-..':'d','.':'e','..-.':'f',
'--.':'g','....':'h','..':'i','.---':'j','-.-':'k','.-..':'l',
'--':'m','-.':'n','---':'o','.--.':'p','--.-':'q','.-.':'r',
'...':'s','-':'t','..-':'u','...-':'v','.--':'w','-..-':'x',
'-.--':'y','--..':'z'
}
for(let i = 0 ; i < letter.split(' ').length ; i++){
answer += morse[letter.split(' ')[i]]
}
return answer;
}
CT(8).프로그래머스 컨트롤 제트는 말장난 같은 느낌이 조금 있었다. 앞의 숫자를 지운다고 했으며 예제도 하나씩 띄엄띄엄 나왔기 때문에 pop의 기능이라기보다는 앞의 숫자 더하기 취소라는 개념으로 접근했다가 오류가 나서 생각해보니 살짝 스택느낌의 문제였다.
아래 방식으로 해결한 다음 제출했다가 런타임 에러가 나서 길이0체크를 삼항연산자로 추가하니 통과되었다.
function solution(s) {
let answer = 0;
let arr = []
for(let i = 0 ; i < s.split(' ').length ; i++){
if(s.split(' ')[i] === 'Z'){
arr.pop()
}
else{
arr.push(Number(s.split(' ')[i]))
}
}
return (arr.length === 0 ? 0 : arr.reduce((a,b) => a+b))
}
CT(9).프로그래머스 구슬을 나누는 경우의 수는 nCm 방식의 조합으로
answer에 곱셈과 나눗셈을 for문으로 돌리는 방식으로 해결했다.
범위가 크다면 dp를 사용했겠지만 범위가 50까지이며 공 갯수도 최대 10개라 오류가 날 문제는 없어보였고 다만 나눗셈보다 곱셈을 먼저 처리해 소숫점을 만들지 않게 했다.
CT(10).프로그래머스 다음에 올 숫자는 등차/등비수열 판단 후 마지막 숫자를 구하는 문제로 등차인지 0,1 1,2 index의 차이를 비교해 같으면 등차로 판단, 아니면 등비로 판단했다.
(common[2]-common[1] === common[1]-common[0] ? common[common.length-1] + common[1]-common[0] : common[common.length-1] * common[1] / common[0])
CT(11).프로그래머스 소인수분해는 말 그대로 소인수분해를 하는 문제인데 들어간 소수를 모두 출력하는 것이 아니라 중복을 없애는 작업을 추가해야만했다.
function solution(n) {
let answer = [];
while(n > 1){ //소인수분해
for(let i = 2 ; i <= n ; i++){
if(n%i === 0){
n = n/i
answer.push(i)
break
}
}
}
return [...new Set(answer)]; //중복제거
}
CT(12).프로그래머스 유한소수 판별하기는 조금 까다로웠는데 0레벨이지만 3점을 줬다.
일단 분모와 분자의 최대공약수를 구해야하고(이미 이걸로 1레벨 이상) b를 최대공약수로 나눈 다음 소인수분해로 2,5가 아닌 다른 인수(1제외)가 있으면 2 없으면 1을 반환했다.
function solution(a, b) {
var answer = 0;
let num = Math.max(a,b)
let before = Math.min(a,b)
while(num%before !== 0){
let aa = before
before = num%before
num = aa
}
let bottom = b/before
let arr = []
while(bottom > 1){
for(let i = 2 ; i <= bottom ; i++){
if(bottom%i === 0){
bottom /= i
arr.push(i)
break
}
}
}
return (arr.filter(el => el !== 2 && el !== 5).length ? 2 : 1)
}
CT(13).프로그래머스 최빈값 구하기는 최빈값을 위해 객체에 각 숫자의 갯수를 적어준 다음 그 값들을 arr로 빼서 max를 구하고 그 값에 해당하는 key를 result에 넣은 다음 길이가 1이 아니면 -1을 반환하고 1인 경우 key를 반환했다.
function solution(array) {
let obj = {}
for(let i = 0 ; i < array.length ; i++){
if(obj[array[i]]){
obj[array[i]]++
}
else{
obj[array[i]] = 1
}
}
let nums = []
for(let key in obj){
nums.push(obj[key])
}
let max = Math.max(...nums)
let result = []
for(let key in obj){
if(obj[key] === max){
result.push(Number(key))
}
}
return (result.length === 1 ? result[0] : -1)
}
CT(14).프로그래머스 진료 순서 정하기는 이중배열로 만들어 순서를 정리한 다음 다시 단일배열로 만드는 과정으로 처리했다.
function solution(emergency) {
let arr = []
for(let i = 0 ; i < emergency.length ; i++){
arr.push([i+1,emergency[i]])
}
arr.sort((a,b) => b[1] - a[1])
let result = []
for(let i = 0 ; i < arr.length ; i++){
let [a,b] = arr[i]
result[a-1] = i+1
}
return result;
}
CT(15).프로그래머스 숨어있는 숫자의 덧셈(2)는 3점을 주는 문제였는데 대,소문자를 제거한 숫자의 합을 구하면 되는 문제로 toLower, toUpper가 같은 경우 숫자로 판단하고 그대로 문자열에 넣어주고 아니면 공백을 넣어줘서 split을 할 수 있는 가공을 마친 다음 split, map(number type), reduce로 해결했다.
function solution(my_string) {
let str = ''
for(let i = 0 ; i < my_string.length ; i++){
if(my_string[i].toUpperCase() === my_string[i].toLowerCase()){
str += my_string[i]
}
else{
str += ' '
}
}
return str.trim().split(' ').map(Number).reduce((a,b) => a+b)
}
CT(16).프로그래머스 문자열 계산하기는 문자열을 계산하라는데 eval이 있다.. 이게 왜 5점?
eval(my_string)
CT(17).프로그래머스 특이한 정렬은 이중배열로 거리를 가공한 다음 크기 역순정렬, 거리정렬로 가까운 거리일 경우 큰 수가 나오게 만든 다음 값들을 반환했다.(2)
문제를 풀던 도중 map을 사용하면 이중배열을 쉽게 풀 수 있다는 사실을 알아냈다.
function solution(numlist, n) {
let arr = []
for(let i = 0 ; i < numlist.length ; i++){
arr.push([numlist[i], Math.abs(numlist[i]-n)])
}
arr.sort((a,b) => b[0] - a[0])
arr.sort((a,b) => a[1] - b[1])
return arr.map(el => el[0])
}
CT(18).프로그래머스 등수 매기기는 map을 이용하는 다른 방식이 생각나서 map으로 점수를 합친 다음 정렬하고 다시 map으로 합친 점수를 위에서 정렬한 점수의 index로 대응했다.
function solution(score) {
let arr = score.map(el => el[0]+el[1]).sort((a,b) => b-a)
return score.map(el => arr.indexOf(el[0]+el[1])+1)
}
CT(19).프로그래머스 로그인 성공?은 해당 아이디가 있고 비밀번호가 일치하는지를 조회하는 문제였다. 비밀번호만 틀린 경우까지 조회해야 했기 때문에 객체조회가 아닌 직접 모두조회로 진행했다.
function solution(id_pw, db) {
let result = "fail"
for(let el of db){
let [a,b] = el
if(a === id_pw[0] && b === id_pw[1]){
return "login"
}
else if(a === id_pw[0]){
result = "wrong pw"
}
}
return result
}
CT(20).프로그래머스 삼각형의 완성조건(2)는 세 변의 길이를 구해서 정렬해야 풀 수 있는 문제였다.
function solution(sides) {
let a = Math.min(...sides)
let b = Math.max(...sides)
let answer = 0
for(let i = 1 ; i < a+b ; i++){
let arr = [a,b,i].sort((a,b) => a-b)
let [q,w,e] = arr
if(q+w > e){
answer++
}
}
return answer;
}
CT(21).프로그래머스 저주의 숫자 3은 3의배수 또는 3이 들어간 숫자인 경우 체크하는 값만 올리는 방식으로 해결했다.
function solution(n) {
let answer = 0;
let now = 0
while( now < n){
answer++
if(answer%3 === 0 || String(answer).split('').filter(el => el === '3').length){
}
else{
now++
}
}
return answer;
}