Human Resource Machine (人力資源機器) 完美通關心得

Human Resource Machine 人力資源機器是一款拚腦力解決問題的遊戲。 推薦給喜愛編碼或是想做點邏輯訓練的玩家。 這並非所謂的解開”謎題”遊戲,而是解決”問題”的遊戲。

只要撇開那些 1 跟 0,還有怪異的恐怖括號,寫程式其實是很簡單、合乎邏輯、美妙的一件事,任何人都能理解跟享受!如果已經是程式專家了?這款遊戲也準備了額外挑戰給你。

最近偏愛玩一些休閒的益智解密遊戲,機緣巧合下看到這款,花費了一些時間完美通關。感覺整體遊戲對編碼和邏輯訓練要求蠻不錯的。通過編寫程式,讓小小工人幫你解開謎題。從最簡單的需求到後面各種算法和各種奇奇怪怪的要求。從入門到精通都有涵蓋,用塊編程的方法讓就算不懂任何編程基礎的人都可以輕鬆發揮腦中的想法。因為關卡都會有指定好的元件讓玩家使用,編碼的行數也沒有硬性要求,有耐心慢慢設計流程是一定可以通過關卡的。

透過解決遊戲的關卡,一層層往上爬,一步步升職。從懵懂無知的IT新人到老資歷的老手。

Steam商店頁面:
https://store.steampowered.com/app/375820/Human_Resource_Machine/

完結心得

這是一個零基礎的編程思想入門。輸入、輸出、存儲器、加法、減法、goto語句、帶條件的goto語句(提供若為0則與若為負則兩種條件)、自加、自減、指針等……

這個小遊戲不厭其煩地把所有常見的基礎指令一步一步地往裡加,通過由簡入難的過程循循善誘地讓你理解不同基本指令的用法和用途。對於一款編程向的遊戲來說,前30關難度並不太高,很時候對編程有興趣的同學嘗試,入門編程來說還可以。但從30關後難度就有所提升,沒有一點點編程思維可能會卡一會。

關卡之間也會插入一些劇情,劇情雖然短但細思極恐,具體就不劇透了,自己進入遊戲感受一下吧。

最後感受就是,還是直接寫代碼比較過癮😆

👇下面附上遊戲完整通關方法以及個人思路,建議自己先嘗試一下再看答案吧。

Year 1 郵務間

一個介紹 inboxoutbox 的教程關卡。

透過很形象的表示方法(我喜歡這個遊戲的其中一個原因)。小人的手中其實就是類似棧頂的區域,他只能拿一樣東西,此時這項物品(數據)是可變的、危險的、容易丟失的,高級編程語言中通常會使用變量來存儲這個值,但我們現在是沒有的。取而代之將採用類似於壓棧和彈棧的操作來對其進行存儲,簡單地說,當需要進行運算時一定要考慮是否需要備份。

另外,

“你不能兩手空空去outbox”。

INBOX : 拿起 INBOX 裡的一樣東西。
OUTBOX : 把手上拿著的東西輸入到 OUTBOX。

方法1

目前關卡只有 inboxoutbox ,所以重複三次就可以把箱子全部運出去。

指令數量:6 /6
運行速度:6 /6

-- HUMAN RESOURCE MACHINE PROGRAM --

    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  

Year 2 繁忙的郵務間

jump 的教程關卡,這個指令威力強大,可以把 jump 箭頭拖到程式的任意部分,直接跳轉到那個位置或者形成一個迴圈。所以從現在開始,程式開始有不同的解法以及所謂的最優解。

JUMP :跳轉到程式中的其他位置。你可以向後跳轉形成迴圈;或向前跳轉以跳過整個段落。沒什麼不可能的。

方法 1

所以這題只需要重複執行 inboxoutbox 指令就可以,利用一下 jump 形成迴圈吧。

指令數量:3 /3
運行速度:30 /25

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    OUTBOX  
    JUMP     a

方法 2

考慮到 jump 本身也是一個執行步驟,在最短步驟解決方案下,原本只需一組 inboxoutbox兩步就可以解決。但上面方法就需要到三步才可以完成一次傳輸。

所以我們可以做一下更改,手動重複 inboxoutbox 12次。已達成最短步驟解決。不過這畢竟是 jump 的教程關卡,所以必須使用到一次 jump

指令數量:17 /3
運行速度:21 /25

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    INBOX   
    OUTBOX  
    JUMP     a

Year 3 影印室

copyfrom 的教程。遊戲中的地毯其實就是一個棧,當然它至少很親切地沒有保存先進後出的特質,不然這遊戲就更複雜了。從這個方面來看也可以認為是一個數組。總而言之這塊地毯是為了彌補這個遊戲中沒有變量賦予的缺陷,並且冷酷地審視著我們變量使用的根本邏輯。

方法1

沒有特別需要留意的,依次取出對應值並輸出即可完成。

指令數量:6 /6
運行速度:6 /6

-- HUMAN RESOURCE MACHINE PROGRAM --

    COPYFROM 4
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    COPYFROM 3
    OUTBOX  

Year 4 拌碼處理器

和上一關一樣是對變量思維的基礎訓練。永遠記住你手上只能拿一個數據就行。這一關算是稍微地模仿了一下“先進後出”的壓棧和彈棧的感覺,可能是一種情趣吧。

copyto:把手中拿著的東西複製到某個特定地毯。

方法1

指令數量:7 /7
運行速度:21 /21

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    INBOX   
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    JUMP     a

Year 6 多雨之夏

變量應用的又一個簡單訓練。 需要注意的是加法的這個步驟並不會更新你已經定義的變量(放在地毯上的數)

add:把地毯的內容和你手上的數值加總。運算結果會回到你手上

方法1

指令數量:6 /6
運行速度:24 /24

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    INBOX   
    ADD      0
    OUTBOX  
    JUMP     a

Year 7 零之終結者

我們有了第一個條件判斷語句。我們簡稱 jump0 需要注意的是這個相當於沒有else的if,被 jump0 包圍部分執行完畢後是會接著執行 jump0 外面的部分的,如果不想要它這樣執行請記得使用jump

方法1

指令數量:4 /4
運行速度:23 /23

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
b:
    INBOX   
    JUMPZ    b
    OUTBOX  
    JUMP     a

Year 8 三倍室

這是一個沒有乘法的冰冷的世界……

方法1

x3即三个相同的数相加,依然注意先储存变量(不记得也没关系,慢慢学到教训就好)。同时要注意 add 是只 add 两次。

指令數量:6 /6
運行速度:24 /24

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    ADD      0
    ADD      0
    OUTBOX  
    JUMP     a

Year 9 零保育行動

jump 的一種新用法。

方法1

常規思路可能是這樣:我先輸入一個數,判斷它是否為0,是的話就輸出,不是的話就跳轉回輸入語句之前進行下一步輸出。但發現計算步驟較多,而多余的计算步骤来自于顺序设计时每一个输出之后必须要用 jump 跳转回到 inbox 之前,本关中有4个0,就有4次这样的跳转,这就是为什么你写出来是28步而被要求只用25步。(同时也说明了正确的算法还会有某一步只执行过一次)

指令數量:5 /5
運行速度:28 /25

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
b:
    INBOX   
    JUMPZ    c
    JUMP     b
c:
    OUTBOX  
    JUMP     a

方法2

要對此進行優化,我們可以注意到轉到 inbox 這一步驟重複了,不管是0還是非0都需要跳轉回輸入,因此我們的優化方向就是去除 outboxjumpinbox 的操作,具體實現方式如下,其中第一個 jump 是只執行一次的語句,可以認為是循環開始前的初始化。

指令數量:5 /5
運行速度:25 /25

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     b
a:
    OUTBOX  
b:
c:
    INBOX   
    JUMPZ    a
    JUMP     c

Year 10 八倍裝置

由於這次題目限制了只能使用3個add,所以普通的思路肯定不行。這個時候就要從8倍本身出發。 8的特別之處在於它是2的三次方,考慮到我們的變量(地毯)可以對每一步運算的結果都進行存儲,x8就可以被分解為三次翻倍

這思路需要理解add的特性,add不會改變初始變量的值。

這裡多講一下,我們在高級程序語言裡進行 x=x+y 這個操作時實際上是兩步,即相加和賦值。這個遊戲的add指令相當於 return (x+y),把 x+y 的值放在手上暫存,賦值的步驟則需要另外一行指令。

方法1

具体来说,每一个输入的数,将它存储在0号地毯处,手上的初值与0号地毯 add (即x2操作,初学者可以注意一下这里的copy思路)后的值存储在1号地毯处,再把手上的值(此时手上的值是x2后的值,初学者可以从这里理解一下栈的操作)与1号地毯 add,达成又一次翻倍(x4),重复到第三个地毯上,最后手上的值就是x8后的值了。

指令數量:9 /9
運行速度:36 /36

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    ADD      0
    COPYTO   1
    ADD      1
    COPYTO   2
    ADD      2
    OUTBOX  
    JUMP     a

Year 11 減法走廊

很简单,subadd 本质是一样的,这一关可以帮助初学者更好地理解什么是计算的中间量,什么是需要反复读取的值,什么是会被丢失的数据,什么是不应该被丢失的数据。形象的来说就是分辨拿在手上的值和放在地毯上的值(不会分辨可以反复调试观看小人的行动)。

sub:把你手上的數值減去地毯的內容。運算結果會回到你的手上。

當然這一關中的兩個數都必須先存儲下來才能進行操作。
另外 copyto 的這個操作即 a=b ,當採用這個指令後我們手上暫存的數也不會消失,因為它是“複製”而非剪切。 (隨時注意手上的值,可以省去一些不必要的讀取操作,對優化很關鍵)

方法1

指令數量:10 /10
運行速度:40 /40

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    INBOX   
    COPYTO   1
    SUB      0
    OUTBOX  
    COPYFROM 0
    SUB      1
    OUTBOX  
    JUMP     a

Year 12 四十倍放大器

思路和之前八倍放大是一樣的,只不過40不再是2的整數次冪,所以可以拆成5x8來算,即先自己反復加5次,再用八倍放大器當時的程序做冪次方。依然分清楚哪些是需要保存的數就行。

方法1

指令數量:14 /14
運行速度:56 /56

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    ADD      0
    ADD      0
    ADD      0
    ADD      0
    COPYTO   0
    ADD      0
    COPYTO   1
    ADD      1
    COPYTO   2
    ADD      2
    OUTBOX  
    JUMP     a

Year 13 相等室

在這關,我們可以透過兩個數值相減後結果是否等於零來判斷是否相等。

方法1

指令數量:9 /9
運行速度:27 /27

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     b
a:
    COPYFROM 0
    OUTBOX  
b:
c:
    INBOX   
    COPYTO   0
    INBOX   
    SUB      0
    JUMPZ    a
    JUMP     c

Year 14 最大化房間

jump if negative:如果手上正拿著負數才跳轉。否則就繼續執行程式中的下一行指令。

方法1

這關有很多方法,而我選擇一種比較討巧的做法。判斷兩個值的大小關係 ( ba 是否為負) 後如何回歸原值輸出:先將 a 儲存,當 a 更大時可以直接讀取 a 的值輸出,而當 b 更大時則有 b=b-a+a,再用一個 add 指令即可。

指令數量:10 /10
運行速度:31 /34

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     c
a:
    COPYFROM 0
b:
    OUTBOX  
c:
    INBOX   
    COPYTO   0
    INBOX   
    SUB      0
    JUMPN    a
    ADD      0
    JUMP     b

Year 16 絕對正向

方法1

和上一關思路類似。正數直接輸出,負數則有 -a=a-a-a

指令數量:8 /8
運行速度:34 /36

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     c
a:
    COPYTO   0
    SUB      0
    SUB      0
b:
    OUTBOX  
c:
    INBOX   
    JUMPN    a
    JUMP     b

Year 17 專屬休息室

條件判斷的訓練題。

方法1

當a為正時,若b為正則輸出0,若b為負則輸出1;
a為負時,若b為負則輸出0,b為正則輸出1。
讀取0或1並輸出的這兩步是共用的,雖然有四種情況但其實只有兩種輸出。

指令數量:12 /12
運行速度:28 /28

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
b:
    INBOX   
    JUMPN    d
    INBOX   
    JUMPN    e
c:
    COPYFROM 4
    OUTBOX  
    JUMP     b
d:
    INBOX   
    JUMPN    c
e:
    COPYFROM 5
    OUTBOX  
    JUMP     a

Year 19 倒數

bump+:把某個特定地毯的數值加一。運算結果會出現在地上,也會回到你手上。
bump-:把某個特定地毯的數值減一。運算結果會出現在地上,也會回到你手上。

方法1

判斷a是否為負數,是就使用 bump+ 累加並輸出,否就使用 bump- 累減並輸出。

指令數量:10 /10
運行速度:83 /82

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    JUMP     c
b:
    OUTBOX  
    BUMPUP   0
c:
    JUMPN    b
d:
    OUTBOX  
    BUMPDN   0
    JUMPN    a
    JUMP     d

方法2

獲取數值後先輸出原數值,再進行判斷。減少判斷的次數。

指令數量:12 /10
運行速度:77 /82

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     c
a:
b:
    OUTBOX  
    BUMPUP   0
    JUMPN    b
    OUTBOX  
c:
d:
    INBOX   
    COPYTO   0
    JUMPN    a
e:
    OUTBOX  
    BUMPDN   0
    JUMPN    d
    JUMP     e

Year 20 乘法研討會

獲取ab,根據b的數值將a與自己不斷相加b次。如b為0,則輸出a值。
在這邊需要先將a值複製兩次,一個結果位,一個原值位。根據b的值將原值與結果相加後更新結果位。b累減。

方法1

指令數量:15 /15
運行速度:135 /109

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     c
a:
    COPYFROM 0
b:
    OUTBOX  
c:
    INBOX   
    COPYTO   0
    COPYTO   1
    INBOX   
    JUMPZ    b
    COPYTO   2
d:
    BUMPDN   2
    JUMPZ    a
    COPYFROM 1
    ADD      0
    COPYTO   0
    JUMP     d

方法2

增加對0相乘的判斷條件,減少多餘的執行步驟。

指令數量:28 /15
運行速度:101 /109

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
b:
    INBOX   
    JUMPZ    i
    COPYTO   0
    INBOX   
    JUMPZ    h
    COPYTO   1
    SUB      0
    JUMPN    d
    COPYFROM 1
c:
    COPYTO   2
    BUMPDN   0
    JUMPZ    g
    COPYFROM 2
    ADD      1
    JUMP     c
d:
    COPYFROM 0
e:
    COPYTO   2
    BUMPDN   1
    JUMPZ    f
    COPYFROM 2
    ADD      0
    JUMP     e
f:
g:
    COPYFROM 2
h:
    OUTBOX  
    JUMP     a
i:
    OUTBOX  
    INBOX   
    JUMP     b

Year 21 以零結尾的總和

利用0作為分隔,將0前的所有數值加總。如第一個值為0,則直接輸出0。

方法1

指令數量:10 /10
運行速度:72 /72

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    JUMPZ    d
b:
    COPYTO   0
    INBOX   
    JUMPZ    c
    ADD      0
    JUMP     b
c:
    COPYFROM 0
d:
    OUTBOX  
    JUMP     a

Year 22 費布那西訪客

用文字來說,就是費布那西數列即費氏數列由0和1開始,之後的費布那西數就是由之前的兩數相加而得出。首幾個費布那西數是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……
通常來說起始值是0,但在這題中我們的起始值是1。

方法1

透過從1+1,1+2,2+3等開始將數值分為起始值,兩個相加值,一個判斷值和一個終點值。將兩個相加值的結果更新到判斷值,如果判斷值大於終點(即終點減判斷值為負數),就停止輸出。

指令數量:19 /19
運行速度:125 /156

-- HUMAN RESOURCE MACHINE PROGRAM --

    BUMPUP   9
a:
    INBOX   
    COPYTO   2
    COPYFROM 9
    COPYTO   8
    COPYTO   3
    OUTBOX  
b:
c:
    COPYFROM 3
    OUTBOX  
    COPYFROM 8
    COPYTO   7
    COPYFROM 3
    COPYTO   8
    ADD      7
    COPYTO   3
    SUB      2
    JUMPN    c
    JUMPZ    b
    JUMP     a

Year 23 最小數值

和21關類似,利用0作為分隔,將0前的最小的值輸出。

方法1

指令數量:13 /13
運行速度:73 /75

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     b
a:
    COPYFROM 0
    OUTBOX  
b:
    INBOX   
    COPYTO   0
c:
d:
    INBOX   
    JUMPZ    a
    SUB      0
    JUMPN    e
    JUMP     d
e:
    ADD      0
    COPYTO   0
    JUMP     c

Year 24 模組運算

使用Mod獲取AB兩值的餘數。考慮到遊戲中目前只有加減,我們可以使用A不斷減B到負數或零為止。如果是負數就加上B再輸出,零則直接輸出零。

方法1

指令數量:11 /12
運行速度:50 /57

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     b
a:
    ADD      1
    OUTBOX  
b:
    INBOX   
    COPYTO   0
    INBOX   
    COPYTO   1
    COPYFROM 0
c:
    SUB      1
    JUMPN    a
    JUMP     c

Year 25 加總倒數

經典的數學。獲取一個值N,將這個值加上N-1,直到0。如輸入3,輸出則6 (3+2+1=6)

方法1

指令數量:11 /12
運行速度:79 /82

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     c
a:
    COPYFROM 1
b:
    OUTBOX  
c:
    INBOX   
    JUMPZ    b
    COPYTO   0
d:
    COPYTO   1
    BUMPDN   0
    JUMPZ    a
    ADD      1
    JUMP     d

Year 26 小試除法

遊戲中並沒有除法,所以要將除法還原到基本的加減。而除法本質就是將被除數減去除數,結果為減到零或負數前的次數。

方法1

指令數量:15 /15
運行速度:73 /76

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     b
a:
    COPYFROM 2
    OUTBOX  
b:
    COPYFROM 9
    COPYTO   2
    INBOX   
    COPYTO   0
    INBOX   
    COPYTO   1
c:
    COPYFROM 0
    SUB      1
    JUMPN    a
    COPYTO   0
    BUMPUP   2
    JUMP     c

Year 28 三數值排序

每三個輸入為一組,將每組的內容從小到大地輸出。

方法1

這裡我先使用冒泡排序,將ABC值互相比對將大的數值放在前面輸出。

指令數量:34 /34
運行速度:132 /78

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   0
    INBOX   
    COPYTO   1
    INBOX   
    COPYTO   2
b:
    COPYFROM 0
    SUB      1
    JUMPN    c
    JUMP     d
c:
    COPYFROM 0
    COPYTO   5
    COPYFROM 1
    COPYTO   0
    COPYFROM 5
    COPYTO   1
d:
    COPYFROM 1
    SUB      2
    JUMPN    e
    JUMP     f
e:
    COPYFROM 1
    COPYTO   5
    COPYFROM 2
    COPYTO   1
    COPYFROM 5
    COPYTO   2
    JUMP     b
f:
    COPYFROM 2
    OUTBOX  
    COPYFROM 1
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    JUMP     a

方法2

為了減少執行步驟,需要將比對大小的步驟減少。
判斷AB,在判斷BC,再判斷AC便可得知結果。用最少的步驟找出排序

指令數量:58 /34
運行速度:75 /78

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
b:
c:
d:
e:
f:
    INBOX   
    COPYTO   0
    INBOX   
    COPYTO   1
    SUB      0
    JUMPN    i
    INBOX   
    COPYTO   2
    SUB      0
    JUMPN    h
    COPYFROM 0
    OUTBOX  
    COPYFROM 2
    SUB      1
    JUMPN    g
    COPYFROM 1
    OUTBOX  
    COPYFROM 2
    OUTBOX  
    JUMP     b
g:
    COPYFROM 2
    OUTBOX  
    COPYFROM 1
    OUTBOX  
    JUMP     f
h:
    COPYFROM 2
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    COPYFROM 1
    OUTBOX  
    JUMP     e
i:
    INBOX   
    COPYTO   2
    SUB      1
    JUMPN    k
    COPYFROM 1
    OUTBOX  
    COPYFROM 2
    SUB      0
    JUMPN    j
    COPYFROM 0
    OUTBOX  
    COPYFROM 2
    OUTBOX  
    JUMP     d
j:
    COPYFROM 2
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    JUMP     a
k:
    COPYFROM 2
    OUTBOX  
    COPYFROM 1
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    JUMP     c

Year 29 儲存池

這一關開始,地毯有了新的特性。手上持有的數值也可以是地毯的位置index,所以接下來程序將有更多的變化。

方法1

根據 inbox 的數值,找到地毯相應的內容,然後輸出。沒什麼難度,

指令數量:5 /5
運行速度:25 /25

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   10
    COPYFROM [10]
    OUTBOX  
    JUMP     a

Year 30 字串儲存地

這一關就要開始熟練使用地毯index的特性,根據 inbox 的數值,獲取對於的地毯內容輸出,然後累加1知道地毯的內容為0。

方法1

用到 bump+jump0 就可以達到效果。

指令數量:7 /7
運行速度:203 /203

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   24
b:
    COPYFROM [24]
    JUMPZ    a
    OUTBOX  
    BUMPUP   24
    JUMP     b

Year 31 倒序字串

inbox 的字串倒序輸出。

方法1

類似上一個的變形,先將輸入的內容順序放在地毯上,利用提供的地毯14號來記錄。每放一個內容,記錄格就+1,inbox 到0就根據記錄格輸出,並將記錄格-1,以此類推。

指令數量:11 /11
運行速度:121 /122

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     e
a:
b:
    BUMPDN   14
    JUMPN    d
    COPYFROM [14]
    OUTBOX  
    JUMP     b
c:
d:
    BUMPUP   14
e:
    INBOX   
    JUMPZ    a
    COPYTO   [14]
    JUMP     c

Year 32 盤點報告

根據 inbox 的字串,數地毯上有多少個相同的,然後輸出數量。

字母也可以進行加減,ABCD對應1234,以此類推。所以Z等於24.

方法1

正常思路,將14號的零另外複製兩份作為個數和地毯坐標,將 inbox和每個地毯相減。等於零就是一樣的字母,將個數+1,否則就不是相同。最後將個數輸出。

指令數量:16 /16
運行速度:404 /393

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
    COPYTO   15
    COPYFROM 14
    COPYTO   16
    COPYTO   17
b:
    COPYFROM [17]
    JUMPZ    e
    SUB      15
    JUMPZ    d
c:
    BUMPUP   17
    JUMP     b
d:
    BUMPUP   16
    JUMP     c
e:
    COPYFROM 16
    OUTBOX  
    JUMP     a

方法2

這道題為了獲取最優解。我們可以用一些計謀來快速計算出結果。首先我們知道這題地毯上的內容是固定的,所以我們知道每個字母在地毯上的數量。但問題就在於我們如何知道 inbox 的輸入並且輸出對於的數量呢?

經過統計,在這道題目中,地毯上的A有4個,B有5個,C有2個,X有3個
所以我們可以將地毯14號格加2,用作處理C的輸出。然後複製一份到任意格,加一用作X的輸出。

inbox 獲取字母,與4號格的C相減。
如果是負數,即 ?-3(C)=負 。存在的可能只有A(1)或B(2)。
A的話,直接將結果的-2加三次14個的2等於4就可以輸出。-2+2+2+2=4
B的話,直接將結果的-1加三次14個的2等於5就可以輸出。-1+2+2+2=5
如果是0,代表一定是C,C的數量是2。所以將手上的0加上14個的2就可以輸出。
如果是正數,代表一定是X,直接將我們一開始準備的3輸出即可。

這種取巧的辦法只適用這款遊戲的這個關卡。真實的程序還是要適配不同的情況比較好。

指令數量:16 /16
運行速度:39 /393

-- HUMAN RESOURCE MACHINE PROGRAM --

    BUMPUP   14
    BUMPUP   14
    COPYTO   8
    BUMPUP   8
a:
    INBOX   
    SUB      4
    JUMPZ    c
    JUMPN    b
    JUMP     d
b:
    ADD      14
    ADD      14
c:
    ADD      14
    JUMP     e
d:
    COPYFROM 8
e:
    OUTBOX  
    JUMP     a

方法3

這個辦法也類似於方法2,基於我們已經找到每個字母的數量,只是需要得知輸入的字母是什麼。所以我們可以預先準備好輸出的答案,即2,3,4,5。
然後將輸入的字母和地毯0(B),1(A),2(X)號相減,等於0即代表就是那個答案,然後輸出對於的答案。如果和地毯0(B),1(A),2(X)號相減也不等於零,就只有一種可能性,C。直接輸出C的答案2即可。

指令數量:30 /16
運行速度:51 /393

-- HUMAN RESOURCE MACHINE PROGRAM --

    BUMPUP   14
    BUMPUP   14
    COPYTO   15
    BUMPUP   15
    COPYTO   16
    BUMPUP   16
    COPYTO   17
    BUMPUP   17
a:
b:
c:
d:
    INBOX   
    COPYTO   18
    SUB      0
    JUMPZ    e
    COPYFROM 18
    SUB      1
    JUMPZ    f
    COPYFROM 18
    SUB      2
    JUMPZ    g
    COPYFROM 14
    OUTBOX  
    JUMP     a
e:
    COPYFROM 17
    OUTBOX  
    JUMP     b
f:
    COPYFROM 16
    OUTBOX  
    JUMP     c
g:
    COPYFROM 15
    OUTBOX  
    JUMP     d

Year 34 母音毀滅者

只能輸出母音以外的字母。即 AEIOU這些字母不可以輸出。

方法1

和上一關的基本思路一樣。將輸入的字母和地毯上的所有字母相減,如果結果都不是0。就代表不是母音,可以輸出。

為此我們需要一個循環,起始格5為0,格6為累加的地毯地址。

指令數量:13 /13
運行速度:318 /323

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
b:
    COPYFROM 5
    COPYTO   6
    INBOX   
    COPYTO   9
c:
    COPYFROM [6]
    JUMPZ    d
    SUB      9
    JUMPZ    a
    BUMPUP   6
    JUMP     c
d:
    COPYFROM 9
    OUTBOX  
    JUMP     b

Year 35 刪除重複

輸入的所有字母都只能輸出一次,已經輸出過的文字直接扔掉。

方法1

和上一關的基本思路一樣。我們需要保持輸入的值,和已經輸出過的值。每次有新的輸入就比多所有過往輸出過的值。如果重複就扔掉,否則就保存一份到地毯,然後輸出。

需要注意的是,這次我們無法用累加的形式,因為我們無法找到地毯的哪一格式結束。所以我們要用累減。從地毯隊列最後往前驗證。如果index是0就終止。

指令數量:17 /17
運行速度:165 /167

-- HUMAN RESOURCE MACHINE PROGRAM --

    INBOX   
    COPYTO   [14]
a:
    OUTBOX  
b:
    INBOX   
    COPYTO   12
    COPYFROM 14
    COPYTO   13
c:
    COPYFROM [13]
    SUB      12
    JUMPZ    b
    BUMPDN   13
    JUMPN    d
    JUMP     c
d:
    BUMPUP   14
    COPYFROM 12
    COPYTO   [14]
    JUMP     a

Year 36 字母排序

利用0作為分隔,將兩組詞比對,輸出整體較小的那組詞。

A=1, B=2, C=3, D=4 ..... Y=25, Z=26

方法1

將第一組詞存儲在地毯。並且記錄詞的長度,最後在詞追尾添加一個0做結束。
然後將第二組詞一個一個字和第一組比對。相同的字就直接輸出,不相同就看正負。
將最小的那個輸出(即結果為負代表第一組大過第二組。反之第二組大過第一組)

指令數量:32 /39
運行速度:69 /109

-- HUMAN RESOURCE MACHINE PROGRAM --

    COPYFROM 23
    COPYTO   22
a:
    INBOX   
    COPYTO   [22]
    JUMPZ    b
    BUMPUP   22
    JUMP     a
b:
    COPYFROM 23
    COPYTO   22
c:
    INBOX   
    JUMPZ    i
    COPYTO   21
    SUB      [22]
    JUMPZ    g
    JUMPN    e
d:
    COPYFROM [22]
    JUMPZ    h
    OUTBOX  
    BUMPUP   22
    JUMP     d
e:
    COPYFROM 21
    OUTBOX  
f:
    INBOX   
    JUMPZ    k
    OUTBOX  
    JUMP     f
g:
    COPYFROM 21
    OUTBOX  
    BUMPUP   22
    COPYFROM [22]
    JUMPZ    j
    JUMP     c
h:
i:
j:
k:

Year 37 資料鏈

熟練使用地毯的指針效果 copyfrom[X]

方法1

指令數量:8 /8
運行速度:63 /63

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    INBOX   
b:
    COPYTO   12
    COPYFROM [12]
    OUTBOX  
    BUMPUP   12
    COPYFROM [12]
    JUMPN    a
    JUMP     b

Year 38 數位爆炸

這關需要將輸入的進行壓縮,化為一個個位值輸出。例如 27 則輸出 2 7471則輸出 4 7 1
輸入的範圍是1-999,輸出的順序是百位,十位,個位。

方法1

關卡已經提供了0,10和100。所以可以利用這些來分別用除法獲取相應的位值。例如600 / 100 = 6,我們就可以獲得百位數。以此類推除以10獲得十位。

指令數量:29 /30
運行速度:209 /165

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    COPYFROM 9
    COPYTO   8
    COPYTO   7
    INBOX   
    COPYTO   6
b:
    SUB      11
    JUMPN    c
    COPYTO   6
    BUMPUP   8
    COPYFROM 6
    JUMP     b
c:
    ADD      11
d:
    SUB      10
    JUMPN    e
    COPYTO   6
    BUMPUP   7
    COPYFROM 6
    JUMP     d
e:
    COPYFROM 8
    JUMPZ    h
    OUTBOX  
    COPYFROM 7
f:
    OUTBOX  
g:
    COPYFROM 6
    OUTBOX  
    JUMP     a
h:
    COPYFROM 7
    JUMPZ    g
    JUMP     f

方法2

方法1雖然簡潔,但執行步驟較多,但如果要減少執行步驟,只能多餘的判斷步驟。一旦獲得答案就馬上輸出。不走多餘的步驟。所以我們需要針對每種結果計算一個輸出。個十百位都要有0-9的可能,所以我們可以覆蓋這些可能已達成快速的輸出結果。

指令數量:187 /30
運行速度:162 /165
過程較長,只附上代碼。

-- HUMAN RESOURCE MACHINE PROGRAM --

a:
    COPYFROM 9
    COPYTO   3
    COPYTO   4
    INBOX   
    SUB      11
    JUMPN    r
    SUB      11
    JUMPN    i
    SUB      11
    JUMPN    h
    SUB      11
    JUMPN    g
    SUB      11
    JUMPN    f
    SUB      11
    JUMPN    e
    SUB      11
    JUMPN    d
    SUB      11
    JUMPN    c
    SUB      11
    JUMPN    b
    SUB      11
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    JUMP     n
b:
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    JUMP     o
c:
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    JUMP     p
d:
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    JUMP     q
e:
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    JUMP     m
f:
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    JUMP     l
g:
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    BUMPUP   3
    JUMP     k
h:
    COPYTO   5
    BUMPUP   3
    BUMPUP   3
    JUMP     j
i:
    COPYTO   5
    BUMPUP   3
j:
k:
l:
m:
n:
o:
p:
q:
    COPYFROM 5
r:
    ADD      11
    SUB      10
    JUMPN    aa
    SUB      10
    JUMPN    z
    SUB      10
    JUMPN    y
    SUB      10
    JUMPN    x
    SUB      10
    JUMPN    w
    SUB      10
    JUMPN    v
    SUB      10
    JUMPN    u
    SUB      10
    JUMPN    t
    SUB      10
    JUMPN    s
    SUB      10
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    JUMP     aj
s:
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    JUMP     ai
t:
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    JUMP     ah
u:
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    JUMP     ag
v:
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    JUMP     af
w:
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    JUMP     ae
x:
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    BUMPUP   4
    JUMP     ad
y:
    COPYTO   5
    BUMPUP   4
    BUMPUP   4
    JUMP     ac
z:
    COPYTO   5
    BUMPUP   4
    JUMP     ab
aa:
    COPYTO   5
ab:
ac:
ad:
ae:
af:
ag:
ah:
ai:
aj:
    COPYFROM 5
    ADD      10
    COPYTO   5
    COPYFROM 3
    JUMPZ    ak
    OUTBOX  
    COPYFROM 4
    OUTBOX  
    COPYFROM 5
    OUTBOX  
    JUMP     am
ak:
    COPYFROM 4
    JUMPZ    al
    OUTBOX  
al:
    COPYFROM 5
    OUTBOX  
am:
    JUMP     a

方法3

這個方法需要一些數學基礎,我們知道這關輸入的值範圍在 1-999。所以我們可以透過進一步計算來驗證出數值的個十百位。

首先我們需要創建出 30, 300 和 3, 6, 9 用於快速的定位數值。
首先將輸入減去10,判斷輸入是否是個位數。是就直接出入個位。
然後將輸入減去100,判斷輸入是否為十位數。
如果都不是就是100以上,我們就可以用 300 來減。

用 300 減法快速定位數值是100-300還是301-600還是601-900901-999
將定位到的百位數先記錄 3/6/9 ,如果是範圍是901-999,就直接輸出百位為9。
然後在將減去的結果餘數繼續減去 100,取得範圍內的精準百位值。

十位也是一樣用 30 減法快速定位數值是10-30還是31-60還是61-9091-99
將定位到的十位數先記錄 3/6/9,如果是範圍是91-99,就直接輸出十位為 9。
然後在將減去的結果餘數繼續減去 10,取得範圍內的精準十位值。

最後剩餘的數值就是個位數的值。輸出即可。

這種方法將方法2的慢慢從位值減1來說,透過範圍快速定位到具體的位值。減少很多多餘的步驟。個位數和十位數直接走快速通道輸出,不需要做多餘的百位或十位驗算。而百位值和十位值也減少例如 6, 7, 8, 9 這類大數值的多步驟。減少這類大數值的驗算步驟。進一步減少運行速度。

指令數量:105 /30
運行速度:133 /165

同樣這邊只附上代碼。

-- HUMAN RESOURCE MACHINE PROGRAM --

    COPYFROM 11
    ADD      11
    ADD      11
    COPYTO   3
    COPYFROM 10
    ADD      10
    ADD      10
    COPYTO   6
    COPYFROM 9
    COPYTO   2
    BUMPUP   2
    BUMPUP   2
    BUMPUP   2
    ADD      2
    COPYTO   5
    ADD      2
    COPYTO   8
a:
b:
c:
    INBOX   
    COPYTO   0
    SUB      10
    JUMPN    v
    ADD      10
    SUB      11
    JUMPN    n
    ADD      11
    SUB      3
    JUMPN    e
    SUB      3
    JUMPN    f
    SUB      3
    JUMPN    d
    COPYTO   0
    COPYFROM 8
    OUTBOX  
    JUMP     m
d:
    ADD      3
    COPYTO   0
    COPYFROM 5
    JUMP     g
e:
    COPYFROM 9
    JUMP     h
f:
    ADD      3
    COPYTO   0
    COPYFROM 2
g:
h:
    COPYTO   1
    COPYFROM 0
    SUB      11
    JUMPN    j
    SUB      11
    JUMPN    i
    COPYTO   0
    BUMPUP   1
    BUMPUP   1
    JUMP     k
i:
    ADD      11
    COPYTO   0
    BUMPUP   1
    JUMP     l
j:
    ADD      11
    COPYTO   0
    COPYFROM 1
k:
l:
    OUTBOX  
m:
n:
    COPYFROM 0
    SUB      6
    JUMPN    p
    SUB      6
    JUMPN    q
    SUB      6
    JUMPN    o
    COPYTO   0
    COPYFROM 8
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    JUMP     a
o:
    ADD      6
    COPYTO   0
    COPYFROM 5
    JUMP     r
p:
    COPYFROM 9
    JUMP     s
q:
    ADD      6
    COPYTO   0
    COPYFROM 2
r:
s:
    COPYTO   4
    COPYFROM 0
    SUB      10
    JUMPN    u
    SUB      10
    JUMPN    t
    COPYTO   0
    BUMPUP   4
    BUMPUP   4
    OUTBOX  
    COPYFROM 0
    OUTBOX  
    JUMP     b
t:
    ADD      10
    COPYTO   0
    BUMPUP   4
u:
    COPYFROM 4
    OUTBOX  
v:
    COPYFROM 0
    OUTBOX  
    JUMP     c

Year 39 再次安置

這關將地毯進行一個二維化的處理。我們需要根據輸入的值,輸出對應在地毯上的X坐標和Y坐標

方法1

觀察到每行只有4格。我們可以利用輸入的值減去4,如果不是0或負數表示在下一行。
如此類推可以得出輸入值的Y值。而減下來剩餘的值就是X值。

地毯從0開始計算。

指令數量:14 /14
運行速度:73 /76

-- HUMAN RESOURCE MACHINE PROGRAM --

    JUMP     b
a:
    ADD      15
    OUTBOX  
    COPYFROM 11
    OUTBOX  
b:
    COPYFROM 14
    COPYTO   11
    INBOX   
c:
    SUB      15
    JUMPN    a
    COPYTO   10
    BUMPUP   11
    COPYFROM 10
    JUMP     c

Year 40 質數工廠

這題考驗需要一些數學基礎,什麼是質數?所謂的質數是指在大於1的自然数中,除了1和該数自身外,無法被其他自然数整除的数。例如7就無法被1以外的數整除,所以7是質數。同理 2, 3, 5, 7, 11, 13, 17, 19, 23, 29... 這類都是質數。

所以這關我們需要輸出輸入值的所有的質因數。質因數在數論裏是指能整除給定正整數的質數。
例如 6 的質因數是 2 和 3 ( 2x3=6 ) 。8 的質因數是 2,2,2 ( 2x2x2=8 ) 。24的質因數是 2,2,2,3 ( 2x2x2x3=24 )。420 的質因數是 2,2,5,3,7 ( 2x2x5x3x7=420 )

簡單來說,就是求質因數分解。
用數學的方式來看就是下面的方式:
45 的質因數是 3,3,5 ( 2x3x5=45 )

方法1

一開始從 2 開始除 (不斷地減到零或負數),有餘數就將餘數繼續減 3,減 4,減 5 ....
如果減到零就代表輸入值是一個質數,直接輸出。

如果輸出了第一個質因數後還有結果除的結果不是0,表示輸入值不是一個質數。我們就需要求出其他質因數。
在被上一個質因數的除完的結果上在繼續除 (不斷地減到零或負數) 來求下一個質因數。以此類推輸出所有的質因數。

指令數量:28 /28
運行速度:365 /399

-- HUMAN RESOURCE MACHINE PROGRAM --

    COPYFROM 24
    COPYTO   19
    BUMPUP   19
a:
    INBOX   
    COPYTO   23
    COPYFROM 19
    COPYTO   22
b:
    BUMPUP   22
c:
    COPYFROM 23
d:
    SUB      22
    JUMPZ    e
    JUMPN    b
    JUMP     d
e:
    COPYFROM 22
    OUTBOX  
    COPYFROM 24
    COPYTO   18
f:
    COPYFROM 23
    SUB      22
    JUMPZ    g
    COPYTO   23
    BUMPUP   18
    JUMP     f
g:
    BUMPUP   18
    COPYTO   23
    SUB      19
    JUMPZ    a
    JUMP     c

Year 41 排序室

這關是遊戲的最後一關了。
這關需要將 inbox 中每個以 0 結尾的字串,將字串中的內容從小到大排序,然後將結果輸出。

方法1

由於有指令數量限制,所以我們可以使用冒泡排序來處理。並且為了加快步驟,我們找到最小值就可以直接輸出,並減少字串長度。

首先我們需要一個格來存儲字串長度,兩個用作儲存比較位置格。
將所有文字讀取出來後,我們從最後一個值往前一個值比較(相減)。
如果結果正數,表示當前的值前一個值大。我們就從前一個值再前一個值比。
如果結果負數,表示當前的值前一個值小。我們就從當前的值再前一個值比。

找出最小值後,我們直接輸出,輸出後需要將整體長度減1,並且輸出值的位置需要用最後的值來填充,減少計算步驟並且避免漏掉數值。

指令數量:31 /34
運行速度:650 /714

-- HUMAN RESOURCE MACHINE PROGRAM --

    COPYFROM 24
    COPYTO   20
    COPYTO   23
    BUMPUP   23
    JUMP     b
a:
    COPYFROM 0
    OUTBOX  
b:
c:
    INBOX   
    JUMPZ    d
    COPYTO   [20]
    BUMPUP   20
    JUMP     c
d:
    JUMP     f
e:
    COPYFROM [22]
    OUTBOX  
    BUMPDN   20
    COPYFROM [20]
    COPYTO   [22]
f:
    BUMPDN   20
    JUMPZ    a
    COPYTO   22
    COPYTO   21
    BUMPUP   20
g:
h:
    BUMPDN   21
    JUMPN    e
    COPYFROM [22]
    SUB      [21]
    JUMPN    h
    COPYFROM 21
    COPYTO   22
    JUMP     g

最終程式

看到這裡表示你也完成了遊戲,你也從剛剛入職的新人編程成為一個白髮蒼蒼的資深員工。恭喜,恭喜。希望你也從這款遊戲中獲得“樂趣”😉。