duangsuse::Echo
718 subscribers
4.26K photos
130 videos
583 files
6.48K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
真应该让那些数学家好好把使用到的记法和基本模型列出来,我都没见过好好列过的

教集合论的时候就应该把逻辑连在一起对比着学,尤其是要把所有逻辑operator列成表给example

否则用讲故事、比喻的方法教也可以,数学家觉得直接套抽象问题好嘛,其实抽象问题比计算机随机生成的输入好多少?难道使用实际问题的益处不够明显?
Abstract Algebra Learning Log.tex
7.2 KB
写不下去了,XeTeX。
Abstract Algebra Learning Log.pdf
102.4 KB
#math PDF 排版 postscript 打印后的版本(我也不清楚是不是,反正我不是TeX的开发者)
虽然这本书《AATA(Abstract Algebra — Theory and Application)》看起来对计算机科学比较友好(我非常吃惊地发现里面的数学都是魔改过的…… 虽然数学本身就毫无规范可言)

(说起来,虽然数学本身毫无规范可言,nm, ij, xy, abc, fgh 还是很通用的?)

但是,我觉得要想好好理解一本外语书的内容,首先我得翻译它……

而且,逻辑、范畴论、偏序理论什么的东西,难道你编程、算法都不会去讨论这些哲学的东西能有什么好效果?它们可不是一般的抽象
就像喝茶一样,不到那个年月悟不出其中的内容,实际上悟出来了又怎么样…… 还是数学证明 我还是愿意先继续写点 for (c1 in up) if (up[c1] == c) up[c1] = up[b]; 那样别的东西,现在时间很紧,很多函数库待写,真的抽不出时间去学哲学,学机器学习都比学哲学好啊

范畴论装X指南 Monad 的那个 eta :: a -> t a、mu :: t t a -> t a 开始看起来很高大上,其实就是 (_ :: List a -> List a) = mu . ((fmap eta) :: List a -> List (List a)),居然就是一个 wrap 一个 flatten
可是即便是这样又有什么用?我还才疏学浅,实在领略不出其中奥妙,大概它们被造出来就是为了解决它们存在的时候可以提出的问题吧,emmm。

连《范畴论装逼指南》都没有讲得很好,然后某JS讲的就太偏差了

总之就是工程界(即便是程序表述这种领域,编译器后端)很少使用,而使用到则更多是逻辑证明的问题,虽然这类问题也很重要(并且有自动化的解决方案)但一般来说用于程序变换优化效果其实不咋样(可想而知我们编程的时候能做多大程度的[程序员弱手动优化的]串行计算呢?经常是存储和控制流上面的问题)

我真不知道那些数学证明应该怎么解析了,怎么越看数学越感觉它不够规范…… {C} 都只能以 { x: x is complex } 的形式定义,可是 { a| a > 1 } 里的 mid 又去哪了,这个 (:) 是 where 的意思可是 where 又是什么意思,|又又是什么意思…… 头疼数学啊

所以我觉得先造一门语言更加重要,而目前我还是有很多程序需要写的……
duangsuse::Echo
Abstract Algebra Learning Log.pdf
TeX的开发者是算法大佬文学编程大佬Donald Knuth
duangsuse::Echo
虽然这本书《AATA(Abstract Algebra — Theory and Application)》看起来对计算机科学比较友好(我非常吃惊地发现里面的数学都是魔改过的…… 虽然数学本身就毫无规范可言) (说起来,虽然数学本身毫无规范可言,nm, ij, xy, abc, fgh 还是很通用的?) 但是,我觉得要想好好理解一本外语书的内容,首先我得翻译它…… 而且,逻辑、范畴论、偏序理论什么的东西,难道你编程、算法都不会去讨论这些哲学的东西能有什么好效果?它们可不是一般的抽象 就像喝茶一样,不…
我来讲一个笑话:

typealias Predicate<T> = (T) -> Boolean
interface Set<in T> {
operator fun contains(elem: T): Boolean
fun union(other: Set<T>): Set<T> = object: Set<T> {
override fun contains(elem: T) = elem in this@union || elem in other
}
fun insect(other: Set<T>): Set<T> = object: Set<T> {
override fun contains(elem: T) = elem in this@union && elem in other
}
}

class LogicalSet<in T>(private val predicate: Predicate<T>): Set<T> {
override fun contains(elem: T) = predicate(elem)
override fun union(other: Set<T>) = (other as? LogicalSet<T>)?.let { LogicalSet(predicate orStmt other.predicate) } ?: super.union(other)
override fun insect(other: Set<T>) = (other as? LogicalSet<T>)?.let { LogicalSet(predicate andStmt other.predicate) } ?: super.insect(other)
}


不一定能编译,所以说是『笑话』


提示两点:

(1) 为什么 not (p or q) 能够推出 (not p) and (not q)
真值表!
不过也可以这么理解: p, q elementof (true, true),..., (false, false) and nexists true. {p, q} => (p, q) = (false, false) => (not p) and (not q)
说白了还是真值表……
就是说 exists true. {p, q} 的逆命题 nexists true. {p, q},我们知道 p, q 不是 true 就是 false(所以非true的case我们知道肯定是false)
排除集合 {true} 的集合 {true, false} 就是梭 all false. {p, q}

(2) 对称性(symmetric) 和交换律(commuative) 有啥区别
一般对称是指逻辑运算符上的、交换律是指所有运算符上的……
事实证明,ADT 版本可以做到更高的健壮性,不会随便 Stack OOM,可是正确性……
systemStack: 20 reports
of: 12.580254ms, 529.422micros, ...
min=129.954micros, max=12.580254ms, mean=824.48265micros, std=2.6990074188995345ms
ascending: 129.954micros, 132.066micros, ...
25%=135.936micros, 50%(median)=154.33micros, 75%=217.637micros

AdtStack: 20 reports
of: 2.592621ms, 694.436micros, ...
min=194.401micros, max=4.149009ms, mean=625.55215micros, std=958.3029449019385micros
ascending: 194.401micros, 194.551micros, ...
25%=218.736micros, 50%(median)=291.062micros, 75%=440.197micros

Nashorn JS: 20 reports
of: 71.968035ms, 4.155004ms, 3.591066ms, ...
min=2.019314ms, max=71.968035ms, mean=6.260406349999999ms, std=15.103676630348096ms
ascending: 2.019314ms, 2.074786ms, 2.077331ms, ...
25%=2.128427ms, 50%(median)=2.39595ms, 75%=3.076965ms


『高性能』实锤了 😂
本来我还打算骂它一通的呢
其实『高性能』的是比 Nashorn,哈哈,这么比有点太过分了……

我花了断续两天时间,结果在输入纯中缀链达到 7KB 的程度上,不考虑构造集合对象的时间,也只是比 use system stack 的极端情况快那么一点点而已 😂
太过分了。
我多写了10行代码,回头我就给它删掉算了
#Kotlin 这是属于比较逗逼的情况 utf16Size*(16/8)/1024
这个方差是属于比较感性的情况,虽然看完数学公式我根本无法把 Sigma 1/N 和 sumBy /size 对应起来,即便代换一下就是我也不知道1还有如此妙用,因为我无法分清它是Real(R, rational)呢还是Integer(Z)呢……都一样吧呵呵
emmm
\sqrt{\frac{1}{N} \sum_i^N{(A_i-mean(A))^2}}
where N = card(A)
这是开始写错但始乱不终弃的case,多亏我看不顺眼逻辑不通畅函数写一半的东西,虽然还是很不顺畅,以至于我以为我连逻辑基础都没有了。
真想早点睡…… 不得不先带头谈谈学校里打算谈的事,虽然
改天我要不要回顾一下之前的历史?

我果然还是进步得太慢…… 最近也才开始看得懂《编译原理实践教程》(指USTC资料,虽然我不是很看得上)和《深入分析GCC》

一般来说, #school 里我记录的笔记(很多是比较逗逼的,比如上面的修错,虽然修久了我会发现我连逻辑推导都做不到了)都会讲一遍
没做笔记的不会讲。

首先当然是 #book 好书(文)推荐

《她是龙》小狱
|Telegraph
注:使用 online OCR 字符识别,哦不,没找到多好的工具。
https://ocr.wdku.net/#
技术还是 Google,MS 家强
排版还要花时间,暂时出不来

他不知道,这个世界没有人有名字,所有人都只有印着一大堆标签的别称。他更不知道的是,其实故事以外的人也是这样的,即便是每个人都有着属于自己的名字,可还是得在脑门上贴上无数的标签过活,他们看别人的时候离开这些纸条就会失去判断力,却埋怨别人不肯了解自己的内心。
自动粘滞(sticky)Regex 有点牛逼啊,我之前的都是那些一匹配啥都匹配的,也不可能用 ?! negative lookahead 断言
虽然我连 GAWK 都不会用
UPDATE: 上面的 "(.*)" 应改成 "(.*?)"、<*?><*> 的意思不一样,它表示『最小匹配』…… 也就是说 takeUntil 到下一项 '"'; 以上 Regex 会把 <abc><123> 弄错,没注意到是因为 <.> 不匹配换行符,感谢细心观众 https://t.me/bystartw_tw. refs
duangsuse::Echo
真想早点睡…… 不得不先带头谈谈学校里打算谈的事,虽然 改天我要不要回顾一下之前的历史? 我果然还是进步得太慢…… 最近也才开始看得懂《编译原理实践教程》(指USTC资料,虽然我不是很看得上)和《深入分析GCC》 一般来说, #school 里我记录的笔记(很多是比较逗逼的,比如上面的修错,虽然修久了我会发现我连逻辑推导都做不到了)都会讲一遍 没做笔记的不会讲。 首先当然是 #book 好书(文)推荐 — 《她是龙》小狱 |Telegraph 注:使用 online OCR 字符识别,哦不,没找到多好的工具。…
她是龙.md
15.4 KB
/(.*)。$/ [$1。\n]
/^(.*):『(.*)』$/ [$1:『$2』\n]
/regex/ [replacement]
替换一下再修改处理出来的Markdown版本
duangsuse::Echo
自动粘滞(sticky)Regex 有点牛逼啊,我之前的都是那些一匹配啥都匹配的,也不可能用 ?! negative lookahead 断言
那我就照本宣科地念了:
+ (信息)声音:就是物体的震动,振子的振幅,就是信号。
+ (信息)图像:就是一堆『像素』的二维矩阵xy……
+ 24bpp:(色彩深度)24个二进制位per pixel
其中一般是 R(8bits), G(8bits), B(8bits); BGR 也有
最多显示 1677万 (R*G*B) 种颜色
+ 32bpp:(色彩深度)一般是带Alpha混成像素色值的颜色
+ 灰度:心理学灰度公式(线性)
Y = 0.2126R + 0.7152G + 0.0722B
显而易见地,数学不好是不能做计算机视觉甚至数字图像处理的……
+ 信息学、熵(shang1)、电子(electron)、热
密码学、加密、隐写、编码技术、千年虫、64k-intro、DEOM技术、huffman算法

最小公倍数、最大公约数(gcd, greatest common division)、fibonacci、函数变化率

我也不知道为什么有这些东西,大概是我看小说看到的,我物理和数学都不好

+ 谈谈 Base=64 是啥意思
这还准备教 Base=1000 呢
后来我觉得我佛系了,我就扔一个公式就走人。

2**(8*n) = 64**x where n, x in N+
看起来这个等式不是很好解啊
两个未知数都在指数的位置
一个解是 n=4; x=3

那Base=1000呢
2**(8*n) = 1000**x
只能用miniKanren解了呢……

https://codon.com/hello-declarative-world
https://github.com/nd/mk.java/blob/master/src/main/java/MicroKanren.java

可是我不会啊…… 这里也有两个未知数呢
def solved(n, x); 2**(8*n) == 1000**x; end
上枚举吧, n=(1, 10]; x=(1, 10]
(1..1000).to_a.combination(2).map { |nx| [solved(nx[0], nx[1])||solved(nx[1], nx[0]), nx] }.find_all { |it| it[0]}

好像还是不行呢…… 可是第一个表达式是有办法的
[[3, 4], [6, 8], [9, 12], [12, 16], [15, 20], [18, 24], [21, 28], [24, 32], [27, 36], [30, 40], [33, 44], [36, 48], [39, 52], [42, 56], [45, 60], [48, 64], [51, 68], [54, 72], [57, 76], [60, 80], [63, 84], [66, 88], [69, 92], [72, 96], [75, 100]]
hhhhhh好无脑
+ 依照CFG(Control Flow Graph) 谈 return early

虽然我好像已经谈过了(而且这次显然我不会扯到SSA的PHI……),
就是说可以要在一个函数返回前添加固定的步骤,所以不能直接 return 这样
我们这里谈的不是和 calling convention 里栈帧末的收尾代码。

说点抽象的,如果我们一直用 if (p) {…} clean(); return;
实际上不管怎么样 if (p) 里面的东西,除非return跳转都会 fallthruclean(); return; (隐式return也一样)

但是如果你
if(!p) return;
if(!p1) return;
clean(); return;
就不一样了,显然直接 return 会跳过 clean();


那该怎么办呢?C宏(辣鸡宏)你可以很dirty的搞个
#define clean(x) { clean(); x; }
void do_sth() {
if (!p) clean(return);
if (!p1) clean(return);
clean(return);
}
#undef
很甜吧,但是稍微有点常识的人都不会用
还有,内联(inline)、嵌套(nested)函数是不允许的

C++ 你可以用 object + finializer,直接RAII(Resource Aquring Is Initialization)
可是 C 里面貌似没更好的解决方法。
一般来说都是
if(!p) goto out;
out: clean(); return;

+ 语文课上居然都谈到区块链
第一时间
《区块链离我们有多远》

我只知道金仨字面意义上的书记有一大堆,所以单单一个书记想伪造敲诈公款是不可能的……
别人说什么造假成本高于造假收益,反正就是密码学啊计算机网络那一些(可信计算?)的东西?


+ 我做梦居然梦到华为EMUI的计算器应用升级
居然还能递等式,还把括号里的东西加了箭头…… 其实我本来可以学学画dot图的,还是直白一点算了
大概是我想 Calc.kt 的二元链解析算法想过分了。
1 + 2 * 3 (梦里比这个复杂得多,我记得当时还是设计质能公式的一个略繁琐的物理算式…… 居然能那样)
= 1 + 6 — 箭头指着上面的 2 [*] 3……
= 7 — 还是有箭头……

+ #book
文章|书 名作者
《她是龙》 小狱
《手机城》 最安神
《盛夏方程式》 东野圭吾
《莫言谈教养》 任万杰
《生气有啥用,还不是在原地转圈圈》 程智超

+ 谈谈知识付费

有时候看到知识付费呢,总会觉得是『知识』要『付费』,付费修饰知识。
可是总觉得,很多人心里会是这么想,实际上却是理解为『能够付费的知识』呢。

就是说,『付费』以得到知识。
『付费』比知识更重要。

付费的东西一定比不付费的强吗?其实这是很大程度依赖上下文的,无法作概论。
知识付费其实不是新概念,实际上学术界也有不少不得不向出版社掏钱的情况,但付费从不是目的,只是为了取得知识不能不拿出来的一点小代价。

如果还看重的是知识的话,就要明白呢…… 不要叫『知识付费』,叫『付费的知识』。

+ 谈谈Calc.kt现在的(基于ADT栈的)解析算法错在哪里

比如,解析词条流 a + b * c + e % c * a
(优先级自己从下面我列的结果推)
(a + (b * c)) + [(e % c) * a]
这是正经情况。
然而实际上,解析器会认为是这样:

a (+) (b*c) (+) [(e%c) * a]
(a + [(b * c) + (e%c * a)])
看到区别了吗?ADT Stack 是右结合的,即便 (+) 的左优先级更大也是一样
只是因为,a+b*c 里要先解析乘法,导致栈是这样:
a (+) (b*c)
如果过一会又出现了加法会怎么样?答案是会归到 (b*c)里:
a (+) ((b*c)+a)
如果又是加乘呢?
a (+) (b*c) (+) (a*c)
所以遇到这种连续两次 (+) 的情况,就都会变成右结合(参考Recursion的reduce方法),实际上应该是左结合的
Expected: (a + (b*c)) + (a*c)
Actual: (a + ((b*c) + (a*c)))

+ 写两个递推式子
我也不知道有啥用,但是笔记上有。

y_0 = (inputs)
y_{n+1} = let x = y_{n} in f_{n+1}(W_{n+1}·x+B_{n+1})

0! = 1
n! = (n-1)!·n
当然也可以这么写,可这好像不是递推式了?
0! = 1
(n+1)! = n!·(n+1)
好奇怪啊

+ PL/0 实践的重点『难点』
1. 实现内嵌函数的作用域嵌套(nested function, leveled stack storage……)
2. 『一个好的解析器应该接受所有输入的所有部分且不能抛出错误』这个不算难,实现『「同步」的keyword token』也不难,就是跳过认不出的token
3. source map (指令序列pc到源码)(其实原教程没有)

+ PL/0 实践教程上的扩展题
虽然我觉得很废

—基础
注释:加入C风格 // 和 /**/
数组:多维数组
函数:传值调用
控制流:加入C风格 for, return,if elif else、exit
判断:(1) 短路求值 (2) && || ! (3) 表达式非零即为真
—提高
提供函数:print(_), print(_, _), random(), random(_)
提供intrinsic:CALLSTACK()
数组多维初始化,var i, j 快速初始化
函数:传地址调用
函数:传procedure调用
do while, switch 和 break, continue 甚至 goto, label
C风格表达式:比如 &, |, <<, ? : ternary 三元表达式, 赋值表达式(愚蠢


虽然照本宣科而且语言设计的也不好,但可见编译原理还是比所谓的『精通』强太多,因为编译原理就可以直接把 if else, do while, swich, break continue goto 什么的结构直接枚举出来,精通还太浅。
Forwarded from duangsuse Throws
笑话:斐波纳奇汤:今天的汤=昨天的汤+前天的汤(自某期《第一时间》笑话部分) #Math
duangsuse::Echo
虽然我连 GAWK 都不会用 UPDATE: 上面的 "(.*)" 应改成 "(.*?)"、<*?> 和 <*> 的意思不一样,它表示『最小匹配』…… 也就是说 takeUntil 到下一项 '"'; 以上 Regex 会把 <abc><123> 弄错,没注意到是因为 <.> 不匹配换行符,感谢细心观众 https://t.me/bystartw_tw. refs
关于正则表达式说几句 #learn 因为这次我错了……(气死,怎么能够犯低级错误,虽然我也没高级到哪里去……)

正则表达式呢…… 就是一种描述『模式(pattern)』的语言
比如说,你大爷喜欢养猫
你大爷有四只猫,分别是黑猫(B)、白猫(W)、花猫(H)、龙猫(L)

—例1
他今天给你带来一只花猫
明天是黑猫
后天是白猫
大后天是龙猫(怎么有点奇怪的东西混进来了……)

你大爷的情绪很波动,所以你需要根据带来猫猫的顺序,判断他情绪的走向。(怎么感觉这个例子举得很是戏谑……)

上面的[例1]可以用我们的『正猫表达式(Regcx, REGular Cat eXpression)』表达:
/HBWL/ — 顺序(sequential)

不过我们比单纯的 "ABCD" 四个字符走得更远,因为可以存在变量 — 而且显然一个『位置』不一定只有一种情况
比如说,你大爷经常带黑猫或者白猫来表示他的心情不好,而你不知道可能(or)『匹配』到的是哪种
/B|W/ — 可能性(or)
花猫或者龙猫表示他的心情好
/H|L/
「括起来」就是给这种情况一个名字,然后我们可以在该『顺序』接下来的时间里以名字使用这个东西
/(H|L)/

我们假设(很平常地):
你大爷情绪波动的时候会带来与昨天不同的猫猫
因为你是有记忆的,所以你只需记住他昨天是带来什么猫就好了
但是有一点:如果我们每次把 (B|W|H|L) 写全就太麻烦了,于是就有了简记法:我们称之为『猫类』
所有猫就这么表示吧: /🐱/
/(🐱)$1/
这就是表达两天里带的是同一种猫($1 是匹配上次的猫 (🐱)),情绪不波动。

可是这只能判断两天里的情况啊!?

于是我们得引入重复的『模式』
不过有一点 — 除了处理现实生活的情况,你可能还要应付你大爷带猫的记录,某个月的记录有可能(因为你的懒惰)是空的
换句话说可能一个猫也没有。

又或者,你尝试匹配的某个模式期待的是 B 黑猫,但是你看到的却是 W 白猫。
这是经常发生的。

/B+/ — 一直是黑猫,且至少有一只(some)
/B?/ — 一只黑猫,不过也可能没有(optional)
/B*/ — 一直是黑猫,也可能没有(many)

/((🐱)\1)*/
就是这个意思了,它会匹配 BBWWHHLL 这种…… 不过这其实不叫『情绪平稳』
/(🐱)\1*/

BBBBBBB; WWWWW; HHH…… 这才叫

== 那么最基本的(顺序、可能性分支、重复)模式就在上面了,下面来说一些表达性的东西,就是 Regex 了。

不过 Regex 是解决字符流匹配的问题,不是猫流(哈哈哈)匹配的问题……

0. 有些项目(item)很特殊,比如 /./ 匹配单个字符、/^/ 匹配一行的开始、/$/ 匹配一行的结尾
一般他们被用于顺序匹配,比如单行 emmm: /^emmm$/
1. 当你想表达『可能是一类』的时候,你可以:
\猫类名
字符流也可以……
\d digits "123"
\w 像 "hello_world123" 这种
\s \S 空格和非空格(基本都是大写逆命题的form,\d \D 也是)

3. 也可以直接用 [...] 区间:
[a-z]
[A-Z]
[a-zA-Z0-9]
[...] 里面是对集合(字符的『类』)所有元素的穷举描述
a-b 这种语法是只有 [...] 里能用的,它表示 a~b 区间里的所有字符…… 字符都是有自己编号的
Unicode 里这个标号叫 code point
是一种枚举(enumeration)!

/a?=(b)/ 是 positive lookahead,意思是我们要 a,但是只有在b前面时才「匹配」
/a?!(b)/ 正好相反,只有不在 b 前面才匹配
这被称为『先行断言』

然后懒得说了…… 😕
https://regex101.com/
Regex 的语法可以很无穷尽的,一般都是以 PCRE (Perl Compatible Regex) 为准