링크 https://www.acmicpc.net/problem/1550
문제 16진수 수를 입력받아서 10진수로 출력하는 프로그램을 작성하시오.
입력 첫째 줄에 16진수 수가 주어진다. 이 수의 최대 길이는 6글자이다. 16진수 수는 0~9와 A~F로 이루어져 있고, A~F는 10~15를 뜻한다. 또, 이 수는 음이 아닌 정수이다.
출력 첫째 줄에 입력으로 주어진 16진수 수를 10진수로 변환해 출력한다.

 

Python 3

result = int(input(), 16)
print(result)

 

Kotlin (JVM)

import java.util.Scanner

fun main(args: Array<String>) {
    val sc: Scanner = Scanner(System.`in`)
    val result = sc.nextInt(16)
    println(result)
}
fun main() {
    val input = readLine()
    if (!input.isNullOrEmpty()) {
        val result = input.toInt(16)
    	println(result)
    }
}

 

node.js

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString();
var result = parseInt(input, 16);
console.log(result);
const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
rl.on("line", function(line) {
    input = line.toString(16);
    let result = parseInt(input, 16);
    console.log(result);
}).on("close", function() {
    process.exit();
});

 

 

링크 https://www.acmicpc.net/problem/1271
문제 갑부 최백준 조교는 동전을 최소로 바꾸는데 성공했으나 김재홍 조교가 그 돈을 발견해서 최백준 조교에게 그 돈을 나누자고 따진다.
그 사실이 전 우주로 알려지자 우주에 있던 많은 생명체들이 자신들에게 돈을 분배해 달라고 당장 달려오기 시작했다.
프로토스 중앙 우주 정부의 정책인, ‘모든 지적 생명체는 동등하다’라는 규칙에 입각해서 돈을 똑같이 분배하고자 한다.
한 생명체에게 얼마씩 돈을 줄 수 있는가?
또, 생명체들에게 동일하게 분배한 후 남는 돈은 얼마인가?
입력 첫째 줄에는 최백준 조교가 가진 돈 n과 돈을 받으러 온 생명체의 수 m이 주어진다. (1 ≤ m ≤ n ≤ 10의 1000승, m과 n은 10진수 정수)
출력 첫째 줄에 생명체 하나에게 돌아가는 돈의 양을 출력한다. 그리고 두 번째 줄에는 1원씩 분배할 수 없는 남는 돈을 출력한다.

 

간단한 나눗셈 문제 같지만 사실 숫자 타입을 묻는 문제다. 10의 1000승은 Double을 넘는 범위로, BigInteger로 처리해야 한다. 파이썬은 int()에서 타입을 자동으로 처리하지만 코틀린과 node.js는 그렇지 않다.

 

 

Python 3

input = input().split()
n = int(input[0])
m = int(input[1])
print(n // m)
print(n % m)
n, m = map(int, input().split())
print(n // m)
print(n % m)

 

Kotlin (JVM)

import java.util.Scanner

fun main(args: Array<String>) {
    val sc: Scanner = Scanner(System.`in`)
    val n = sc.nextBigInteger()
    val m = sc.nextBigInteger()
    println(n / m)
    println(n % m)
}
fun main() {
    val input = readLine()?.split(" ")
    if (!input.isNullOrEmpty()) {
        val n = input[0].toBigInteger()
        val m = input[1].toBigInteger()
        println(n / m)
        println(n % m)
    }
}

 

node.js

const fs = require("fs");
const input = fs.readFileSync('/dev/stdin').toString().split(" ");
var n = BigInt(input[0]);
var m = BigInt(input[1]);
var quotient = (n / m).toString();
var remainder = (n % m).toString();
console.log(quotient);
console.log(remainder);
const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
rl.on("line", function(line) {
    input = line.split(" ");
    let n = BigInt(input[0]);
    let m = BigInt(input[1]);
    let quotient = (n / m).toString();
    let remainder = (n % m).toString();
    console.log(quotient);
    console.log(remainder);
}).on("close", function() {
    process.exit();
});

 

 

링크 https://www.acmicpc.net/problem/1001
문제 두 정수 A와 B를 입력받은 다음, A-B를 출력하는 프로그램을 작성하시오.
입력 첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)
출력 첫째 줄에 A-B를 출력한다.

 

Python 3

num = input().split()
a = int(num[0])
b = int(num[1])
print(a - b)
a, b = map(int, input().split())
print(a - b)

 

Kotlin (JVM)

import java.util.Scanner

fun main(args: Array<String>) {
	val sc: Scanner = Scanner(System.`in`)
	val a = sc.nextInt()
	val b = sc.nextInt()
	println(a - b)
}
fun main() {
	val input = readLine()?.split(" ")
	if (!input.isNullOrEmpty()) {
		val a = input[0].toInt()
		val b = input[1].toInt()
		println(a - b)
	}
}

 

node.js

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().split(" ");
var a = parseInt(input[0]);
var b = parseInt(input[1]);
console.log(a - b);
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on("line", function(line) {
    input = line.split(" ");
	let a = parseInt(input[0]);
	let b = parseInt(input[1]);
	console.log(a - b);
}).on("close", function() {
	process.exit();
});

 

 

링크 https://www.acmicpc.net/problem/1000
문제 두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.
입력 첫째 줄에 A와 B가 주어진다. (0 < A, B < 10)
출력 첫째 줄에 A+B를 출력한다.

 

Python 3

num = input().split()
a = int(num[0])
b = int(num[1])
print(a + b)
a, b = map(int, input().split())
print(a + b)

 

Kotlin (JVM)

import java.util.Scanner

fun main(args: Array<String>) {
    val sc: Scanner = Scanner(System.`in`)
    val a = sc.nextInt()
    val b = sc.nextInt()
    println(a + b)
}
fun main() {
    val input = readLine()?.split(" ")
    if (!input.isNullOrEmpty()) {
        val a = input[0].toInt()
        val b = input[1].toInt()
        println(a + b)
    }
}

 

node.js

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().split(" ");
var a = parseInt(input[0]);
var b = parseInt(input[1]);
console.log(a + b);
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.on("line", function(line) {
    input = line.split(" ");
    let a = parseInt(input[0]);
    let b = parseInt(input[1]);
    console.log(a + b);
}).on("close", function() {
    process.exit();
});

백준 코드 13277번 문제 풀이

 

 

자바스크립트에서 큰 수는 지수로 표현되므로 문제에서 원하는 출력값으로 바꾸려면 문자열로 출력하거나 bigInt를 써야 한다.

 

첫 번째 답안(실패)

: 큰 수로 변환하는 것을 생각하지 못하고 그냥 숫자로 계산해서 틀림

const fs = require('fs');
const input = fs.readFileSync('/dev/stdin').toString().split(' ');

let results = Number(input[0]) * Number(input[1]);

console.log(results);

두 번째 답안(실패)

: 시간 초과

const input = ["893724358493284", "238947328947329"];

console.time("timeCheck");

let results = String(BigInt(input[0]) * BigInt(input[1]));

console.log(results); //213553048277135320552236238436

console.timeEnd("timeCheck"); //timeCheck: 5ms - 타이머 종료됨

세 번째 답안

const input = ["893724358493284", "238947328947329"];

console.time("timeCheck");

let shortNumber, longNumber;
let results = [];

if (input[0].length <= input[1].length) {
    shortNumber = input[0].split("").reverse();
    longNumber = input[1].split("").reverse();
} else {
    shortNumber = input[1].split("").reverse();
    longNumber = input[0].split("").reverse();
}

for (i = 0; i < shortNumber.length; i++) {
    for (j = 0; j < longNumber.length; j++) {
        let n = Number(shortNumber[i]) * Number(longNumber[j]);
        n = String(n).padStart(2, "0").split("");

        if (results[i + j] == undefined) {
            results[i + j] = 0;
        }
        if (results[i + j + 1] == undefined) {
            results[i + j + 1] = 0;
        }

        results[i + j] += Number(n[1]);
        results[i + j + 1] += Number(n[0]);
    }
}

results.forEach(function (value, i, results) {
    v = String(value).padStart(2, "0").split("");
    results[i] = v[1];
    results[i+1] += Number(v[0]);
});

if (isNaN(results[results.length-1])) {
    results.pop();
}
if (results[results.length-1] == "0") {
    results.pop();
}

results.reverse();
results = results.join("")
console.log(results);
console.timeEnd("timeCheck");

배울 점

 

 

 

첫 번째 답안

: 아까 공부한 divmod로 몫과 나머지 쉽게 가져오기

def solution(s):
    n, rest = divmod(len(s), 2)
    
    if rest == 0:
        answer = s[n - 1 : n + 1]
    else:
        answer = s[n]
        
    return answer
    

두 번째 답안

: 다른 방법은 없나 하고 생각해보다가 낸 결론인데 장씨가 첫 번째 답안이 낫다고 했다.

def solution(s):
    n = len(s) // 2
    a, b = s[:n], s[n:]

    if len(a) == len(b):
        answer = a[-1], b[0]
        answer = ''.join(answer)
    else:
        answer = b[0]

    return answer
    

 

배울 점

: 없다. 그냥 그런 문제였음. 그냥 좀 쉬운 게 나와서 좋았다.

 

 

첫 번째 답안

: 리스트에 값을 넣을 때 insert로 넣어서 reverse하지 않고도 값을 쓸 수 있게 함. enumerate를 알고도 쓰지 못했는데 드디어 써 봄. 근데 첨에 값을 두 개(idx, x) 받게 써 놓고도 enumerate쓰지 않고 li만 써서 오류가 났었음. 인덱스와 값을 함께 받을 땐 enumerate 꼭 기억하자.

def solution(n):
    base = 3
    li = []
    while True:
        if n < base:
            li.insert(0, n)
            break
        else:
            li.insert(0, n % base)
            n = n // base
    answer = sum([x * (base ** idx) for idx, x in enumerate(li)])

    return answer

두 번째 답안

: 다른 사람의 답을 보고 divmod로 몫과 나머지를 함께 받는 방법을 배움. 그리고 다시금 join과 map을 쓸 수 있다는 것을 배움. 문자열은 join으로 합칠 수 있고, 이 문자열을 int(문자열, 진수)와 같이 넣으면 자동으로 해당 진수에 따라 값이 계산된다. 

def solution(n):
    base = 3
    li = []

    while n > 0:
        n, rest = divmod(n, base)
        li.append(rest)

    li = ''.join(map(str, li))
    answer = int(li, base)

    return answer

 

배울 점

: 이미 한 번 다른 사람의 코드를 봐서 아는 것들도 실제로 내가 떠올려서 쓸 수 없으면 무용지물이다. 코드를 배운 뒤에는 공부한 코드를 덮어두고 다시 처음부터 시작하는 마음으로 코드를 짜 봐야 한다. 그래야 배웠던 것을 떠올려서 스스로 쓸 수 있게 될 거다.

 

첫 번째 답안

: datetime 모듈을 불러오고 요일의 줄임말로 바꾼 뒤 upper로 대문자 처리

import datetime

def solution(a, b):
    year = 2016
    date = datetime.date(2016, a, b)
    day = date.strftime('%a')
    answer = day.upper()

    return answer
    

두 번째 답안

: 축약해서 제출함

import datetime

def solution(a, b):
    date = datetime.date(2016, a, b)
    answer = date.strftime('%a').upper()

    return answer
    

세 번째 답안

: 그런데 다른 사람의 답안을 보니 모듈을 쓰지 않고 계산하는 방법이 있었다. 2016년 1월 1일이 금요일이므로 5를 더해서 계산하고, 하루를 뺀 뒤에 7로 나눈다.

def solution(a, b):
    days = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]
    dayLen = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    firstday = 5
    
    return days[(sum(dayLen[:a-1]) + b + firstday - 1) % 7]
    

배울 점

: 모듈을 쓰지 않고 간단하게 계산할 수 있는 방법도 찾자.

 

첫 번째 답안

: 답은 맞췄지만 알아보기 어렵고 지저분하다. 그리고 start, end, k에 x[0], x[1], x[2]라고 값을 직접 입력한 것도 불필요하다. 리스트가 길어질수록 입력받는 변수 목록을 하나하나 작성하는 것도 오래 걸릴 거다.

def solution(array, commands):
    n = len(commands)
    start = [x[0] - 1 for x in commands]
    end = [x[1] for x in commands]
    k = [x[2] - 1 for x in commands]
    answer = []

    for idx in range(n):
        answer.append(array[start[idx]:end[idx]]) # 슬라이스
        answer[idx] = sorted(answer[idx])[k[idx]] # k번째 숫자 찾기

    return answer

두 번째 답안

: 다른 사람들의 답안을 보고 변수 값을 한 줄로 받는 것을 참고했다. 훨씬 깔끔하다. 그리고 인덱스 번호를 쓸 때는 안에 쓰는 숫자를 띄어서 쓰지 말아야 한다는 것도 알았다. 띄어서 쓰면 더 알아보기 힘들다. 

def solution(array, commands):
    answer = []
    
    for command in commands:
        start, end, k = command
        li = array[start-1:end]      # slice
        li.sort()                    # sort
        answer.append(li[k-1])       # find k
        
    return answer

 

배울 점

: 다른 사람의 답안 중에 list와 map, lambda를 써서 한 줄로 해결한 것도 있었는데 대단하다는 생각은 들었지만 읽기가 너무 어려웠다. 그래서 내 최종 답안은 숏 코딩이 아니라 읽기 쉬운 것으로 정했다. 그래도 list와 map, lambda를 의식적으로 써 보는 연습을 해야겠다.

 

한참 삽질하면서 왜 안되는지 자가진단 하려고 짠 테스트 코드... 짜 놓고도 원인을 못 찾아서 문제였지만 그래도 comprehension 연습한 셈 치자.

import random

student_number = random.randint(2, 30)
lost_list = sorted(set(random.randint(1, student_number) for x in range(random.randint(1, student_number))))
reserve_list = sorted(set(random.randint(1, student_number) for x in range(random.randint(1, student_number))))

print("n      (%d)" % student_number)
print("lost   (%d) =" % len(lost_list), lost_list)
print("reserve(%d) =" % len(reserve_list), reserve_list)
print(solution(student_number, lost_list, reserve_list))

for 문의 범위 안에 있는 인자를 for 문 안에서 삭제해서 오류가 남. 한참 끙끙대다 if 문에서 reserve 조건을 처리해서 해결하나 싶었는데 학생 수만큼 도느라 lost에 [3, 4]가 있고 reserve에 [4]가 있을 때 3을 처리하면서 reserve의 4를 삭제해버려서 답이 틀리는 경우가 있었다. 그걸 보완해서 바로 제출한 게 아래 코드.

def solution(n, lost, reserve):
    for student in range(1, n + 1):
        if student in lost and student in reserve:
            lost.remove(student)
            reserve.remove(student)
        elif student in lost and student - 1 in reserve:
            lost.remove(student)
            reserve.remove(student - 1)
        elif student in lost and student + 1 in reserve:
            if student + 1 not in lost:
                lost.remove(student)
                reserve.remove(student + 1)
    answer = n - len(lost)

    return answer

그리고 좀더 깔끔하게 하고자 장 씨의 도움을 받은 게 아래 코드.

if를 두 번 쓴 이유는 조건이 위아래가 다르므로 구분하기 위함.

def solution(n, lost, reserve):
    for student in range(1, n + 1):
        if student not in lost:
            continue
        if student in reserve:
            lost.remove(student)
            reserve.remove(student)
        elif student - 1 in reserve:
            lost.remove(student)
            reserve.remove(student - 1)
        elif (student + 1 in reserve) and (student + 1 not in lost):
            lost.remove(student)
            reserve.remove(student + 1)
    answer = n - len(lost)

    return answer

for 문을 학생 수만큼 돌지 않아도 되므로 회전을 최소화하려고 lost로 돌게 만든 코드

마지막 elif 문처럼 여러 문이 중첩되어 있으면 구분하기 쉽게 괄호()를 넣어주는 게 좋다고 한다.

def solution(n, lost, reserve):
    recover_count = 0
    for student in lost:
        if student in reserve:
            recover_count += 1
            reserve.remove(student)
        elif student - 1 in reserve:
            recover_count += 1
            reserve.remove(student - 1)
        elif (student + 1 in reserve) and (student + 1 not in lost):
            recover_count += 1
            reserve.remove(student + 1)
            
    answer = n - (len(lost) + recover_count)
    return answer

집합은 교집합, 합집합, 차집합을 구할 수 있다. 교집합은 집합 사이에 &를 넣어 표기한다. 여기서 lost와 reserve를 교집합을 빼고 집합으로 for 문에 넘겼다. 이러면 .remove를 했을 때 list에서보다 처리가 빠르다.

def solution(n, lost, reserve):
    dupl = set(lost) & set(reserve)
    lost, reserve = set(lost) - dupl, set(reserve) - dupl
    answer = n - len(lost)
    
    for student in lost:
        if student - 1 in reserve:
            reserve.remove(student - 1)
            answer += 1
        elif student + 1 in reserve:
            reserve.remove(student + 1)
            answer += 1

    return answer

그 이유는 리스트에서 뭔가를 찾아서 지운다는 것은 아래처럼 for문으로 리스트 안에 있는 그 값을 찾아서 지우느라 시간이 걸리기 때문이다. 반면 사전형이나 집합은 hash이므로 바로 값을 찾아서 삭제할 수 있다. 그래서 처리 속도가 빨라지는 것이다.

_lost.remove(f)

def remove(f):
    for item in _lost:
        if item == f:
            del _lost[f]
            break

 

+ Recent posts