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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
Forwarded from 神奇的笔记 (立音喵)
Forwarded from 神奇的笔记 (立音喵)
x86 模拟都出来了?!
#Kotlin #design 提问!怎么写 matcher 库呢?

你需要了解如何写可组合的操作,这里是 predicate: (T) -> Boolean ,当然实际上必须维护可阅读的结果报告(String path, Map mismatchs)

接着,考虑是 val 还是 fun,用不用 receiver 参数或带 receiver 参数的 Scope 闭包即可。

组合很简单,用函数的闭包(即 #OOP 对象)拼凑实际表达式
1.match { all(eq(1), lt(5)) } 其中 lt 是 lessThan 的意思。
const eq=a=>b=>(a==b), //lt也是一样模式,除了(b,a)=>(a<b)倒个语序
all=(...ps)=>x=>{ for(let p of ps) if(!p(x))return false; return true; }


咱可以看到,这个「高复用」办法本质只是在隐式化、拼凑参数罢了,其实 ==,!=,<>,in 等二元逻辑算符的引入都是预提供一个参数,等另一个参数 ,而 all, any, none (&|, !|) 则是在组合 Predicate 类型,用 for 循环解释 && 等算符短路(即惰性)求值的语义(any,all 等列表处理操作本是如此性质)。

当然,它们本身也是可被组合的,就像程序结构本身一样;但,原来十行代码的东西就只用写一行了,多快好省。

如果只是这样根本没必要单独开项目,反正计算开销小,可以取消 all 等组合器的部分求值,即便已知 mismatch 也只是存到一个结果报告(Map+path 足矣)里继续测试,这只需要让 all matcher 能知道自己的「路径」并且给子项们接上「新路径」。

只需把只能 apply() 的 function value 变成带构造器和 .var 的 interface ,在构造器里给子项进行 .path= 的「注入」隐式提供其路径,它之后的生命里全复用即可。
不过,这么一来就变成 interface Matcher { var name:String, fun test(x:T, m:Map<String,ErrMsg>) } 了,不需要给父组合器提示返回值了呢。
不过,这也照应了程序本身树穷尽遍历的性质,不再是逻辑表达式的「解释器」了。
Forwarded from Sauro 🍏 邮包在哪里
Forwarded from dnaugsuz
https://t.me/dsuse/16941 早上没起床就写了点相关知识……

嘛其实我觉得 mvc.perform(httpOp).andExpect(matcher) 挺冗余的, mvc.expect(arrayOf(httpOp to matcher)) 合适点

status=>ResultMatcher { AssertionErrors.assertNotEqual("status", status.value(), it.response.status) }

mockMvc.perform(post(path)).andExpect(status().isNotFound) 不能 Matcher.not() 是肯定的,如果要的话需要更改最下层的(==)命题,直接否决(不对…… ParserKt 的问题是 Repeat.not 的肯定要 rewrap ,但是这个的数据类型没有不同(不对,这个靠 ErrList 依然会有变换后否决错误信息缺失的问题……

如果让动苏来设计就不会有这种问题
Forwarded from dnaugsuz
有时候虽然他们只是在吐槽过于简单,我都觉得有点太爱秀了的意思,大概是老「反向偏见」了
可能是我对数学的一些人的某些作风有一些成见吧,不过本苏也不会算法和 DP 动态规划,当然递归和缓存是会的。

不过这道题 JavaScript 里也可这样答:
const
int2float=(n)=>applyKeepSign(n, i=>digitCat(0.0, [...digitPop(i)].reverse())),
digitPop=function*(n){ let acc=n; while(acc>0) { yield acc%10; acc=Math.floor(acc/10); } },
digitCat=(init,ds)=>{ let acc=init; for(let d of ds)acc=acc*10+d; return acc },
applyKeepSign=(n,op)=>Math.sign(n)*op(Math.abs(n));

然后 [-10, 251, 0].map(int2float) == [-10,251,0]

其实我最大的成见就是,算法在实际应用中不是最重要的;学会设计和编程调试在大部分应用/服务里对性能及健壮性、易用性的影响更显著,很多时候看似简单的算法反而有更低时间复杂度;人的能力不是通过「不明觉历」能评价的。 🤔💭
Forwarded from 浪人新闻
AI:你们卷吧,我先去赛博坦了
#日常精神分裂 #DOM #game #js
A: 你看到了吗,那个从视口顶部丢球球下来,像俄罗斯方块一样的球碰撞游戏,是叫合成大西瓜来着
B: 那是个逻辑相当简单的游戏,也看见有三四个人做了翻版(奥利给等),如果按环节重复、更新规则、动画细节三项而言,细节不超过六个
A: 如果我们利用 canvas 做碰撞检测复刻一个,你觉得怎么样?整个绘制只有 Ball(p,r) 一种类型两个参数!简直和只有 fillRect 的贪吃蛇一样简单
B: 和 web asteroids 的 doc.elementFromPoint 不一样-_-|| 这次要手写 2D 游戏引擎碰撞检测部分,除了基础的加速度和碰撞方向检测;老实说都是数理密集算法
A: (不考虑与边界矩形的碰撞)我想到了三种方法做纯圆球的碰撞检测,首先是遍历球表算距离……
B: 没用!这样相当于每个配对你都要检测一次,要知道这个游戏后期会有 20 来个的,为保证不穿模,每一帧都计算?!
A: 那我参考整体动量,间隔毫秒或者帧号判断呢?
B: 都说了会穿模了
A: 第二种方法,参考物体的运动方向延长线,看交点,每对 ab,ba 缓存下只算一次
这种方法也可以用来优化一个物体不动的碰撞,或可预判碰撞发生时间,有变再 cancel 重算
B: 好啊,你怎么取射线和圆的交集?
A: 第三种方法,其实理论上只有画特效需要用到 canvas ,其它的尽量用 DOM 元素,就可以利用浏览器的既有算法,我知道有个 Element.nearest(selector) ,这样每对物体检测一次 d(p1,p2)<(r1+r2) 就够了;对边框是特例,只要对所有物体增加 x,y in clientRect.innerDist(r) 就可以了
B: 是个可取的方法,你不会用框架吗,整个游戏只有 ellipse collision 和 gravity 、force ,再简单点就只有放球和贴图,碰撞只是换贴图+增长,球与上框碰撞结束而已。
A: 嫌大了。 DOM 已经足够强大,何须更多修饰? 高射炮打蚊子

B: 好了,谈谈复用问题吧,假设你不用框架,却又写了个用途单一的正圆碰撞检测算法…… 我猜测应用部分是这样的:

gameStart() = rateLimit(waitPutBall, 4000)
onEach(ball)
limitInRect(world.rect.innerMinus(ball.r), ball) // 模拟边框碰撞体
if ball.p.y<yTopline: gameOver()
waitPutBall()
ball = newBall(randPick(cfg.sizes), randPick(cfg.colors))
ball.y = yTopline; ball.g = cfg.weight
onmousemove = ev=> ball.x=ev.x
onmousedown = ()=> world.attach(ball) // 球开始下落
onCollide(a,b)
a.r += b.r
a.onChange()
b.remove()


gameOver() 的条件也可以换成在放球和最近球的碰撞检测 避免每个都判断

A: 我相信关于代码复用和框架组织,咱会有办法的!
#rust #parser 普通的 Lex/Recurive 流解析器,分词靠 regexp,中缀优先级分左右,Lua 模式;最后教了 Scheme 的 s-expr 解析