문제

Hello World!를 출력하시오.

 

 

입력

없음

 

 

풀이

말 그대로 "Hello World!"라는 문자열을 출력하는 것이기 때문에

console.log()를 사용해 출력해주면 된다.

 

input 자체가 없기 때문에 따로 받을 필요도 없으며

주의사항이라고 한다면 문자열이기 때문에 " " 또는 ' '로 감싸서 문자열임을 알려줘야 한다.

(감싸지 않을 경우 변수명이라고 생각하고 에러가 난다)

console.log('Hello World!')

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2739번 구구단  (0) 2023.03.06
[백준 JS] 2558번 A+B - 2  (0) 2023.03.06
[백준 JS] 2475번 검증수  (0) 2023.03.06
[백준 JS] 2438번 별 찍기 - 1  (0) 2023.03.06
[백준 JS] 2420번 사파리 월드  (0) 2023.03.06

문제

컴퓨터를 제조하는 회사인 KOI 전자에서는 제조하는 컴퓨터마다 6자리의 고유번호를 매긴다. 고유번호의 처음 5자리에는 00000부터 99999까지의 수 중 하나가 주어지며 6번째 자리에는 검증수가 들어간다. 검증수는 고유번호의 처음 5자리에 들어가는 5개의 숫자를 각각 제곱한 수의 합을 10으로 나눈 나머지이다.

예를 들어 고유번호의 처음 5자리의 숫자들이 04256이면, 각 숫자를 제곱한 수들의 합 0+16+4+25+36 = 81 을 10으로 나눈 나머지인 1이 검증수이다.

 

 

입력

첫째 줄에 고유번호의 처음 5자리의 숫자들이 빈칸을 사이에 두고 하나씩 주어진다.

 

 

풀이

결국 각각의 숫자를 나눠야 하기 때문에 .split(' ')으로 배열로 변경한 다음

배열에 담긴 각 문자열을 숫자로 바꾸기 위해 .map(Number) 처리를 해주고

해당 배열을 for문으로 접근해 각각을 제곱한 다음 sum이라는 변수에 더하고

최종적으로는 sum%10으로 10으로 나눈 나머지를 출력한다.

const input = require('fs').readFileSync('/dev/stdin').toString().split(" ").map(Number)
let sum = 0

for(let i = 0 ; i < input.length ; i++){
    sum += input[i]**2
}

console.log(sum%10)
const input = '0 4 2 5 6'.split(" ").map(Number)
let sum = 0

for(let i = 0 ; i < input.length ; i++){
    sum += input[i]**2
}

console.log(sum%10)

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2558번 A+B - 2  (0) 2023.03.06
[백준 JS] 2557번 Hello World  (0) 2023.03.06
[백준 JS] 2438번 별 찍기 - 1  (0) 2023.03.06
[백준 JS] 2420번 사파리 월드  (0) 2023.03.06
[백준 JS] 1330번 두 수 비교하기  (0) 2023.03.05

문제

첫째 줄에는 별 1개, 둘째 줄에는 별 2개, N번째 줄에는 별 N개를 찍는 문제

 

 

입력

첫째 줄에 N(1 ≤ N ≤ 100)이 주어진다.

 

 

풀이

별을 하나씩 추가해서 출력하기를 원하기 때문에

for문의 i의 증가를 통해 문제를 해결할 수 있다.

 

for문의 for(let i = 1 ; i <= input ; i++){}와 같은 조건을 사용할 수 있으며

.repeat(Number)를 통해 반복 횟수를 지정할 수 있기 때문에 Number 자리에 i를 넣어주면 해결할 수 있고

또는 증가만 하는 규칙을 가지고 있기 때문에 특정 문자열을 담을 변수를 선언한 다음 

해당 변수를 출력하는 방식도 가능하다.

const input = Number(require('fs').readFileSync('/dev/stdin').toString().trim())
for(i = 1 ; i <= input ; i++){
    console.log('*'.repeat(i))
}
//8개월 전 초반에 시도했던 코드로 .trim이 없어 불편하다.
const input = require('fs').readFileSync('/dev/stdin').toString().split(" ").map(Number)
let a = ''
for(i = 0 ; i < input[0] ; i++){
    a = a+ '*'
    console.log(a)
}
const input = Number('5')
for(i = 1 ; i <= input[0] ; i++){
    console.log('*'.repeat(i))
}

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2557번 Hello World  (0) 2023.03.06
[백준 JS] 2475번 검증수  (0) 2023.03.06
[백준 JS] 2420번 사파리 월드  (0) 2023.03.06
[백준 JS] 1330번 두 수 비교하기  (0) 2023.03.05
[백준 JS] 1271번 엄청난 부자2  (0) 2023.03.05

문제

사파리월드는 인터넷으로만 존재하는 미스테리한 나라이다. 사파리월드에는 2개의 서브도메인이 seunghwan.royal.gov.sw와 kyuhyun.royal.gov.sw 이 있는데, 이것이 couple.royal.gov.sw으로 합쳐질 것이다. 그러나 도메인 관리 센터 SWNIC(센터장: 김동규)에는 엄격한 룰이 있다. 두 서브도메인을 합칠 때, 유명도의 차이가 너무 차이나지 않을 경우에만 두 서브도메인을 결혼시키는 것이다. 서브도메인의 유명도는 정수이다. 두 서브도메인의 유명도가 주어졌을 때, 그 차이를 구하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 두 도메인의 유명도 N과 M이 주어진다. (-2,000,000,000 ≤ N, M ≤ 2,000,000,000)

 

 

풀이

이전에 A,B 관련 문제들에서 자주 사용했던 구조분해 할당 및 map(Number)를 통해 a, b 값을 각각 받아준 다음

절대값으로 반환하는 Math.abs()를 사용해 문제를 해결할 수 있었다.

const [a, b] = require('fs').readFileSync('/dev/stdin').toString().split(" ").map(Number)

console.log(Math.abs(a-b))
const [a, b] = '-2 5'.split(" ").map(Number)

console.log(Math.abs(a-b))

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2475번 검증수  (0) 2023.03.06
[백준 JS] 2438번 별 찍기 - 1  (0) 2023.03.06
[백준 JS] 1330번 두 수 비교하기  (0) 2023.03.05
[백준 JS] 1271번 엄청난 부자2  (0) 2023.03.05
[백준 JS] 1008번 A/B  (0) 2023.03.05

문제

두 정수 A와 B가 주어졌을 때, A와 B를 비교하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 A와 B가 주어진다. A와 B는 공백 한 칸으로 구분되어져 있다.

 

 

풀이

A와 B가 들어가는 문제들과 같은 방식으로 

구조분해할당, .map(Number)을 사용해 a와 b 값을 받아온 다음

해당 값의 비교를 조건문으로 판단해 대소비교 결과를 출력하는 문제였다.

 

if문으로 조건을 걸어 비교를 한 다음

각각의 경우마다 직접 ">", "<", "=="를 출력해도 괜찮으며

result를 출력한다는 사실을 알려주고 싶으면 최종적인 결과를 출력해도 된다.

 

if else를 사용할 경우 조건이 만족한 하나만 처리되기 때문에

추가적인 연산이 더 많이 들어가거나 하지는 않으며

result라는 변수의 저장에 약간의 메모리가 더 소모될 것 같다.

(실제 테스트 결과 둘의 메모리 및 시간 차이는 유의미하지 않아 보였다)

위(console.log로 바로 출력), 아래(result 선언 후 값 저장 후 if 처리한 다음 result 출력)

const [a,b] = require('fs').readFileSync('/dev/stdin').toString().split(" ").map(Number)

let result
if(a>b){
    result = '>'
}
else if(a===b){
    result = '=='
}
else if(a<b){
    result = '<'
}
console.log(result)
const [a,b] = '10 2'.split(" ").map(Number)

let result
if(a>b){
    result = '>'
}
else if(a===b){
    result = '=='
}
else if(a<b){
    result = '<'
}
console.log(result)

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2438번 별 찍기 - 1  (0) 2023.03.06
[백준 JS] 2420번 사파리 월드  (0) 2023.03.06
[백준 JS] 1271번 엄청난 부자2  (0) 2023.03.05
[백준 JS] 1008번 A/B  (0) 2023.03.05
[백준 JS] 1001번 A-B  (0) 2023.03.05

문제

갑부 최백준 조교는 동전을 최소로 바꾸는데 성공했으나 김재홍 조교가 그 돈을 발견해서 최백준 조교에게 그 돈을 나누자고 따진다.

그 사실이 전 우주로 알려지자 우주에 있던 많은 생명체들이 자신들에게 돈을 분배해 달라고 당장 달려오기 시작했다.

프로토스 중앙 우주 정부의 정책인, ‘모든 지적 생명체는 동등하다’라는 규칙에 입각해서 돈을 똑같이 분배하고자 한다.

한 생명체에게 얼마씩 돈을 줄 수 있는가?

또, 생명체들에게 동일하게 분배한 후 남는 돈은 얼마인가?

 

 

입력

첫째 줄에는 최백준 조교가 가진 돈 n과 돈을 받으러 온 생명체의 수 m이 주어진다. (1 ≤ m ≤ n ≤ 10^1000, m과 n은 10진수 정수)

 

 

풀이

입력값이 10의 1000제곱이기 때문에 number type에서는 감당할 수 없고

큰 수는 모두 BigInt를 사용해야만 한다.

 

그렇기 때문에 일반적으로 BigInt값으로 변환해서 써야 하기 때문에

기존의 .map(Number) 대신 .map(BigInt)를 사용했다.

 

BigInt의 형태는 1n 2n 3n 등 뒤에 n이 붙어있는 형태로

원하는 출력 형태인 숫자와는 다른 모습을 가지고 있기 때문에

String으로 감싸는 등 문자열로 바꿔줘야 n이 제거된다.

 

또한 BigInt는 +, -, *, **, %연산을 정상적으로 처리하지만

나누기 연산(/)은 제대로 처리하지 못하는데

MND를 참고하자면 아래의 설명과 같이 소수점이하가 사라진다는 것을 알 수 있다.

곰은 사람을 찢고 BigInt는 소수점을 버려!

마지막으로 백준 문제를 풀면 주의해야 하는 점이 있는데 바로 .trim()이다.

백준에서는 input값을 지 멋대로 넣어주기 때문에 '12 23'과 같은 형태로 들어올 것이라고 기대하지만

' 12 34' 또는 '12 34 '처럼 앞뒤에 마음대로 공백이 들어올 수 있고 

그런 경우 input이 이상하게 들어와서 ["", "a", "b"] 형태로 배열이 되어버리고

구조분해할당 또는 a = input[0]과 같은 형태로 값을 받을 경우 엉망이 되는 것을 모르고 

오답이라는 메세지만 반복해서 받으며 포기하고 싶어질 수 있다.

 

.trim()으로 앞뒤 공백을 제거하는 것을 잊지말자.

const [a,b] = require('fs').readFileSync('/dev/stdin').toString().trim().split(" ").map(BigInt)
console.log(String(a/b))
console.log(String(a%b))
const [a,b] = '1000 100'.split(" ").map(BigInt)
console.log(String(a/b))
console.log(String(a%b))

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2420번 사파리 월드  (0) 2023.03.06
[백준 JS] 1330번 두 수 비교하기  (0) 2023.03.05
[백준 JS] 1008번 A/B  (0) 2023.03.05
[백준 JS] 1001번 A-B  (0) 2023.03.05
[백준 JS] 1000번 A+B  (0) 2023.03.04

문제

두 정수 A와 B를 입력받은 다음, A/B를 출력하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

 

 

풀이

A/B는 이전 A+B, A-B와 같이 연산을 해결하면 되는 문제로 

반올림을 요구하거나 소숫점 몇번째 자리까지만 구하라는 출력 형태가 있지 않기 때문에

단순히 입력값을 받아 A/B로 처리하면 해결할 수 있는 문제다.

const [a, b] = require('fs').readFileSync('/dev/stdin').toString().split(' ').map(Number)
console.log(a/b);
const [a, b] = '1 2'.split(' ').map(Number)
console.log(a/b);

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2420번 사파리 월드  (0) 2023.03.06
[백준 JS] 1330번 두 수 비교하기  (0) 2023.03.05
[백준 JS] 1271번 엄청난 부자2  (0) 2023.03.05
[백준 JS] 1001번 A-B  (0) 2023.03.05
[백준 JS] 1000번 A+B  (0) 2023.03.04

문제

두 정수 A와 B를 입력받은 다음, A-B를 출력하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

 

 

풀이

A-B는 또한 A+B와 마찬가지로 단순히 a-b의 연산을 처리해주면 되는 문제로

a-b를 console.log로 출력했다.

 

이번에도 구조분해 할당을 통해 a,b값을 나눠 출력했다.

또한 이전에는 설명을 까먹었는데 split(' ')을 통해 공백을 제거하고 배열화 했으며

.map(Number)를 통해 각각 Number() 처리를 진행해 string type에서 number type으로 변경했다.

 

일반적인 백준의 숫자로 된 내용들은 모두 .map(Number)를 사용하는 것이 편리하다.

const [a, b] = require('fs').readFileSync('/dev/stdin').toString().split(' ').map(Number)
console.log(a - b);
const [a, b] = '1 2'.split(' ').map(Number)
console.log(a - b);

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2420번 사파리 월드  (0) 2023.03.06
[백준 JS] 1330번 두 수 비교하기  (0) 2023.03.05
[백준 JS] 1271번 엄청난 부자2  (0) 2023.03.05
[백준 JS] 1008번 A/B  (0) 2023.03.05
[백준 JS] 1000번 A+B  (0) 2023.03.04

문제

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

 

 

입력

첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)

 

 

풀이

A+B는 단순히 a+b의 연산을 처리해주면 되는 문제로

출력을 요구했기 때문에 a+b를 console.log로 출력했다.

 

다만 입력값을 받아올 때 구조분해할당을 사용해 [a,b]형태로 받아왔다는 것이 차이가 있으며

일반적으로는 const input = xxxx 형태로 받은 다음 input을 다시 가공하는 방식을 사용하기도 한다.

const [a, b] = require('fs').readFileSync('/dev/stdin').toString().split(' ').map(Number)
console.log(a + b);
const [a, b] = '1 2'.split(' ').map(Number)
console.log(a + b);

'알고리즘 > 백준' 카테고리의 다른 글

[백준 JS] 2420번 사파리 월드  (0) 2023.03.06
[백준 JS] 1330번 두 수 비교하기  (0) 2023.03.05
[백준 JS] 1271번 엄청난 부자2  (0) 2023.03.05
[백준 JS] 1008번 A/B  (0) 2023.03.05
[백준 JS] 1001번 A-B  (0) 2023.03.05

핵심만 먼저 말하자면 객체의 키/값 추가는 O(NlogN)정도의 시간복잡도를 가진다고 한다.

(정확하지는 않고 O(N)이상의 시간복잡도를 가진다고만 알아둬도 괜찮다)

 

문제를 풀던 도중 효율성에서 100점을 맞지 못했다.

시간복잡도를 생각하며 문제를 풀었다고 생각했는데 의아했고

다른 방식으로 문제를 풀어 제출했더니 100점이 나왔다.

사실 여기서 중요한 것은 100점이 나왔다는 것이 아니라

더 좋은 시간복잡도를 가지고 있는데 100점이 나오지 않았던 코드였다.

(코드는 하단에 있다)

 

분명 sort를 사용한 문제는 시간복잡도 O(NlogN)이 나올거고

객체를 사용한 문제는 시간복잡도 O(N)이 나올거라고 생각했는데

아래와 같은 코드 작성을 통해 시간을 계산해봐도 문제는 객체일 수 밖에 없었다.

(sort를 사용한 것이 훨씬 더 빨랐으며 100만단위 규모(문제 사이즈)에서 12배가량 빨랐다)

function solution(A) { //내가 생각하는 O(NlogN)
    let arr = A.sort((a,b) => a-b)
    let start = A.indexOf(1) 
    if(arr.indexOf(1) === -1){
        return 1
    }
    else{
        for(let i = start ; i < arr.length ; i++){
            if(arr[i+1] > arr[i]+1){
                return arr[i]+1
            }
        }
        return arr[arr.length-1]+1
    }
}

function solutionTwo(A) { //내가 생각했던 O(N)
    let obj = {}
    for(let i = 0 ; i < A.length ; i++){
        obj[A[i]] = 1
    }
    for(let i = 1 ; i <= 100000 ; i++){
        if(obj[i] === 0) return i
    }
}
let arr = []
for(let i = 10000000; i > -10000000 ; i--){ //정렬이 우세해서 비정렬 상태로 만들었다
    arr.push(i)
}
let befor = Date.now()
solution(arr)
let after = Date.now()
let beforT = Date.now()
solutionTwo(arr)
let afterT = Date.now()

console.log(after-befor, afterT-beforT)

 

 

객체의 시간복잡도를 검색해도 객체 자체에 대한 이야기는 나오지 않았고

오히려 공식문서 등에서는 시간복잡도에 대한 언급조차 되지 않았다.

 

외국인들이 쓴 칼럼을 봐도 객체 짱짱맨!! 같은 찬양글만 보였을 뿐이고

나와 같은 궁금증을 가진 사람은 없는 것 같았다.

 

도움의 손길을 찾아보다가 문득 얼마 전 멘토님이 보내주셨던 리뷰에서

부담없이 질문해도 괜찮다는 말씀이 생각났고

질문을 드리니 생각해보지 않았던 말씀을 해주셨다.

 

당연하지만 생각해보지는 않았던 부분

 

시간복잡도 계산에서 조건동일에 대한 부분을 언급하는 것을 본 기억이 없었는데(좀 당연하기도 하지만)

처리갯수(N)과 관련되지 않은 다른 부분에서 동작마다 시간이 다를 수 있다는 것이 새로웠고

그 뒤에 말씀해주신 객체에 값을 추가할 때 정렬된다는 놀라운 사실을 알려주셨다.

객체의 배신..!!!

 

간단결론

결국 객체에 값을 할당하고 읽는 작업에는 우리가 생각하는 O(1)의 시간이 소모되지만

키 자체를 추가하면 재정렬이 계속 들어가기 때문에 O(N?/정렬시간)*O(N/for문 1회)이 진행된 것이었다.

 

그래서 평소에는 대규모 데이터를 처리하면서 고정된 몇개의 키를 사용했기 때문에 시간복잡도 정렬문제를 겪지 않았고

그로 인해 객체를 맹신하게 된 것이었고

이번에는 모든 값들이 다 달랐기 때문에(내가 만든 수치지만) 정렬을 N번 진행해버리는 참사가 벌어진 것이었다.

 

대규모 데이터에서 소규모 키 변동인 경우에는 객체가 유리하고

대규모 데이터에서 서로 다 다른 값인 경우에는 객체가 불리한 것이라고 마무리할 수 있다.

(배열에 넣고 정렬때리면 NlogN이지만 정렬해가며 추가하는 것은 N*정렬이기 때문에)

 

@멘토님의 대화를 보던 중 생각난 포인트 하나 더 추가

+ Recent posts