欢迎光临散文网 会员登陆 & 注册

【深圳 IO 攻略】第 19 关:智能电网控制路由

2022-06-04 21:01 作者:ココアお姉ちゃん  | 我要投稿

本文首发于 B 站《深圳 IO》文集(https://www.bilibili.com/read/readlist/rl569860)。原创不易,转载请注明出处。

关卡展示

本关需要将从三个输入口发出的数据包按照以下规则转发到指定的输出口中:

  • 首数字小于锁中的数字时,将数据包转发到【较小输出】端口;

  • 首数字等于锁中的数字时,将数据包转发到【电表输出】端口;

  • 首数字大于锁中的数字时,将数据包转发到【较大输出】端口。

数据包中的第二个数字是在此之后还剩余的数字数量,也就是说数据包的总长度 = 第二个数字 + 2。

这一关我们需要将首数字读入 dat,第二个数字读入 acc 并倒数,完成整个数据包的传送。如果我们尝试将所有逻辑写在同一块芯片里,会发现根本写不下。我们现在只能退而求其次,用两块芯片来传输。第一块芯片判定好数据方向后,将数据方向的值写入 p 口通道,后面就只管给第二块芯片传数据了。具体往哪个方向传,由第二块芯片来操作。

我们先看左边的“判断方向并传输数据”的芯片。首先,等待 x1 口的数据包(slx x1),然后将前两个数字分别存入 dat 和 acc 中(mov x1 dat, mov x1 acc)。我们在两块芯片中用可以反复读取的 p 口来表示数据包的输出方向,0 为【较小输出】,50 为【电表输出】,100 为【较大输出】。我们首先假设首数字和锁中的数字一样,将输出方向设为【电表输出】(mov 50 p0)。然后我们判断首数字和锁中的数字的大小(tcp dat x0),若首数字比锁中的数字小,则将输出方向改为【较小输出】(- mov 0 p0);若首数字比锁中的数字大,则将输出方向改为【较大输出】(+ mov 100 p0)。方向决定好后,我们只管往右边的芯片传数据。首先是把前两个数字传过去(mov dat x3, mov acc x3),对于剩下的 acc 个数字,我们使用循环来完成。传一个(mov x1 x3),然后判断刚才传的数字是不是最后一个(tcp acc 1)。若不是最后一个,则令剩余数字数 -1(+ sub 1),并跳回到第 10 行继续传(+ jmp a),直到将所有的数字都传给右边的芯片后,回到第一行,等待下一个数据包(slx x1)。

然后我们看右边的芯片。因为收到数据以后 p 口所表示的方向肯定是已经确定下来的了,所以我们只需要 tcp 三态判定,并将收到的数字发送给指定方向的输出口就行了。首先我们等待从左侧芯片发来数字(slx x1)。如果指定的方向是【电表输出】方向(teq p0 50),则将发来的数字传入【电表输出】端口(+ mov x1 x3)。如果指定的方向不是【电表输出】方向,则判定是【较小输出】还是【较大输出】(tcp p0 50),并将发来的数字送入指定方向的端口(- mov x1 x2, + mov x1 x0)。

点击左下角的【模拟】,稍等片刻,便会弹出结算界面:

优化三项指标

我们观察到,数据包中的第一个数字一定是三位数,其余数字则一定不是三位数。所以,当我们收到一个三位数时,意味着这是一个新数据包的首数字。每当收到一个新的首数字,我们就更换一下方向。如此便可大幅优化三项指标。

我们不断等待 x1 发来新的数字(slx x1, mov x1 acc)。当发来的是三位数时(tcp acc 99),说明是数据包的首数字。将该首数字放入 dat 中,作为将来判断传送方向的依据(+ mov acc dat)。如果首数字和锁中的数字一致(teq dat x0),那么就把当前数字发往【电表输出】方向(+ mov acc x3)。如果首数字和锁中的数字不一致(tcp dat x0),那么当首数字小于锁数字时,发往【较小输出】方向(- mov acc x2);当首数字大于锁数字时,发往【较大输出】方向(+ mov acc x0)。

以上的电路图中,我们发现 MC6000 的 x0 口既和锁子相连,又和【较大输出】相连。但两者并不矛盾,因为锁子是一个【只读】口,而【较大输出】是一个【只写】口。当我们从 x0 口读数据时,数据只会从锁子进来;当我们向 x0 口写数据时,数据只会传往【较大输出】口。

成本 ¥10→¥5,电量 391→315,代码行数 19→9。

【深圳 IO 攻略】第 19 关:智能电网控制路由的评论 (共 条)

分享到微博请遵守国家法律