最高分

最高分

簡單

說明

管理遊戲玩家的高分陣列。

你的任務是為經典遊戲《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 回傳值。 乾淨俐落。

使用者自訂的排序函式

使用者自訂的排序函式接受 4 個參數: 一個陣列元素的索引和值,以及另一個陣列元素的索引和值:

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

回傳值代表:

  • 小於零:idx1 排在 idx2 前面
  • 大於零:idx1 排在 idx2 後面
  • 零:這兩個索引的排序優先順序相同,但它們的相對順序未定義。

除了用 PROCINFO["sorted_in"] 控制 for (idx in array) 的順序之外, asort 和 asorti 也都可以把比較函式的名稱當成第 3 個參數傳入。

參考資料


出處

向八〇年代大型電玩遊戲 Frogger 致敬
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
AWK Exercism

準備好開始 最高分 了嗎?

註冊 Exercism,透過 3 個概念92 個練習 和真人引導來學習並精通 AWK,全部免費。