트랙
/
AWK
AWK
/
연습 문제
/
최고 점수
최고 점수

최고 점수

쉬움

지침

게임 플레이어의 최고 점수 목록을 관리해요.

이번 과제는 역사상 가장 많이 팔린, 가장 중독성 있는 게임 중 하나이자 아케이드 시대의 고전인 Frogger 게임의 최고 점수 컴포넌트를 만드는 거예요. 목록에서 가장 높은 점수와 마지막으로 추가된 점수, 그리고 가장 높은 점수 세 개를 반환하는 메서드를 작성해요.

AWK에서 정렬하기

이 연습 문제는 출력을 특정한 방식으로 정렬해야 해요. 많은 프로그래밍 언어와 마찬가지로, 배열을 순회하는 순서는 구현에 따라 달라지고 겉보기에는 무작위처럼 보여요. 보통 사람이 보고 싶어 하는 순서는 이게 아니죠. GNU awk는 몇 가지 정렬 기능을 제공해요.

  1. asort: 숫자로 인덱싱된 배열을 배열의 _값_을 기준으로 정렬해요.

    #!gawk 
    BEGIN {
        for (i = 1; i <= 5; i++)
            nums[i] = int(100 * rand())
    
        # returns the array size
        n = asort(nums, sorted)
    
        for (i = 1; i <= n; i++)
            print i, nums[i], sorted[i]
    }
    

    이렇게 출력돼요

    1 92 30
    2 59 57
    3 30 59
    4 57 74
    5 74 92
    

    n = asort(array) 형태는 지정한 배열을 제자리에서 정렬해요.

    이 방법은 숫자로 인덱싱된 배열에 가장 유용해요. sorted 배열을 채우는 과정에서 원래 배열의 인덱스는 버려져요. sorted 배열은 1부터 n까지의 인덱스를 가져요.

  2. asorti: 배열을 배열의 _인덱스_를 기준으로 정렬해요.

    asorti 함수는 "원본" 배열의 인덱스를 정렬한 값을 담은 "대상" 배열을 채워요.

    #!gawk
    BEGIN {
        nums["foo"] = int(100 * rand())
        nums["bar"] = int(100 * rand())
        nums["qux"] = int(100 * rand())
    
        print "unordered"
        for (i in nums)
            print i, nums[i]
    
        print "ordered by index"
        n = asorti(nums, sorted)
        for (i = 1; i <= n; i++)
            print sorted[i], nums[sorted[i]]
    }
    

    이렇게 출력돼요

    unordered
    foo 92
    qux 30
    bar 59
    ordered by index
    bar 59
    foo 92
    qux 30
    
  3. PROCINFO["sorted_in"]: 지정한 순서대로 배열을 순회해요.

    내장 PROCINFO 배열에는 실행 중인 awk 프로세스에 관한 많은 정보가 들어 있어요. 이 배열에서 흥미로운 원소 중 하나가 sorted_in이에요. 이 배열 키의 값은 for (indx in array) 루프에서 배열 인덱스를 처리하는 순서를 제어하는 함수의 이름이에요.

    이 함수는 사용자가 정의한 함수의 이름일 수도 있고, 다음과 같이 편리하게 미리 정의된 정렬 함수들 중 하나일 수도 있어요.

    • "@ind_str_asc", "@ind_str_desc": 인덱스를 기준으로 알파벳순으로 정렬해요. 오름차순 또는 내림차순이에요.
    • "@ind_num_asc", "@ind_num_desc": 인덱스를 기준으로 숫자순으로 정렬해요. 오름차순 또는 내림차순이에요.
    • "@val_str_asc", "@val_str_desc": 값을 기준으로 알파벳순으로 정렬해요. 오름차순 또는 내림차순이에요.
    • "@val_num_asc", "@val_num_desc": 값을 기준으로 숫자순으로 정렬해요. 오름차순 또는 내림차순이에요.

    위의 asort 예제는 이렇게 구현할 수 있어요:

    PROCINFO["sorted_in"] = "@val_num_asc"
    for (idx in nums)
        print idx, nums[idx]
    
    3 30
    4 57
    2 59
    5 74
    1 92
    

    asorti 예제는 이렇게 쓸 수 있어요:

    PROCINFO["sorted_in"] = "@ind_str_asc"
    for (idx in nums)
        print idx, nums[idx]
    
    bar 59
    foo 92
    qux 30
    

    이 방법을 쓰면 임시 sorted 배열과 n 반환값을 따로 만들지 않아도 돼요. 깔끔하고 좋아요.

사용자 정의 정렬 함수

사용자 정의 정렬 함수는 매개변수 네 개를 받아요. 한 배열 원소의 인덱스와 값, 그리고 다른 배열 원소의 인덱스와 값이에요:

function compare(idx1, val1, idx2, val2) {...}

반환값은 다음과 같아요:

  • 0보다 작으면: idx1이 idx2보다 앞에 와요.
  • 0보다 크면: idx1이 idx2보다 뒤에 와요.
  • 0이면: 두 인덱스의 정렬 우선순위가 같지만, 서로의 순서는 정해져 있지 않아요.

for (idx in array) 순서를 제어하는 PROCINFO["sorted_in"] 외에도, asort와 asorti는 둘 다 비교 함수의 이름을 세 번째 매개변수로 받을 수 있어요.

참고 자료


출처

80년대 아케이드 게임 Frogger에 대한 오마주
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
AWK Exercism

최고 점수 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 AWK 트랙을 개념 3개연습 문제 92개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.