致小读者 · 这本书怎么读
适读 5–9 岁:5–7 岁听大人念,7 岁后自己读;单集 5 分钟。第四集按印、第九集倒水、第十集猜数,请大人陪着做;其余可独立完成。
先别急着从头读。这本书里有十二件「乱了」的事:珠子撒了一地、饭煮糊了、雾里迷了路……小骏总抢着先跑,小灵总说「别急,我算一下」,最后一起收拾好。你可以先挑一集,只读「白话一句」和「演义」;喜欢了,再回头看那几十个字的「卷中原文」。每集末尾有「童试」,拿豆子、瓶盖、纸就能做;「今解」是写给大人的。十二集都看完,你手上会多一样本事:再乱的东西,也能一件一件理出来。
卷 首 · 术数即编程
古人所谓「术数」,拆开来看是两个字:数者,可算之物;术者,算之之法。河图列黑白之点,一六共宗、五十同途,说的是万物各有其数与位;洛书布九宫之法,纵横斜皆十五,说的是使万物各归其位的规则。前者是物,后者是法。
今人换了说法,叫它「数据结构」与「算法」。名虽异,其实一也。所以这一季十二则寓言,表面讲木珠、九宫、河浪与卷册,内里讲的是一件最要紧的事:如何把纷乱的世界整理成可算之物,再为它写下可循之法。编程从这里起手。计算思维说来大,归根也只是这一件事。
还要先说一物。书中屡屡提到的「点」,并非玄虚之物,是河洛司里一匣黑白木珠:黑珠实心、白珠中空,摸得着、数得清、装得进匣、摆得进格。古人画河图洛书用的正是这样的黑白点,司里照着做了两色珠子,点数、记账、布阵皆用它。后文或称珠、或称点记、或称阵上的点,都是这同一匣东西。故事里也尽量用孩子见过的物件——煮粟的釜、盖章的木印、分珠的木匣、记账的册子——不拿空泛的「点」来搪塞。
河洛司有二小司掌,皆非寻常童子:小骏是负图龙马所化,额上金角与那撮螺旋浪鬃便是龙马相;小灵是载书灵龟所化,头上龟甲九宫冠与甲片刻纹便是龟甲相。小骏主生数,撒珠成物,敢想敢试,常把事情越弄越乱;小灵主定术,布宫归位,慢而能谋,专收残局。一散一收、一圆一方,缺一则乱,缺二则空。每集都先交代一句为什么做这件事,再让两人各自施展;故事里的人只管撒珠、归位、拌嘴,一句行话都不说;可变量、循环、函数、递归、并发与调试,就藏在这些动作里,一集演一件给你看。
此本每集分作数层:先存卷中原文(简古的寓言),再以一句白话说清发生了什么,而后是演义——补足当时的天光、器物、尘土与人声,写出两人各自的动作、神色与对话,使故事可以像小说一样读下去。每集另附一幅依本集场景绘成的插图,作故事的定格;末了以「术数曰」点题,「今解」讲给大人、「童试」留给孩子动手,「镜头」供动画分镜;各层顺序见下方层次条。
图者,物也;书者,法也。物与法合,是谓能算。
寓言原文→白话一句→小说演义→逐集插图→术数曰→今解 / 童试 / 镜头
HE TU / 生数者 · 龙马化身
小骏
撒珠成物,从无到有。负责生成、枚举、试错、把可能性全部摊开;冲动、好奇、永远先跑三步。演义里他脚步咚咚、袖子先惹祸、圆眼睛说亮就亮,急起来连耳根都红。他代表「数据」与「发散」,也代表每个初学者最常犯、却最宝贵的那种错。
对应计算思维:分解 · 试错 · 生成实例
LUO SHU / 定术者 · 灵龟化身
小灵
布宫归位,化乱为序。负责命名、分类、约束、校验;不追着珠子跑,只把规矩立好,珠自会各归其位。演义里她总先把袖口拢好、说话前停半拍,眼帘半垂,着急时也只是指尖在罗盘沿轻叩一下。她代表「规则」与「收敛」。
对应计算思维:抽象 · 模式识别 · 算法设计
概念图 · 卷中之卷动画采用「书中书」结构:3D 河洛司里翻开一卷古书,进入平面绢本设色的寓言世界;故事结束,合卷回场。两种画风不冲突,反而有了叙事层次。
目 录
十二目 · 概念对照
Fable → Concept Map
十二集分三卷:卷一识数,学会「东西放在哪里、按什么次序」;卷二立法,学会「把做法写成法,让法自己跑」;卷三合道,学会「多法并行时如何自处,以及物与法终究是一件事」。点击篇名可跳至全文。
| 集 | 篇名 | 术数曰 | 编程概念 | 思维维度 |
| 一 | 哪一颗是哪一颗 | 数必有名,名必有位 | 变量与地址 | 抽象 |
| 二 | 先跑三步 | 事同而序异,其果亦异 | 顺序执行 | 算法设计 |
| 三 | 两头也算 | 两端皆数,缺一不成 | 边界条件 / off-by-one | 算法设计 |
| 四 | 一枚点印 | 重复者,一法可当百手 | 循环与模式 | 模式识别 |
| 五 | 借法的龟甲 | 法可授人,不必身至 | 函数与封装 | 抽象 / 分解 |
| 六 | 岔口三问 | 先设问,后分行 | 条件分支 if / else | 算法设计 |
| 七 | 河浪不止 | 知其一推,则知无穷 | 递推与递归 | 模式识别 |
| 八 | 两只匣子 | 纳之有序,取之亦有道 | 栈与队列 | 数据结构 |
| 九 | 多点一颗 | 同其时者,必约其序 | 并发与同步 | 算法设计 |
| 十 | 错了一颗 | 善问者,一问减半 | 二分查找 / 调试 | 算法设计 |
| 十一 | 空着的那一格 | 空者未书,零者已书 | 零 / 空值 / 初始化 | 抽象 |
| 十二 | 河出图,洛出书 | 物法相合,是谓能算 | 程序 = 数据结构 + 算法 | 全维收束 |
人与物 · 一页速查
先认住脸,再翻故事 / Who & What
故事里翻来覆去就这十来件东西。读之前扫一眼,读到一半卡住了,回来查一行,就知道它长什么样、是谁在用、在哪一集出现过。不用背,认得住脸就行。
| 人 | 一句话是什么 | 在哪几集出现 |
| 小骏 | 朱红袍、额上有金角、留一撮螺旋卷的小司掌,腿比脑子快,急起来耳根发红,口头禅是「走,先去看看」 | 十二集都在 |
| 小灵 | 玄青衣裙、头戴龟甲九宫冠的小司掌,说话前先停半拍,着急也只轻叩一下盘沿,口头禅是「别急,我算一下」 | 十二集都在 |
| 物 | 一句话是什么 | 在哪几集出现 |
| 黑白木珠 | 一匣两色珠子,黑的实心、白的空心,故事里所有的「数」都是它;撒出去还能变成山、船和人 | 十二集都在,第三、八、九、十集用得最多 |
| 九宫盘 | 画着九个小格子的盘(第三集那只新打的是铜的),珠子的「家」;说得出格名,就找得到那颗珠 | 第一、二、三、八、十二集 |
| 九宫罗盘 | 小灵随身带的圆盘,盘沿一圈刻着九宫,她心里在算的时候,指尖会在盘沿轻轻叩一下 | 第九、十二集 |
| 界尺 | 一把量纸用的直尺,横在阵中央,就把「该查的那一半」划出来,另一半先暗下去 | 第十集 |
| 小珏 | 炉里烧了半宿铸出的一枚小牌子,谁拿着谁先放珠子,是两个人约好的「排队凭证」 | 第九集 |
| 枣木点印 | 一小段枣木刻出的圆印,蘸墨一按就是一个点;按一下、挪一寸,再按一下 | 第四集,之后一直揣在小骏怀里 |
| 龟甲 | 磨平的龟甲片,上面刻着三步做法;谁拿着它照着做,就像小灵亲自到了 | 第五集 |
| 卷轴 | 河洛司里那卷古书,故事都写在上面;一翻开,人就走进故事里,读完再合上 | 十二集,每集开场翻卷、结尾合卷 |
| 九宫账册 | 一格一格的册子,专记每处有多少颗珠子;没数过的格子先画个空圈,数清了才落笔 | 第一、十一集 |
| 三只小碟 | 一只空着、一只扣着盖还没揭、一只里躺着一颗白珠——三种「空」长得根本不一样 | 第十一集 |
卷 一 · 識 數第一至第四集 / 物各有位,事各有序
第 一 集
哪一颗是哪一颗
变量与地址 · 抽象
寓言 · 卷中原文
岁初,司中清匣。小骏揭盖,黑白木珠哄然滚地。珠皆同貌,小骏欲寻昨日所记之一颗,遍拾不得,愈拾愈乱。小灵取九宫盘,画格而编其号,曰:「上左一,上中二,上右三……」逐珠安之,各占一格,号与珠并录于册。明日小骏欲易其一,但报「上左」,探手即得;复置新珠,亦知归处。小骏怔然:「原来不是珠子认得我。」小灵曰:「数必有名,名必有位。」
白话一匣黑白木珠撒了一地,长得全一样,怎么也找不出要找的那颗;后来给每个格子编号、每颗珠子按号放好,说一声「上左」就能准确取到,换新珠也知道放回哪儿。
演义 · 白话小说
岁初清点,河洛司要把各处器物一一登记造册。西厢的纸窗透进一道斜光,光里浮着细尘,靠墙木架从地面摞到房梁,一格格排着竹筒。案上摊着新册子,墨迹还没干透——小骏领了差事,要把那匣黑白木珠数清楚、记下来。他嫌一颗颗数太慢,索性想掀开匣盖一股脑倒出来,袖子先扫到匣角,啪,盖子翻了个身。
木珠哗啦滚了满地,黑珠实心、白珠中空,滚进竹筒缝里、钻到凳脚下,撞上纸窗簌簌响。小骏趴下去捡,捡起一颗看看,又放下;再捡一颗,还是一样。「昨儿我记下的那颗……是有个小缺口的吧?」他抓着头发,圆眼睛在满地珠子里打转,耳朵尖慢慢红了——珠子全都一个模样,谁也认不出谁。越捡越乱,末了索性坐在地上,两只手都是灰,册子还空着。
小灵进来时没帮他捡。她先把袖口拢好,将九宫木盘平放在案上,取炭条在九格边上一格格编号:上左一、上中二、上右三……这才蹲下,把珠子一颗颗按号安进去,安完把册子推过来,号与珠一一对上。「它不是长得特别,」她说,「它是待在上左。」第二天小骏要换掉其中一颗,只报了「上左」两个字,手一探就取着了;换上新的,也知道该放回哪一格。他捏着珠子愣了愣,圆眼睛眨了两下:「原来不是珠子认得我。」小灵低头合上册子:「是每一颗,都有了名字和地方。」
插图 · 其一岁初清点,木匣翻盖,黑白木珠滚了满地;小骏趴在地上认不出哪颗是哪颗,小灵已把九宫盘摆在门槛内。
术数曰数必有名,名必有位。
今解变量与地址。长得一样的数据,光靠"内容"分不出来;要先给它一个名字(变量名)和一个位置(地址、下标),程序才找得到、读得出、改得动、放得回去。追着满地珠子认,不如先给每格编号。河图十数各居其方,正是最古老的「命名与寻址」。
童试把九颗一样的豆子撒在桌上,不编号,能不能让伙伴一次拿到你心里想的那颗?给每格编号再试;再试试「换掉第三格那颗」,看是不是一伸手就着。
镜头①大远景转全景:3D 河洛司内景,案上卷轴自行展开、镜头顺卷面俯冲入画,立体景渐次转为平面绢本;落点西厢纸窗一道斜光、光里浮尘、靠墙竹筒架与墨迹未干的新册(18 秒|音效:卷轴展开、纸窗风;旁白「岁初清点,河洛司要把器物一一登记造册」)②全景:小骏想一股脑倒出木珠,袖子先扫到匣角,啪,匣盖翻身,黑白木珠哗啦滚满一地、滚进竹筒缝、钻到凳脚下、撞得纸窗簌簌(22 秒|音效:木珠滚地噼啪、纸窗簌簌;小骏「昨儿我记下的那颗……是有个小缺口的吧?」)③近景转特写:小骏趴地捡起又放下、抓头发、圆眼睛打转、耳朵尖泛红,末了坐在地上两手是灰、册子还空着;小灵拢好袖口、九宫木盘平放案上,炭条一格格编号「上左一、上中二、上右三」,蹲下把珠子一颗颗按号安进格,册子推过来号与珠一一对上(50 秒|音效:炭条划木、木珠入格轻叩;小灵「它不是长得特别,它是待在上左」)④近景:次日小骏只报「上左」两字,手一探即取着,换上新的也知道放回哪一格,捏着珠子愣了愣;小灵低头合册「是每一颗,都有了名字和地方」;镜头上摇、卷面收拢,合卷回到 3D 河洛司(40 秒|音效:木珠轻搁、卷轴合拢)全片合计 130 秒。
第 二 集
先跑三步
顺序执行 · 算法设计
寓言 · 卷中原文
入冬,司中煮粟以御寒。小骏自告奋勇:「此易耳!」先燃火,后取水,再取米,终乃洗釜。火烈水涸,釜底尽墨。小灵不言,取九宫盘,于第一格画「洗釜」,二格「取水」,三格「下米」,四格「燃火」,五格「候熟」,曰:「依格而行。」俄而粟香满室。小骏搔首:「吾四事皆做矣。」小灵曰:「事皆是,序非也。」
白话小骏煮饭,四件事一件没落,可全做反了顺序,锅烧糊了;小灵把步骤按顺序写进九宫格,照着走一遍就成了。
演义 · 白话小说
灶房里先响起来的,是风。呼——一股寒气从门缝挤进来,把挂在灶上的陶釜顶得釜盖轻轻一跳。入冬头一场寒。柴垛堆得半人高,水缸沿结了一层薄薄的凉气,米袋还扎着口搁在墙角;司里说好,今日煮一锅粟给大家暖暖。小骏搓着手闯进来,袖子一挽,圆眼睛亮亮的:「这个我会!」话音没落,火折子已经凑到松柴上,嚓的一声,橘红的火苗腾地舔上锅底,映得半间屋都暖了。
然后他才想起没淘米,转身去舀水;水舀回来,发现釜还是脏的,又拎着釜往外跑;等把米倒进去,灶上的空锅早烧得发白,一股焦味顺着梁缝爬满整间屋。小骏掀开釜盖,白烟扑了他一脸,呛得连咳三声,眼睛里全是雾,睫毛湿成一绺:「我……四样都做了呀。」锅底黑得能照出人影,他自己凑过去看,看见一张同样发懵的圆脸。
小灵进来时先把窗推开一条缝放烟,没责备,也没接他手里的勺。她取过九宫盘搁在灶台边,用炭条一格一格写:洗釜、取水、下米、燃火、候熟。写完把炭条搁下,指尖点了点第一格:「从这儿。」小骏凑过去,脑袋跟着格子一格一格往右挪,挪到第四格忽然「啊」了一声,耳根又红了:「火……我头一个就点了。」第二遍照着走,水声、米声、柴声一样样按着次序来,不多时粟香稳稳漫出来,把焦味盖了过去。小灵这才极轻地弯了下嘴角:「事都是那些事。」小骏捧着碗,闷闷地接:「……是次序不对。」
插图 · 其二灶房柴烟未散,焦黑的釜底冒着白烟;小骏被呛得直咳,小灵在灶台边一格格写下五个步骤。
术数曰事同而序异,其果亦异。
今解顺序结构。算法不是「做哪些事」,而是「按什么次序做」。程序一行一行往下执行,每一步都对、次序错了,结果照样错。洛书九宫能当法用,就因为它把先做什么、后做什么,连同方位一起定死了。
童试把「刷牙」拆成五步,故意打乱念给家人听,看在哪一步会闹出笑话;再按正确顺序念一遍。
镜头①大远景转全景:3D 河洛司翻卷入画,落灶房——柴垛堆得半人高、陶釜挂在灶上、水缸沿一层薄凉气、米袋扎着口搁在墙角,暖光与柴烟(16 秒|音效:卷轴展开、柴火噼啪;旁白「入冬头一场寒,司里要煮一锅粟」)②中景:五格九宫逐格亮起作分镜框;小骏挽袖把火折子凑上松柴,橘红火苗腾地舔锅底,随即才想起淘米、舀水、发现釜还脏又拎釜外跑,倒米时空锅已烧得发白,掀盖白烟扑脸、呛咳三声、睫毛湿成一绺(45 秒|音效:火苗腾起、白烟扑、连咳;小骏「我……四样都做了呀」)③中景:小灵先推开窗一条缝放烟、没接他手里的勺,取九宫盘搁灶台边,炭条一格一格写「洗釜、取水、下米、燃火、候熟」,指尖点第一格「从这儿」;小骏脑袋跟着格子一格格往右挪,挪到第四格忽然「啊」一声、耳根又红(42 秒|音效:炭条划盘;小骏「火……我头一个就点了」)④全景转近景:一镜到底照格走完五格——水声、米声、柴声一样样按次序而来,粟香稳稳漫出盖过焦味;小灵极轻弯了下嘴角「事都是那些事」,小骏捧碗闷闷接「……是次序不对」;镜头上摇、合卷回场(45 秒|音效:水、米、柴三声次第、卷轴合拢)全片合计 148 秒。
第 三 集
两头也算
边界条件 · 算法设计
寓言 · 卷中原文
司中新制九宫盘,令小骏布珠验之,横竖斜皆当十五。小骏曰:「首末为边,不足算也。」乃于中间七格各安一珠,两端空焉。纵横索之,皆不得十五。小灵取二珠,分置第一格与第九格,曰:「边非格乎?」盘上光起,三道皆盈。小骏搔首:「我只少数了两颗。」小灵曰:「两端皆数,缺一不成。」
白话要在九格上摆珠验十五,小骏觉得头尾两格是「边」不算,只摆中间七格,怎么算都不对;把第一格和第九格也补上,立刻就成了。
演义 · 白话小说
新制的九宫铜盘一大早送到司里,盘面还带着打磨的细痕,九格刻得方方正正。老司掌交代得清楚:横、竖、斜,三道都得凑成十五,这盘才算验收合格,年前要挂到厅堂去。小骏把一匣黑白木珠抱来,往盘边一坐,卷起袖子:「九格而已,我摆给你看。」窗外的日头刚爬过檐角,照得铜盘亮晃晃的。
他捏起珠子往格里放,放到第一格前忽然停了手,歪头想了想:「这两头是边……边不算吧?」于是跳过第一格,从第二格一路摆到第八格,整整七颗,端端正正。摆完他双手一摊,还挺得意。可一验就傻了:横着十四,竖着十四,斜着还是十四。他把珠子挪来挪去,挪得盘面叮当响,那撮螺旋卷被自己抓得翘起来,圆眼睛越瞪越大:「明明都摆满了呀……」七颗珠子看着确实齐整,就是差着一口气。
小灵一直在旁边理线,这时才伸手,从匣里取了两颗珠子,一颗轻轻按进第一格,一颗按进第九格。「第一格不是格吗?」她问。小骏张了张嘴:「……是。」「那第九格呢?」「也是。」铜盘上的光从两端往中间一汇,横、竖、斜齐齐亮成十五,映得他脸上一亮一亮。小灵把匣子推回他面前:「你不是摆错了中间七颗,是把两头忘在数外头了。」小骏数了数自己少放的那两颗,小声嘟囔:「就两颗啊。」「就两颗,」小灵点头,「整盘就不成立。」
插图 · 其三新制的九宫铜盘上,小骏只摆了中间七格,第一格与第九格空着;小灵正取两颗木珠,要把首尾补齐。
术数曰两端皆数,缺一不成。
今解边界条件与 off-by-one。从第一格到第九格,两头都要算进去;数人数时从头数到尾、还是把两头漏掉;排队时第一个和最后一个算不算——都是同一类「差一个」的错。「十五」是这盘要验的总数,少算一个端点,整盘就不成立——程序里最常出的错,往往不是逻辑错,是边界漏了一个。
童试在纸上并排画九个格子,只在中间七格里放豆子,一共放了几格?两头那两格算不算格子?再想想:从第 1 数到第 9,一共几个数?
镜头①大远景转全景:3D 河洛司翻卷入画,落厅堂——新制的九宫铜盘一大早送到,盘面还带打磨细痕、九格刻得方正,窗外日头刚爬过檐角,照得铜盘亮晃晃(15 秒|音效:卷轴展开、铜盘轻搁;旁白「横、竖、斜,三道都得凑成十五」)②中景:小骏抱一匣木珠往盘边一坐、卷起袖子「九格而已,我摆给你看」,捏珠放到第一格前忽然停手、歪头「这两头是边……边不算吧」,跳过第一格从第二格摆到第八格、整整七颗,摆完双手一摊还挺得意(35 秒|音效:木珠落格、衣料摩擦)③近景:一验就傻——横十四、竖十四、斜十四,珠子挪来挪去叮当响,那撮螺旋卷被抓得翘起,圆眼睛越瞪越大「明明都摆满了呀……」(30 秒|音效:珠子挪动叮当、盘面轻震)④特写转近景:小灵取两颗,一颗按进第一格、一颗按进第九格,「第一格不是格吗」「……是」「那第九格呢」「也是」;铜盘光从两端往中间一汇,横竖斜齐齐亮成十五;小灵「你不是摆错了中间七颗,是把两头忘在数外头了」,小骏嘟囔「就两颗啊」「就两颗,整盘就不成立」;镜头上摇、合卷回场(55 秒|音效:两珠轻叩、光起微鸣、卷轴合拢)全片合计 135 秒。
第 四 集
一枚点印
循环与模式 · 模式识别
寓言 · 卷中原文
岁末录事,长卷之上,每笔当志一记,凡百。小骏执笔,一一画之,才十余,腕已酸,且大小不齐。小灵刻一圆木印,蘸墨一按即成一记,曰:「不必画百回。按一下,移一寸,再按一下。」小骏依之,百记俄顷而毕,累累如一。叹曰:「吾向者以为要做一百件事。」小灵曰:「其实只做一件,做一百遍。」
白话要在长卷上留一百个一样的点记,小骏一个一个画,手酸还画得大小不一;小灵刻了一枚圆点木印,按一下、挪一寸、再按一下,很快整卷都齐整了。
演义 · 白话小说
岁末录事,一年的收成要记进长卷:每记一笔,就在卷上留一个圆点作记号,满一百个才好封卷归档。长案从东墙铺到西墙,四角压着铜镇纸,砚台里的墨刚研开,窗外的雪落得很慢,窗台上一枝腊梅顶着薄雪。小骏挽起袖子坐下,提笔蘸墨,一笔一点往卷上画:「一个、两个、三个……」头几个还圆,画到十来个,手腕就酸了,点也越画越歪,大的像豆、小的像芝麻。他趴在案上吹了吹墨,长长叹了口气:「还有九十个啊。」
小灵没接他的笔,转身从木料筐里翻出一小段枣木,拿刻刀在端面旋出一个圆,吹掉木屑,又拿到砚台边轻轻一蘸。她把木印往卷上一按,抬起——一个圆滚滚、墨色匀净的点记就留在纸上,和前一个一般大小。她把印往旁边挪一寸,再按,又是一个。「按一下,移一寸,再按一下。」她说得平平的,「不用重新想,每一步都和刚才一样。」小骏凑过去,圆眼睛跟着那枚木印一寸一寸往西挪,耳朵一动:「那……我不用画一百遍?」
他接过小印自己按起来。沙、沙、沙,印起印落,点记一个挨一个排过去,间距匀得像量过,雪光从窗纸透进来,照得整卷黑白分明。按到最后一个,他甩了甩手腕,忽然笑出声:「我先前以为要做一百件事呢。」小灵把镇纸一只只收起来,摞齐:「其实只做一件,做一百遍。」小骏把那枚枣木印在袖口蹭了蹭,趁她转身偷偷揣进怀里——明年封卷还用得上。
插图 · 其四岁末长案铺开长卷,小骏手画的几个点大小不一;小灵以一枚刻圆的枣木印蘸墨按下去,卷上已排了一长串一模一样的点记。
术数曰重复者,一法可当百手。
今解循环与模式识别。发现「每一步都一样」是计算思维的第一步;把这一个动作只定义一次,再让它重复执行,就是 for / while。人力按次数增长,法力不按次数增长——而且机器重复一百遍,还能保证每一遍都一模一样,这是手画做不到的。
童试用一枚瓶盖蘸一点清水,在桌面或石板上按十下,能不能得到十个一模一样的圆?再用手画十个比一比,哪个更齐、哪个更省事?
镜头①大远景转全景:3D 河洛司翻卷入画,落岁末长案——长卷从东墙铺到西墙、四角压着铜镇纸,砚里墨刚研开,窗外雪落得很慢、窗台一枝腊梅顶着薄雪(16 秒|音效:卷轴展开、研墨、远处落雪;旁白「每记一笔留一个圆点,满一百个才好封卷归档」)②近景(延时):小骏挽袖提笔一笔一点「一个、两个、三个……」,头几个还圆,画到十来个手腕就酸、点越画越歪、大的像豆小的像芝麻;趴在案上吹了吹墨,长长叹气(40 秒|音效:笔尖沙沙转疏、延时加速;小骏「还有九十个啊」)③特写:小灵从木料筐翻出一小段枣木,刻刀在端面旋出一个圆、吹掉木屑、拿到砚台边一蘸,往卷上一按抬起,一个圆滚滚墨色匀净的点记;印往旁挪一寸再按「按一下,移一寸,再按一下」「不用重新想,每一步都和刚才一样」(40 秒|音效:刻刀旋木、木屑落地、按印沙沙)④全景转近景:小骏接过小印自己按,沙、沙、沙,点记一个挨一个排过去、间距匀得像量过,雪光透窗纸照得整卷黑白分明;按到最后一个甩了甩手腕笑出声「我先前以为要做一百件事呢」,小灵收镇纸「其实只做一件,做一百遍」;小骏趁她转身把枣木印在袖口蹭了蹭偷偷揣进怀里,合卷回场(44 秒|音效:按印沙沙成节拍、卷轴合拢)全片合计 140 秒。
卷 二 · 立 法第五至第八集 / 法可授人,法能自行
第 五 集
借法的龟甲
函数与封装 · 抽象
寓言 · 卷中原文
邻邑珠册散乱,遣使求小灵。小灵方守司,不能去。乃取片甲磨平,刻归位之法三行:一曰列九宫,二曰呼其名,三曰验和十五。刻竟,吹去石青之屑,以麻绳贯其孔,授使者曰:「持此往,如吾亲至。」使者归,依法行之,果定。后三邑俱来借甲,小灵足不出户,而诸邑渐理。小骏异之:「汝分身乎?」小灵徐徐抬眼:「吾不分身,吾分法。」
白话邻邑来请小灵去救急,她走不开,就把「怎么把珠子归位」刻在一片龟甲上让人带回去照做;后来好几座城都来借甲,她一次门都没出。
演义 · 白话小说
开春没多久,邻邑的珠册散了架:各处木珠的数目与格子对不上,账也核不清,眼看要误了春耕的分派。门外一阵急马蹄声,帘子被风掀得老高,驿使进来时斗笠边还滴着泥水,靴上溅满黄泥,一开口就请小灵即刻动身。小灵正站在卷架前整理竹简,手没停,只轻轻摇头:「我这里也走不开。」驿使愣在门口,手里绞着缰绳,看看她,又回头望一眼那匹还在喘气的马,话到嘴边又咽了回去。小骏从架子后探出半个脑袋,圆眼睛在两人之间转了一圈,刚要拍胸脯说自己能去,被小灵用指尖不轻不重地按了回去。
她从案下取出一片磨平的龟甲,坐下,拿刻刀一笔一笔刻起来。刀口很浅,石青填进刻痕,她低下头,把浮粉轻轻吹散,又用袖角顺着甲面擦净,三行字便清清楚楚地露出来:一曰列九宫,二曰呼其名,三曰验和十五。刻完,她取麻绳从甲孔穿过,打了个死结,双手递过去:「照着做,如我亲至。」驿使捧着甲片翻来覆去看了两遍,指甲在最后那行上蹭了蹭,半信半疑地揣进怀里;出门时还回头望了一眼,这回脚步比来时稳了些。
第七日,邻邑来信道谢,说账已理清。又半月,另外三邑的使者竟一块儿挤在门口,斗笠挨着斗笠,谁也不肯后进,把门槛都踏得发亮。小骏扒着门框数人头,越数越糊涂,回头看小灵——她仍旧坐在卷架前,连凳子都没挪过,只是案上多了一摞新磨好的甲片,齐齐压着一张薄纸。「你……分身了?」他把门帘掀起一角,又放下。小灵把甲片摞齐,推到案边,这才慢慢抬眼:「我不分身。」停了半拍,语气还是平平的:「我分法。」
插图 · 其五驿使斗笠滴着泥水候在门口;小灵吹去龟甲上的石青粉屑,把刻好的归位之法系上麻绳递出去。
术数曰法可授人,不必身至。
今解函数、封装与复用。把一段做法取个名字、写清先做什么后做什么、验什么才算成,谁都能照着调用;不必把同一套步骤抄到每个地方,改一处便处处生效。龟甲就是最早的「函数」,上面刻的是方法,不是答案。
童试把「整理书包」写成三条别人也能照做的指令,交给家人执行,看结果和你自己做的一不一样;不一样就改指令,别改人。
镜头①大远景转全景:3D 河洛司翻卷入画,落开春司门——一阵急马蹄,帘子被风掀得老高,驿使斗笠边滴着泥水、靴上溅满黄泥,开口就请小灵即刻动身;小灵站在卷架前整理竹简,手没停,只轻轻摇头(18 秒|音效:卷轴展开、马蹄、帘子扑打;小灵「我这里也走不开」)②特写:小骏从架子后探出半个脑袋、刚要拍胸脯,被小灵用指尖不轻不重按了回去;她从案下取出一片磨平的龟甲,一笔一笔刻出「一曰列九宫,二曰呼其名,三曰验和十五」,低头吹散石青浮粉、用袖角顺甲面擦净,麻绳从甲孔穿过打个死结,双手递过(45 秒|音效:刻刀浅划、吹粉、麻绳穿孔;小灵「照着做,如我亲至」)③全景(分屏):甲片一化为三,飞向三座小城,三城同时亮起九宫;又半月,另外三邑使者一块儿挤在门口、斗笠挨着斗笠把门槛踏得发亮;小骏扒着门框数人头越数越糊涂(42 秒|音效:风声过城、九宫次第亮起、门槛脚步声;旁白「法可授人,不必身至」)④近景:回头看小灵——仍旧坐在卷架前,连凳子都没挪过,只案上多了一摞新磨好的甲片、齐齐压着薄纸;「你……分身了?」小灵把甲片摞齐推到案边,慢慢抬眼「我不分身」停了半拍「我分法」;合卷回场(35 秒|音效:甲片摞齐轻叩、卷轴合拢)全片合计 140 秒。
第 六 集
岔口三问
条件分支 · 算法设计
寓言 · 卷中原文
山间书院索新抄《数书》,老先生待以开讲,小骏请行。道逢三岔,雾深不辨。小骏曰:「吾尽走之!」往返数四,日暮犹在松下。小灵立木牌,书曰:「若见溪,则左;若见石,则右;二者皆无,则直行。」再行,一往而达。小骏曰:「牌不识途,何以引路?」小灵曰:「牌使人先问一句,路便自明。」
白话给山上的书院送一部新抄的书,雾里遇三岔,每条都跑一遍还是绕回原地;写清「看见什么就往哪走」,一次就到了。
演义 · 白话小说
山间书院捎信来,要一部新抄的《数书》,老先生等着开春给学童讲第一堂课。小骏把书用油布裹了两层,装进小书箱背在背上,天没亮就出了门,圆眼睛亮得很:「路我认得!」小灵不放心,扣好袖口跟在后头。石阶上的露水浸得发亮,走到半山腰,雾从谷里一股一股漫上来,松针上挂满水珠,几步之外就只剩白茫茫一片。
三岔口立着棵老松。左边隐隐有溪声,右边堆着一片灰石,中间那条道被雾吞得看不见头。小骏把书箱往上颠了颠:「都走一遍不就知道了!」话音没落人已窜进左道。一炷香后他从左边跑回来,书箱带子在肩上勒出一道红印,袍角沾满草籽;又钻进右道,再一炷香,喘着气冒出来,额上那撮螺旋卷跑得歪到一边。中间那条他也没落下。日头一点点偏西,三道岔口被他踩出一层乱脚印,人却还站在老松底下扶着膝盖直喘,肩膀一起一落:「怎么……每条都绕回这儿啊。」
小灵一路没追,这时才慢慢蹲下,捡了块炭,从袖里抽出一块备用的木牌,就着松根把字写上去:若见溪,则左;若见石,则右;二者皆无,则直行。指腹蹭得发黑,她也不擦,把牌往岔口一插,退开半步:「再走。」小骏半信半疑迈出去,先低头看路——石阶边没有溪,也没有碎石——便照着最后那句一直往前。雾散开一线,书院的檐角就在前头露了出来,隐约还听见学童念书的声音。他回头喊,声音在谷里撞了个来回:「这牌子它又没走过,怎么知道路!」小灵把炭块收进袖里,跟上来,走过牌边时顺手把被风吹歪的木牌扶正:「它不知道路。」她抬眼看了看那三行字,「它只是让你每回都知道,该先看什么。」
插图 · 其六给山间书院送书,雾里三岔口左边是溪、右边是碎石,乱脚印绕成一团;小灵蹲在老松下往木牌上写字。
术数曰先设问,后分行。
今解if / else 条件分支。程序靠「判断」选择路径,而不是把所有路都跑一遍。把判断条件写清楚,比跑得快更重要;几条条件最好互不重叠,又别漏掉一种。漏了,就会掉进没人管的那条路。牌上最后那句「否则直行」,就是替这一种留的。
童试写三条「如果……就……」的规则,让伙伴据此猜你今天早饭吃了什么;记得留一条「否则」。
镜头①大远景转全景:3D 河洛司翻卷入画,落天未亮的山道——小骏把《数书》用油布裹了两层、装进小书箱背在背上出门,小灵扣好袖口跟在后头;石阶露水浸得发亮,走到半山腰雾从谷里一股股漫上来、松针挂满水珠(18 秒|音效:卷轴展开、夜虫、脚步踏露;小骏「路我认得」)②中景:三岔口立着棵老松——左边隐隐溪声、右边堆着灰石、中间那条被雾吞得看不见头;小骏窜进左道,一炷香后跑回、书箱带子勒出红印、袍角沾满草籽;又钻进右道,再一炷香喘着气冒出来、螺旋卷跑得歪到一边;中间那条也没落下。日头偏西,三道岔口踩出一层乱脚印,人还扶着膝盖直喘(50 秒|音效:脚步来回、喘息渐重、溪声隐现;小骏「怎么……每条都绕回这儿啊」)③特写:小灵一路没追,这时才慢慢蹲下、捡块炭、从袖里抽出备用木牌,就着松根写「若见溪,则左;若见石,则右;二者皆无,则直行」,指腹蹭得发黑也不擦,把牌往岔口一插、退开半步(35 秒|音效:炭条划木牌;小灵「再走」)④全景:画面分出三条支线,只亮中间一条;小骏先低头看路——石阶边没有溪、也没有碎石——照最后一句一直往前,雾散一线、书院檐角露出、隐约学童念书声;他回头喊「这牌子它又没走过,怎么知道路」,小灵走过牌边顺手扶正被风吹歪的木牌「它不知道路」「它只是让你每回都知道,该先看什么」;合卷回场(45 秒|音效:雾散风轻、远处念书声、卷轴合拢)全片合计 148 秒。
第 七 集
河浪不止
递推与递归 · 模式识别
寓言 · 卷中原文
春汛将至,司中修历,欲记一潮之浪数,以告舟人收缆之候。小骏请往,立河浒数之:「一浪、二浪、三浪……」数至百而浪不止,颓然坐。小灵曰:「勿数浪,观一浪可矣。此浪推彼浪,其状尽同,所异者唯后一息。知一浪如何生下一浪,则虽千万浪,皆在掌中。」小骏凝视久之,忽喜曰:「吾不必数尽,只需知『下一步』。」既而小声曰:「然亦须有个止处。」小灵颔之:「止处亦当写入法中。」
白话春汛前要替船家弄清一潮有多少浪,小骏蹲在河边数,数到一百也数不完;后来明白只要看清「一浪怎么推出下一浪」,后面多少浪都不用数了——但法里还得写清什么时候停。
演义 · 白话小说
春汛快到了,河边的老舟子拄着篙来问:一潮到底起多少浪?司里要把它记进历书,好教船家知道第几浪该收缆靠岸。小骏一听就举了手:「我去数!」那天傍晚河风带着水腥气,芦苇被压得齐齐往一边倒,哗啦哗啦响成一片。他蹲在湿沙上,伸着指头点浪:「一浪、二浪、三浪……」浪一层推着一层,从脚边一直铺到看不清的对岸,每数到一处,前头又生出新的。数到一百,手指僵在半空,声音被浪声盖了下去,索性一屁股坐进沙里,鞋边洇出一圈湿印,眼睛望着水面,半天没眨一下:「老舟子还等着回话呢……根本数不完。」
小灵没往水边去,在他旁边蹲下,先把被风掀起的袖口压住,然后折了一根芦苇秆,在湿沙上画了两道挨着的弧。「别数浪,」她说,「看这一道,和它推出来的下一道。」小骏凑过去,脸几乎贴到沙面:两道弧弯得一模一样,只是后头那道往前挪了半指,弧梢上都带着同样一小撮碎白沫。「一样的?」「一样的。差的只是后一息。」她把秆子搁下,指尖点着前一道弧,「知道一浪怎么生出下一浪,第一浪之后的,就都在里头了。历书上要写的,其实是这一句。」
小骏盯着那两道弧看了很久。风把芦苇吹得沙沙响,浪还在推,一浪接一浪,谁也没打算停。他忽然一骨碌爬起来,抓起秆子在沙上又添了第三道、第四道,越画越快,末了回头咧嘴一笑,眼睛亮得很:「那老舟子问的不是『一共多少』,是『下一浪什么时候来』!」小灵站起身,拍掉裙角的沙,把那根芦苇秆也插回他手里。走出去几步,他又小声补了一句,声音被风压得低低的:「……可历书总得写个头、写个尾吧?船也不能一直数下去。」这回小灵停了半拍,认真点了头:「嗯,什么时候停,也得写进法里。」
插图 · 其七春汛前替船家数浪,黄昏河浒芦苇倒伏;小骏坐在湿沙上数不动了,小灵在沙上画出相邻两道相同的浪弧。
术数曰知其一推,则知无穷。
今解递推关系与递归。只要说清「头一个数是多少」和「后一个比前一个多多少」,再长的一串都能用短短一句话讲完。递归函数同理,还必须有停下来的条件(base case)——否则就像数不完的浪,程序永远回不来。
童试摆出 1、3、5、7、9 五堆豆子,看看后一堆总比前一堆多几颗;照这个「多几颗」,第十堆该摆多少?摆出来数一数;再想想,如果让你一直数下去,什么时候该停?
镜头①大远景转全景:3D 河洛司翻卷入画,落春汛前的河浒——老舟子拄着篙来问一潮到底起多少浪,要记进历书、教船家第几浪收缆靠岸;傍晚河风带水腥气,芦苇被压得齐齐往一边倒、哗啦哗啦响成一片(18 秒|音效:卷轴展开、河风、芦苇哗啦、水声;小骏「我去数!」)②全景:小骏蹲在湿沙上伸指头点浪「一浪、二浪、三浪……」,浪一层推着一层铺到看不清的对岸、每数到一处前头又生出新的;数到一百手指僵在半空、声音被浪声盖了下去,索性一屁股坐进沙里、鞋边洇出一圈湿印、圆眼睛望着水面发直(45 秒|音效:浪声层层推近渐强、盖过数数声;小骏「老舟子还等着回话呢……根本数不完」)③特写:画面收拢成相邻两浪特写;小灵在他旁边蹲下、先压住被风掀起的袖口,折一根芦苇秆在湿沙上画两道挨着的弧——弯得一模一样,只是后头那道往前挪了半指、弧梢同样挂着一小撮碎白沫;「一样的?差的后一息」「知道一浪怎么生出下一浪,第一浪之后的,就都在里头了」(45 秒|音效:沙上划秆、浪声退为底;小灵「别数浪,看这一道,和它推出来的下一道」)④近景:小骏一骨碌爬起、抓过秆子又添第三道第四道、越画越快「那老舟子问的不是『一共多少』,是『下一浪什么时候来』」;走几步又低声「……可历书总得写个头、写个尾吧」,小灵停了半拍认真点头「什么时候停,也得写进法里」;湿沙上两道弧叠成一枚自生纹样,合卷回场(42 秒|音效:浪声、脚步、卷轴合拢)全片合计 150 秒。
第 八 集
两只匣子
栈与队列 · 数据结构
寓言 · 卷中原文
库中新至木珠,命分纳二匣:一给厨下叠碗,一给司门排队领珠。小骏自上叠下,取时先得最后所纳;小灵依次平列,取时先得最先所纳。二人均曰「吾匣无误」,及并倾于九宫盘,次序大乱,数珠不知所终。争久,小灵忽悟:「纳同而取异,非匣之过,法之异也。」遂刻字于匣:一曰「后来先出」,一曰「先来先出」。自是各司其用。小骏曰:「原非匣错,是各有各的取法。」
白话新到一批木珠要分装两只匣子,装法不同,倒出来的先后就不同,合在一起全乱了;后来给每只匣子刻清楚「谁先出」,各用各的场合,就再也不乱。
演义 · 白话小说
小骏两只手各托一只新匣,往长凳上一搁。老司掌吩咐:库房新到一批黑白木珠,深的搁厨下配叠碗,浅的搁司门口给领珠的人依次取。匣是新打的,一深一浅。清香还没散。窗格漏进几道窄光,照见案角一摞待洗的碗和一把竹签。他捧起珠子往深匣里倒,图省事,一颗压一颗往上叠,叠到最后一颗还拍了拍匣盖,挺得意:「看,多整齐。」小灵那边不慌不忙,把珠子一颗颗平着排进浅匣,先来的靠里,后来的靠外,拿竹签在匣沿划了记号,轻轻合上盖。
两人各说各的匣子没错,索性把两只匣一起倾进九宫盘合验。头一颗出来就岔了:小骏匣里先滚出的是他最后放的那颗,小灵匣里先出来的却是最早那颗。两股珠子在盘沿撞了个正着,噼里啪啦滚了一地,有几颗钻进凳脚底下,滴答、滴答,响了好一会儿才停。小骏趴到地上伸胳膊去够,抬起头时脸上全是茫然,腮帮子还沾了点灰:「明明都是九颗啊。」小灵也蹲下来,却没急着捡。
她从指间拈起一颗,慢慢转了半圈,忽然极轻地「哦」了一声。她把两只匣拉到一处,取刻刀在深匣上刻「后来先出」,浅匣上刻「先来先出」,刻完吹掉木屑,抬眼看小骏:「装的时候一样,取的时候不一样——不是匣错了,是各有各的取法。」小骏看看这行字,又看看那行字,抓了抓头,那撮螺旋卷被他揉得更乱了。第二天厨下叠碗,他自动抱走了深匣,最后洗净的那只果然先被拿走;司门口排队领珠的人,被小灵引到浅匣那一边,先来的先领,谁也没争。
插图 · 其八库房窄光下深匣与浅匣并排,两股木珠在九宫盘沿撞作一团、滚了满地;小灵拈起一颗在指间细看。
术数曰纳之有序,取之亦有道。
今解栈(LIFO)与队列(FIFO)。同样的数据,取出的规则不同,结果完全不同;选哪种结构本身就是设计。撤销操作用栈,排队打印排队用队列。这两种结构没有谁更好,只看你把它用在哪一步。
童试一摞盘子只能从顶上拿,是「先进先出」还是「后进先出」?排队买点心呢?再想一件家里的事该用哪只匣子。
镜头①全景:3D 河洛司翻卷入画,落库房——新到一批黑白木珠,新打的深匣与浅匣并排搁在长凳上、木头清香还没散,窗格漏进几道窄光,照见案角一摞待洗的碗和一把记数竹签(16 秒|音效:卷轴展开、木匣轻搁;旁白「一只搁厨下配叠碗,一只给司门口排队领珠的人依次取」)②中景(对称构图):左边小骏往深匣里倒、一颗压一颗往上叠,叠到最后一颗还拍了拍匣盖「看,多整齐」;右边小灵不慌不忙把珠子一颗颗平着排进浅匣、先来的靠里后来的靠外,排完拿竹签在匣沿划了道记号、轻轻合上(42 秒|音效:珠入深匣闷响、珠入浅匣清响,左右二分;小骏「看,多整齐」)③全景:两匣一起倾进九宫盘合验,头一颗就岔了——小骏匣里先滚出他最后放的那颗、小灵匣里先出来最早那颗;两股珠子在盘沿撞个正着,噼里啪啦滚了一地、几颗钻进凳脚底滴答滴答;小骏趴地伸胳膊去够「明明都是九颗啊」,小灵也蹲下却没急着捡,从指间拈起一颗慢慢转半圈、极轻「哦」了一声(45 秒|音效:珠流对撞、满地滚动、凳脚滴答渐止)④特写转全景:小灵取刻刀在深匣刻「后来先出」、浅匣刻「先来先出」,吹掉木屑「装的时候一样,取的时候不一样——不是匣错了,是各有各的取法」;次日厨下叠碗,小骏自动抱走深匣、最后洗净那只果然先被拿走,司门口排队的人被引到浅匣那边先来先领、谁也没争;两股珠流分路各归,合卷回场(45 秒|音效:刻刀走木、吹屑、碗碟轻碰、卷轴合拢)全片合计 148 秒。
卷 三 · 合 道第九至第十二集 / 多法并行,物法归一
概念图 · 河出图,洛出书小骏撒珠化作山川舟树,小灵以九宫收珠为序,中央圆图与方书合为一体。此帧即第十二集的视觉落点,也是整季「物与法合」的图像定义。
第 九 集
多点一颗
并发与同步 · 算法设计
寓言 · 卷中原文
岁中制图,九宫大阵将成,中宫尚欠一珠。小骏自左探手,小灵自右探手,各纳一珠,同时而落。及视盘上,竟有二珠,和乃十六。小骏曰:「吾只放一颗。」小灵曰:「吾亦一颗。」相视良久,俱笑。乃铸一小珏,约曰:「持珏者先落,余者待之。」后再无多珠。小骏曰:「原不是珠多,是手齐。」
白话赶制九宫图只差中宫一颗木珠,两人同时伸手去补,结果多出一颗;后来约定「谁拿着小珏谁先放」,另一个等着,就再没出过错。
演义 · 白话小说
年中要赶制一幅九宫大图,年前挂在厅堂供来客观览。木珠一颗颗摆到日头偏西,横竖斜都验过了,只差中宫那一颗。铜盘搁在案心,午后的光从窗棂斜切进来,把盘面照得发亮,旁边还摊着没来得及收的图样。小骏在左,小灵在右,几乎是同时看见那个空格,也几乎是同时伸的手——两只袖子在盘上擦过,影子叠成一片。两颗珠子一前一后落下去,其实只差了眨一下眼的工夫,可谁也没看清先后。盘面泛起一圈光,横、竖、斜,齐齐报出十六。
屋里静了一瞬。小骏的手还悬在半空,圆眼睛慢慢眨了一下:「我就放了一颗。」小灵低头看盘,指尖仍搭在罗盘边上,眼帘抬起来:「我也只放了一颗。」两人隔着那圈光对望,一个脸上还挂着「先去看看」的急劲,一个还维持着「先算一下」的从容,僵了三息,忽然一起笑出声,笑得小骏直拍案沿,把旁边一摞竹简都震歪了。他把两颗珠子都拈起来又放回,试了两回,回回十六:「不是珠多。」小灵替他把话接完,声音里也带着点笑:「是手齐。」
后来司里铸了一枚小珏。炉火烧了半宿,小骏凑在钳边看得眼睛发亮,被热气逼得直往后仰,鼻尖还是蹭了一道灰。规矩定得极简:持珏者先落,另一个等着。第二日再补中宫,小骏把珏往小灵手里一塞,自己乖乖把手背到身后,脚尖在青砖上点了又点,等她那颗落定、光稳了,才轮到自己。十五,一次就成。他甩了甩发麻的手,小声嘟囔:「等这一下,比跑三趟还累。」小灵把珏收回袖里,没笑,可眼睫轻轻动了动。
插图 · 其九赶制九宫图只差中宫一颗,午后斜光里两只袖子同时伸过去、影子叠成一片,盘上多出一颗木珠。
术数曰同其时者,必约其序。
今解并发与竞态条件(race condition)。两个任务同时改同一份数据,结果就取决于谁先谁后,于是出现「明明各放一颗却多出一颗」。加锁、发令牌,让两个动作排成一列,一个一个来。故事里那枚小珏,就是令牌。
童试两人同时往同一个杯子倒水,怎样约定才不会溢出来?试试「谁拿勺子谁先倒」。
镜头①大远景转全景:3D 河洛司翻卷入画,落年中厅堂——赶制中的九宫大图,木珠一颗颗摆到日头偏西、横竖斜都验过,只差中宫那一颗;铜盘搁在案心,午后光从窗棂斜切进来把盘面照得发亮,旁边还摊着没来得及收的图样(18 秒|音效:卷轴展开、木珠轻落、午后静;旁白「只差中宫一颗」)②中景(画面一分为二):小骏在左、小灵在右,几乎同时看见那个空格、也几乎同时伸手,两只袖子在盘上擦过、影子叠成一片;两颗珠子一前一后落下去,只差眨一下眼的工夫;盘面泛起一圈光,横、竖、斜齐齐报出十六(42 秒|音效:珠落双响几近重叠、光起微鸣)③近景:定格——小骏手还悬在半空「我就放了一颗」,小灵眼帘抬起「我也只放了一颗」;两人隔着那圈光对望,僵了三息,忽然一起笑出声,小骏直拍案沿把一摞竹简都震歪了;他把两颗拈起又放回、试了两回回回十六「不是珠多」,小灵接完「是手齐」(40 秒|音效:案沿拍击、竹简滑落、笑声)④特写转近景:炉火烧了半宿铸出一枚小珏,小骏凑在钳边看得眼睛发亮、被热气逼得往后仰、鼻尖蹭了一道灰;次日再补中宫,他把珏往小灵手里一塞、自己把手背到身后、脚尖在青砖上点了又点,等她那颗落定光稳才轮到自己,一前一后、和复十五;他甩了甩发麻的手嘟囔「等这一下,比跑三趟还累」,小灵把珏收回袖里、眼睫轻轻动了动;合卷回场(45 秒|音效:炉火、珏入掌轻响、脚尖点砖、卷轴合拢)全片合计 145 秒。
第 十 集
错了一颗
二分查找与调试 · 算法设计
寓言 · 卷中原文
岁末,以木珠布大阵于厅,将悬以奉客。验之,纵横当皆十五,独一行不合,不知错在何珠。小骏请逐珠验之,夜分未半。小灵取界尺,横于阵中,曰:「先观左半之和。」左半和合,则错在右;再画一横,右半之上和舛,则错在上;三画、四画,遂指一珠曰:「此。」易之,全阵复明。小骏曰:「汝未尝遍验诸珠。」小灵曰:「但能每问去其半,何必遍看。」
白话岁末要在厅堂挂起全年总图,验收发现有一行不对;一颗颗查到半夜也没查完,小灵用尺每次把阵分掉一半、只查有问题的那半,四步就找出了错珠。
演义 · 白话小说
岁末,全年的总图要用木珠在厅堂里摆出来,次日一早挂起,供来司里作客的各邑使者观览。珠子从门槛一路排到北墙,纵横各九,本该行行十五。天擦黑时最后验一遍,最上头那一行却怎么算都是十四。夜渐渐深了,两排烛台烧得只剩半截,烛泪在铜盘里堆成小丘,把人的影子拉得满地都是,风从门缝里进来时,一整片火苗齐齐歪一歪。小骏跪在阵边,从东头第一颗验起,一颗一颗点过去,膝头压得发麻,才验到第三列:「还有……好多。」声音都有点闷了。
小灵没蹲下去。她从案上取来那把量纸的界尺,走到阵中,蹲身,把尺轻轻横在正中央,灰尘被尺风带起来,在烛光里跳了跳。「先看左半的和。」她只算了一句,左半合,便抬手把右半留着,左半整片随烛影暗下去。再一竖、再一横,每落一次尺,亮着的格子就少一半,厅堂里像有人在缓缓收灯。第四尺落下时,她伸手,指尖稳稳点在西北角一颗白珠上:「这颗。」换过,一整片阵从东到西次第亮回来,横、竖、斜,齐齐十五。
小骏还跪在原地,仰头看着满室的光,半天才撑着膝盖爬起来,拍了拍袍子上的灰:「你……一颗都没挨着验啊。」小灵把界尺夹回腋下,转身去收烛台:「不用挨着看。每一次只问一句『错在哪半边』,问四回,就只剩一格了。」她吹熄第一支烛,青烟直直往上,回头补了一句,「急着找,不如先想清楚该问哪一句。」小骏望着暗下去的半边厅堂,把这句在心里默了两遍,然后悄悄把界尺也拿到了自己手边——明天挂图前,他还想再试一回。
插图 · 其十夜半厅堂两排残烛,巨大的木珠阵铺满地面;界尺一横,半边阵暗下去,只剩西北角一颗白珠发红。
术数曰善问者,一问减半。
今解二分查找与调试策略。与其一颗颗翻,不如每问一句就划掉一半:先问「错在前半边还是后半边」,要找的范围一下就小了;「先定位、再修复」也是调试的第一心法。会问对问题,比闷头把每一颗珠子都翻一遍快得多。
童试在 1 到 100 里想一个数,让伙伴最多问七次「比 X 大吗」,看能不能猜中;想想为什么七次就够。
镜头①大远景转全景:3D 河洛司翻卷入画,落岁末厅堂——全年的总图用木珠从门槛一路排到北墙、纵横各九,天擦黑最后验一遍,最上头那一行怎么算都是十四;夜渐深,两排烛台烧得只剩半截、烛泪在铜盘里堆成小丘,风从门缝里进来时一整片火苗齐齐歪一歪(20 秒|音效:卷轴展开、烛芯轻爆、门缝风;旁白「次日一早挂起,供各邑使者观览」)②全景(俯拍):巨大珠阵俯拍,小骏跪在阵边从东头第一颗验起、一颗颗点过去,膝头压得发麻才验到第三列(35 秒|音效:更漏、指尖点珠极慢;小骏「还有……好多」)③特写:小灵取来量纸的界尺,走到阵中蹲身、把尺轻轻横在正中央,灰尘被尺风带起来在烛光里跳;一尺落下左半合、左半整片随烛影暗下去,再一竖、再一横,每落一次尺亮着的格子就少一半、厅堂像有人在缓缓收灯;第四尺落下,只剩一格发红,指尖稳稳点在西北角一颗白珠上「这颗」(45 秒|音效:界尺落阵四记、烛焰依次低伏;旁白「先看左半的和」)④全景转近景:换过,一整片阵从东到西次第亮回,横、竖、斜齐齐十五;小骏仰头看满室的光,撑膝爬起拍了拍袍子灰「你……一颗都没挨着验啊」;小灵把界尺夹回腋下、吹熄第一支烛「每一次只问一句『错在哪半边』,问四回,就只剩一格了」「急着找,不如先想清楚该问哪一句」;小骏悄悄把界尺也拿到自己手边,合卷回场(45 秒|音效:烛熄青烟、卷轴合拢)全片合计 145 秒。
第 十一 集
空着的那一格
零、空值与初始化 · 抽象
寓言 · 卷中原文
岁末核珠,九宫账册逐格当书其数。小骏见三格空白,皆填曰「无」。及复核:一果无珠,一尚未数,一则珠为邻邑借去、明日乃还。三事混为一「无」,账遂不可问。小灵曰:「未数与数而无,岂可同书?」乃教以空圈志未数之格,数讫乃落笔为数;果无者书「零」。自是账册了然。小骏曰:「原不是都空着。」小灵曰:「空者未书,零者已书。」
白话账册上空着三格,小骏全写成「无」;后来才发现一格是真的没有、一格是还没数、一格是借走了明天还——三种「空」根本不是一回事。
演义 · 白话小说
小骏向来嫌慢。人还没坐稳,手已经摸到笔上。岁末核珠,九宫账册要逐格登记各处木珠的数目,开春好照册分派。账案上摊着册子,一格一格画得方正,旁边摆着三只小碟:一只空着,一只扣着盖子还没揭开,一只里躺着一颗白珠。窗外天色发灰,炭盆偶尔哔一声,墨刚研好,还带着一点松烟味。他见有三格空着,提笔想也不想,三格都写了个「无」,写完把笔往笔山上一搁,还挺痛快:「都空着,省事。」
午后复核就乱了。老司掌问第一格,答「无」——那处确实一颗珠子也没有;问第二格,也答「无」,可那一格压根还没人数过,谁也不知道里面有几颗;第三格还是「无」,珠子却是昨儿被邻邑借走、说好明日送还的。三件完全不同的事,被写成了同一个字,账便再也问不明白。小骏被问得直眨眼,圆眼睛在册子和三只小碟之间来回跑,耳根一点点红起来,伸手想去涂改,反把墨蹭了一道,越抹越花。
小灵取过册子,一手轻轻按住他还举着的笔,另一手另取细笔,在那一格画了个空圈:「没数过,就先留个圈,别写死。」数清了,才把圈改成数;真的一颗没有,才落笔写「零」。「空是还没填,零是数过了才写下来的。」她把三只小碟一一推到对应的格边——空碟、盖着的碟、躺着一颗白珠的碟,「你看,它们本来就不一样。」小骏盯着那个空圈看了半晌,忽然跑去把扣着盖的碟子掀开,一颗一颗认真数完,才回来落笔。那本册子后来再没被人问住过。
插图 · 十一岁末账案上摊着九宫账册,三只小碟各不相同(空碟、盖着的碟、放着一颗珠);小灵按住小骏的笔,在空格里画一个待填的空圈。
术数曰空者未书,零者已书。
今解0、空值与初始化。「没赋值」「值是 0」「还没数过」是三件不同的事(null / 0 / undefined),混写成同一个「无」,后面就再也查不出真相。先给每个位置一个干净的初始状态,第一次写入才有意义;空着的那一格,不是缺了内容。它是特意留出来的,等人来填。
童试拿三张纸:一张什么也不写,一张写「0 颗糖」,一张折起来先别看,三者一样吗?说说差在哪;再想想,作业本上没写的那一格,是「不会」还是「没做」?
镜头①全景:3D 河洛司翻卷入画,落岁末账案——九宫账册一格格画得方正,旁边摆着三只小碟:一只空着、一只扣着盖还没揭、一只里躺着一颗白珠;窗外天色发灰、炭盆偶尔哔一声、墨刚研好带一点松烟味(18 秒|音效:卷轴展开、炭盆哔剥、研墨;旁白「九宫账册逐格登记,开春好照册分派」)②中景:小骏捧着册子过来,见有三格空着,提笔想也不想三格都写了个「无」,写完把笔往笔山上一搁(25 秒|音效:三记落笔、笔搁竹山;小骏「都空着,省事」)③近景:午后复核——第一格答「无」,那处确实一颗也没有;第二格也答「无」,可那格压根还没人数过;第三格还是「无」,珠子却是昨儿被邻邑借走、说好明日送还的。三件完全不同的事被写成同一个字,账再也问不明白;小骏被问得直眨眼、圆眼睛在册子和三只小碟之间来回跑、耳根一点点红起来,伸手想涂改,反把墨蹭了一道、越抹越花(40 秒|音效:纸页翻检、笔锋滞涩、墨蹭纸面)④特写转近景:小灵取过册子,一手轻轻按住他还举着的笔,另一手另取细笔在那一格画了个空圈「没数过,就先留个圈,别写死」,数清了才把圈改成数、真的一颗没有才落笔写「零」;她把三只小碟一一推到对应格边「空是还没填,零是数过了才写下来的」「你看,它们本来就不一样」;小骏盯着空圈看了半晌,忽然跑去把扣着盖的碟子掀开、一颗一颗认真数完才回来落笔;册页收拢、账册了然,合卷回场(45 秒|音效:细笔走纸、掀盖、数珠、卷轴合拢)全片合计 128 秒。
第 十二 集
河出图,洛出书
程序 = 数据结构 + 算法 · 季终
寓言 · 卷中原文
岁暮,天下诸事皆乱:节气失序,道路相缠,言语散不能收。小骏登丘,尽撒其匣中珠,山川草木、舟车人畜,一一自珠中生,然纷纷无纪。小灵临水,布九宫,立纵横斜十五之法,诸珠各就其位,万物各循其序。一撒一定之间,天地间忽现一图:左圆而右方,圆者为图,方者为书。观者但见其明,不知孰为物、孰为法。有老叟拄杖过而叹曰:「图者,物也;书者,法也。徒有物则乱,徒有法则空。物与法合,而后天下可算。」小骏与小灵相视,一曰「走,先去看看」,一曰「别急,我算一下」,遂并肩入图。
白话岁暮天下大乱,小骏撒珠生出山川万物,小灵立九宫让万物各归其位;一撒一定之间,圆形河图与方形洛书合成一整幅图。
演义 · 白话小说
岁暮那天,天色是少见的灰黄,风从三个方向一齐灌进河谷,吹得檐下的旧帘子啪啪翻卷。乱得毫无章法:本该立春才开的花,一夜之间铺满腊月的山坡,粉白压着枯草;溪水倒着往源头卷,把落叶一片片送回山里;几条官道像被谁揉过又随手一扔,彼此缠成解不开的结,车马在结上打转;连人说话都不落地,一句话出了口就散成半空里的细屑,飘着飘着就没了,听话的人只能张着嘴等。司里的册子自己翻页,铜盘在案上轻轻震,满匣黑白木珠在匣中沙沙作响,像也待不住了。
小骏登上丘顶。风把他的朱红袍角吹得几乎平展开,金河浪纹在灰天里一闪一闪,额上那撮螺旋卷被吹得直颤,两只金角嗡嗡发亮,圆眼睛却亮得从没有过。他回头看了小灵一眼,没等她开口,双臂一扬,把整匣木珠朝坡下泼了出去。黑珠白珠在半空炸成一片急雨,落处便生出东西:砸在土坡上,土缓缓隆起成山,山脊一层层长出松;落进河里,木珠一沾水就拉长成舟,桅与篷依次舒开;飘在风里的,散作云、散作树冠、散作远处几缕炊烟;还有几颗滚到路边,化作挑担的人、拉车的牛、檐下晾着的布。一眨眼满眼都是物,密密匝匝,可全挤错了地方——花开在船头,山路绕进人家堂屋,几只舟搁在树梢上晃,牛站在云里。
小灵已走到水边。她没急着收,先在一块青石前蹲下,把被风掀起的袖口一寸寸压平,再把九宫盘端端正正摆在石上,盘面映着灰天,九格沉稳如旧。然后她一格一格呼名,声音不高,风却像让开了一条道。第一声落,最近的那座山往后退了半里,回到该在的高度;第二声落,树梢上的舟一艘艘顺回水面,篷上的花抖落进河里;第三声落,缠成结的官道一条条松开、抻直,各自接回自己的渡口;散在半空的话语也一颗颗落回人嘴边,挑担的重新吆喝出声,檐下的布重新垂好。她呼到第九格,最后几粒珠子归位,横、竖、斜三道光从盘上缓缓铺开,爬过山坡、爬过河面,所过之处,万物各安其位。风就是在这时候停的。
就在这一撒一定之间,天地间浮出一幅图:左半是圆,星点缓缓流转,像一整条河在天上打了个旋;右半是方,九宫沉沉列开,格线一笔不苟;圆与方在正中接上,接缝处先是一线金,继而晕成一片温软的光,把坡上的残雪、河上的舟、路边的炊烟都照得清清楚楚,连老叟杖头沾的泥都看得见。坡下那位拄杖的老叟早看呆了,杖头在泥里戳了半天,才叹出一句:「图者物也,书者法也。只有物,就乱;只有法,就空。两样凑齐,天下才算得出数来。」一片花瓣正正落下来,打了个旋,停在罗盘边上。小骏从丘上跑下来,衣摆全是草屑,鼻尖还蹭着一点灰,站到小灵身边,两人谁也没先说话。他侧过头,眼睛又亮起来:「走,先去看看?」小灵把盘收进袖里,眼帘一弯:「别急,我算一下。」然后并肩往那片光里走进去,一圆一方的两道影子越靠越近,慢慢合成了一个。
插图 · 十二岁暮反季的花开满坡、道路缠成一团;小骏登丘撒珠生万物,小灵临水布宫,圆星图与方九宫在天上合为一体。
术数曰物法相合,是谓能算。
今解程序 = 数据结构 + 算法(Algorithms + Data Structures = Programs)。小骏生的是数据,小灵立的是规则;两者缺一,一个乱、一个空。这也是整季的落点:编程不看你背下多少语法。看的是你能不能把眼前这一摊乱事理成能算的东西,再给它写一套照着走的法。
童试先把房间的东西全摊出来(这是「物」),再定一条「积木回红盒、书回架子」的规矩照着收(这是「法」);如果只做其中一样,房间会变成什么样?
镜头①大远景:3D 河洛司内景,满匣木珠在匣中沙沙作响、册子自己翻页、铜盘在案上轻轻震;镜头随翻卷入画,落岁暮河谷——天色少见地灰黄,风从三个方向一齐灌进河谷、吹得檐下旧帘啪啪翻卷;本该立春才开的花,一夜之间铺满腊月山坡。溪水倒着往源头卷,把落叶一片片送回山里。几条官道缠成解不开的结,车马在结上打转。人话出口,就散成半空里的细屑(33 秒|音效:木珠簌簌、三向风、帘子扑卷;旁白「岁暮,天下诸事皆乱」)②大远景(左暖金·粒子大场面):小骏登上丘顶,朱红袍角被吹得几乎平展、金河浪纹在灰天里一闪一闪、螺旋卷直颤、两只金角嗡嗡发亮;他双臂一扬,把整匣木珠朝坡下泼出,黑白珠在半空炸成一片急雨——砸在土坡,土隆起成山、山脊长出松;落进河里,木珠一沾水拉长成舟、桅与篷依次舒开;飘在风里,散作云、树冠与几缕炊烟;滚到路边,化作挑担的人、拉车的牛、檐下晾着的布。一眨眼满眼皆物,却全挤错了地方:花开在船头、山路绕进堂屋、几只舟搁在树梢上晃、牛站在云里(48 秒|音效:珠雨爆裂、万物生长声层叠;旁白「徒有物,则乱」)③大远景(右石青):小灵已走到水边,先在一块青石前蹲下、把被风掀起的袖口一寸寸压平,再把九宫盘端端正正摆在石上,一格一格呼名,声音不高、风却像让开了一条道——第一声,山退半里;第二声,舟顺回水面,篷上的花抖落进河;第三声,缠成结的官道松开、抻直,各自接回渡口;散在半空的话语,也一颗颗落回人嘴边;呼到第九格最后几粒归位,横、竖、斜三道光从盘上缓缓铺开、爬过山坡爬过河面,万物各安其位,风就在这时候停了(49 秒|音效:呼名声一格一落、光流铺展、风止;旁白「徒有法,则空」)④全景转特写:左半是圆、星点缓缓流转,右半是方、九宫沉沉列开,圆与方在正中接上,接缝先一线金、继而晕成一片温软的光,把坡上残雪、河上舟、路边炊烟都照清;坡下老叟拄杖看了半天,杖头在泥里戳了又戳才叹「图者物也,书者法也。只有物,就乱;只有法,就空。两样凑齐,天下才算得出数来」;一片花瓣打旋落在罗盘边;小骏跑下丘、衣摆全是草屑鼻尖还蹭着灰「走,先去看看?」小灵把盘收进袖里、眼帘一弯「别急,我算一下」;两人并肩往光里走,一圆一方两道影子越靠越近合成一个;镜头上摇、卷面收拢,合卷回到 3D 河洛司(45 秒|音效:花瓣落盘、杖头点泥、双人脚步合一、卷轴合拢)全片合计 175 秒。
卷 尾 · 给大人的一句话
这十二则故事不教任何一门语言,也不出现一行代码。它们只反复演练四件事:把复杂的事拆开(分解)、从重复里看出规律(模式识别)、给杂乱的东西起名字与定位置(抽象)、把一次的成功写成可重复的步骤(算法设计)。这四件事合起来,就是计算思维。
后人只记住了图,把方法丢了,术数才被当成玄学。让它回到「可算之物 + 可循之法」的本义,孩子读的是故事,带走的是一辈子受用的思考方式;对外讲,这是文化;对孩子讲,这是他能上手、往后一直用得着的思考方式。白话演义这一层不为稀释原文,只为让灯影、柴烟、河风与两个人拌嘴的声音先把人带进去——道理到时候自己会浮上来。
有灵感,也有章法。
附
读法与用法
How to Use
01 / 亲子共读先演义,后原文
先读小说演义,让孩子看见画面与人;再回看卷中原文,感受几十个字如何说完同一件事;接着读「术数曰」,最后一起做「童试」。白话一句留给赶时间的读者。今解是给大人的,不必念出来。
02 / 动画分集演义即分镜依据
每集 3 分钟:3D 河洛司开场 → 翻卷进入平面绢本寓言世界 → 合卷回场。演义里的天光、器物、动作与对话可直接拆成分镜;古画段落可做成无对白,靠木珠与动作叙事。
03 / 课堂工作坊十二讲不插电
一集一讲,配不插电活动(编号豆子、瓶盖盖章、猜数七问、三只小碟辨空与零)或 Scratch 小任务:第四集做循环画点阵、第六集做岔路小游戏、第十集做猜数程序。演义可当课堂朗读剧本。
术语速查表 · 三种说法对一对
同一件事,有三种叫法。故事里是「上左一」;跟孩子聊天,说「格子贴了名」;翻到程序那边,它叫「变量与地址」。这张表把三种说法并排:读故事看左边,跟孩子聊天看中间,想知道它讲到编程哪一步就看右边。不用背,遇到不懂的回来查一行就好。
| 寓言词 | 生活里的说法 | 编程里叫什么 |
| 上左一、上中二 | 书包每层贴个名字,说得出名字就找得到东西 | 变量与地址——给每份数据起个名,记住它放在哪儿 |
| 洗釜、取水、下米、燃火、候熟 | 刷牙得先挤牙膏再刷,顺序一乱就闹笑话 | 顺序执行——一步接一步,次序不能颠倒 |
| 第一格与第九格 | 数排队的人,排头和排尾都得算进去 | 边界条件与「差一个」——头和尾到底算不算 |
| 一枚点印,按一下、移一寸 | 用瓶盖蘸水按一百下,比手画一百个圆又齐又省事 | 循环与模式识别——同一个动作只写一次,让它照着重复做 |
| 龟甲刻三行法 | 把「怎么整理书包」写成三条,别人照着做也成 | 函数与封装——把做法打包成一份,谁都能拿去用 |
| 若见溪则左,若见石则右 | 出门看天:下雨带伞,不下雨就不带 | 条件分支——先问一句,再按答案选一条路 |
| 此浪推彼浪 | 豆子一堆比一堆多两颗,照这个数一直摆下去 | 递推与递归——知道头一个、知道下一步,还得知道何时停 |
| 深匣后来先出,浅匣先来先出 | 一摞盘子从顶上拿;排队买点心从队头来 | 栈与队列——后进先出、先进先出,各用各的场合 |
| 两只手同时伸向中宫 | 两人同时往一个杯里倒水,得先约好谁先倒 | 并发与同步——两件事同时来,要排个先后 |
| 界尺一横,每问一句去一半 | 猜数先问「比 50 大吗」,一次砍掉一半 | 二分查找与调试——会问对问题,比一颗颗翻更省力 |
| 空圈、零、「无」 | 作业本空着=没做;写「0 分」=做了得零分;本子没发=不知道 | 零、空值与初始化——「没数过」「是零」「还没填」是三件事 |
| 一撒一定,左圆右方合为一图 | 先把房间东西全摊出来(物),再定一条「什么回哪儿」的规矩(法) | 程序=数据结构+算法——物是数据,法是算法,缺一不可 |
给大人的一页 · 童试思路与器材清单
十二道童试都不用买东西:豆子、瓶盖、纸杯、盘子、勺子、三张纸、九个格子,家里随手就有;涉及水或小物件的题目请大人陪着做。这里给思路,不给标准答案:第三集「从第 1 数到第 9」是 9 个数,第七集摆到第十堆是 19 颗,第十集七次够用,因为每问一次就砍掉一半(2⁷=128,盖得住 100)。孩子答错了,别急着纠正。照他的想法再摆一遍,让他自己看见哪一步乱了。报个答案最快,可这一集要讲的东西就漏掉了。
内容日历:12 集正片按月更新,24 支节气短片按节气投放;「童试」能单拎出来,做成互动 H5,也能做成线下物料。看完再动手玩,玩着就把这一集的事学会了。每集的「术数曰」亦可作海报主文案,直接复用于品牌传播。