From 0fc1c8aa548886207de1bde74d55cc221585af48 Mon Sep 17 00:00:00 2001 From: AlephAlpha Date: Fri, 7 Jun 2024 11:58:36 +0800 Subject: [PATCH] :bookmark: v0.6.1.0 --- .github/workflows/test.yml | 2 +- CHANGELOG.md | 2 +- Nekomata.cabal | 2 +- analysis/Ideas.md | 24 ++++++++++++----------- analysis/corpus.txt | 2 ++ analysis/freq_1gram.txt | 40 +++++++++++++++++++------------------- analysis/freq_2gram.txt | 26 ++++++++++++++++++++----- analysis/freq_3gram.txt | 19 ++++++++++++++++++ analysis/freq_4gram.txt | 17 ++++++++++++++++ analysis/freq_5gram.txt | 15 ++++++++++++++ doc/GettingStarted.md | 2 +- test/Eval.hs | 21 +++++++++++++++++++- 12 files changed, 131 insertions(+), 41 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 346390d..426670a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: ghc: ['9.0.2', '9.4.8', '9.6.5', '9.8.2'] steps: - uses: actions/checkout@v4 - - uses: haskell/actions/setup@v2 + - uses: haskell-actions/setup@v2 with: ghc-version: ${{ matrix.ghc }} - run: cabal build diff --git a/CHANGELOG.md b/CHANGELOG.md index b7425b3..3b899d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Revision history for Nekomata -## 0.6.1.0 -- Unreleased +## 0.6.1.0 -- 2024-06-07 * Now the REPL saves the history to a file named `.history` in the current directory. * New built-in functions: `\isLong`, `\sumEach`. diff --git a/Nekomata.cabal b/Nekomata.cabal index f07b0da..ebb066e 100644 --- a/Nekomata.cabal +++ b/Nekomata.cabal @@ -21,7 +21,7 @@ name: Nekomata -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change -version: 0.6.0.0 +version: 0.6.1.0 -- A short (one-line) description of the package. synopsis: diff --git a/analysis/Ideas.md b/analysis/Ideas.md index 40a7b38..9819efc 100644 --- a/analysis/Ideas.md +++ b/analysis/Ideas.md @@ -8,7 +8,7 @@ .W`w ``` -如果 CodePage 中的 256 个字符都用完了,可以考虑用像 05AB1E 那样,用 `.` 开头的字符来表示双字节的内置函数。现在的 CodePage 还远远没有用完,先不考虑这个问题,但 `.` 也先不要用掉。 +如果 CodePage 中的 256 个字符都用完了,可以考虑用像 05AB1E 那样,用 `.` 开头的字符来表示双字节的内置函数。现在的 CodePage 还没有用完,先不考虑这个问题,但 `.` 也先不要用掉。 LiberationMono 字体所支持的字符列举于[此文件](analysis/LiberationMonoGlyphs.txt),以供选取。 @@ -17,20 +17,21 @@ LiberationMono 字体所支持的字符列举于[此文件](analysis/LiberationM 写了个[脚本](analyze.py)来统计、分析现有的解答。得到一些有趣的结果(以下排名可能不是最新的): * 最常用的一个字符是 `{`,用来开启一个 block。 -* 单个字符中,排第二、第三的分别是 `:`(`\dup`)和 `$`(`\swap`),都是常见的栈操作。其它 stack-based 的 golfing 语言中,这两个操作也排名很靠前。 -* 四到七名分别是 `=`(`\eq`)、`+`(`\add`)、`∑`(`\sum`)、`←`(`\decrement`)。这些也都是常见的操作。 -* 第八名是 `ᵐ`(`\map`),是最常用的助词。 -* `1` 排到第十,是最常见的常量。 +* 单个字符中,排第二、第三的分别是 `$`(`\swap`)和 `:`(`\dup`),都是常见的栈操作。其它 stack-based 的 golfing 语言中,这两个操作也排名很靠前。 +* 四到八名分别是 `=`(`\eq`)、`+`(`\add`)、`∑`(`\sum`)、`ᵐ`(`\map`)、`→`(`\increment`)。这些也都是常见的操作。 +* 第九名是 `R`(`\range1`)。这个操作用于生成一个 1 到 n 的列表。另一个类似的操作是 `r`(`\range0`),用于生成一个 0 到 n-1 的列表,相对来说用得较少,排到了六十多名。这是因为很多列表操作会把单个元素自动转换成从 0 开始的列表,可以省去一个 `r`。 * `}` 排到第十二,出现次数不到 `{` 的一半。看来代码结尾可以省略 `}` 的设计是正确的。 -* `a`(`\allValues`)排第十五。这是 non-deterministic 语言特有的操作,算是 Nekomata 的特色之一。 -* `ç`(`\cons0`)能排到第十六。这个完全出乎我的意料,因为很多别的 golfing 语言中根本没有这个操作。它的作用是给列表加一个 0,通常是配合 `\head`、`\last`、`\minimum`、`\maximum` 等函数使用,来处理空列表的特殊情况。需要看一看其它语言是怎么处理空列表的。 -* 在两个字符的组合中,排前五的分别是 `ᶦ{`、`ᵖ{`、`ʷ{`、`ᵑ{`、`ᶠ{`,`ˡ{` 排第七。也许可以像 Vyxal 等语言一样,让这些助词自动开启 block,省去一个 `{`。不过另外一些助词通常只修饰单个 built-in,自动开启 block 反而会额外需要一个 `}`。尤其是 `ᵖ`、`ᵑ`、`ᵐ`,两种用法都很常见,不好取舍。详见 [`analysis/particles.txt`](particles.txt)。 -* `{$` 在两个字符的组合中排第六,`{:` 排第九。这两个组合没有特别的意义,只是因为 `\dup` 和 `\swap` 是最常用的两个操作,因此它们的组合也很常用。 -* `1>` 在两个字符的组合中排第八。可以考虑增加一个 `\significant` 函数,用来检查一个数的绝对值是否大于 1。Jelly 中有与之相反的函数 `insignificant`。到底是添加 `\significant` 还是 `\insignificant`,还要考虑一下。可能两个都要加。名字也可以再改改,比如说叫 `\nontrivial` 和 `\trivial`,甚至叫 `\isBig` 和 `\isSmall`。 +* `1` 排到第十四,是最常见的常量。 +* `ç`(`\cons0`)能排到第十八。这个完全出乎我的意料,因为很多别的 golfing 语言中根本没有这个操作。它的作用是给列表加一个 0,通常是配合 `\head`、`\last`、`\minimum`、`\maximum` 等函数使用,来处理空列表的特殊情况。需要看一看其它语言是怎么处理空列表的。 +* 与 non-deterministic 机制有关的操作,除了 `=`(`\eq`)没有一个排到前二十。排最高的是第二十四的 `a`(`\allValues`)。 +* 在两个字符的组合中,排前六的分别是 `ᶦ{`、`ᵖ{`、`ʷ{`、`ˡ{`、`ᵑ{`、`ᶠ{`。也许可以像 Vyxal 等语言一样,让这些助词自动开启 block,省去一个 `{`。不过另外一些助词通常只修饰单个 built-in,自动开启 block 反而会额外需要一个 `}`。尤其是 `ᵖ`、`ᵑ`、`ᵐ`,两种用法都很常见,不好取舍。详见 [`analysis/particles.txt`](particles.txt),以及下文的[关于助词](#关于助词)。 +* `{$` 在两个字符的组合中排第七,`{:` 排第八。这两个组合没有特别的意义,只是因为 `\dup` 和 `\swap` 是最常用的两个操作,因此它们的组合也很常用。 +* `Jᵐ` 在两个字符的组合中排第八,和 `{:`、`ᵐ{`、`Ťđ` 并列。这完全出乎我的意料。`J` 是将输入 non-deterministic 地拆成若干部分,`ᵐ` 是对后一个函数进行 map,这两个操作的组合并没有特别的意义。也许值得为它增加一个助词。 +* `Ťđ` 在两个字符的组合中也排第八,和 `{:`、`Jᵐ`、`ᵐ{` 并列。这个组合是将二维列表转置,然后进行 unpair 操作。看起来确实比较常用。先等更多的解答出现再决定是否增加这个 built-in。 * `Ňᵖ{` 在三个字符的组合中排第一,也许值得为它增加一个助词。 * 统计结果与其它语言的差异,除了考虑到语言本身的特点之外,还要考虑到语言的使用者的偏好。目前 Nekomata 的使用者基本上只有我自己,解答的也主要是我感兴趣的题目类型,string 相关的题目较少,ascii-art 更是完全没有。 -随着已有解答的增多,增加新的内置函数时,很难再把已有的解答都看一遍,看看是否能用新的内置函数来改进。因此,这一统计结果不再代表最优的方案。但它仍然可以作为参考。 +随着已有解答的增多,增加新的内置函数时,很难再把已有的解答都看一遍,看看是否能用新的内置函数来改进。因此,这一统计结果不再代表最优的方案,但仍有一定的参考价值。 ## 来自 codegolf 题目的想法 @@ -223,3 +224,4 @@ LiberationMono 字体所支持的字符列举于[此文件](analysis/LiberationM - [ ] 为每个函数增加例子。可以考虑把这些例子用作单元测试。 - [ ] 重写现有的 Tutorial。考虑分成多个文件,每个文件只讲一个主题。 +- [ ] REPL 的 `\Info` 命令,可以考虑改成能一次输出多个函数的信息。 diff --git a/analysis/corpus.txt b/analysis/corpus.txt index f64cf92..8bcad1b 100644 --- a/analysis/corpus.txt +++ b/analysis/corpus.txt @@ -333,3 +333,5 @@ Z:Ť‼Ť$ḟ ᵐ#:x+Ṁ$ᵒ%ᵐᶻ@ji ŤđᵃSᵒÐj↕= ↕JᵐŤŤđ≡¿ᵐ≡ +Ňr26%→Ɔ64+$∑→řH +7R¢ɔ∙11¦ diff --git a/analysis/freq_1gram.txt b/analysis/freq_1gram.txt index 20fd150..a21972e 100644 --- a/analysis/freq_1gram.txt +++ b/analysis/freq_1gram.txt @@ -1,25 +1,25 @@ { : 76 -$ : 54 +$ : 55 : : 48 = : 48 ++ : 42 ᵐ : 42 -+ : 41 -∑ : 36 +∑ : 37 +→ : 32 +R : 31 ← : 30 -→ : 30 -R : 30 * : 29 } : 28 j : 26 +1 : 25 - : 25 x : 25 -1 : 23 o : 23 ç : 23 , : 22 +2 : 22 ᵉ : 21 Ť : 21 -2 : 21 ↕ : 20 a : 20 # : 19 @@ -41,13 +41,13 @@ t : 15 " : 14 J : 14 Ƃ : 14 +Ɔ : 14 +Ň : 14 ᶦ : 13 ≡ : 13 -Ɔ : 13 ∫ : 13 Z : 13 Ɗ : 13 -Ň : 13 ; : 13 L : 13 < : 12 @@ -59,6 +59,7 @@ q : 12 ʷ : 11 Q : 11 ᵃ : 11 +r : 11 c : 11 Ë : 11 N : 11 @@ -67,19 +68,19 @@ _ : 11 ũ : 10 ˡ : 10 Ţ : 10 -r : 10 E : 10 ŋ : 10 ? : 10 +% : 10 ᶠ : 10 ∏ : 10 O : 10 z : 10 ᶜ : 9 ž : 9 -% : 9 ŗ : 9 ≈ : 9 +∙ : 9 i : 9 C : 9 P : 8 @@ -93,38 +94,38 @@ f : 8 ≥ : 8 ‼ : 8 ƒ : 8 -∙ : 8 +4 : 8 @ : 8 Ƶ : 7 +H : 7 Ä : 7 / : 7 ɗ : 7 Ħ : 7 +¦ : 7 Ĉ : 7 ᵗ : 7 ṁ : 7 Ĩ : 7 h : 7 ä : 7 -4 : 7 > : 7 Ř : 7 ᵈ : 7 +¢ : 7 ᵏ : 6 ƃ : 6 -H : 6 Ď : 6 Ø : 6 ŧ : 6 Ĭ : 6 -¦ : 6 ş : 6 Ŝ : 6 +ɔ : 6 ĕ : 6 ∩ : 6 į : 6 0 : 6 -¢ : 6 B : 6 ƀ : 5 I : 5 @@ -133,11 +134,11 @@ y : 5 d : 5 ≤ : 5 Ç : 5 +ř : 5 ʳ : 5 G : 5 Å : 5 s : 5 -ɔ : 5 µ : 5 8 : 5 √ : 5 @@ -148,16 +149,17 @@ s : 5 b : 5 A : 5 Ł : 4 -ř : 4 Ḟ : 4 k : 4 F : 4 ƥ : 4 D : 4 M : 4 +7 : 4 ÷ : 4 § : 4 & : 4 +6 : 4 ˣ : 4 ň : 4 õ : 4 @@ -165,7 +167,6 @@ M : 4 Ṃ : 3 Y : 3 T : 3 -7 : 3 X : 3 ƶ : 3 þ : 3 @@ -184,7 +185,6 @@ g : 2 ḟ : 2 ē : 2 K : 2 -6 : 2 Š : 2 ¥ : 2 Ĝ : 1 diff --git a/analysis/freq_2gram.txt b/analysis/freq_2gram.txt index 70f9ac5..1afa02a 100644 --- a/analysis/freq_2gram.txt +++ b/analysis/freq_2gram.txt @@ -58,6 +58,7 @@ pN : 3 {ˣ : 3 Ṁ→ : 3 {į : 3 ++$ : 3 +} : 3 *$ : 3 #← : 3 @@ -136,12 +137,15 @@ o; : 2 +→ : 2 Qƥ : 2 {C : 2 +4+ : 2 ḞŤ : 2 Oᵐ : 2 +$∑ : 2 ∑= : 2 ᵐ↔ : 2 +1 : 2 12 : 2 +%→ : 2 {- : 2 ᵗ{ : 2 {≈ : 2 @@ -209,7 +213,6 @@ x: : 2 ĭ? : 2 {* : 2 *+ : 2 -+$ : 2 ᵃ{ : 2 x- : 2 ŋ+ : 2 @@ -240,6 +243,7 @@ rj : 2 ĭ, : 2 Jĭ : 2 ←ᶠ : 2 +∑→ : 2 ᵉt : 2 ti : 2 ᵐz : 2 @@ -470,7 +474,6 @@ il : 1 ĝj : 1 j= : 1 C4 : 1 -4+ : 1 +> : 1 >‼ : 1 RḞ : 1 @@ -484,7 +487,6 @@ X< : 1 äK : 1 *ĕ : 1 ĕ$ : 1 -$∑ : 1 +7 : 1 7f : 1 ↔Ĭ : 1 @@ -493,7 +495,6 @@ $∑ : 1 8Ɗ : 1 Ɗ+ : 1 2% : 1 -%→ : 1 -Z : 1 Z3 : 1 3¦ : 1 @@ -1225,7 +1226,6 @@ v∩ : 1 ∑h : 1 hÅ : 1 ʷ∑ : 1 -∑→ : 1 ᵉb : 1 bD : 1 {Ƃ : 1 @@ -1363,3 +1363,19 @@ Sᵒ : 1 ŤŤ : 1 đ≡ : 1 ᵐ≡ : 1 +Ňr : 1 +r2 : 1 +26 : 1 +6% : 1 +→Ɔ : 1 +Ɔ6 : 1 +64 : 1 +→ř : 1 +řH : 1 +7R : 1 +R¢ : 1 +¢ɔ : 1 +ɔ∙ : 1 +∙1 : 1 +11 : 1 +1¦ : 1 diff --git a/analysis/freq_3gram.txt b/analysis/freq_3gram.txt index 7a40cc4..128e3ca 100644 --- a/analysis/freq_3gram.txt +++ b/analysis/freq_3gram.txt @@ -1355,3 +1355,22 @@ JᵐŤ : 1 đ≡¿ : 1 ≡¿ᵐ : 1 ¿ᵐ≡ : 1 +Ňr2 : 1 +r26 : 1 +26% : 1 +6%→ : 1 +%→Ɔ : 1 +→Ɔ6 : 1 +Ɔ64 : 1 +64+ : 1 +4+$ : 1 ++$∑ : 1 +$∑→ : 1 +∑→ř : 1 +→řH : 1 +7R¢ : 1 +R¢ɔ : 1 +¢ɔ∙ : 1 +ɔ∙1 : 1 +∙11 : 1 +11¦ : 1 diff --git a/analysis/freq_4gram.txt b/analysis/freq_4gram.txt index 2af881f..0bc7e7d 100644 --- a/analysis/freq_4gram.txt +++ b/analysis/freq_4gram.txt @@ -1094,3 +1094,20 @@ JᵐŤŤ : 1 Ťđ≡¿ : 1 đ≡¿ᵐ : 1 ≡¿ᵐ≡ : 1 +Ňr26 : 1 +r26% : 1 +26%→ : 1 +6%→Ɔ : 1 +%→Ɔ6 : 1 +→Ɔ64 : 1 +Ɔ64+ : 1 +64+$ : 1 +4+$∑ : 1 ++$∑→ : 1 +$∑→ř : 1 +∑→řH : 1 +7R¢ɔ : 1 +R¢ɔ∙ : 1 +¢ɔ∙1 : 1 +ɔ∙11 : 1 +∙11¦ : 1 diff --git a/analysis/freq_5gram.txt b/analysis/freq_5gram.txt index d3c0335..f9ae366 100644 --- a/analysis/freq_5gram.txt +++ b/analysis/freq_5gram.txt @@ -854,3 +854,18 @@ JᵐŤŤđ : 1 ŤŤđ≡¿ : 1 Ťđ≡¿ᵐ : 1 đ≡¿ᵐ≡ : 1 +Ňr26% : 1 +r26%→ : 1 +26%→Ɔ : 1 +6%→Ɔ6 : 1 +%→Ɔ64 : 1 +→Ɔ64+ : 1 +Ɔ64+$ : 1 +64+$∑ : 1 +4+$∑→ : 1 ++$∑→ř : 1 +$∑→řH : 1 +7R¢ɔ∙ : 1 +R¢ɔ∙1 : 1 +¢ɔ∙11 : 1 +ɔ∙11¦ : 1 diff --git a/doc/GettingStarted.md b/doc/GettingStarted.md index 8046c35..05bdfd7 100644 --- a/doc/GettingStarted.md +++ b/doc/GettingStarted.md @@ -2,7 +2,7 @@ ## Installation -Nekomata is written in [Haskell](https://www.haskell.org/). You need [Cabal](https://www.haskell.org/cabal/) (version 3.0 or newer) and [GHC](https://www.haskell.org/ghc/) (version 9.0.2 or newer) to build Nekomata. +Nekomata is written in [Haskell](https://www.haskell.org/). You need [Cabal](https://www.haskell.org/cabal/) (version 3.0 or newer) and [GHC](https://www.haskell.org/ghc/) (version 9.0.2 to 9.8.5, version 9.10.1 is not yet supported) to build it. The easiest way to install these tools is through [GHCup](https://www.haskell.org/ghcup/). The packages provided by your Linux distribution's package manager may be too old to build Nekomata. diff --git a/test/Eval.hs b/test/Eval.hs index 4ec6b25..030fb4e 100644 --- a/test/Eval.hs +++ b/test/Eval.hs @@ -3601,4 +3601,23 @@ testEval = describe "Evaluation" $ do , ("[[1,1],[1,1],[1,2],[2,1],[2,2]]", Check False) , ("[[1,4],[7,4],[9,6]]", Check False) , ("[[6,1],[1,6]]", Check False) - ] \ No newline at end of file + ] + describe "q273467: Looping counter extended" $ do + specEval + "Ňr26%→Ɔ64+$∑→řH" + [("", truncate_ ["A", "BB", "CCCC", "DDDDDDD", "EEEEEEEEEEE", "FFFFFFFFFFFFFFFF"])] + describe "q273479: Is this a valid PZN?" $ do + specEval + "7R¢ɔ∙11¦" + [ ("[0,0,0,0,0,0,0,0]", Check True) + , ("[1,3,7,2,4,8,5,7]", Check True) + , ("[0,8,1,0,8,7,5,4]", Check True) + , ("[0,4,8,6,1,8,8,0]", Check True) + , ("[1,6,0,8,6,3,3,4]", Check True) + , ("[0,1,3,4,9,0,3,5]", Check True) + , ("[0,0,0,0,0,0,0,1]", Check False) + , ("[0,0,0,0,0,0,0,2]", Check False) + , ("[0,6,7,6,5,7,7,4]", Check False) + , ("[0,8,1,0,8,7,5,9]", Check False) + , ("[0,0,1,0,0,0,1,0]", Check False) + ]