Contents

交大的社團生活與 PCCA

看到台大資工榜單那天,雖然對於自己的表現很失望,但想想交大也是不差的地方,因此也沒有太難過。即使並非心裡最嚮往的第一志願,我還是對於即將到來的新的大學生活非常期待。

會打比賽好像很厲害的樣子

來到交大之前就有在臉書上逛資訊社團的習慣。社團裡很容易發現一種現象:在提問貼文的下方,常常見到固定(臉書演算法的禍害)一群高中生或大學生的回覆。這些回覆通常不太正經,往往伴隨一些與資訊相關的專有詞彙,口氣或多或少表現出傲慢。點開這些人的 profile,可以知道是活躍於資訊競賽的學生。伴隨著這些回覆的是更多競賽選手的吹捧與打鬧。這是我對於資訊競賽圈的第一印象。

我認為這就是未來出社會後以個人能力論高下的現實,因此雖然對這種現象感到嫌惡,心裡還是很希望能成為這種威風的競賽選手。這是一個我討厭炒房但如果我有房我也要加入的概念。於是來到交大資工的時候,心裡便決定未來有機會一定要參加一些資訊競賽。

主流的資訊競賽分為兩種:以演算法為主題的解題競賽以及以資訊安全為主題的搶旗競賽 (CTF)。在交大,這兩樣競賽各自有對應的社團在經營,分別是 PCCA 程式競賽社Bamboo Fox 網路安全策進會

社團博覽會時策進會在工三門口附近有擺攤,攤位上沒有太多人員或設備,只有一張桌子跟一台筆電。筆電瀏覽器上的網頁含有一個 input,只要在 input 中輸入文字 XXX 並送出表單,就會顯示一個 Hello XXX 的頁面。顯然這是很裸的 injection。由於我知道這種攻擊的原理,問了社課的時間之後就很高興地離開了,心想自己的程度應該還行吧。找了很久,發現程式競賽社沒有擺攤。

這個你不知道喔

/posts/pcca/bamboofox.webp

網路安全策進會好像有很多不同稱呼的樣子:「交大網路策進會」「交大安全策進會」「Bamboo Fox」「CCCA」「CSC」,如果我的理解沒錯的話,這些全都是指同一個社團。策進會每個星期有一堂社課,社課模式是請一位擅長資訊安全領域的講師上台講東西,社員在下面聽,剩餘時間社員自己解題目練習。沒記錯的話當年的教室是 EC329。

第一堂社課的講師是 ss8651twtw,當時經常出現於社群且非常擅長資安的大學長。活躍於資安領域的人物似乎有一種默契,往往以一串不可發音的英數字(甚至符號)做為稱呼,而非以本名或習見於一般常識的暱稱。講師做了簡單的自我介紹之後就開始講課,印象中是一些 linux 指令的樣子,但我完全聽不懂。然後,社員被要求 SSH 到某機器,裡面有一些題目,你需要使用剛剛社課上教過的指令去解這些題目。

那時候我還不知道 SSH 是啥,也幾乎沒有用過 Linux 或 CLI 的經驗,對這些操作感到很不熟悉。然後,我不知道怎麼執行程式。在 Linux 系統上,如果你想要執行當前目錄下的某個可執行檔的話,你要在檔名前面加上 ./ 前綴。因為這個關係我連第一題都解不出來(這是經典的 CTF 題目設計,你要去執行一個 setuid 的 executable 來撈 flag),直到後來策進會社長走過來看見我求助的眼神。社長幫我敲了我需要的指令 ./xxx 之後,講了一句「這個你不知道喔」就走了。

這個你不知道喔
這個你不知道喔
這個你不知道喔

那是四年前的事情。其實那一天發生的事我已經幾乎忘光了,我但記得自己有繳 200 元的社費,然後因為那句話受到很大的刺激。在那之後,我沒有再碰過策進會的社課或活動,並且發誓一定要好好培養技能,以後被嘴的時候可以噴回去。

競技程式設計一

競技程式設計,簡稱競程,是一種以演算法與資料結構為核心的解題競賽。

/posts/pcca/2021_TOPC_standings.webp
演算法競賽的 scoreboard。淺綠色或深綠色表示該題 AC(過關),紅色表示沒過。前十名的隊伍中有八隊來自台大,這種一校輾壓的情況已經是各種演算法競賽的常態。

卡車

在 2021 年資工系課程規劃大魔改之前,卡車會在每學年的下學期會在資工系開設〈競技程式設計一〉,簡稱〈競程一〉。這堂課是標準的以演算法競賽為導向開設的課程,作業與考試內容就是教你一直解題目。每學年度上學期,卡車會開〈競程二〉與〈競程三〉,不難猜出其實〈二〉與〈三〉是給已修過〈一〉的非一年級新生開的。但我還是加選並出席了〈二〉的第一堂課。

在第一堂課上,卡車講了一下交大、台灣以及國際上的演算法競賽的現況,然後要求學生進行組隊並在學期間參加各種全國競賽,拿到足夠好的成績以通過這堂課。作為 PCCA 程式競賽社的指導老師,卡車順便介紹社團的事情(i.e. 招攬社員)。我當時完全不在狀況內,只感覺到這門課不是我現在應該修的,加上卡車的危言聳聽,所以就退選了。後來我還是有兩次在程式競賽社團隊練(社課)期間去找卡車,想詢問入社的事情。當時我只會寫 Java,對 C 與 C++ 都非常不熟,卡車知道這些事情之後就把我勸退了。

在那之後很長一段時間,我打消了作為演算法競賽選手的念頭。演算法是競賽是國內最主流的資訊競賽(其次是 CTF),有很多選手從高中甚至國中就開始訓練。作為一個到大學才知道排序最快不是 O(N2) 的破大學生,我認為即使自己未來參與演算法競賽,也只是被別人踩在腳下而已。

Kelly

〈競程一〉〈二〉〈三〉這一系列的課程在當時有著非常詭異的現象:〈一〉在系上總是非常熱門的課程,每年都有百餘個學生修課,但〈二〉與〈三〉常年乏人問津。關於後者,可能跟〈二〉的極高通過門檻有關:修課生必須三三組成隊伍,參與一系列的國內或國外演算法競賽,並在至少一次競賽中達到以下任意一項門檻。

  • 打敗台大第六的隊伍
  • 打敗清大第四的隊伍

成大的隊伍不在門檻裡,因為 … 額 …

/posts/pcca/cp.webp
在課程大改制之前,〈競程一〉一直都是資工系很熱門的課程,〈二〉〈三〉相反。

〈競程一〉也存在著詭異的修課現象:雖然這門課一直都是很熱門的課程,但學期中的停修人數非常高,每年穩定有高於三分之一的比例。這是因為即使是最初階的全國水準的演算法競賽的難度,也足以考倒三分之二以上的資工系學生(尤其是大一新生)。我猜因此即使〈三〉的通過門檻非常非常低 ─── 學期間參與 10 次線上模擬練習並寫解題歷程 ─── 也沒什麼人修這門課。

如果你看到大一新生曬課表的時候,露出自己跳過〈一〉〈二〉逕修〈三〉的表現,這就是經典又精緻的招搖撞騙,因為〈三〉反而三門課程中最簡單的。

〈競程一〉的期中考與期末考是個人上機,沒有演算法競賽需要三三組隊的事情。儘管這樣,卡車仍然會在下課期間宣傳 PCCA 的事情。〈一〉是程式競賽社招收新社員的重要管道,因為在這堂課中,卡車可以透過作業或考試挑選出有具備潛力的學生。〈一〉的其中一項學期加分條件是參與線上演算法模擬賽,為了刷 GPA,我很需要這個管道。但是模擬賽需要以三人為一隊,我很需要隊友。

當彼時,忽有一奇女子乍現,其名曰 Kelly,方才入社未幾,尋伴無果,趁下課的時候跑到講台拿麥克風施展全頻徵友附帶大範圍強制收音。做為一個把技能全點在社恐的廢物,我覺得這是不能錯過的機會,考慮了半分鐘之後皺著眉頭到台前 +1。這個行為很可能決定了我未來三年的大學生活,甚至是造成一輩子的影響。

第一次隊練

程式競賽社的社課是每週三晚上六點半,在一間有大白板的教室內進行。這不是一間電腦教室,大家帶著自己的筆電三三兩兩找位子坐下來。教室內的桌子是可移動式的長桌,每張桌子可以塞三個人,剛好適合一隊一桌。

第一次對隊練的套題出自 2014 年北歐與波羅的海八國大專電腦程式設計競賽,用時五小時。賽制上是一隊三人,但我跟 Kelly 當時兩個人就開賽了。在那一次隊練中我們 AC(解出)四題:Kelly 三題,我則是只解了最簡單的一題。我的心裡是非常傷心的,覺得自己是個人頭擺設而已。

這樣已經達到〈競程一〉可以加分的條件,我本來打算就這樣收手了,不過 Kelly 馬上就跟我討論下一次隊練的事情。咦,不對阿,我只有說要跟她練題目而已,我什麼時候說要跟妳組隊了。可是如果我現在就退出,就是在利用 Kelly 撈自己〈一〉的分數,這是非常不符合倫理的作法,於是只好硬著頭皮答應了。

接下來的第二、第三次隊練基本上就是 Kelly 在帶我飛。這段期間我始終感到很恐懼,覺得 Kelly 心裡一定很嫌棄,大概已經在尋覓新的隊友了吧。也是在這期間,我開始慢慢學會使用 vector 之類的基本的 STL 資料結構,還有演算法的基本技巧諸如二分搜和 DFS、BFS 等等。

雖然 Kelly 什麼話都沒有說,但她帶給我的刺激不小於策進會的社長,讓我心裡感到非常疙瘩。為了報復 (?) Kelly,整個五月下旬和六月上旬 ─── 也就是〈競程一〉期末考前夕 ─── 我很努力在 Codeforces 上各種刷題與練習 STL 的使用方法。做為一個常常閱讀 Java API 的開發者,我很快就掌握各種實用的 STL 資料結構以及使用方法。在期中考之前,由於對 C++ 非常不熟悉,我幾乎是用 C 在解題,只有在期中考時勉強使用了下 C++,當時的成績只有在中段。

我在〈競程一〉期末考成績比期中考好上許多,來到班上第二,這讓我感到全身上下充滿信心。Kelly 應該不會把我踢掉了,也打消了「被別人踩在腳下」這樣的想法。雖然在我看來,演算法題目是一些在現實生活上幾無實用價值的題型,就跟數獨一樣,但我很享受解題的樂趣。加上跟隊友感情非常好,我決定做為一個演算法選手繼續努力下去。

演算法競賽

交通大學程式競賽社(NCTU Programming Challenging Contest Association),簡稱 PCCA,是交大校內活躍於演算法競賽的社團。

根據可靠消息,PCCA 此名當時抄襲自隔壁策進會 CCCA 之簡稱。似乎可以推斷 PCCA 的創社時間晚於策進會。

NCTU_Pusheen

交大每年九月舉辦新生程式設計競賽與校內程式設計競賽。從這兩個競賽的名稱便可以看出一個資訊文化的陋習:大家總喜歡把演算法競賽稱為程式設計競賽,彷彿程式設計的本質就只是演算法的樣子。這是極為嚴重與偏頗的錯誤。演算法只是程式設計的一部分,而且是不怎麼重要的那一部分:如果有一個人(資工系學生也好、出社會的軟體工程師也好)在進行程式設計時遇到困難,我相信他遇到演算法相關的困難的機率小於百分之一;隨機抓一個 GitHub 上熱門專案的一個 issue,我可以打賭那跟演算法相關的機率也小於百分之一。

在交大資工的第一個暑假,我的 YouTube 恰好輪轉到 Kalafina 與 Aimer 的歌曲,我常常在深夜聽著她們的歌,手敲著筆電鍵盤眼睛注視著螢幕,日常生活便是日日夜夜地刷著更多 Codeforces 上的題目。我的目標是成為能夠與 Kelly 肩並肩的隊友,然後在校內賽摘下一個夠好的排名。如果能夠拿到前三名,就可以拿到公費補助的機票與住宿,到國外去參加 ICPC 的競賽。儘管現在已經退役了,只要聽到 Kalafina 或 Aimer 的歌,就會想到那個活得孜孜矻矻的充實的暑假。

最終我和 Kelly、以及新隊友 udchen 組成的 NCTU_Pusheen 在學期初的校內賽壓線拿到第三。Kelly 和 udchen 都是 TOI 選手,壓力倍增。卡車規定交大的隊伍要以 NCTU_ 前綴開頭,Pusheen 是 Kelly 很喜歡的奶頭貓,因為她是大隊長,隊伍名稱就給她取了。

Yokohama ICPC Regional

/posts/pcca/pass.webp
桃園往羽田機場的機票

〈競程二〉這門課的學期成績很特別:只有 PASS or FAIL 兩種,沒有數字。也就是說,這是一門不影響學期排名或 GPA 的課程,雖然過關門檻非常高,但對刷分仔來說是很好的機會。話是這樣講,但這個難度是真的,很高,很高。

在接下來的 TOPC 與 NCPC 中,Pusheen 連續兩次挫賽,拿到非常差的成績。於是能通過〈二〉的機會只剩下兩次:一次是日本橫濱的 ICPC Regional,另一次是台灣台北的 ICPC Regional。橫濱的 ICPC 是在校內賽撿到才報名的;這並不是說如果沒在校內賽拿到前三名就不能報名國外的競賽,只是學校不會補助。當年第四名的隊伍就自掏腰包前往馬尼拉的樣子。除了日本之外,還有韓國、馬來西亞、新加坡、印尼、越南、泰國、緬甸(當時還沒發生政變)和柬埔寨可以選。如果是有機會進 World Final(國際決賽)的強隊(校內賽第一的隊伍),就要策略性挑選比較弱的國家(e.g. 印尼、菲律賓)來提高進入決賽的機會;對於 Pusheen 這樣的弱隊,挑選自己喜歡的國家就好。

台大與清大派往橫濱站的隊伍各只有一隊,而且都是校內第一,因此我們都不指望能在橫濱達成門檻。Pusheen 的最終表現平平如預期落在中段偏後,但台大第一和清大第一似乎被詛咒的樣子,我們甚至贏過清大第一的隊伍,撿到三學分。

橫濱站是我參加過最豪華的一次競賽。從賽前介紹到賽後的活動,橫濱主辦方都打理得有條不紊。雖然整體名次非常普普通通,但我們拿到最佳女選手獎(含有至少一個女性隊員的最佳隊伍),又在賽後的活動拿到很豐富的獎品,還賺到兩天的日本觀光假期。

PCCA 的日常

PCCA 每個星期有固定的社課時間,也就是進行隊練的時段。在那個中國肺炎還沒流行的美好年代,每次隊練都有免費的晚餐,經費來自社費。社團有兩個重要的職位:社長和總務,前者好像是個虛名,至少我當社長的時候我好像不太需要負責什麼事情;總務很重要,以負責每個星期隊練時幫大家訂便當作為代價,以可以選擇自己喜歡的店家作為回報。

/posts/pcca/food.webp
總務是社團裡最具存在感的人,所有社員都必須認識他,否則沒飯吃。

隊練時間是每個星期三晚上六點半,在 EC330 進行。大概晚上五點半的時候教室門就會打開,總務會比較早到,拎著一帶食物。大家通常六點過後才會到,然後速速吃完便當準時六點半開始隊練,或者邊吃邊打。

隊練的題目通常來自 Codeforces,這是一個很熱門的資訊演算法練習網站,上面有很多單題與套題,後者包含國際各大學各競賽的考古。經典的套題是一場五個小時的競賽,因此如果六點半開始準時隊練,結束時間通常是接近子夜了。而且結束後大家不見得會立刻走人,會有人留下來繼續討論題目,因此教室熄燈時通常都已經超過十二點半,甚至半夜一點了。

那是一段非常快樂的日子。生活的大部分時間努力奉獻給自己喜歡的東西,同時周圍圍繞著一群喜歡的朋友。

後記

Pusheen 在後來的台北站拿到很不錯的排名,打敗清大第三再一次通過〈競程二〉的門檻。

2019 年末賽季結束,接著進入二年級下學期,社團內部進入一連串的隊伍分裂與重組,這是 PCCA 每年最不合諧的時候。雖然 Kelly 仍在,但 udchen、筱、璽安等等熟悉的朋友漸漸淡出或離開,加之自己逐漸忙於計中的事情,賽季過後也不再把重心放在演算法與社團上。疫情來到,實體隊練被取消,熟悉的那個簽到、開始隊練、賽後討論的生活不再,社團的氣氛已經完全不是我熟悉的那個 PCCA。

三年級,有了微軟的實習,生活變得更加忙碌。社團來了一大批大一非常有實力的 TOI 社員,心裡知道自己已經不可能再有更亮眼的表現。在那之後,新組成的 Pusheen 在各賽場上幾乎再也沒有什麼可圈可點的成績;儘管曾再拿一次校內賽第三獲得出國門票,也因為疫情而歸於無。

於是,作為一個不怎麼隊練、只有在競賽期間才出現的社團幽靈,直至 2021 年冬天最後一次的 ICPC 台北站而後退役。之後我再也沒有參與過 PCCA 任何事務或活動。