一 前言

洛谷新增加了文言语言的功能,但是我并没有听说过这玩意……

我折腾了半天,顺便写了这篇文章

二 安装&编译

我推荐使用vscode进行编译 因为我在用

sublime也有插件支持 但由于我不用所以暂不介绍(逃 请大家自行研究 谢谢

vim也被支持了 但是太难所以不介绍 应该没人在用吧~

dev的同学们难道不觉得dev很难看吗?当然你可以尝试直接使用命令行编译你的程序,但这会很麻烦,你可以直接在cmd输入npm install -g @wenyanlang/cli来安装文言编译器,并输入wenyan来查看教程

如果你没有npm的话可以先安装python,在windowspython安装包中可以选择安装npm

linuxmac的同学也可以安装vscode或者sublime的插件

vscode真是个好东西啊~,它可以支持python,C++ 甚至支持markdown预览

进入vscode的插件商店,搜索wenyan,第一个就是了,点击install就可以了

然后会变成这个样子

图片.png

随便找一段文言代码(后缀为.wy),可以发现右上角多了两个按钮:

图片.png

第一个按钮是另一个插件的

那个蓝色的代码按钮可以将代码编译成javascript的代码(编译为python也可以,只是代码前会多)

那个绿色的运行按钮可以编译运行文言代码

试一试吧

Animationb8eed687592a3b86.gif

妙啊

三 写代码

我们用洛谷题目举例子吧

首先 你需要把你的输入法调成繁体,怎么调不多叙述

我们来看P1000 超级玛丽游戏

(代码太多 我们只看第一行的输出 文言没有代码高亮抱歉)

吾有一言。曰「「                ********」」。書之。

吾有一言:定义一个字符串,这里没有说明字符串的名字。

:相当于定义时的'=' 这里的制表符一个是括号,一个是双引号

如果你使用vscode的文言插件的话只需按'键(键盘asd一行最左边)就可以自动输入这些奇怪的符号了

書之:输出它

文章大意: 我有一句话,是" ****",输出它

cout<<"                ********";

注: 后面所有因翻译为C++过于抽象,大多翻译为javascript语法,少部分直译

我们再来看P1001 A+B Problem

标准代码真烦……

我们先复制下来再看

施「require('fs').readFileSync」於「「/dev/stdin」」。名之曰「數據」。
施「(buf => buf.toString().trim())」於「數據」。昔之「數據」者。今其是矣。
施「(s => s.split(' '))」於「數據」。昔之「數據」者。今其是矣。
注曰。「「文言尚菜,無對象之操作,故需 JavaScript 之语法」」。

夫「數據」之一。取一以施「parseInt」。名之曰「甲」。
夫「數據」之二。取一以施「parseInt」。名之曰「乙」。

加「甲」以「乙」。書之。

先看第一句

施「require('fs').readFileSync」於「「/dev/stdin」」。名之曰「數據」。

施a于b: 相当于a(b),将b作为参数传入名为a的函数中

/dev/stdin: 标准输入文件

注意:javascript并不支持直接从console读入数据,但是在linux下,此文件相当于控制台的输入,Windows则只能使用绝对路径进行本地测试,如C:/users/xxx/desktop/1.in

名之曰……: 将其命名为……

數據: 数据

所以这句相当于(C++表示已无能为力)

数据=require('fs').readFileSync("/dev/stdin")

看第二句

施「(buf => buf.toString().trim())」於「數據」。昔之「數據」者。今其是矣。

昔之a者。今b是矣: 相当于a=b

这就很好理解了

数据 = (buf => buf.toString().trim())(数据)

将输入转为字符串

看第三句

施「(s => s.split(' '))」於「數據」。昔之「數據」者。今其是矣

没啥说的,分开输入数据成一个数组,和pythonsplit操作接近

看第四句

注曰。「「文言尚菜,無對象之操作,故需 JavaScript 之语法」」。

注曰。: 注释

很好理解,就是个注释

第五,六句

夫「數據」之一。取一以施「parseInt」。名之曰「甲」。

夫「數據」之二。取一以施「parseInt」。名之曰「乙」。

夫a之b: 同a[b]。这里下标不减一

取k以施a: 将刚才列的后k数作为参数传入名为a的函数中

不难理解:

甲=parseInt(数据[0])
乙=parseInt(数据[1])

将数据转为整数格式,与pythonint()类似

最后一句

加「甲」以「乙」。書之。

加a以b: 同a+b

不解释。

接下来来看P1046 陶陶摘苹果

输入变成了一串数……

但是没关系,只要稍微处理下即可。

这次分开上代码,完整代码可以看这里

前三句

施「require('fs').readFileSync」於「「C:\\02Cpp\\文言\\dev\\stdin.in」」。名之曰「數據」。

施「(buf => buf.toString().trim())」於「數據」。昔之「數據」者。今其是矣。

施「(s => s.split('\n'))」於「數據」。昔之「數據」者。今其是矣。

老样子,只是因为是两行数据,变成按换行分了

注:也可以用正则表达式input_str.split(/[\s\n]/)来分割,只是这样无法辨别出哪些数在哪一行

第五句

这里是把输入的第一行拿出来按空格分开成一个数组“甲”。

第六句

凡「甲」中之「數」。

凡a中之b: 枚举a中的每个元素b,注意这里是中之,不是之中

第八句

充a以b: 在a后添加一个元素b

第九句

云云: 可以理解为后面的大括号

第十四,十五,十六句

若……者……也:if(……){……}

其他部分显而易见

其他语法

不用例题做示范。

函数系列

吾有一術。名之曰「吸星大法」。是術曰。⋯⋯是謂「吸星大法」之術也。: 定义一个叫吸星大法的函数

吾有一術。名之曰「翻倍」。欲行是術。必先得一數。曰「甲」。乃行是術曰。乘「甲」以二。名之曰「乙」。乃得「乙」。是謂「翻倍」之術也。: 定义一个有参数的函数

乃得k: return k

吾嘗觀「「算經」」之書。方悟「正弦」「餘弦」之義。: 调用标准库中的函数,具体可见这里

循环系列

为是k: 循环k遍(k可替换成十一万四千五百十四等等)

恒为是: while循环

乃止: break

其他请看官方语法手册

四 彩蛋

视频

还有一个re掉的并查集代码

求查错

施「require('fs').readFileSync」於「「dev/stdin」」。名之曰「數據」。
施「(buf => buf.toString().trim())」於「數據」。昔之「數據」者。今其是矣。
施「(s => s.split(/[\s\n]/))」於「數據」。昔之「數據」者。今其是矣。
吾有五列。名之曰「輸入」。名之曰「id」。名之曰「n」。名之曰「m」。名之曰「答案」。
吾有二數。曰一。曰一。名之曰「p」。名之曰「tmp」。
吾有五數。名之曰「甲」。名之曰「乙」。名之曰「丙」。名之曰「戊」。名之曰「己」。
凡「數據」中之「數」。
    若「數」不等於「「」」者。
        夫「數」。取一以施「parseInt」。名之曰「某數」。
            充「輸入」以「某數」。
    也。
云云。
吾有一術。名之曰「得入」。是術曰。
    昔之「p」者。今「p+1」是矣。
    夫「輸入」之「p-1」。乃得矣。
是謂「得入」之術也。
吾有一數。名之曰「id之x」。
吾有一術。名之曰「尋」。欲行是術。必先得一數。曰「x」。是術曰。
    若「id」之「x」等於「x」者。
        乃得「x」。
    若非。
        夫「id」之「x」。取一以施「尋」。昔之「甲」者。今其是矣。
        昔之「id」之「x」者。今「甲」是矣。
        夫「id」之「x」。乃得矣。
    也。
是謂「尋」之術也。
吾有一術。名之曰「合」。欲行是術。必先得二數。曰「x」。曰「y」。是術曰。
    施「尋」於「x」。昔之「甲」者。今其是矣。
    施「尋」於「y」。昔之「乙」者。今其是矣。
    昔之「id」之「乙」者。今「甲」是矣。
    乃歸空無。
是謂「合」之術也。
施「得入」。昔之「m」者。今其是矣。
施「得入」。昔之「n」者。今其是矣。
昔之「甲」者。今一是矣。
為是「m」遍。
    充「id」以「甲」。
    昔之「甲」者。今「甲+1」是矣。
云云。
注曰。……
為是「n」遍。
    施「得入」。昔之「甲」者。今其是矣。
    施「得入」。昔之「乙」者。今其是矣。
    施「得入」。昔之「丙」者。今其是矣。
    若 「甲」等於 一 者。
        夫「乙」。夫「丙」。取二以施「合」。
    若非
        施「尋」於「乙」。昔之「戊」者。今其是矣。
        施「尋」於「丙」。昔之「己」者。今其是矣。
        若 戊 等於 己 者。
            夫「「Y」」。書之。
        若非。
            夫「「N」」。書之。
        也。
    也。
云云。

五 谢谢!