아직 해결하지 못한 것들

[해결] 백준 2588 런타임에러

DesignThinker 2021. 10. 24. 12:55
import Foundation
let line = readLine()!
let lineArr = line.components(separatedBy: "\n")
let a = Int(lineArr[0])!
let b = lineArr[1]
let c = a * Int(String(b[b.index(b.startIndex, offsetBy: 2)]))!
let d = a * Int(String(b[b.index(b.startIndex, offsetBy: 1)]))!
let e = a * Int(String(b[b.index(b.startIndex, offsetBy: 0)]))!
let f = a * Int(b)!
print(c, d, e, f, separator: "\n")


위 코드는 런타임 에러를 발생시켰다.

런타임 에러가 무엇인지부터 차근차근 알아보자.

런타임 에러의 정의

코딩 이후 거치는 과정에 기반하여 여러 에러를 정의하고 있었다. (런타임 에러의 정의로 검색한 결과)

  1. 컴파일타임 에러
    컴파일 도중에 발생한 오류로, 대개 소스 코드의 문법적 오류로 인해 발생
  2. 링크타임 에러
    컴파일타임 오류와 같이 프로그램 실행 전 발생하는 오류의 하나. 프로그램에 필요한 리소스(그림, 문자열 등)나 라이브러리의 부재로 발생
  3. 런타임 에러
    프로그램이 동작 중 잘못된 데이터를 갖게되어 잘못된 처리를 진행하려 할 때, 프로그램 자체적으로나 또는 OS가 끼어들어 프로그램을 중단시키는 것

내 코드의 런타임 에러는 어디에 속할까

  1. 문법 오류 검토해보기 (컴파일타임 에러 검토)
    백준의 입력값을 상수로 설정하여 Playgound로 실행해보았을 때, 기대하는 출력값이 나왔다. 따라서 컴파일 오류는 아닐 것 같다.

  2. 프로그램에 필요한 리소스 검토하기 (링크타임 에러)
    이 알고리즘에서 필요한 리소스라고 하면 채점 과정에서 제공되므로 링크타임 에러는 아닐 것 같다.
  3. 잘못된 데이터를 가졌을까? (런타임 에러)
    한 줄에 하나씩 입력되는 세자리 자연수이다. 총 두 줄로 입력되는 것을 다음과 같이 입력했다.

    let line = readLine()!
    let lineArr = line.components(separatedBy: "\n")​
    처음 이 코드를 쓰게 된 것은 1 3 5 와 같은 식으로 공백으로 나뉘어진 입력값을 한줄에 받을 때 쓰던 코드를 응용한 것이었다.

    let line = readLine()!
    let lineArr = line.components(separatedBy: " ")​
     공백을 줄바꿈으로 응용해서 작성한 것을 의심해보았고 다른 사람들은 여러줄 입력을 어떻게 코드로 작성했는지 검색해보았다.

    let line1 = readLine()!
    let line2 = readLine()!
    아주 단순하게 readLine()을 두 번 작성하고 있었다.

    import Foundation
    let line1 = readLine()!
    let line2 = readLine()!
    let a = Int(line1)!
    let b = line2
    let c = a * Int(String(b[b.index(b.startIndex, offsetBy: 2)]))!
    let d = a * Int(String(b[b.index(b.startIndex, offsetBy: 1)]))!
    let e = a * Int(String(b[b.index(b.startIndex, offsetBy: 0)]))!
    let f = a * Int(b)!
    print(c, d, e, f, separator: "\n")​
    이 방법을 내 코드에 적용해보니 런타임에러가 발생하지 않았다.

회고: 줄바꿈으로 여러 값 입력받기

입력이 "첫째줄에 A와 B가 주어진다"라고 했을 때 다음과 같이 했다면,

let line = readLine()!
let lineArr = line.components(separatedBy: " ")

입력이 "첫째줄에 A가 주어지고 둘째줄에 B가 주어진다"라고 했을 때,

let line1 = readLine()!
let line2 = readLine()!

위와 같은 방법이 아닌, separatedBy를 줄바꿈("\n")으로 응용하는 것은 왜 런타임 에러를 발생시킬까?

let lineArr = line.components(separatedBy: "\n")

알고리즘 문제의 채점로직과 충돌했다고 해야할까?