Shuttle CCH24 记录帖

日志 / 部落格 303 views 17 replies
#1 · (edited)

Shuttle CCH24 全称 Shuttle Christmas Code Hunt 2024,官方描述如下:

"Shuttlings" (inspired by rustlings) are hands-on code challenges we made for learning the basics of backend development in Rust and using the Shuttle platform.

Christmas Code Hunt is a set of Rust challenges where you build a web server for helping Santa get prepared for Christmas. Open the tutorial challenge (-1) for a guide on how to get started! Complete all challenges by December 31 to have a chance to win prizes!

大致就是圣诞节前的几天逐步开放一些 Rust challenges,全做完就能参与抽奖。笔者长期没有实践编码,技巧生疏,借着这个机会尝试重拾编码的乐趣。本帖是笔者参与该活动的记录。

Day -1 的挑战主要是练习使用 Shuttle 平台和相关的 Web server 库,由于本次挑战的提交全部都是采用构建 Web server 的形式,这部分知识是必要的。Rust 的相关生态相对丰富,笔者选用 Axum 进行游玩。

Day -1 的挑战也很简单,输出一些最基本的 HTTP 响应即可,基本上没有难度。

接下来看 Day 2 的挑战。我实际上开始玩的时候已经是 Day 3 了,不过没有关系,只有 2, 5, 9, 12, 16, 19, 23 这些日子有新的挑战开放。笔者 把这些数字扔 OEIS 查了查,也没看出什么名堂,大概真的只是圣诞倒计时。

Day 2, Task 1|448x500

Day 2 的挑战主要和 IP 有关,大概就是做些加加减减的小学数学。笔者随便截了张图放在上面。按照题意的话,只需要把 IP 的每个部分分别加加减减一下就好了。笔者有些好奇这种做法在实际生活中有没有用到,但实在兴趣缺缺,也就没有自行查阅资料。

Day 2, Task 3 (Bonus)|690x360

这个挑战的每一天都有一个额外的 bonus part,不做也算任务完成,但做了能获得少许加分。笔者为了充分享受这个挑战的过程,尽量都会去试一试。Day 2 的 bonus part 主要是引入了 IPv6 的一个 XOR,做法上似乎没有什么不同,况且最难的解析与构造 IPv6 地址都有现成的库函数实现,于是很快也实现出来了。

Day 2, Code snippet|690x456

由于编码时心态比较随便,看起来像💩山。

最后放一张 Day 2 通关证明:

Day 2, Submissions|690x263

P.S. 发这个帖子的时候 Day 5 也已经开放并被笔者收拾掉了,目前的心情还是很愉快的。时间有些晚了,Day 5 的记录就留待下次吧。

❤️👍️😍️🤩️
12
#2 ·
ucw ucw

帅的,我也做做看

#3 ·
ucw ucw

undefined|690x77
想打了

admin
#4 · (edited)
Zerick Zerick

我也想打

#5 ·

Day 5 主要是做 manifest 解析,需要接收一个 POST 上来的纯文本 Cargo.toml 格式数据,解析出 package.metadata.orders 部分。

Day 5, Task 1|472x500

反应快的小伙伴可能读完 task 1 就开始用工具生成对应的 scheme 了,但笔者的习惯是先看完所有 tasks,以便确定设计到何种粒度。这里对于 scheme 的要求是“Cargo manifest”,遂 add 一个 cargo-manifest 的 dependency,这样也就不用手写 scheme 了。把 plaintext 做成一个 Manifest 对象,然后随便怎么数据操作都很 easy。

bonus part 要求推广到 YAML 和 JSON 格式,这可以简单地用对应格式的 serde integration 来实现。serde_yaml 竟然已经因为作者没有需求而不维护了,几经查找决定用 serde_yml。这一天的挑战还是比较 straightforward 的。

Day 5, Code snippet|521x500

笔者在写代码的时候感觉到这个 scheme 里成吨的 Option<T> 有一点卡手,也许是打开方式不对,没有细想。无论如何,it works. 最后还是放一张 Day 5 的通关证明:

Day 5, Submissions|690x279

下一个挑战应该是 9 号开放,暂且拭目以待。

❤️
3
#6 ·

一个小插曲,笔者刚刚重新审视了 serde_yml,发现这玩意比较可疑。具体来讲,它干掉了 unsafe-libyaml 这个依赖,然后加上了一个 libyml

unsafe-libyamlserde_yaml 的作者是同一人,即放弃维护这些 YAML 相关项目的 dtolnay;libymlserde_yml 的“作者”也是同一人,是 fork 了 dtolnay 这两个项目的 sebastienrousseau。后者的 id 也太长了,笔者暂且叫他 S 先生。

由于好奇,笔者 compare 了 unsafe-libyamllibyml,先看看 Cargo.toml 都改了啥:

Safe? Stop making me laugh!|690x320

这可太厉害了。对于一个 fork 来的项目,S 先生完全删掉了原作者,简直是厚颜无耻;对于一个仅仅是 c2rust 翻译过来的东西,S 先生大言不惭地 claim 它 "safe and efficient",简直是精神错乱。

S 先生把原项目 fork 过来具体加了什么新的 features 笔者暂时不得而知,maybe just "code refactoring and new unit tests"。尽管如此,它在 crates.io 中 yaml 关键词下的最近下载排名已经到达了第四位,十分具有迷惑性。

Oh, great ranking.|611x500

综合 S 先生的各种 overclaim,笔者做出了换回 serde_yaml 的决定。希望笔者今天所看到的这些 overclaim 只是因为 S 先生还没有完全完成他的大业,而不是另有所图。

❤️😰️
8
#7 ·

Day 9 启动!目前耗费时长最多、调试开销最大的挑战。一个 rate limiter,缝合奇妙单位换算。先放成功截图:

Day 9, Submissions|690x281

要求给 endpoint 加 rate limit,每 5 秒允许 5 次,所谓的“漏桶算法”,用 leaky-bucket 即可实现。

恶心就恶心在同一个 endpoint 有多种模式,JSON 的逻辑和不带 body 的逻辑完全不一样,却要共用路由;单位换算的公式也不给,只能自己查资料,查出巨量恶心小数。

bonus part 要实现一个 refill 功能,leaky-bucket 本身没有这个功能,手搓不太可能,加 Mutex 用重初始化代替草草了事。

哪怕是娱乐玩法,公式也是可以给一给的,笔者真的一点也不想知道 liters, gallons, litres, pints 这些单位之间的关系。

Day 9, Code snippet|523x500

❤️wave_gif
4
mod
#8 ·
ucw ucw

牛逼

❤️hugging_face_cat
2
#9 · (edited)

Day 12: Connect 4 小游戏,一张有意思的视觉图:

Day 12, Subject|500x500, 75%

玩法就是有 4x4 的格子,每一方可以选择(未满的)某一列,在该列的顶上放上 🍪 或者 🥛 。大概像这样:

Day 12, Task|225x379

比前一次好得多的一个挑战。一顿狂写之后解决。笔者现在已经把至今为止的 solutions 全部 push 到 GitHub 上,欢迎感兴趣的朋友们来交流:

https://github.com/wuxianucw/shuttlings-cch24

最后仍然是一如既往的通关证明,生活中需要正反馈:

Day 12, Submissions|690x264

❤️wave_gif
8
mod
#10 · (edited)
ucw ucw

我小学时候玩过类似的玩具,可能是 6 ×\times 6 的或者 8 ×\times 8 的 😸 规则好像是四子棋(五子棋的简略版)不知道你的这个游戏是否有斜向获胜这个赢法

年月擦身过,暂且问,会更好吗?

❤️
1
#11 ·
ucw ucw
ucw:

一张有意思的视觉图

确实好有意思,感觉像是早八套餐,上面是奶糖,下面是小面包,迟到了就抓起一包拿到教室吃……

——發自我的手機
❤️👍️hugging_face_exploding_head
4
#12 · (edited)
一只玉米人 玉米🌽

是有的,你说的游戏我也玩过 :hugging_face_cat:

diagonal|183x157

❤️wave_gif
2
#13 ·

Day 16 太累了,且有别的优先级更高的事,所以没有当天立即开。现在补上。

这次的 Tasks 出奇简单,就是 JWT,纯送。笔者作为万年互联网搬砖调包侠,做这种既不恶心人又没有很多流程的题就是随便写写的事。

今天写代码有 buff 加成:室友剩了小半瓶二锅头,可以先喝再写甚至边喝边写,如有神助。如图。

Day 16, Buff|375x500

看瓶子上写的 42%vol,感觉已经不低了。写代码而言的话,笔者更喜欢配不超过 15%vol 的酒,能够喝得相对频繁一点也不上头。

Day 16 挑战的 bouns task 给了 200 分,比前几天的 75 更上了一个档次,实际上难度也确实提高了。题目没有把所有的细节说清楚,而是需要一定的探索。给了一个额外的 PEM 文件作为解码 JWT 的 key,但是没有具体说使用什么算法。当然这也构不成什么阻碍,一通调试也就搞定了。

最后仍然是通关证明:

Day 16, Submissions|690x253

❤️💯️
5
admin
#14 ·
ucw ucw

蹲一个开奖

#15 · (edited)
ucw ucw

milk 可以接收 payload: Result<Json<>, JsonRejection<>>

JsonRejection 是个 enum,里面有一个 MissingContentTypeHeader,match 到这一分支就 acquire milk,match 到其他错误就 400 Bad Request。所以不用读 headers

现代英制单位是拿公制单位定义的,所以可以精准换算,就是小数比较长(

❤️
1
#16 ·
ucw ucw

怎么没后续了(
今天至少把 core tasks 做完了,可以参与抽奖,赚到(

image|690x332

#17 ·
uika_winwing uika_winwing

后续是去和女友玩了,烂尾

❤️rolling_on_the_floor_laughing_kissing_heart
4
#18 ·
ucw ucw

草。