이 페이지는 코딩도장 데이터의 읽기 전용 정적 보관본입니다.

버전비교(풀버전)

연관문제: 버전비교

원문: Semantic Versioning 2.0.0, (한글번역) 유의적 버전 2.0.0

라이센스 를 표기해줘야 한답니다.

문제

소프트웨어 버전들을 입력 받아, 우선순위가 높은 순서로 출력하시오.

위 글에서 형식 부분만 정리했습니다.

배포 버전

예) 0.1.0, 1.5.0, 4.12.2

X.Y.Z 로 표기한다. X, Y, Z 모두 0 이상의 정수이다.

0을 앞에 붙이지 않는다 (예: 1.03.0 (X), 1.3.0 (O))

pre-release 버전

예) 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92

X.Y.Z 뒤에 붙임표 "-"를 넣고, 마침표 "."로 구분된 1개 이상의 식별자(id)를 붙인다.

식별자(id)는 한 글자 이상이다(예: 1.0.0-1..1 (X), 1.0.0-1.0.1 (O))

식별자(id)는 반드시 아스키(ASCII) 문자, 숫자, 붙임표로만 구성한다: [0-9A-Za-z-]

숫자 식별자 앞에 0을 붙이지 않는다.

빌드 메타데이터

예) 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85

X.Y.Z 뒤, 또는 pre-release 버전의 뒤에 "+"를 넣고, ,마침표(".")로 구분된 1개 이상의 식별자(id)를 붙인다.

식별자(id) 작성 규칙은 pre-release 버전에 기술한 바와 같다.

버전 우선순위 비교

대원칙

식별자를 차례로 비교해서 다른 부분이 나타나면 우선순위가 결정된다.

숫자로만 구성된 식별자는 수의 크기로 비교하고,

알파벳이나 붙임표 "-" 가 포함된 경우에는 아스키 문자열 정렬을 한다.

(사전 순서를 의미하는 듯함)

비교 방법

1) X.Y.Z 에서 X, Y, Z 를 차례로, 숫자로서 비교한다.

1.0.0 < 2.0.0 < 2.1.0 < 2.1.1

마침표 "." 는 소수점이 아님을 주의하라. 아래의 예에서 비교 순서는 1 == 1 그리고 5 < 12 이다.

1.5.0 < 1.12.0

2). X.Y.Z 가 같으면 pre-release 버전의 우선순위가 더 낮다.

1.0.0-alpha < 1.0.0

3) 숫자로만 구성된 식별자는 그렇지 않은 식별자보다 우선순위가 무조건 더 낮다.

1.0.0-10 < 1.0.0-alpha

4) 빌드 메타데이터는 버전 우선순위에 영향이 없다.

아래 두 버전의 우선순위는 같다.

1.0.0-alpha+001, 1.0.0-alpha+exp.sha.5114f85

5) pre-release 버전에서 앞선 식별자가 모두 같으면 필드 수가 많은 쪽의 우선순위가 더 높다.

1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

입출력 예시

우선순위가 높은 순서대로 출력한다.

우선순위가 같으면 전체 길이가 긴 버전을 먼저 출력한다.

입력

1.2.0
1.0.0-beta+exp.sha.5114f85
1.12.0
1.0.0-beta.1.2
1.0.0-alpha
1.0.0-rc.1
1.0.0-rc.2
1.2.1
1.0.0-beta.2
1.0.0
1.10.0
1.0.0+20130313144700
1.0.0-alpha.beta
1.0.0-10
1.5.0
1.0.0-beta.11
1.0.0-alpha.1
1.0.0-alpha+001
1.0.0-beta.1

출력

빈 줄은 보기 편하도록 넣었으니 실제 출력할 때는 없어도 관계없습니다.

1.12.0
1.10.0
1.5.0
1.2.1
1.2.0

1.0.0+20130313144700
1.0.0

1.0.0-rc.2
1.0.0-rc.1

1.0.0-beta.11
1.0.0-beta.2
1.0.0-beta.1.2
1.0.0-beta.1
1.0.0-beta+exp.sha.5114f85

1.0.0-alpha.beta
1.0.0-alpha.1
1.0.0-alpha+001
1.0.0-alpha

1.0.0-10

2018/09/04 01:42

Noname

+1 출력 예시 pre release 우선순위 거꾸로 된 듯 합니다 - Creator, 2018/09/06 19:14
감사합니다. 수정했습니다. - Noname, 2018/09/07 14:46

2개의 풀이가 있습니다.

def ver(x):
  length = len(x)
  m = x.find('+')
  if m > -1: x = x[:m]
  p = x.find('-')
  if p == -1:
    return [[int(i) for i in x.split('.')], 1, length]
  else:
    pre = x[p+1:].split('.')
    tmp = max(len(i) for i in pre)
    return [[*map(int, x[:p].split('.'))], 0, [i.zfill(tmp) if i.isdigit() else i for i in pre], length]

test = '''\
1.2.0
1.0.0-beta+exp.sha.5114f85
1.12.0
1.0.0-beta.1.2
1.0.0-alpha
1.0.0-rc.1
1.0.0-rc.2
1.2.1
1.0.0-beta.2
1.0.0
1.10.0
1.0.0+20130313144700
1.0.0-alpha.beta
1.0.0-10
1.5.0
1.0.0-beta.11
1.0.0-alpha.1
1.0.0-alpha+001
1.0.0-beta.1'''
test = [i.strip() for i in test.splitlines()]

for i in sorted(test, key=ver, reverse=True): print(i)
1.12.0
1.10.0
1.5.0
1.2.1
1.2.0
1.0.0+20130313144700
1.0.0
1.0.0-rc.2
1.0.0-rc.1
1.0.0-beta.11
1.0.0-beta.2
1.0.0-beta.1.2
1.0.0-beta.1
1.0.0-beta+exp.sha.5114f85
1.0.0-alpha.beta
1.0.0-alpha.1
1.0.0-alpha+001
1.0.0-alpha
1.0.0-10

2018/09/06 18:44

Creator

# 유효성 검사는 하지 않는다.
class Identifier(str):
    def __lt__(self, other):
        if self.isdigit() and other.isdigit():
            return int(self) < int(other)
        else:
            return str(self) < str(other)


class Version(str):
    def __init__(self, src):
        super().__init__()
        self.rel, self.pre = [], []

        if '+' in src:
            src = src[:src.index('+')]

        if '-' in src:
            i = src.index('-')
            self.pre = [Identifier(x) for x in src[i + 1:].split('.')]
            src = src[:i]

        self.rel = [Identifier(x) for x in src.split('.')]

    def __lt__(self, other):
        if self.rel != other.rel:
            return self.rel < other.rel
        else:
            # X.Y.Z 같음
            if not self.pre and not other.pre:
                return len(self) < len(other)   # release X 2
            elif bool(self.pre) != bool(other.pre):
                return bool(self.pre) # pre-relese, release
            else:
                # pre-release X 2
                if self.pre == other.pre:
                    return len(self) < len(other)
                else:
                    return self.pre < other.pre


versions = [Version(x) for x in inp_str.split('\n')]
print('\n'.join(sorted(versions, reverse=True)))

2018/09/14 00:35

Noname

목록으로