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
Forwarded from LetITFly News (LetITFly 让技术飞)
华为曾经说过「我们为了避免用户刷机出现问题,将在60天后永久关闭解锁码申请服务」-> 「我就是死外边,从这里跳下去,也不会再开放 Bootloader 解锁」

不能预装 Google 服务导致对海外的销售有影响了,然后考虑允许 Mate 30 用户解锁 bootloader -> 「真香?」

but,频道主仍然基于个人原因不建议各位买华为的智能手机。
curry (f :: * -> *) = f
curry (\_ -> curry g) = \x -> g x
🤔 这周的主要问题是完成部分的 BinaryStreamIO,虽然只有一个晚上。

本来,BinaryStreamIO 设计的有 struct 和 nat 包,不得不暂时不写
struct 包依赖 org.duangsuse.condel,是一门独立的嵌入式编程语言,可能不能立刻写

此外,列表的部分如下

1. 谈谈区块链技术的应用方向、实际能力和「巴菲特午餐」
2. Dijkstra:WDAG 的文本表示方法
5元 ->
10元 ->
20元 ->
整数币 ->
现金 ->
人民币 ->
货币
(a) 有 N 个集合被称为前驱集合,存在前驱栈里
(b) 在扫描过程中,视前部(初始 MAX_VALUE)空格(缩进)的个数,如果它大于上行则前驱集合所有元素转移为当前行
如果等于则当前行后继元添加到前驱集合
如果小于,则开启新前驱集合
3. 新的强制类型转换 + 泛型类方式封装使用 typealias 的 Dijkstra 算法实现(object Solver + class Dijkstra<T>),同时提供 JavaScript 和 Python 的弱类型版本
4. 迫真猜测 Bellman-Ford — 两种支持负权重的方法:反向平均/重新传递
5. 关于 NBMAK (名字 Arkita_ADNKBot) 的基本交互 — /approve 引入方式和群聊专有的 flags, /lex
6. BinaryStreamIO
7. 🤔??? 这里有一个项目,可是 duangsuse 不想写出
8. 分享三篇文章《预支奖金》《火车盒饭难吃的背后》《知识晒成咸鱼干》
9. 分享一些书(如果没有)《时间深渊》《云养汉》《天贼》
10. #FP Agda:终于基本理解了 rev.rev = id 的归纳法
11. KotlinCN: inline fun <reified T> isz(vararg xs: Any) = xs.all { it is T }
以上是我靠着一个 counted memo 记忆了一个一个星期的东西,可能有遗漏,不过遗漏恰恰说明它不是最重要的东西 🤔
Forwarded from duangsuse Throws
#school 本苏国庆放假,没啥计划,就是几个 lib 加上一个数据统计的,本苏写应用最辣鸡了(连 DOM 可调节大小位置的悬浮窗都要想半天,得出 i.width += (pos.x - i.x) / 2 都莫名兴奋)

应用上,我对状态机熟悉一点了,同时也稍微考虑了一下应用常做的动画应该是怎么样子用

// 告诉你们什么叫真正的『形式化设计』
fun trimMarks(input: CharSequence, beg: Char = '<', end: Char = '>'): String {
val trimstr = StringBuilder()
var isInTag = false
for (char in input) {
// (0) => initial
// initial <- c = trimstr.append(c)
// initial <- beg => inTag
// inTag <- _ = {}
// inTag <- end => initial
if (!isInTag) {
if (char == beg) { isInTag = true }
else { trimstr.append(char) }
} else {
if (char == end) { isInTag = false }
else {}
}
}
return trimstr.toString()
}
这里有一点可以注意:每次状态转移不会粘滞,也就是 initial <- beg => inTag 直接转移到了 inTag 状态,而不触发 initial <- c。我使用了一个 if (…) {} else {} 完成这个分支,保证了状态转移的 case 不会和其他 case 碰撞,当然也应该有更好的方法。
当然这个函数也可以写得更像状态机一样。
object TrimMarks {
const val defaBeg = '<'
const val defaEnd = '>'
enum class State { INITIAL, IN_TAG }
fun process(input: CharSequence, beg: Char = defaBeg, end: Char = defaEnd): String {
val trimmed = StringBuilder()
var state = State.INITIAL
for (char in input) { when (state) {
State.INITIAL -> if (char == beg) { state = State.IN_TAG } else { trimmed.append(char) }
State.IN_TAG -> if (char == end) { state = State.INITIAL } else { }
}}
return trimmed.toString()
}
}
当然,这里 defa* 常量其实可以不写,因为这么抽提无必要
一般应用的话,如果用 Kotlin 的 Coroutine + await/async 自然是最好的,因为非常直观,不需要老设置 callback,只是为了维护一个链条
我是这么想的,当然是空想,可是……

fun showInputAnimated(): Unit {
val line = CubicBezierLine(0.3, 0.2, 0.5)
val fadeout = ObjectPropertyAnimation(btnStart, "alpha", line, Pair(1, 0), 2000 /* aka. (2 as kotlin.Int).sec */)
fadeout.setOnAnimationEndListener { // boilerplates
val fadein = ObjectPropertyAnimation(btnStart, "alpha", line, Pair(0, 1), 1000)
fadein.animate()
}
fadeout.animate()
}

Kotlin 的 infix funtailrec fun 也比较有用啊,还有 inline valdata class : *

说起来,这个人的水平啊,我感觉还真的是越来越难用『代码行数』这种不讲理的东西决定了,反而是最厉害的大佬会去写最傻瓜式的代码,不是因为他们不知道,真的是因为他们已经经历过了、看透了。
傻瓜式的代码真的是一种奇妙的东西啊,只有突破思维定式才能写出简单又优雅的代码,和原来的那种机械重复感觉完全不是一个档次的东西。
Forwarded from duangsuse Throws
我曾经写的『倒序』(那时候我连字节序到底是什么都不知道)
我记得就这程序我当时至少写了 5 分钟,当然现在我优化了自己对 bound 模型的理解力,所以会快很多(不过写错了,Kotlin 也骗我,我以为 a..b(a, b] 区间的意思……Kotlin 变成全开区间了)

def rev(hex); l = hex.length; "#{hex[0..l-(2*3 +1)]}#{hex[l-(2*3 +1)..l-(2*2 +1)]}#{hex[l-(2*2 +1)..l-(2*1 +1)]}#{hex[l-(2*1 +1)..l]}"; end
请问这 TMD 是哪门子代码啊?当时就是这样,规模小一点而已,我都不知道 16 位是啥子,只看 FFFF 这种东西,然后瞎 🐔 写… 类似这种代码,而且我用的还是常量(而不是 2*n+1
当然我用 for 循环和 mod 取模也一样
def revmod(hexstr)
reversed = []
for x, i in hexstr.each_char.with_index
reversed << x
if i % 2 !=0; resv = reversed[i-1] # replacement: (i+1)%2 ==0
reversed[i-1] = reversed[i]
reversed[i] = resv
end
end
return reversed.join
end

比如别人(也算是个好程序员)写的,可是还差了一点

// 别的程序员怎么写(大意)
int reverseByteOrd(int i) { return ( i&(0xFF << 8*0) )<< 8*3 | ( i&(0xFF << 8*1) )<< 8*2 | ( i&(0xFF << 8*2) )<< 8*1 | ( i&(0xFF << 8*3) )<< 8*0; }
为什么 0x7F_FF_FF_FFInteger.MAX_VALUE 呢?
我们看这个 0x7F,就是 0b0111_FFFF0b0 的第二个0(第一个是 0b 二进制前缀的『0』)
它这个 0 代表 8(2**3), 之后的依次是 4(2**2), 2(2**1), 1(2**0),叠加上就可以了
第一位是符号位,每次计算中取两次反就可以得到正确结果,但是为 0 表示正数

reverseByteOrd(0x00_00_00_7F) == 0x7F_00_00_00
//true

这么做是很秀(不过有点坑,& 的优先级没有 << 高,如果括号写漏就炸了),可是还有更好并且更快的方法

后来我看函数式程序员写的 atoi,才觉悟出 i<<1<<1 = i<<2 的道理,而通过这种道理和 Kotlin 的 functional inline 我可以写出性能比一个一个去 bitwise & | 强百倍而且好看百倍的代码,最重要的是它可以做到 Java 7 程序员叹为观止的『极限』代码复用,真的是一行模板都没有

typealias Cnt = Int
const val wbyte = 8

inline fun <T> rotatePrimOrd(
crossinline shl: T.(Cnt) -> T, crossinline or: T.(T) -> T, // construct T
crossinline shr: T.(Cnt) -> T, crossinline and: T.(T) -> T, // destruct T
bitselect: T, bytew: Cnt): (T) -> T = closure@{
var stack = it
var swapped = it // clone
for (_t in 1..bytew) {
val shifted = stack.and(bitselect)
stack = stack.shr(wbyte) // |00 [FF]<<00 FF|
swapped = swapped.shl(wbyte).or(shifted)
}
return@closure swapped
}

fun rotateInt32(i: Int) = rotatePrimOrd(Int::shl, Int::or, Int::shr, Int::and, 0xFF, 4)(i)

然后可以
 const val BYTE_1: Byte = (0x7F or -0x01)

rotateInt32(0x00_00_00_7F) == 0x7F_00_00_00 //true

你看这个数组逆序的,后来如果从输出要符合的『性质』property 来看,有时候突然觉得莫名其妙视野开阔了许多,虽然实现起来还是只知那几种而已

forall i in (0, length xs]. xs[i] = xs[lastIdx - i]
where lastIdx = (length xs -1)

然后我们发现其实靠交换 (0, length xs `div_ceil` 2] 就可以实现这个目标了:

#include <bits/stdc++.h>

using namespace std;

template <typename T>
void reverse(T *ptr, size_t len) {
size_t lastIdx = len -1;
size_t end = (len / 2) +1;
for (unsigned i = 0; i < end; ++i)
{ swap(ptr[i], ptr[lastIdx-i]); }
}

int main() {
char str[7]; const char strorig[] = "abcdefg";
memcpy(str, strorig, sizeof(strorig));
reverse(str, 7);
cout << str << endl;
}

Haskell 里我也还记得两种方法
reverse' xs = foldr (:) [] xs -- 刚才发现我误解了这个思路… 还想 foldl (:) [] 的,可是 foldl 需要 (b -> a -> b),等等好像的确是可以写,不过要 flip 一下
reverse'' = foldl (++) []
reverse''' = foldl (flip (:)) []

rev'' (x : xs) = (rev'' xs) ++ x
rev'' [] = []
rev''' = rev_rec''' []
where
rev_rec''' ac (x : xs) = rev_rec''' (x : ac) xs
rev_rec''' fin [] = fin

几个 lib(BinaryStreamIO, 后来我改叫 BinaryStream 了,再后来我起了个昵称叫 Doku(日语的『読』)、Duava(Data/Utilities Abstraction for Java)、CondEL) 嘛也比较 excited,(对自己)算是革新…

但是在听老师发成绩的时候,我觉得有必要写个应用程序去做图表,比如用 Qt Charts(可以顺便熟悉下 C++)
可是毕竟我还是不熟悉 C++ 啊(这个应用程序名叫 DataMet)!我又想 (1) 再复习一下 Python 经典分析数据可视化了 Avg, Mid { Pie, Rect }, Scatter2D, Scatter1D (2) 我也可以用 JavaScript + DOM + echarts.js

最近设计点什么东西都莫名其妙想写 Parser 想设计新的 Expression Language 了,这次就是设计也想了一个、打算实现了一个(实现的那个就是迷你版 CondEL,用来从 Set<Tuple<*>> 里 filter 东西用来 plot 的,当然有些 plot 基于的 DataFrame 是 Tuple<Set<I>, Set...>)… 居然还要写 Type checker(而且要支持 currying 还比较头疼要用 vector,如果想支持 optional arguments 就会很 dirty 不可能,不过好处就是没有本地变量,直接用很重的 curried fun…),然后用 C++ 实现,虽然 GC 可以直接忽视掉因为 shared_ptr Refcount 能够解决,晕

不过不管怎么样我都还得先写点教程、观点之类的东西…

今天晚上会先说点闲话,如果说完还有时间就出图表、写 TrieTree…
duangsuse Throws
我曾经写的『倒序』(那时候我连字节序到底是什么都不知道) 我记得就这程序我当时至少写了 5 分钟,当然现在我优化了自己对 bound 模型的理解力,所以会快很多(不过写错了,Kotlin 也骗我,我以为 a..b 是 (a, b] 区间的意思……Kotlin 变成全开区间了) def rev(hex); l = hex.length; "#{hex[0..l-(2*3 +1)]}#{hex[l-(2*3 +1)..l-(2*2 +1)]}#{hex[l-(2*2 +1)..l-(2*1 +1)]}#{hex[l…
c=b; b=a; a=c 是一个『swap』程序里常用的逻辑
为什么 不这么看呢(当然和原来的不一样啦) 🤔
c « b « a « c « ...
也就是递归模式(迫真
I = c « b « a « I
突然想到 Fibonacci 序列
a b c
1 1 2
1 2 3
……
b=1, c=1
loop { a=b, b=c; c=a+b; yield c }

a b c
- 1 1
1 1 2
1 2 3
……

有什么区别呢?其实第一个是 c = b; b = a, a = c, 根本不是什么递归,成环了(而 c 也就只能算是 附带给 b 的第二存储)
第二个是 b < a < f c < … 真正的可递归(显然 b,a 依赖上一个 c,c 依赖 b,a)

既然太抽象没啥用,其实 Kotlin 里用 sequence 也很容易写的…… 我不会

def fib():
b, c = 1, 1
while True:
a = b; b = c
c = a+b
yield c
🤔 我还想写一个 Nat 包用于支持 Unsigned 类型的,Kotlin 官方逼死同人啊,看来只能可怜 Java 用了…
Kotlin 现在真的是什么都有啊… 都不缺
Forwarded from dnaugsuz
ring.kt
1.6 KB
Forwarded from dnaugsuz
This media is not supported in your browser
VIEW IN TELEGRAM
Forwarded from dnaugsuz
Ring.xcf
102.9 KB
源文件,动画是我一帧一帧拿 VisualGimp 工具肝的
Ring.kt
2.3 KB
#Kotlin #code Ring buffer
Forwarded from dnaugsuz
加上了 mark/reset 就很迷,但是为了保护之前还没出队的数据的(markDistance 对 avaliable 从数值大小上看和 free 是一样的,可是用 markDistance 会导致 add 不能使用(锁住了 freeSpaces),加 free 就不会)
如果完全不加注释还真的是有点莫名其妙
一般的话加个『可视化』文本注释会比较好吧
Forwarded from dnaugsuz
再写了一遍,花了 8 分钟居然一遍编译过,开心(虽然还是看不清楚……)
Forwarded from dnaugsuz
🤔 看起来 mark 以后已经读取的数据还是不能遍历第二次,如果想的话,就要把 distance 减去 markerPosition,或者不看 free;基本理清了
duangsuse Throws
我曾经写的『倒序』(那时候我连字节序到底是什么都不知道) 我记得就这程序我当时至少写了 5 分钟,当然现在我优化了自己对 bound 模型的理解力,所以会快很多(不过写错了,Kotlin 也骗我,我以为 a..b 是 (a, b] 区间的意思……Kotlin 变成全开区间了) def rev(hex); l = hex.length; "#{hex[0..l-(2*3 +1)]}#{hex[l-(2*3 +1)..l-(2*2 +1)]}#{hex[l-(2*2 +1)..l-(2*1 +1)]}#{hex[l…
template <typename T>
void reverse(T *ptr, size_t len) {
size_t lastIdx = len -1;
size_t end = (len / 2) +1; // 其实这个 +1 可以去掉,因为即便输入是单数个,最中间的一个也不存在顺序之说,无须逆序
for (unsigned i = 0; i < end; ++i)
{ std::swap(ptr[i], ptr[lastIdx-i]); }
}
#Cplusplus
此外,有些程序员还通过 (a + (a-1)) / b 的方式来 div_ceil, 此时只要有余数,结果自动加一
duangsuse::Echo
Ring.kt
🤔 #Duava 打算加入迫真豪华套餐
#China 梯子国庆活动
Forwarded from null
[CloudHammer 国庆活动公告]

庆祝中华人民共和国成立 70 周年,CloudHammer 特推出全站 7 折优惠码:国庆70,7 天时间,全场 7 折,迎 70 华诞!

https://console.cloudhammer.site/user/shop