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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
WebPack Gradle http://ice1000.org/gist/posgen-gradle/
知乎 Haskell 蜘蛛 http://ice1000.org/gist/rina-spider-zhihu-stu/
C++ Vector http://ice1000.org/gist/vector/
Agda 类型安全 printf http://ice1000.org/gist/safe-printf-agda/

#recommended #backend #blog #lisp(希望大量转载不会引发版权问题 😶
http://ice1000.org/2017/07/01/AntiOptimization/

duangsuse 阅读时注意到的事情(本文第二次,作为位运算优化我还只知道右移二倍 times2...)

1. 普通运算优化为位运算的代码在网上被批判为没有用
2. JavaScript 的 Number 只支持到 2 ^ 53 (53 位二进制数,IEEE 754 浮点的锅)
3. 在进行一些需要比较大精度的运算时就会出现一些诡异的问题
4. JavaScript Number 位运算支持到 32 位
5. Number 类似于 C 里面的 double,但 C 里面的不一定是两个字的数据,所以类似 Java 的 double 或 Rust 的 f64
6. 原版赛高(不要在意 ES6 的 => 箭头函数语法,冰冰非常喜欢使用类似这种的语法...)
fastMul = (a, b, m) => {
var ret = 0;
a %= m, b %= m;
while (b) {
if(b & 1) ret = (ret + a) % m;
b >>= 2, a = (a << 1) % m; // patched
}
return ret;
}

7. 快速乘就是用于计算 (a×b)%m 的一个巧办法,可以避免 a×b 过大导致整数溢出而使结果不准确。
8. 由于掐掉前面的位并不影响 n&1 这个操作,因此我们还能继续使用(位运算) &
9. b = Math.floor(b / 2), a = (a + a) % m;
10. 原版是
b >>= 2, a = (a << 1) % m
;
11. Math.floor(x) 是向下(单舍)取整的意思
12. b >> 2b / 2 不是等价(废话)(部分等价的是 b >> 1)的,不过我不知道这是不是弄错了
13. 1 << m 换成 Math.pow(2, m)
14. 我去,1 << mm << 1 有区别?一个是 m ** 2 一个是 m * 2 (m + m)
15. 加法溢出问题就是说这个

var a = 9007199254740992;
var mod = 1000000007;
(a + a) % mod;
两个都是合法的 JavaScript Number 可是溢出了,因为 a + a 太大了当然损失精度,但是不知道为什么出现了溢出到负数的结果
等价运算 (a % mod + a % mod) % mod == (a + a) % mod

16. 原版 fashPlus,就是说
fastPlus(x) = (a + b) % m
分情况检查做了几个分支保护原版 fastPlus 不受溢出侵蚀吧

(define fast-plus (lambda (a b m)
(mod (+ a b) m))))


好吧,由于 Chez Scheme 貌似是用 BigIntegter 的(无限长度不会溢出,真・自然数)... 所以换 ES6

fastPlus = (a, b, mod) => {
let plus = (a1, b1, m1) => return (a + b) % m, s = a + b;
if (s >= a && s >= b) return s % mod;
if (a > m) return plus(a % mod, b, mod);
if (b > m) return plus(a, b % mod, mod);
return a - mod + b;
}
http://ice1000.org/2017/04/24/JniObjGlobalRef/

看到字典树,我首先想到的就是 RegularPP 的字符串批量替换功能需要这种数据结构优化.... 😶
但可惜天不遂人愿,C 程序设计语言是不自带 HashMap 的实现的
而且我也懒得再去研究下 HashMap 该怎么写... 据说挺复杂,之前我都没看懂
那么问题来了

class Node():
def __init__(self):
self.children = {}
self.value = None

我们看看第四行的 {} 它是什么?

In [2]: dict()
Out[2]: {}

嗯,一个 dict,或者说是 HashMap,或者管他什么 Map,但是 Python 里这是 HashMap

不过我要做的是被称为 ByteTrie 的东西,幸好 Byte 只有 256 种可能
目前计划好的算法呢... 就是使用 ArrayMap 替换 HashMap 实现 ByteTrie,不过添加额外的优化,类似这样

#include <stdint.h>
#include <list.h>

typedef uint8_t byte;

typedef struct bytepair { byte key; byte value; } BytePair;
typedef struct bytemap { LinkedList list; } ByteMap;

typedef struct bytetrie {
LinkedList bin0;
LinkedList bin1;
LinkedList bin2;
LinkedList bin3;
LinkedList bin4;
LinkedList bin5;
LinkedList bin6;
LinkedList bin7;
} ByteTrie;

struct bytetrienode {
LinkedList bin0to31;
} ByteTrieNode;

根树有 8 个静态桶,所有子树都有 32 个虚拟桶
就是说根树查找最坏 32 次比较 byte (或许已经对齐到 int)可以得到答案(子树或者结束符),而子树最多需要 8 次,虽然是模拟的(所以有额外桶查找开销,桶最坏情况得比较 32 次 byte 才找得到)

API 是这么计划的

typedef struct bytetrieresult {
byte flags;
union {
byte result;
void *node;
};
} ByteTrieResult;

struct bytetrieapi {
ByteTrieResult (*set)(ByteTrie tree, string key, byte value);
ByteTrieResult (*get)(ByteTrie tree, string key);
ByteTrieResult (*nget)(ByteTrieNode node, string key);
ByteTrieResult (*remove)(ByteTrie tree, string key);
ByteTrieResult (*dirs)(ByteTrie tree, string key);
ByteTrieResult (*objs)(ByteTrie tree, string key);
};

const struct bytetrieapi btrie = { /* Func ptrs */ };
https://github.com/duangsuse/AnalFuck

1+ done

做啊 
好啊!
啊!啊!
那个啊… 那个啊… 那个啊… 做啊
啊! 啊! 啊!
做啊
来啊!
啊!啊!那个啊… 那个啊… 做啊 做啊
野兽!?
duangsuse::Echo
qqq.c
其实我之前也写过一个 BF 解释器(
不过流程控制没有那么高层就是了

QQQ 语言使用了特殊的操作符切换开闭括号
不过由于 QQQ 的文档不是很详细,没有理解 BF 的流程控制办法,所以 TQVM 实际上的某操作符实现是错的
冰封大佬也 fork 了?(指女装)
duangsuse::Echo
待会给大家科普贝塞尔函数
当然还是不如科普 Parser Combinator 好了,可惜现在我也不了解它...
duangsuse::Echo
冰封大佬也 fork 了?(指女装)
177k...
看来以后除了 C,类 C 的 D 也不失为一个好程序设计语言选项了
#android #reveng #recommended #dev #learn #java
https://github.com/rk700/YAHFA

Yet Another Hook Framework For ART(Dalvik AOT Mode)

提供了和 Xposed 不一样,和 Cydia Substrate 类似的 Hook 模式,backup() 是覆盖之前的方法 hook() 是替换钩子方法
Xposed 框架则可选替换 Before 和 After (Hooked Method)

Like this

public class XposedPlugin implements IXposedHookZygoteInit, IXposedHookLoadPackage {
private static final String methodName = "getText";
private XC_MethodHook getTextHook;

static {
getTextHook = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {}
};
}

@Override
public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) throws Throwable {}

@Override
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
Class<?> targetClass = XposedHelpers.findClass("org.duangsuse.Test", lpparam.classLoader);
XposedBridge.hookAllMethods(targetClass, methodName, getTextHook);
}
}
duangsuse::Echo
https://github.com/duangsuse/AnalFuck 1+ done 做啊 好啊! 啊!啊! 那个啊… 那个啊… 那个啊… 做啊 啊! 啊! 啊! 做啊 来啊! 啊!啊!那个啊… 那个啊… 做啊 做啊 野兽!?
花了足足一个小时我学会了什么: #learn

+ AWK & SED 入门
+ Makefile 隐含规则编写
+ git stash 是干嘛的
+ git commit --amead
+ 复习 Vim 基本使用
+ D 语言入门 & LDC 使用
+ 理解 Brainfuck & BF 解释器 分支&循环控制
+ 知道如何翻译日语(会看翻译器
+ 复习淫梦萌百(知识胶囊
+ 我终于第一次修好了别人写的没法编译通过的代码(虽然就是加了四个字符的 typecast)
#recommended #crystal 这里有一打工程系程序员喜欢的设计模式,我可能过会把它翻译成 Kotlin 再来一遍...

https://github.com/crystal-community/crystal-patterns
https://github.com/bthachdev/crystal-design-patterns

前者比后者少的:

Creation Patterns/Lazy Initialization Pattern
Behavioral patterns/Chain Of Responsibility Pattern
Behavioral patterns/Interpreter Pattern