-
항해 99 5기 TIL_11항해 99 2022. 1. 21. 01:04
▶ Today I Learned
<CS 스터디>
[2진수 쉽게 표현하기]
BCD: 10진수를 2진화 한 것 Binary Coded Decimal
ex)
2진수: 1101
BCD: 0001 0011 좌측 4자리: 십의 자리 우측 4자리: 일의 자리
But 비트를 너무 많이 낭비한다는 단점이 있음
[8진법]
비트 3개를 사용하여 2진수를 8진수로 나타내기
ex) 2진수 101 8진수 5
8진수 015 -> 8**2*0 + 8**1*1 + 8*0*5 = 8 + 5 = 13
그러나 컴퓨터는 만들 때 8의 배수를 이용해 만드는 경우가 많음
4비트 2비트... 그러나 8진수는 한자리당 3개의 비트가 쓰여 갯수가 맞아 떨어지지 않음
요즘 많이 쓰이진 않음
[16진법]
비트 4개를 사용하여 2진수를 16진수로 나타내기
ex) 2진수 1001 = 16진수 9
그러나 16진수의 경우 수를 표현할 때 10이상 부터는 10진수 2개이상을 써야한다는 단점이 있음
-> 그래서 10 ~ 15는 기호로 표현
[비트 그룹의 이름]
비트 그룹 이름에는 여러가지가 있는데 그중 워드라는 말은 컴퓨터가 빠르게 처리하기 좋은 단위를 말함
ex) 워드 = 32비트
큰 수를 가리키는 표준용어도 있음
KB MB GB TB
1024 = 2**10
1024*1024 = 2**20 와 같은 방식으로 단위가 늘어남
그러나 이 이름들은 미터법 kilo mega 등에서 따온 것으로 10진법을 기반으로 하고 나타내는 수는 2진법 기반임
=> 헷갈림을 방지하기위해 IEC라는 국제기구에서는 kibi 와 같은 이름을 쓰고 단위를 10진법 단위로 하기로 명명
하지만 그 이후에도 헷갈려 하는 사람들이 많은 것으로 보임
(아직까지 실제로 kibi라는 것을 쓰는 걸 본적은 없다..)
실제로 stackoverflow에서도 실제로 사용하냐는 물음들이 꽤 있었고
인터넷의 다른글을 보아도 실제로 쓰는 것이 별로 없어보인다..
<알고리즘 기초>
[제일 작은 수 제거하기]
https://programmers.co.kr/learn/courses/30/lessons/12935
소요시간: 3시간
어제에 이어 고민하다가 짰던 코드
function solution(arr) { let answer = [] let i = 0 if (arr.length == 1) { return [-1] } else { while(0 < arr.length-1) { if (arr[i] < arr[i+1]) { answer = arr.push(arr[i+1]) arr.splice(i+1, i+2) } else { answer = arr.push(arr[i]) arr.splice(i, i+1) } i++ } return answer } }
식은 맞게 짠것 같다. 테스트 실행을 돌려보니 -1을 반환하는 건 잘 작동하는데
배열의 길이가 2이상일 경우 연산이 느린 듯 하다.
실행시간이 10초를 넘어간다며 다음과 같은 문구가 뜬다.
와우..이런건 처음보는데
진짜 코드가 잘 안돌아가나..?
기능을 쓰지 않고 구현해보고 싶었는데 성능이 좋지 못한 코드라 그런 것 같다.
여튼 제출이 안되니 새로운 방법을 찾자!
그렇게 제출한 코드
function solution(arr) { return arr.length == 1 ? [-1] : arr.filter(m => Math.min(...arr) < m) }
cf) Math.min() 쓸 때 ()안에 배열이 들어간다면 저렇게 ...을 해주어야한다.
깔끔하긴 한데 기능을 많이 썼다.
다른 방식으로 해보고 싶어 모범답안을 찾아보았는데
상위권 대부분은 위와 같이 Math.min 이나 filter, apply 등을 썼다.
그러던 중 발견한
프로그래머스 모범답안
function solution(arr) { var answer = []; var smallest = arr[0]; if (arr.length > 1) { for (var i = 1; i < arr.length; i++) { // i를 1부터 준 게 인상적이었다. // 단순하게 i는 0 부터 찾기 시작해서 앞뒤 관계 비교후 위치를 바꿔주게되면 // 전체의 크기에 따라 나열하지 못한다. 이분처럼 최소값을 따로 빼두고 밑에서 하나하나 비교하는게 //훨씬 효율적인 방법 :) if (arr[i] < smallest) { smallest = arr[i]; // 가장 작은 값을 찾아서 따로 빼주는 방식 } } for (var j = 0; j < arr.length; j++) { if (arr[j] > smallest) { // 최솟값과 비교해서 최솟값보다 크면 배열에 집어넣고 그것을 출력 answer.push(arr[j]) } } } else { answer.push(-1) } return answer; }
참고해서 다음에 비슷하게 풀어보아야지 :)
[콜라츠 추측]
https://programmers.co.kr/learn/courses/30/lessons/12943
소요시간: 15분
처음 제출한 코드
function solution(num) { let count = 0 while(1 < num) { if (num%2 == 0) { num = num/2 } else { num = num*3 + 1 } count++ } return 500 <= count || num !== 1? -1 : count }
여기서 주의할 것은 count || num에 count && num을 하면 안 된다는 것이다. 위 while문은 무조건 n이 1이 될 때 까지 돌아가게 되는데
우리는 횟수가 500이 넘어가기만 해도 -1을 출력해야하기 때문이다.
위 코드는 count가 500을 넘어가도 연산을 하는 것이 문제이다.
따라서 연산을 중간에도 멈춰줄 수 있게 다음과 같이 바꿔보자
let count = 0 while(1 < num || count < 500) { if (num%2 == 0) { num = num/2 } else { num = num*3 + 1 } count++ } return 500 <= count || num !== 1? -1 : count
이러면 count가 500이 되기만 해도 빠져나올 것이다!
대신 조건이 추가되었으니 컴퓨터 쪽에선 고려할 조건이 늘어서 위와 아래 중 어느쪽이 더 효율적일지는 성능을 따져보아야겠다..
더 효율적이거나 기발한 방법은 없을까?
프로그래머스 모범답안
function collatz(num,count = 0) { return num == 1 ? (count >= 500 ? -1 : count) : collatz(num % 2 == 0 ? num / 2 : num * 3 + 1,++count); }
음 사실 내가 쓴 반복문과 조건문을 삼항 연산자로 나타낸 것 외에는 똑같다. 다른 답안들도 구조 자체는 똑같다.
애초에 문제에서 콜라츠 수를 구하는 식을 알려줬기에 다들 같은 방법을 생각하는 듯 하다.
문득 드는 생각이지만 만약 콜라츠 수를 구하는 법을 알려주지 않았다면
시간은 훨씬 오래 걸렸겠지만 다들 기발한 방법을 생각해보지 않았을까 라는 생각이 든다.
생각의 틀이 제한되지 않을테니까 :3
[전화번호 양식 갖추기]
소요시간: 20분
제한조건
‘1012345678’로 저장된 전화번호를 다시 ‘010-1234-5678’ 형식으로 바꾸려고 한다.
phone은 length는 10으로 고정function solution(phone){ let firstPart = "0" + phone.substring(0,2) + "-" let secondPart = phone.substring(2,6) + "-" let thirdPart = phone.substring(6,10) let result= firstPart + secondPart + thirdPart return result; } console.log(solution("1062509911"))
splice를 활용해 간단히 만들어볼 수 도 있다.
like this
phone = "1012345678" let num = phone.split('') let first = "0" + num.splice(0,2,"-").join('') let second = num.splice(0,5,"-").join('') let third = num.join('') console.log(first + second + third)
splice(시작인덱스, 종료인덱스[이것 전까지 반환], 잘라낸 부분에 추가하고 싶은 것)
[공부시간 구하기]
소요시간: 2시간
제한 조건
체크아웃을 할 때 익일 시간은 24+a 로 계산한다. 즉 새벽 2시는 24+2 인 26으로 표기한다.체크인 페이지는 새벽 5시까지 체크아웃이 되어 있지 않으면 체크아웃을 깜빡한 것으로 간주한다.따라서 체크인 시스템은 새벽 5시 정각이나, 새벽 5시를 넘겨서 체크아웃을 하게 되면 자동으로 체크아웃을 오후 9시(21:00)로 한 것으로 처리한다.function solution(arr1, arr2){ let i = 0 for (i ; i < arr2.length ; i++) { 29 <= arr2[i].split(":")[0] ? arr2[i] = "21:00": arr2[i] } // 체크아웃 시간 5시 정각이거나 넘을 경우 21:00로 초기화 let checkInHours = arr1.map(v => v.split(":")[0]) let checkInMins = arr1.map(v => v.split(":")[1]) let checkOutHours = arr2.map(v => v.split(":")[0]) let checkOutMins = arr2.map(v => v.split(":")[1]) //체크인과 체크아웃을 시간과 분으로 쪼개어 배열 생성 let studyHours = checkOutHours.map((v, i) => checkOutHours[i] - checkInHours[i]) let studyMins = [] let j = 0 // 분의 인덱스로 활용할 변수 for (j ; j < arr2.length ; j++) { if (checkOutMins[j] - checkInMins[j] < 0) { studyMins[j] = (checkOutMins[j] - checkInMins[j] + 60) /*이 부분에서 사실 크게 간과했다. 한시간이 100분이 아니라 60분 이라는 점이다. 그래서 시간에서 1시간 제하는 대신 얻어야 하는 건 마이너스값의 절대값도 아니고 100분에서 마이너스 값을 제하는 것도 아닌 60분에서 마이너스 값을 제하는 것이다..!*/ studyHours[j] = studyHours[j] - 1 // 마이너스 분단위 계산 대신 1시간 빼버리기 } else { studyMins[j] = checkOutMins[j] - checkInMins[j] } } let totalHours = studyHours.reduce((acc, cur) => acc + cur ) let totalMins = studyMins.reduce((acc, cur) => acc + cur ) // 총 공부 시간과 분 배열로 구한 것 시간은 시간대로, 분은 분대로 합치기 if (60 <= totalMins) { totalHours = totalHours + Math.floor(totalMins/60) totalMins = totalMins%60 // 60분 초과하면 60분 단위로 시간에 넘기기, 다빼고 분은 60 미만으로 남는 분 적용하기 } let answer = `${totalHours}시간 ${totalMins}분` return answer; } let arr1=["8:42", "9:00", "8:50", "8:47", "9:01", "8:51", "8:59"]; let arr2=["21:42", "23:10", "25:30", "29:10", "23:11", "26:44", "29:26"]; console.log(solution(arr1, arr2))
▶ 느낀 점
어제는 전체 발표도 있었고 오늘 아침에 바로 CS스터디 발표를 하다보니 부랴부랴 준비해서 깊이 있게 다루진 못했다. 우선은 가볍게 이런게 있구나 정도를 이해하고 추후에 필요한 지식을 좀 더 파보면 좋을 것 같다..! (실제로 적용도 해보아야 내것이 될 테니)
그리고 5일간의 알고리즘 스터디가 드디어 끝이났다..!
약 30문제 정도를 풀었고 빨리 푸는 대신 관련 개념과 사용법을 이해하는 것, 그리고 문제를 다각도로 접근하는 것에 좀 더 치중했다. 속도는 많이 느렸지만 좋은 기반이 되어 나중에는 날개를 달아주리라 :)
그동안 함께 해주신 팀원 분들덕에 또 즐거운 한주가 되었다! 매주 좋은 분들만 만나 기분이 좋다 ㅎㅎ
다들 고생많으셨습니다..! :3
다음 주차도 화이팅팅!
▶ 공부 시 참고 링크들
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://hianna.tistory.com/404
'항해 99' 카테고리의 다른 글
항해 99 5기 TIL_13 (0) 2022.01.22 항해 99 5기 TIL_12 (0) 2022.01.22 항해 99 5기 TIL_10 (0) 2022.01.19 항해 99 5기 TIL_9 (0) 2022.01.18 항해 99 5기 TIL_8 (0) 2022.01.18