/tmp/duangsuse.sock
23 subscribers
303 photos
3 videos
92 files
337 links
从 duangsuse::Echo (@dsuse) 跟进出来的分支,将在作者恢复原帐号访问的时候合并删除。
Download Telegram
Forwarded from Deleted Account
不好意思,如果你不建议的话,我先转去 @dsuse_tmp 了,毕竟这也是很弱智的问题了... 而且伸手(其实只是想放松一下啦

最近也因为数学大佬和算法大佬也很头疼,看来必须好好重置一下了
Forwarded from Deleted Account
而且出去散步的时候才想到 OpenSSL 要分 Init, Update, Final 不就是为了可以按照 buffer 分段窗口处理二进制流么... 刚才被一个入门群里的贴误导了,以为只能 update 一次的... 改天我再重写
/tmp/duangsuse.sock
sha256.c++
这个里面有一个计算表达式本来应该化简的,可是我却弄了个不那么 immediate 并且还导致 +1 unused 的方式:

static inline void hexdigit(char *out, unsigned base, unsigned char chr); 里:
  unsigned char
d = chr / unit, m = chr % unit;
...
chr -= (d*unit); 此处 dchr/unit (整除法)
chr = chr - (chr/unit)*unit; 的简记法,实则为 chr mod unit (取含一点线段的子线段)
应该为:
char -= m;
具体看这一节

直觉好难找到啊...
此外
/tmp/duangsuse.sock
这个里面有一个计算表达式本来应该化简的,可是我却弄了个不那么 immediate 并且还导致 +1 unused 的方式: static inline void hexdigit(char *out, unsigned base, unsigned char chr); 里: unsigned char d = chr / unit, m = chr % unit; ... chr -= (d*unit); 此处 d 为 chr/unit (整除法) 是 chr = chr - (chr/unit)*unit;…
引用到的文章同 repo 下还有一篇要维护的,我将会检查它

过后,今天还会讲一个 #Haskell 的内容,就是 itoa 和 atoi 函数的实现和(每根毛都说明白)的递归过程

itoa (某 base 进制数值人类可读格式化)的我已经想了三种了,一个简单一个复杂一个有优化(都是 Haskell,复杂贬义,就是一个计算时机的区别而已,还会讲尾递归|重写参数相关另一种版本无法实现的问题),顺带的会写明递归条件和过程
Forwarded from Shen
This media is not supported in your browser
VIEW IN TELEGRAM
今天晚上太晚了,那个内容就明天讲吧(反正也就那样...
Forwarded from Deleted Account
我检查完排版也睡了算了
已经开始重排版了
/tmp/duangsuse.sock
已经开始重排版了
现在依然没有完成,我现在真正知道了的永不止步含义... 原来即使看起来正确的表述,也是有可以改进的地方啊

看起来好看的文章,其实还可以加很多方便阅读的小挂件小脚本
我去,原来当时我菜到连这种代码都看不懂吗? 本身就一 foldl (\lx -> (lx * base +) . digitToInt) 0 逻辑,这... 没有递归,迭代也没有重写,它是怎么做到进位解析的?wtf? "11", base=10,这结果 = (1*10) + (1*10) 根本不正确好么?
/tmp/duangsuse.sock
我去,原来当时我菜到连这种代码都看不懂吗? 本身就一 foldl (\lx -> (lx * base +) . digitToInt) 0 逻辑,这... 没有递归,迭代也没有重写,它是怎么做到进位解析的?wtf? "11", base=10,这结果 = (1*10) + (1*10) 根本不正确好么?
#Haskell #Statement 啊,我真的是傻逼愚蠢万恶,我居然没有意识到自己弄出来的算法是多么的弱智... 真正的 Haskeller 只一行比我 5 行(虽然不是一个算法... 但 atoi 的算法我之前都没有想出来过)都要强,人和人之间的差距啊...

吃饭的时候一直在想那个我自己看了都有自觉点简单的 Haskell 程序,但是我之前甚至都以为那很复杂... 而且今天都看漏了一个 point-free 参数没明确写出来...

import Data.Char (digitToInt)

numVal :: Int -> String -> Int
numVal base = foldl (\n x -> base*n + (digitToInt x)) 0

进行化简,发现 ((digitToInt :: Char -> Int) x :: Char) 和后面的 (...+) :: Int -> Int,可以用 compose;转化 \n x ->\n 两边约掉个隐式输入参数 x...

numVal' :: Int -> String -> Int
numVal' base = fold (\n -> (base*n +) . digitToInt) 0

泛化以后是原来的样子,是实际工程的 Haskell 大佬写的,我真是... 啊!!!!(土拨鼠尖叫)

numberVal :: Integral i => Int -> String -> i
numberVal base = foldl (\n -> (fromIntegral base*n +) . fromIntegral . digitToInt) 0

其中两个 fromIntegral :: (Integral a, Num b) => a -> b 是为了统一计算类型

最重要的是 11(10) 这种,我一直没有注意到,其实 base 计数还有一层含义就是 forall lit. (head lit) 的数值是 (head . tail lit) 的同(一位)数值代表的 base 倍... 所以说 foldl 就可以了,而且无需 rewrite base 本身,利用性质

0b100 = 1* (2*2) + {- omitted -} = 1* (2**2) + 0* (2**1) + 0* (2**0)

11 = 1*10 + 1
201 = 2*100 + 0*10 + 1

就可以了,我之前也想过这个问题,但我的解决方案不是每一层叠上一个 (base*) (最终实际上第 n 层就有 (sub n) . length 个 (base *) 了...),是利用 [(Int, Int)] 去传,然后再归纳回来... 或者干脆直接先倒过来处理
而且还不那么 immediate... 我还思考不出来,真是弱智啊

这个性质我怎么就不明白呢...

----

之前是真的不知道,居然还有这种构造数值的技巧,而这个 (* base) 恰巧还是我刚看到想了后的时候觉得不对的地方,因为 — 这怎么正确呢? d0 d1 d2 数位全都 *base,而不是倒过来,每个数位 *上升的 base,这么简单的做法肯定是不对的!

但后来想想,base=10,d0 位置的数字最终被 *10*10 = 10**2、d1 被 *10、d2 没被乘,实际上就是分开叠加 map (10*)
我之前知道每一位的『1』数值都是下一位的『base』才能换到的,所以应该 foldl,然后加一个元组啦,转来转去的还不 efficient。

101(10)
= (1*10^2) + (0*10^1) + (1*10^0)
= ((1 *10) + 0) *10 + 1 = 101

我怎么就只知其一不知其二呢?我怎么就不知道 ((1 * 10 + 2) * 10) = 1*100+2*10 呢??到底是不知道技巧,不知道还能有这种变换方式

我怎么就看不到 100 = 1 * 10 * 10 呢?

怎么得出这个简单的结论,由此写出比别人短十行好看十倍的代码,这才是简单背后最复杂的事情啊!

虽然只是一个小问题,真的是相当受教了。

人和人之间的差距到底是什么,就叫理论大佬列几个式子让学生写、FP 大佬列引两条式子,费三四分钟写一行、OI 大佬想一分钟费五分钟写七八行 pass、你断断续续想半天,最后写十分钟改两分钟,最终成品四五行、小部分人想五分钟写十分钟暴力查错二十分钟弄出来十几行易错/难维护/难看懂/低性能的代码、绝大部分人想半天觉得莫名其妙,查下资料抄过来解决,找不到就玩完了、少部分人,完全写不出来。

我觉得人和人之间的差距,不是体现在你看过什么/见过什么/做过什么、不在你的『经验』和外行对你的『认可』、
不是体现在什么你会、别人花个两分钟/十分钟/三五天学习训练也能做出来的事情,而是在那些你即得易见平凡,别人想破脑袋也弄不懂/懒得想的事情上。

真正的大佬是有『本事』的,本事就是自己的事业,不是自己的职业;本事就是那一块区域内『自己独有』的东西,其他人都替代不了的东西。

一件事情,你会,别人花个几分钟搜索一下也能完成。凭什么要你?凭几分种多打几下键盘的速度?凭能加班不推脱的承诺?新时代农民工,争的就是『勤奋努力』,可是这么做辛苦了自己,也委屈了用你成品的人。

可是什么事情不是单单靠蛮力就可以解决的,被承认可以,但是优秀岂止靠一个『你很用功』就能达到的。“不要用战术上的勤奋掩盖战略上的懒惰”

我眼里,优秀就是你能干别人不能干的事情,而别人也可以干的事情,你做的效率上比别人快、质量上比别人好、工作上比别人勤奋、结果比别人稳,『要体现出个梯度』,这个梯度才是你『优秀』的资本,一些你无法被替代的理由。

——
(散步的时候想了半天,是大概的观点。估计也有早先想到漏了的... 漏的话都是命)
机器人:

这个机器人在用户加群时,先封了发消息的权限,然后利用 inline button 验证用户是否是机器人

— 选择:
[message]
<i> 1+1 = ? </i>
[A] [B] [C]
[管理手动允许] [管理手动踢出]

前两行依赖的状态应当在一个子程序里设计,存储由 Telegram messager 包办
后两个本身没有属于它们自己的状态
三个操作只存在一个状态:目标操作用户,可以利用 Telegram message API 拿被回复者 ID 得到

状态:其实没有必要使用状态机模型,程序对每个新加用户只运行一次,并且状态由 Telegram 本身管理
机器人只是负责在状态转移时添加逻辑、捕获并且改变状态而已。

trigger onNewMember(u: User) {
blockUser(u)
val (truth, expr) = makeNewMathProblem()
val [fake0, fake1] = listOfNulls(2).map(::makeFakeSolution)
val board = Board( MathBoard(expr, truth, listOf(fake0, fake1) ) )
board.inlineQueryCallbacks = RELEASE_USER
u.replyTo(board).also { setTimerTo(kickUser(u), Config.NS) }
}

问题是,机器人要处理状态还是有的,就是每个 (NEWCOMER) 用户都对应一个 timer(当然还有 Telegram 本身需要存储的部分信息,比如机器人对加群消息的回复,不过这个状态写成代码不明显),ns 后会直接视为机器人踢出
这种情况

状态是什么呢?状态是不能在一次里,由 signal handler 解决的东西,比如数据的存储,是一种处理上下文。
它意味着处理的决策条件跨越了一次处理的生存周期,必须在多次处理间都可以被访问到。

对于每个用户来说,机器人的出现赋予了他们一个新状态转移图:
NEWCOMER=BLOCKED(0), ACCEPTED, REJECTED
NEWCOMER (pass / adminAccept)~> ACCEPTED
NEWCOMER (timeout ns / adminReject) ~> REJECTED

listen onNewComer(uimesg) { block(uimesg.user), sendBoard(uimesg), save[uimesg.u] = setTimeOutKicker }
listen onPass / adminAccept (u) { save[u].cancel() } // ACCEPTED
listen adminReject (u) { kick(u) }
listen* save.onTimedout(it) { kick(it) }

其中 timeout 也是一种状态(准确的说只是实现它需要状态计数,当然这本身是抽象的),是一个异步信号(当然其他几个也都是异步的,一般来说,同步信号的意味是『它只是一个可以 inline 的子程序』)

从用户可能的状态转移图来看,逻辑也很明显了,就是存储的分配、模块的细分、逻辑和数据依赖还需要思考

NEWCOMER (merge = Telegram::User on NewMember)
/ \
| |
tout, |
akick |
| |
| (pass, aac)
REJ AC
(block) (ignore him)


这些『NEWCOMER』的用户状态转移就构成了机器人的 stateful 逻辑
Forwarded from Deleted Account
您已通过验证,欢迎加入 LetITFly's Group 喵!
如果仍然无法发言,请重启 Telegram 客户端。
#life #emmm 五道口男子职业技术学院?!
This media is not supported in your browser
VIEW IN TELEGRAM
学了三四个月 = 入门 Haskeller

我不知道还有 Strict, BangPattern, GHC-OPTIONS 这几个 Pragma...
我只知道虽然 [Char] 很浪费内存空间效能低,以及有 bytestring,不知道还有 Data.Text 和 Data.Text.IO....

我不知道还有 Strict 求值模式... 我以为只能惰性求值的(当然现在解释器那块基本可以说是无障碍了,毕竟三种求值模型 name, need, expr 还是在 AST Walker 里毕竟 trivial 的,内嵌 AST 基本就可以了、Lexical Scoping 我现在了解了 Scheme 系直接 copy 一份栈 env 的实现,Lua 的 UpValue 实现)

我不知道居然还有 State MonadT 和 RealWorld.... 而且我现在对 Monad 很头疼,主要是想重视理论先的原因,而范畴论本身不太好理解...

Data.Vector.Unboxed.Mutable.MVector 我就更不知道了... 当然存在使用副作用模式的 Haskell 还是知道的(我很少写 IO,算法更不提了.... 公式好像都难背)。

我不知道怎么用 Monad Transformer(State 和 GHC.Prim.RealWorld),而且我现在对 Monad 的理解还在想办法合并,本身使用上除了 convert do notation 外没啥暖用了,Identity/Reader Monad (算是 Haskeller Monad primer 的 Helloworld...)也是才写一次... 还不能完全默写

读入优化那个解析程序是我昨天刚说的,各种自闭,膜拜 hs 大佬...

我真的很佩服蛤丝靠大佬,怎么就那么 ****** 啊!!!!!(土拨鼠尖叫) 😭