又到了年末 Advent of Code 的時間了。關於這個活動還請參照去年的文章;不過鑑於去年前幾天發生的事情,今年新增了一條「禁止使用 AI 去登入全站排行榜」的規則——並沒有全面禁止 AI,只有不允許使用 AI 讓自己登入全站前百名的排行榜而已。算是個滿合理的限制就是了。
話說這一年來還真的沒多少文章貼出來過……在檯面下做的東西一直有在轉,但範圍稍微大了一點(有一個跟 Advent of Code 相關的東西差了最後那 5% 還沒完成,結果今年的又來了),工作又相對忙了一些(忙到連 GMTK Game Jam 2023 都沒能參加……那個週末整個累壞了),所以一直沒能貼些東西。
那麼照例繼續閱讀之後就是各題的簡要心得 (於是自然有各題的雷),然後也是照例文章押 12/1 發出,但之後每天題目做完都會來更新。原始碼整理在同一個 github repo 上了。
1. Trebushet?!
照例第一題是暖身題,不過可能因為今年一號在週五吧,今年的第一題有好些個陷阱在:
- Part 1 一行中只有一個阿拉伯數字:
這不太算是陷阱,但至少算是個要小跨一下的崁沒錯。 - Part 2 所給的文字中沒有 zero,由 one 開始:
所以如果只是單純建表然後迴圈跑就可能會有差一問題 ("one"
在[0]
之類的)。 - Part 2 數字之間可能重疊,例如範例的 eightwo:
所以如果是將文字取代成數字再套 part 1 的就可能會死;我在的 DC 群裡1有一個人就中了這招。
我則是因為一年沒有用 AOC 函式庫了,差點忘記要怎麼讀字串進來 XD。這題還不能用先前用過的只讀數字的招,因為即使只讀阿拉伯數字的 part 1 也是要把數字當成文字去取首位,全部讀成一個大數字再取就會很難搞。
2. Cube Conundrum
標準的輸入分析題。於是又是複習我的輸入函式庫的時候了。DC 群裡的某人把這種寫法叫做 slice spam,主要是因為 JavaScript 的字串有一個叫 .slice()
的函數可以將輸入字串以給定字串做分界點切開,所以這題的分析就會變成:用冒號切開,前面是第幾局;後面用分號切開,每一段是一次抽的結果;這一段用逗號切開,每一段是一種顏色;最後再用空格切開,[0] 是個數,[1] 是顏色。我的程式差不多也是一樣的邏輯,只是我是用我自己的切割函數就是了。
我其實一直覺得,字串處理練習題是測試一個程式初學者對他所學習的程式語言的熟悉度很棒的題材。這兩天的題目可以看出這一點:Day 1 part 2 是尋找子字串,Day 2 的輸入本身則是標準的字串拆分,而這兩天都很常看到 reddit 上有各種求救無從下手的提問;AoC 輸入檔案的多樣性可以讓人練習簡單程度的輸入分析,我覺得是件不錯的事。
3. Gear Ratios
結果今年的開場都是字串分析題嗎 XDDDDD 寫文當下還沒爬文,不過我可以想見會有不少人抓破頭想不到要怎麼做。
我的做法比較直接一點:Part 1 以數字為準,找到數字之後去四周看一看有沒有符號;Part 2 想了一下,發覺如果以符號為主條件會不太好寫,所以仍然使用原本以數字為準的找法,只是對周圍所有符號,如果是星號就記下這個位置有這個數字,然後最後再跑一次所有星號紀錄就行了。
之所以以符號為主條件不好寫的原因是:例如看到了一個星號。要怎麼判斷上面或下面的數字哪些是一起的,哪些是分開的?要怎麼從符號四周的數字去找出它的左右端點?這種問題的判斷條件很細節,很容易寫錯,然後就有一堆邊界條件要測試;但當有 part 1 的基礎程式碼之後,只要注意到 part 1 所判斷的條件其實就是建立了我們 part 2 所需要的連結——這個數屬於這裡的符號,那麼 part 2 就只是對這個連結進行反向查詢而已,不必要重新從另一端再次建立連結。
補註:結果稍微爬過 reddit 後發現最大的坑其實是 indexOf
類型的函數……至少看到有三個人掉到這個坑裡。主要問題在他們是先篩出數字再用 indexOf
類型函數回頭找位置,然後就被同一行中前面出現的相同數字給坑了。
補註的補註:寫上面這段話時我只看到三個,但看了一晚上我發現掉進這坑的人不是普通的多……會掉進去的幾乎都是支援 regex 搜尋的語言,如 python、javascript 等,大概因為有的是這種找出「字」而不是找出「位置」的函數才會掉進回頭搜尋搜錯地方的坑裡;嘛,認真說起來其實這類型的函數的回傳結果一定不只是找到什麼字,但我想從範例學程式的人應該很難會主動去找函式庫資料看有沒有其他東西可以用就是。
4. Scratchcards
終於回到了標準化輸入的題目了。這題是簡單的樂透對獎題,應該不是什麼困難的東西;大概因此 part 2 加了一個滾雪球式兌獎法,是個要想一下怎麼寫會比較容易的題目。
……只是我果然還是小看了思考一直線的人是怎麼想的。Reddit 上看到的問題主要是:用最直覺的方法滾雪球,所以一張中了三個就去呼叫後三個來算。這樣當然會遞迴爆炸啊……
5. If You Give A Seed A Fertilizer
今年的難度看起來會很飄:前五題是 1、3、5 偏難,2、4 偏簡單。
這題的題目敘述看起來很無辜:給定一連串的對應函數 (一個函數由多列 dest src len
表示,每一個這樣的列表示由 src 到 src+len-1 的值經過函數後依序變成 dest 到 dest+len-1),求給定值序列經過這一串函數後的最後結果中最小的那個。看起來很 OK 對吧?然後當你打開輸入檔發現所有數字都是 9 位 10 位的整數。好,那就用範圍比對一路查過去行了吧?然後 part 2 告訴你「噢,給你的這序列其實每一對數字是一個範圍,所以其實輸入值也有 (某 10 位數) 個」。
為此我在 part 1 到 part 2 中間把 part 1 裡寫在對照表裡的整數區間給完全重構出來,獨立成一個區間 class。好在各種細節上的實作沒有什麼問題,區間 class 搞定之後主邏輯一次通關;然後又讓我好好 (濫) 用了 <=>
這東西了。
6. Wait For It
雖然有其他做法,但這題對我來說是百分之百的數學題。
然後 part 2……Eric 你今年是不是有一個裏主題叫做防止暴搜啊 (笑死)。
7. Camel Cards
慣例2的撲克題。好在這題一來沒有順子,所以牌型判斷直接累計之後看累計數就好了;二來不排牌,牌的大小只和牌的順序有關 (而不是像一般撲克一樣要先看多張牌的牌值大小),所以直接把牌接成一個整數就能比大小了。
倒是 part 2 的鬼牌確實是神來一筆,好在我寫撲克練習題時都習慣把 A 當做 14 點來用,所以當 J 變成鬼牌時只要當 J 是 1 點就行了;牌型判斷則容易知道因為沒有順,所以所有鬼牌都當最多張的那個點數會最大,所以在牌型判斷的排序前先把鬼牌拿出來,排下去後再把鬼牌塞進最多張數的那格去。
然後我應該可以期待 reddit 上各種花式判斷牌型的條件式和鬼牌的處理 XD
8. Haunted Wasteland
這題我覺得 Eric 出壞了。雖然往年不是沒有過題目輸入只有所描述範圍的一小部份,但是這題也限縮的太小了;其中一個簡單解需要的性質不是那麼容易驗證的。嘛,不過考慮到前面題數有一大堆所謂「情理之中意料之外」的輸入,倒也不太能說 Eric 怎樣就是了。
Part 1 沒什麼好爭議的就是跑過去就對了,但 Part 2 就不是這樣了。理論上,要求這種共同目的應該要先求出每個迴圈的開頭,因為迴圈不一定會跑回原節點 (範例就已經不是了,只是個別 Z 的下一步等同於 A 的第一步);但看起來給定的輸入就是利用了類似於跑回原節點的方式讓求解者不用去算迴圈前的長度,直接把迴圈長度做 LCM 就是答案。不然的話就會需要中國剩餘定理了,而根據往年的經驗這並不是人人都能應用的技巧。(要用上中國剩餘定理的話這題可能要往後推至少一星期,像去年的 Day 17 那樣)
我會說出題出壞了的原因是,這個性質其實應該要在題目中提出來的,只是可能這故事的寫法讓 Eric 不太好整合吧,所以只有留下一個「A 尾和 Z 尾的個數一樣」的 (連一半都稱不太上的) 提示。
9. Mirage Maintenance
這真的是初級週末題嗎?!是啦,對初學者來說陣列管理是個中型的題材,但這感覺不像是個週末題……就算要把它放在週末這題也應該是 Day 3 這種暖身週末題才是。
題目沒什麼特別的,就照做就行了;注意到題目裡的遞迴結構這甚至有一個很自然的遞迴解。Part 2 也沒什麼特別的,就只是往前算而已。有人甚至發現了可以不用倒算回來的方法,還滿巧的。
……然後我今年就在這裡吃了第一次 WA。去年寫了個只讀數字的讀取函數,然後因為看起來就是一堆數字所以就拿來用了,然後就被輸入檔裡的負號給婊了。應該要直接用切開後轉換的函數的。(嘆氣) 然後在 reddit 發現還不只我一個人中招。(再次嘆氣)
10. Pipe Maze
Part 1 是個很簡單的 BFS 搜尋題,所以就把搜尋函式庫拿來用了;用 BFS 搜的話最後一個點就是最遠的點,那個點的距離就是所求了。
Part 2 則意外地是個計算幾何題。我貼到 reddit 上去的解法我在那裡把它叫做「皮克的鞋帶」,直接應用了兩個計算簡單多邊形的公式:皮克定理和鞋帶公式。
既然是計算幾何題,因此判斷點在圈內或圈外當然也有其他方式,但是因為我們的圈邊界和座標軸平行,例如像射線法可能會有射線和邊界重合的狀況,條件判斷會變得比較麻煩;我是在吃中餐時才想到有皮克定理可以拿來用。其他我也看過有把圖形放大,把原來的每個字放大成 3×3,然後就可以用淹水演算法來鑽過原題裡管線之間的洞的做法。
11. Cosmic Expansion
又是一個「Part 1 的『直覺』做法在 Part 2 被婊慘」的題型了。題目不難,但要做對確實需要一點組織;不過如果有期待到某個倍數會變大的話是可以做成 Part 1 只改一行就變成 Part 2 的解的。
然後我應該是找到一個在掃完 # 字之後只要排序+線性時間的做法了。
12. Hot Springs
於是這題是一維數織 (nonogram) 的題目。說起來這讓我想到我好久以前有寫過一個不怎麼樣的數織解題程式,它的解題邏輯全部靠在輸入題目時生成的每列所有種類,然後再去做篩選;想當然這支程式只能做像 15×15 這種小兒科的東西,像 50×50 那種一定沒救。
不過也是有寫過那玩意的經驗才馬上想到這題可以對 (列格, 線索索引) 的數對做 DP,存的是此列自此格之後的已知圖案配上線索列自此索引起的線索的種類數;求的時候就嘗試看看下一個線索能夠放在開始的什麼地方,取走之後查 DP 表即可。我是把它寫成記憶遞迴函數啦,不過概念是一樣的。
然後 part 2 果然沒讓我們失望,直接把輸入變成五倍!3還好這個 DP 做法的在兩個都變五倍時用的時間只有 25 倍,還是可以輕鬆搞定。
補註:居然 IOI 2016 有一題就是這題的再進階版……
13. Point of Incidence
應該是個沒什麼好說的一題。就連 part 2 的極暴力解應該都有機會跑完,問題應該只會在輸入分析跟眼殘吧。
不過倒是稍微研究了一下有沒有 Manacher 上場的機會;看起來只有 part 1 能用,part 2 會比較麻煩。(補註:有人實作出來了,可以參考看看)
14. Parabolic Reflector Dish
算是題很直接的模擬題。這題其實會讓我想到 2021 Day 25,同樣都是要把一群東西同時往某個方向移的題目;不過那題東西在移時如果前面有東西,不論前面是不是要移開一律自己不移;這題則是真的要考慮前面是不是要移開了。
我在 part 1 寫的是固定往上的函數,不過 part 2 這個動四個方向的我不想要複製一份改三次,所以還是多花了一點時間寫成把移動方向當成參數的函數。除錯寫了一堆,確定搞定之後換成迴圈偵測搞砸了,還因此吃了一個 WA……
最後的迴圈偵測是最暴力的那種,把要輸出的值跟當時的盤面給存起來,以輸出值當做一個很簡單的 hash 做迴圈偵測,看到輸出值一樣才去比對盤面,盤面比對一樣才算迴圈。
首頁的地圖終於到了最高點了,接下來要一路向下了吧 XD
15. Lens Library
今天是資料結構實作題,就是資料結構課程上到雜湊表時要你回去實作一個的那個練習題。所以沒什麼好說的。
不過星期五這麼簡單,是不是這個週末要有暴風雨 (?) 來臨了呢……
16. The Floor Will Be Lava
是個很普通的模擬題。是說我到解完了去看 reddit 文章時才發現這其實就是 BFS 搜尋……
說起來這題的題目跟今年我想在這段期間內做的事情有一點點重疊到了,所以其實有點嚇了一跳就是。
17. Clumsy Crucible
說好的最短路徑題終於來了。不過這次還多了一個梗:路線中直線長度只能在某個範圍裡——part 1 是 1 到 3,part 2 是 4 到 10。可能是因為格子上的最短路徑題很容易想說「一步就是一格」吧,我第一次的寫法裡把直線長度當成狀態的一部份來記了,然後還因此在 part 2 範圍有變時將狀態變成唯一值的函數發生碰撞了以致於吃了個 WA。
然後,在 reddit 上看討論才發現「對耶,我可以一次跨大一點」——不過其實我一開始的寫法就已經有一部份地用了這個點子了:在 part 2 要跨 4 到 10 步時,我為了不想另外寫說 1 到 3 步不允許轉彎,所以在轉彎時就已經是一口氣轉完後走 4 步了。從這裡改成一口氣跨 4 到 10 步只是再多跨一點格子 (和邏輯) 而已。這樣就可以不必把直線長度放到狀態裡了。(Repo 裡的 17large.cpp 即是整個改成這個方式的做法。)
18. Lavaduct Lagoon
Part 1 本來還在想說大概之後要對這張圖做事所以做了一些實際填圖的程式,結果 part 2 一出來直接笑死:原來這天的題目是鞋帶 (公式) 的逆襲 XD 就是要稍微想一下我們這個簡單多邊形的外框額外佔多少。
19. Aplenty
今天的 part 1 是基本的狀態機,比較複雜的除了分析輸入之外就是資料組織了,如果沒有組織好程式會非常亂。Part 2 …… Day 5 的區間運算逆襲了。我差點想把 Day 5 的區間結構先重構出來再寫 part 2,好在仔細想想之後發現這次其實沒那麼複雜,雖然是 4D 超立方區間,但每次切割頂多切成兩塊,然後他們就分開給不同狀態了,所以就直接切下去分開了。
20. Pulse Propagation
結果真的來這招了。Part 1 是個表面上有點可怕的自動機模擬題,不過至少資料結構好一點就能輕鬆寫得出來;不過 part 2 就出事了。這又是一個直接模擬不可能在合理時間內模擬出結果的輸入:這次逆襲的是 Day 8 的循環偵測跟 Day 14 時大家討論中有討論到的互質迴圈複合,兩個東西合在一起就是這次題目的輸入資料。
在發現直接跑跑不完的時候果斷放棄,利用一些空檔思考了好些迴圈偵測方式之後,最後決定:只讓每個模組在每次傳完之後紀錄自己的狀態,然後直接用這個狀態尋找是否有迴圈,等到每個模組都 (以某個簡單條件) 認為自己在迴圈裡之後把所有人認為的迴圈長度給印出來。在跑了約兩萬多次後跳出模擬,果然結果當中出現了四個中等大的數字,於是稍微用了點 vim 把輸入改成 graphviz 描述語言來畫圖,果然出現了計數器結構,也從這結構中讀出了輸出中的數字,進一步確定了這四個數字就是四塊的迴圈長度,所以答案就是它們全部乘起來了。
有一點點關連的題外話是:也許是因為 Minecraft 1.21 新增銅燈,一堆人用銅燈做了極簡單的計數器的關係,當讀到題目中的兩種模組是正反器跟合併運算時馬上想到的是這正反器該不會拿來當計數器了吧;所以看到畫出來的圖時完全不意外,只有解讀寫在裡面的數字要怎麼讀花了約莫十分鐘左右而已。
21. Step Counter
照例,part 1 是個相對友善的題目,是個很基本的格子圖上的單點最短路徑問題,這部份應該不用多說。
然後 part 2 就要進入平行宇宙4了。好在輸入檔又有花招:除了比較明顯的鑽石形斜向空路之外,其實還有好幾個行列是全空的,這代表就算要走到遠處,我可以沿著全空的路先衝到附近再走出去。這表示,當地圖展到很遠的時候,可到達點的樣式會是一個中間隨著地圖重覆也一起重覆的樣式,邊界樣式數量會線性成長,中間滿圖樣式數量則是二次成長 (不論奇圖或偶圖都是),所以最終當取固定步數間隔取樣時 (我是取兩個平行宇宙長,以保持奇偶性正確),總可到達點數量會是一個二次函數。於是跑久一點跑出前幾項,就能外插出最終結果了。
22. Sand Slabs
意外的是個基礎圖論題。Part 1 簡單的依底部排序 (因為大家都是長方體) 之後就能從底下一路試掉,只要再紀錄一個高度圖就能簡單的檢查每個方塊會掉到什麼地方去,以及它會被誰給接著,把這個接著的關連反過來就是自己支撐著誰;那麼題目要的檢查,就是當取走一塊時,這一塊所支撐的方塊還有沒有別的方塊可以支撐。
Part 2 則讓我想到我在做編譯器理論時接觸到的節點支配的概念,不過鑑於這題的圖是個 DAG,是不太需要這麼複雜的處理的。這題如果照題意去推到底拿掉這塊會有誰掉下來的話,重覆的工很多;但反過來的關係——當誰被拿掉時自己會掉——則是個很容易往後推的關連:我會掉的充要條件就是拿掉那一塊會使得所有支撐我的人都會掉。因此就檢查支撐著自己的方塊,如果只有一塊那就是他的掉落條件加他本身,如果有多塊則是這些塊的掉落條件的交集。(所以難得在這裡用了一次 set_intersection
了) 因為這只是反過來的關係,題目所求同樣是這些關係數量的和。
23. A Long Walk
今天的題目某種程度上頗為「惡質」,所以擺在最後一個星期六我覺得是最好的位置。(今年的最後一個星期日因為是 24 號比較不能擺這種題目。)
題目敘述上是一個標準的最長路徑問題,而有些格子只能走單向。如同維基百科所說,一般的最長路徑問題是 NP-Complete,因此這題的輸入上一定有些梗在裡面。Part 1 的梗是這些單向格連成一個 DAG (有向無圈圖),所以直接以普通的 BFS 搜尋即可求得最長距離。Part 2 不管單向格了,每一格都能到處走;這裡的梗則是行走區域形成的圖和一個只考慮交叉點和其之間連接長度的圖同胚,所以我們可以在這個同胚但節點數小很多的圖上去做,畢竟指數時間做法只要節點數能少一點都是賺。
往年其實也不是沒出過只能硬做的題目 (最經典的是首年 (2015) 有一題要你真的挖一個簡化版的加密貨幣),不過我會說這題某種程度上有點「惡質」的原因是,他出的是一個 (也是經典的)「難」題,但這種題目的「難」卻不是隨便一個來嘗試的人都能馬上看得出來的。一個只有接觸過少數這方面材料的人,在前面題目當中學到了要改良演算法以「最佳化」程式效率,但卻在這裡被一個跨不過去的「NP-Complete」高牆給擋住了。
嘛,我應該對為什麼會這樣做有些想法,不過那就留到最後總結時再來討論吧。
24. Never Tell Me The Odds
真是殘酷的一題。這題從一開始就是計算幾何的題目:給你一堆三維空間的射線 (起點和單位時間內移動的向量),part 1 要先忽略 z 方向,只看 x y,問這些射線有多少交點在給定的座標範圍內;part 2 則是告訴我們,存在一條特定的射線,使得一個小石頭自此沿著這條射線以給定速度飛的話,會和所有沿著前面給的射線跑的冰雹在交叉的時候正好撞上那些冰雹,求出這條特定的射線。
我自認計算幾何不算是我的弱項,part 1 給定兩條射線直接聯立參數式就能解交點,再去判斷交點是不是在射線移動方向的未來以及其座標即可;但 part 2 我是列出式子了,但那是六條六元二次聯立方程式,我盯著它好幾個小時就是找不到方法可以化簡它,最後是因為在 Mathematica 裡亂試發現它竟然神奇的可以解出答案來,實在萬策盡了只好就把給我的輸入的式子丟進去給它解。
然後後來才知道原來一般來說,要能唯一決出一條直線穿過其他直線的數目是四條,不過看起來好像也沒什麼好算法去求解;這個連結裡面好像提到要在射影平面去解它,然後中間仍然還是會出現二次曲面的樣子?所以二次式這件事好像還是躲不掉的樣子……
補記:果然想法轉個彎就能解了。Reddit 上的這個解法我轉寫一下:
25. Snowverload
依照慣例,最後一天只會有一題,而且會相對簡單一些。這題是個無向圖 min cut,於是我在維基百科上翻了翻發現這個 Karger’s algorithm,雖然是隨機演算法但跑起來意外的快,輸入檔一千四百多個節點在第 15 次嘗試就找到這個 3 edge cut 了。
年度心得
可以看得出來今年的題目有「複雜化」的傾向。許多輸入檔案的數字都是直接超過 32-bit 數值直逼 2535,加上 part 2 的題目設計基本上就是要解題者認真想方法解,不要總是用力量撞。(今年 reddit 上的好些迷因都是在說不管什麼問題,撞個三天總是會跑出答案來 XD) 雖然 Eric 沒有公開承認過 (他在 reddit 上總是說他今年做的除了加上不要用 AI 的規則之外沒什麼不一樣的),但我想他今年的出題方向確實有在朝著不要讓生成式 AI 有機會猜中答案前進:生成式 AI 對這種一串隨機數字的東西來說是最頭痛的,因為除了確實去從數字中去猜關係之外,其他對文字預測的知識不會對正確答出這些東西有所幫助。這一點可能也是今年前三題都有輸入字串分析的元素在裡面的原因:從一團亂碼文字裡找資訊也不是生成式 AI 的強項,他們可能會淹沒在雜訊當中。
同樣的傾向也表現在出題方向:往年的題目相較起來比較沒有那麼多「專業」題——我指的是在一般資料結構及演算法課程裡會學到的各類型的演算法;以前大概最多就是最短路徑或動態規劃這種程度,這些對於程式初學者來說只要找到好教材上手不是問題,但今年不但有三題計算幾何 (Day 10、Day 18、Day 24),最後這幾題真的已經開始有 leetcode 的感覺了。Day 23 會出一題 NP-Complete 可能也是這個原因吧。
不過如此調整的結果,今年的題目相對往年真的有變難,也有看到不少今年才跳進來的人沒三四題就跳車了的文章;而有些題目為了調整難度讓題目出的有點問題 (像是 Day 8 的狀況;同樣狀況出在 Day 20 好像就相對好一些,但出在 Day 8 讓題目變得有點糟),這可能也是未來需要改進的地方。
那麼這就是今年的 Advent of Code 了。之前提過我後面在做的東西可能過年期間看能不能比較有空把它收尾掉放出來 XD Merry Christmas!
註腳
- 我去年的文章裡有提到過那個 DC 群;前年 (2021) 我會跑回來做也是因為在那群裡看到的原因。 ↩︎
- 有人在 megathread 裡提到 PE054,所以果然撲克題型是程式設計練習挑戰題的慣例 XD ↩︎
- 現在還有多少人記得「今年是五倍」的哽啊?! ↩︎
- 有在看迷因的應該知道「我領先你四個平行宇宙」的馬利歐的迷因吧?這個迷因裡的「平行宇宙」在其原始來源裡就是在講地圖重覆,不過這要細講下去就是一篇短文的程度了所以在此略過;有興趣了解的可以看 knowyourmeme 的解說。reddit 上也有人提到這個哽。 ↩︎
- 對還不知道這個數的特殊性的人:253-1這個數在 JavaScript 裡稱做 Number.MAX_SAFE_INTEGER,是倍精確度浮點數能夠正確表示 (+1 或 -1 不會因為精度不夠而變回自己) 的整數最大值。實際數值約是 9×1015,亦即幾乎涵蓋 16 位整數的範圍。這對一些數字型態只有浮點數的程式語言 (如 JavaScript 或 Lua) 來說是代表了「整數」的上限值。 ↩︎