프로그래머스의 코딩테스트 C# 버전 확인

C# 환경의 버전 확인

By 전경원

프로그래머스의 코딩테스트 문제를 풀다 보면 최신 버전의 C# 기능을 쓸 수 없다는 점을 알게 됩니다.

예를 들어 대표적으로 PriorityQueue를 쓸 수 없습니다.

시험 시간이 빠듯한 만큼, 지원하지 않는 문법 때문에 구현을 바꾸지 않으려면 지원 범위를 미리 파악할 필요가 있습니다.

지원되는 기능과 지원되지 않는 기능을 미리 파악해 두는 것

문제는 프로그래머스의 코딩테스트 환경에서 터미널에 접근할 수 없다는 점입니다. dotnet --version 같은 명령으로 확인할 수 없습니다. 직접 코드로 확인해야 합니다.

들어가기 전에

사실은 프로그래머스는 C# 컴파일러 버전을 공개하고 있습니다. 코딩테스트 연습 인터페이스의 오른쪽 위에 있는 컴파일 옵션을 클릭하면, 지원하는 언어의 컴파일러 버전과 컴파일 커맨드를 확인할 수 있습니다. C#의 컴파일러와 컴파일 커맨드는 아래와 같습니다.

  • 컴파일러: Mono C# Compiler 6.10.0
  • 컴파일 커맨드: mcs -out:FILENAME -r:System.dll

런타임 버전 확인하기

간단한 코드를 실행해 런타임 버전을 확인해 보겠습니다.

using System;

public class Solution {
    public int[] solution(int target) {
        int[] answer = new int[] {};
        Console.WriteLine(Environment.Version);
        return answer;
    }`
}

이 코드를 실행해보면,

...
출력 〉	4.0.30319.42000

런타임 버전 번호로 추정할 수 있는 .NET Framework 버전은 4.6~4.8 정도입니다. 이 버전에는 일반적으로 C# 6~7.3을 지원하는 컴파일러가 설치됩니다.

운좋게도 C# 7.1에서 지원하는 default literal을 시험해보다가 컴파일러가 지원하는 C# 버전을 확인할 수 있었다.

using System;

public class Solution {
    public int[] solution(int target) {
        int x = default;      // C# 7.1
        return new int[] { x + target };
    }
}
/Solution0.cs(5,17): error CS1644: Feature `default literal' cannot be used because it is not part of the C# 7.0 language specification

지원되는 C# 버전은 7.0

Tuple + Pattern Matching 문제

지원 C# 버전은 확인했지만, 프로그래머스 같은 온라인 저지는 컴파일러·런타임·참조 어셈블리의 구성에 따라 일부 기능만 깨질 수 있습니다. 따라서 주요 문법과 지원 라이브러리도 확인할 필요가 있습니다.

예를 들어 C# 7.0에서 처음 들어온 기능 가운데, 온라인 코딩테스트에서 유용한 튜플과 패턴 매칭을 함께 쓰면 문제가 발생할 수 있습니다.

using System;

public class Solution {
    public int[] solution(int target) {
        (int x, int y) t = (target, 1);

        if (t.x is int n) {
            return new int[] { n };
        }

        return new int[] { 0 };
    }
}
/Solution0.cs(7,17): warning CS0183: The given expression is always of the provided (`int') type
/Solution0.cs(7,17): error CS0584: Internal compiler error: constant in type pattern matching
/Solution0.cs(8,32): error CS0841: A local variable `n' cannot be used before it is declared

t.x는 이미 int로 확정된 값입니다. 이 경우 is int n은 항상 참이며, 특정 컴파일러 경로에서 내부 오류가 발생합니다. 패턴 매칭을 빼거나 박싱을 이용하면 피할 수 있습니다.

방법 1 — 패턴 매칭 제거

return new int[] { t.x };

방법 2 — object로 감싸기

object o = t.x;
if (o is int n) {
    return new int[] { n };
}

프로그래머스 C# 환경 정리

프로그래머스 C# 환경을 정리해 보겠습니다.

✔ 지원

  • C# 7.0 문법
  • Tuple 문법 및 분해
  • out var
  • local function
  • pattern matching
  • LINQ
  • Dictionary, HashSet, List, Queue, Stack
  • StringBuilder
  • BigInteger

✘ 미지원

  • C# 7.1 이상
  • default literal
  • PriorityQueue

결론

프로그래머스 C# 코딩테스트 환경은

C# 7.0 + .NET Framework 4.6 - 4.8 기반 환경

핵심은 두 가지입니다.

  1. C# 7.1 이상 기능은 쓰지 않습니다.
  2. PriorityQueue는 직접 구현하거나 대체합니다.
Tags: csharp pccp
Share: LinkedIn