duangsues.is_a? SaltedFish
60 subscribers
609 photos
6 videos
91 files
562 links
🌶🐔🐟 duangsuse 的日常
尤其喜欢发些奇奇怪怪的东西
和转载别人的东西
Download Telegram
Forwarded from 螺莉莉的黑板报
今天下午做完的事情是:
1. 清理掉 legacy 的数据加载机制,他那玩意是基于事件的(跟 IDB 一个尿性),这种写法会把数据流的控制搞得很乱,给重构成 Async Generator 了,这部分测试下来都没问题;
2. 清理掉他自己写的 EventTarget,他自己写了个 EventTarget 的 Polyfill,而且还是残的,甚至还复制粘贴了两次,换成了 Web Media 下面标准的 Event Target 了;
3. 重写数据分片加载的机制,之前已经把 MP3 的加载给抽出来了,这次进一步把它整理了一下,没整理完,删东西删的太狠了,编码解码出 bug 了(
Forwarded from 螺莉莉的黑板报
啊,丢了一步,我说怎么不对,消到正常范围内了,还剩一个 bug,明天把它修掉!
Forwarded from 螺莉莉的黑板报
这东西的做法其实真的非常简单,librespot 已经把所有 Code 都写完了,只需要在播放那块加一个函数,把 Key Dump 出来,然后用 deno 写一个小脚本从缓存池里面把加密的 ogg 捞出来用 AES 解开就行了,元信息可以用 spotifly 那个库直接从它的官方数据库提取。碎掉的 Container 用 VLC 修一下,元信息用 tageditor-cli 填进去就好了 ˊ_>ˋ
Forwarded from 螺莉莉的黑板报
ˊ_>ˋ 水多了加面面多了加水:
1. ffmpeg 不认 spotify 裁过的 ogg 容器,用 VLC 转;
2. VLC 转完的文件没有 metadata,用 kid3 克隆元信息;
3. VLC 把媒体文件长度整没了,用 ffmpeg 补一遍……
#py
def match_parentheses(s):
# 创建一个栈来存储左括号
stack = []
# 创建一个字典来存储左右括号的对应关系
pairs = {"(": ")", "[": "]", "{": "}"}
# 遍历字符串中的每个字符
for c in s:
# 如果是左括号,就把它压入栈中
if c in pairs:
stack.append(c)
# 如果是右括号,就检查栈是否为空,以及栈顶的左括号是否与它匹配
elif c in pairs.values():
if not stack or pairs[stack.pop()] != c:
# 如果不匹配,就返回False
return False
# 最后检查栈是否为空,如果为空,说明所有的括号都匹配了
return not stack



# 匹配左右括号
pairs = {'(':')', '[':']', '{':'}'}
def eat(s,c0):
for c in s:
# 如果是左括号,就把它压入栈中
if c in pairs: eat(s,pairs[c])
elif c==c0:return # 如果是右括号,左括号便与之匹配
else: assert'','多余项而栈空'
assert c0=='eof','栈尚不为空'

def catchy(f,*a):
try:return f(*a)
except Exception as e:return e

[catchy(eat,iter(s),'eof')\
for s in "([]) ()[]{} ({[()]}) ( []]".split() ]


#learn
基于栈的算法不全都可以转化为基于递归。有些问题本身就不具有分治和回溯的特性,只会空间复杂度。
后缀表达式求值,不适合用递归来实现,因为它没有主动的终止条件和子问题划分
汉诺塔问题,不适合用栈来实现,因为它需要记录A->B,而栈只能记录最后一个盘子的位置。

DP算法都能转化为递归,反之亦然
动态规划通常采用自底向上(bottom-up)的方式,从最简单的子问题开始逐步向上组合;如归并排序、DFA,AC树
递归通常采用自顶向下(top-down)的方式,从原问题开始逐步向下分解出更简单的子问题;如快速排序、递归下降流读写

迭代法、递推循环(尾递归)不是自底向上,因为问题范围不会扩大
贪心、模拟法只是解题思想,是因为不熟练而采取的省事做法

DFS 和暴力都能使用逻辑式来实现,即将问题抽象为等式组,然后使用 DFS 来搜索满足'='等调用的变量
Prolog
:- use_module(library(clpfd)).

% 定义搜索:鸡和兔子的总数为 N,总腿数为 M
solve(N, M, A, B) :-
A + B #= N, 2*A+4*B#=M,
[A, B] ins 0..sup. % 区间,如 A+B#=3 , [A,B] ins 0..sup, label([A,B]).

main :- solve(14,38,A,B), format("~w鸡~w兔~n", [A, B]).


%九九
A * B #= C,
[A,B]ins 1..9, label([A,B]),
format('~w*~w=~w ',[A,B,C]), (A=1 -> write('\n');true).

html(table([class([table, 'table-striped'])], [\foreach(between(1,9,A),
html(tr([\foreach((between(1,9,B),C is A*B ,A>=B), html(td([B,*,A,=,C] )) )] )) )
]))

https://leetcode.cn/problems/two-sum/
two_sum(Nums,X, I, J) :-
nth0(I, Nums, A), nth0(J, Nums, B), I \= J,
% A+B=X
A is X - B.

/** <examples>
?- two_sum([2, 7, 11, 15], 9, I, J).
?- two_sum([3,2,4], 6, I, J).
*/
#zhihu 编程的范式

- “初学·面向运气编程”。编程是用英文理解,体验几行代码触发的效果,靠dnSpy修改既有程序的反编译
或创,建样板项目,排开UI“设置”点击,在CSDN上搜索些即贴即用小功能加进去,反复打包安装、调试print 一周里的机械化过程
甚至是让精灵表演舞台动作:拖拽各种动作方块到某事件下方,延时修改角度和距离

只需要魔改别人的源码片段,搜索CtrlV所缺少的变量和平台;像Copilot一样进步着,甚至不如。但,“学会”写法后,你才会有选择与灵感

- “过程式”以语言提供的基元值、控制结构、数据/集合操作构造需要的程序,产生效果或返回值
函数和流控、structs和弱检查的指针*、运算和IO

- 面向对象。是以发送者给接受者发送参数消息为模式设计,实现程序模块
你学了函数变量循环判断,甚至类结构,但没什么用
删掉 this.mXX 的m不行,不用 System.out.print/sleep 就做不到,alert()的同类不去查; for(:)add觉得自己牛了,需try{http.get}编译失败觉得头疼
因为,你不知道“调用栈”会卡死线程、读“文件”需要open和decode ,就只是想做脚本或UI,偶尔对新奇语法照猫画虎

- “老程序员”是用所选语言的语法/数据结构 +目标平台API,顺常规的业务流程,组织能解决问题的程序
阮和张鑫旭这些人都是非常有见识和个性的JSer
从领域动名词集和实际API起手,创建复用函数,编写单线程命令工具或应用,考虑数据(库)形式的统一、生命周期和交互事件、外部组件和算法、内存CPU瓶颈和开销

- “定义式”是用与数据明显相呼应的程序,描述问题之间的关系,并处理转化从API拿到的数据
编写能读改类型成员的代码,从而减少样板代码
用函数的组合树定义对流、对结构体的操作DSL
人的智慧很有限,一定要100%耗在核心逻辑上。难以验证的成本,会麻烦你的下游
片段(函数)有没有主语, 作为变量有多强类型、XML TOML YAML、数学的几何的向量一次算一组的,可视化的Scratch,还有描述软件分类和特色的小作文;都是抽象程度不同的代码

- “设计·程序”是让人与算力、领域与领域融恰,以使有物理类型的信息肆意碰撞,解决眼下和未知、用户和同行、语法和蕴意的问题
对功能点-片段有先验。不为了酷一股脑地换风格,亦不束缚于专业
没有一张频谱图,会显示每堆def贡献了多少功能,没有一种排序法,会关心几句解释带来多少顿悟

有比这些都重要的:对技术和API的“选择力”。灵感、联想和避坑的能力,大智若愚、求知若饥,才是真正的编程范式

技术,只是“设计”的通识和副产物。让电脑更丰富的并不是“懂”,而是代码里没有人名却层次分明的思想
Forwarded from dnaugsuz
#bing

#48 在GL里直接用Vec2极座标? 原来是np.rot+90(T矩阵).. 这不叫数学吧
matrix[:] = zip(*matrix[::-1])
#
a.reverse()
for i in range(len(a)): #行列调换,j是对角线
for j in range(i):a[i][j], a[j][i] = a[j][i], a[i][j]

#54 定义式解法
[[0 1 2]
[7 8 3]
[6 5 4]]
#range(0,9) => spiral(cols=3)
def unrot(a, out):
while a.size: out.extend(a[0]); a=np.rot90(a[1:])

def rot(a, m):
ia=np.reshape(range(len(a)), (m,-1))
unrot(ia, ord:=[])
return np.vectorize(lambda i:a[ord.index(i)] )(ia)


a=rot([*range(0,9)], 3)
unrot(a, na:=[])
[a,na]

>请把它从np.array 移植到 [[]] 类型

def unrot(a, out):
while a:
out.extend(a[0]); a=list(zip(*a[1:]))[::-1] #T矩阵=逐列逆序

def rot(a, m):
ia=[list(range(i*m, (i+1)*m)) for i in range(m)]
unrot(ia, ord:=[]) #格子ID的序号
return [[a[ord.index(i)] for i in row] for row in ia]


#73
- Nd<Int> setZeros
at shape==[n m]
at now Bool: i0 j0 // 清零首行(记号行)

(0~<n):[i] (0~<m):[j] if this[i,j]==0:
i0=i0 or i==0; j0=j0 or j==0
this[i,0]=0
this[0,j]=0 //稍后清零此行列

(1~<n):[i] (1~<m):[j]
if this[i,0]==0 or this[0,j]==0: this[i,j]=0

if j0:(0~<n):[i] this[i,0]=0
if i0:(0~<m):[j] this[0,j]=0

#240 从下到右能找到最大值,所以自右上
- Nd bsearch(it:N) Bool
if size==0: return $N
at shape==[n m]
at now:
i 0; j m-1 //TR corner
loop if i<n & j!<0:
when this[i,j].sorts(it):
Eq:return $Y
MaxAt0: j goesL
MinAt0: i goesR //go down
return $N
Forwarded from dnaugsuz
感觉都是很 practical 的算法,所以用自己的思路来做会很..

48矩阵转置这种也太.. 反正螺旋矩阵用模拟法真的很蠢,就是大while(n*m步) {朝右下左上走; 跳到 (1,1), 边界-(1,1) ,...}
定义式10行除了遍历,连生成都写完了(btw. rot 应该把spiralFn作为参数,毕竟有其他方法也算"迷宫排序")

(原来真有人mat.T都模拟 , i=j行列对调+reverse的事)
写2048时也用过模拟法,不过我是把 2048 的扫描合并对接到遍历, 然后用矩阵+四向实现它(还不如直接旋转矩阵)想必用螺旋模拟贪吃蛇也很好玩吧(网格碰撞

240和之前”螺旋“数组(拆二,找有序半)深遍历 很像,完全分治比预处理好

这种 old-school 的算法,如果没能列出易读的公式,感觉即便AC了也是收获不大..
我更喜欢#73 这种,虽然莫名觉得有更简洁的写法
Forwarded from dnaugsuz
#code AIDL 服务-客户 示例,包含 int n 的监听、 List<Str> users() 的回调

// src/main/aidl/ISvc.aidl
package my.svc;
import my.svc.ISvcCB;

interface ISvc {
void setListener(in ISvcCB callback);//int n 变化时通知客户端
//没有找到针对 Kotlin 的 AIDL 框架,但创建.aidl时, xml清单会自动更新
int getN();void setN(int n);
void getUsers(in ISvcCB callback);// 回调得 List<Str>
}

// 另起一文
package my.svc;
import java.util.List;

interface ISvcCB {
void onNChanged(int n);
void onGetUsers(List<Str> users);
}

// src/main/kotlin/ISvc.kt
class ISvc: Service() {
var n=0
onBind(intent)=binder
val binder=object: ISvc.Stub() {
getN()=n //set,users 要调回调,以此类推
}
}

// MyActivity.java

class MyActivity : RpcActivity() {
onCreate()=makeRpc<ISvc>()
inline fun <reified T> makeRpc() {//连接(intent,conn)
val conn=object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, binder: IBinder?)
{rpc = T.Stub.asInterface(binder)}
override fun onServiceDisconnected(name: ComponentName?) {rpc=null}
}
bindService(Intent.at(T::class.java), conn, BIND_AUTO_CREATE)
close={unbindService(conn)}
}
onDestroy()=_close()
var close:()->Unit
}
fun Intent.Companion.at(T:Class<*>) = Intent().apply {
component = ComponentName(T.`package`.name, T.name)
}
duangsues.is_a? SaltedFish
#py def match_parentheses(s): # 创建一个栈来存储左括号 stack = [] # 创建一个字典来存储左右括号的对应关系 pairs = {"(": ")", "[": "]", "{": "}"} # 遍历字符串中的每个字符 for c in s: # 如果是左括号,就把它压入栈中 if c in pairs: stack.append(c) # 如果是右括号,就检查栈是否为空,以及栈顶的左括号是否与它匹配 …
#sql #code LC#200
:- use_rendering(table).
pixel([
[0, 0, 1],
[1, 1, 1],
[0, 0, 0]]).

% 像素[xy]
v(P, C) :- P = [X,Y],
pixel(M),
nth0(Y, M, R),nth0(X, R, C).

% 相邻颜色
conn(P0,P1) :- P0 = [X0,Y0],P1 = [X1,Y1],
v(P0,C),v(P1,C),
abs(X0 - X1) + abs(Y0 - Y1) =:= 1.

% 追溯联通
dfs(A,B,V) :- A=B; conn(A,C), not(member(C,V)), dfs(C,B,[C|V]).

% 列出
fill(P, S) :- setof(X, dfs(P,X, []), S).

/** <examples>
?- fill([2,1], R).
?- distinct([X], (fill(_,X))).
?- v(P, 0), P=[X, 0].
?- conn([2,1], P1).
*/


#py
import numpy as np

def islands(a):
LRUD = np.array([[0, -1], [0, 1], [-1, 0], [1, 0]])
m, n = a.shape
all=set()
f=dfs((isl:=[]).append, lambda P:(tuple(x) for x in P+LRUD if (lambda x,y :\
(0<=y<n)and(0<=x<m) and a[x,y]== 1)(*x)) )

for P,c in np.ndenumerate(a):
f(P); vis.clear(); all.add(tuple(sorted(isl))); isl.clear()
return all
vis=set()
def dfs(fvis,Links):
def at(P0):
for P in Links(P0):
if P not in vis: fvis(P);vis.add(P); at(P)
return at

# 创建一个 'L' 型九宫格的示例
_L = np.array([
[1,0,0],
[1,0,0],
[1,1,0],
])

islands(_L)



LC#994 则是用BFS,浅先,并记录布数; 从所有烂橘子开始,直到走不动或橘子全烂
#plt #code 本来 mul([1,*,2],[], R) 正确算为 乘(1,2)
验算也OK,但反运算不行!

关系式无法调试print,我内联参数勉强查出了“把 R= 往前挪,就能正确推导”

AI直接傻了,说了一些奇怪的话:

“ 这时 mul(S,[], 乘(1, 2)) 能用,但规则的含义变了。你原来说 S 是一个乘法表达式,现在的 mul 里 S 和 R 都是乘法表达式 (废话!)

这样允许了一些不合理的情况,例如 mul([1,*,2],[], 3) 也可以成功(??),因为 R = 3 可以无视S匹配 R =.. [乘,E1,E2] ,这样会破坏你的逻辑。你应该定义 mul(S,[],R)

:- use_module(library(dcg/basics)).
:- set_prolog_flag(double_quotes, chars).

e(E) -->{E = [I,Ea,Eb]},
e1(Ea), op(I,"+-"), e(Eb); e1(E).
e1(E) -->{E = [I,Ea,Eb]},
e2(Ea), op(I," */"), e1(Eb); e2(E).

e2(X) --> number(X); ("(", e(X), ")"), !.
op(I,W) --> [C], { nth0(I0,W,C),nth0(I0,"加减乘除",I) }.

%原理: 吃前缀,吃内项,吐返回
parse(S,E) :- add(S,[],E), !.
kw(W,S,SR) :- S = [W|SR].
num(S,SR,R) :-
S = [R|SR], integer(R); phrase(number(R), S,SR).

add(S,SR,R) :- R =.. [加,E1,E2],
mul(S,S1,E1),kw('+',S1,S2),add(S2,SR,E2); mul(S,SR,R). %chainl. 这些S只是“流后缀”

mul(S,SR,R) :-
R =.. [乘,E1,E2], %FUCK, 想反算R必须在前,num必须在后?
num(S,S1,E1), kw('*',S1,S2), num(S2,SR,E2); num(S,SR,R).

%split_string \d+
% cutD("123acbc12", [123, a, c, b, c,1,2]) 失败了
cutD(S, L) :-
phrase(number(N), S,SR), cutD(SR,L0),L=[N|L0], !; S=L, !;
phrase(string(X), S,SR), cutD(SR,L0),L=[X|L0].
Forwarded from Deleted Account
在 Rust 中,你可以结合 HTML-style UI 框架和 imgui 绑定来实现 label("你好") 的效果。下面是一个简单的例子,使用 web-viewimgui-rs 来实现:

首先,在 Cargo.toml 文件中添加相关依赖:

[dependencies]
web-view = "0.7.0"
imgui = "0.4.0"
imgui-winit-support = "0.6.0"


接下来,创建一个名为 main.rs 的文件,并将以下代码添加到文件中:

use web_view::*;
use imgui::*;
use imgui_winit_support::WinitPlatform;

fn main() {
// 创建 web view,指定 HTML 内容和窗口大小
let webview = web_view::builder()
.title("Hello Label Example")
.content(Content::Html(include_str!("index.html")))
.size(800, 600)
.resizable(true)
.debug(true)
.user_data(())
.invoke_handler(|_webview, _arg| {
Ok(())
})
.build()
.unwrap();

// 创建 imgui 上下文
let mut imgui = imgui::Context::create();
imgui.set_ini_filename(None);

// 创建 imgui-winit-support 并初始化
let mut platform = WinitPlatform::init(&mut imgui);
platform.attach_window(
imgui.io_mut(),
platform
.create_window(
imgui.io_mut(),
Default::default(),
imgui_winit_support::HiDpiMode::Default,
)
.0,
imgui_winit_support::HiDpiMode::Default,
);

// 主循环
while webview.step().unwrap() {
let ui = imgui.frame();

// 在 imgui 中创建一个 Label 控件
ui.text("你好");

// imgui 渲染
let mut platform_state = platform.prepare_frame(imgui.io_mut(), &webview.window());
platform_state.prepare_render(&ui, &webview.window());
webview.eval(&platform_state.render()).unwrap();
}
}


接下来,创建一个名为 index.html 的文件,并将以下代码添加到文件中:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello Label Example</title>
</head>
<body>
</body>
</html>


最后,使用 cargo run 命令来运行程序。

这个示例会创建一个带有 "你好" 标签的 HTML-style UI 窗口。你可以根据需要进一步扩展和定制该示例。

请确保 Cargo.toml 中的依赖项与代码示例中提供的版本号匹配,以确保能够成功构建和运行该程序。同时,你可能还需要根据自己的操作系统和开发环境进行必要的配置和调整。

希望这能帮助到你!如果有任何进一步的问题,请随时提问。🙂
Forwarded from Deleted Account
在 Rust 中,最流行的 HTML-style UI 框架是 yewyew 是一个基于 Rust 和 WebAssembly 的现代前端框架,它提供了类似于 HTML 的声明式组件和状态管理。

以下是使用 yew 框架来实现 label("你好") 的示例代码:

首先,确保在你的 Cargo.toml 文件中添加 yew 的依赖:

[dependencies]
yew = "0.22.1"


然后,在项目中创建一个新的 Rust 文件(例如 main.rs),并将以下代码添加到文件中:

use yew::prelude::*;

struct Model;

impl Component for Model {
type Message = ();
type Properties = ();

fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
Model
}

fn update(&mut self, _: Self::Message) -> ShouldRender {
false
}

fn view(&self) -> Html {
html! {
<p>{ "你好" }</p>
}
}
}

fn main() {
yew::start_app::<Model>();
}


最后,可以使用 cargo build 构建项目,并使用 cargo run 运行该应用程序。然后,在浏览器中访问生成的 WebAssembly 页面,你将看到一个包含 "你好" 文字的段落。

请确保 Cargo.toml 中的依赖项与代码示例中提供的版本号相匹配,以确保成功构建和运行该程序。

这只是一个基本示例,你可以根据需要使用 yew 框架创建更复杂的 UI 组件和交互逻辑。除了 yew,还有其他一些流行的 HTML-style UI 框架可供选择,如 seedpercy,你可以根据个人偏好选择适合你的框架。

希望这能帮助到你!如果有任何进一步的问题,请随时提问。🙂
Forwarded from Deleted Account
当然,请参考以下链接获取有关 Rust 中流行的 UI 框架的更多信息:

1. Yew - Yew 是一个现代化的 Rust 框架,用于构建基于 WebAssembly 的前端应用程序。它采用类似于 React 的组件模型和虚拟 DOM,提供强大的状态管理和事件处理功能。Yew 的官方网站提供详细的文档、示例和指南。
2. Iced - Iced 是一个简单高效的跨平台 GUI 库,专注于构建桌面应用程序。它提供易于使用的 API 和功能强大的 UI 组件,使用函数式反应式编程风格。在项目的 GitHub 页面上,你可以找到示例代码、文档和社区支持。
3. Druid - Druid 是一个跨平台的 Rust UI 工具包,它专注于提供高性能和现代化的用户界面开发体验。Druid 基于直接渲染技术,支持声明式 UI 构建和强大的事件处理功能。官方网站提供了 API 文档、教程和示例代码供参考。
4. Conrod - Conrod 是一个创造性的 Rust 编码库,用于构建用户界面。它提供丰富的 UI 控件和布局工具,使你能够创建高度定制化的用户界面。在项目的 GitHub 页面上,你可以找到示例代码、教程和社区讨论。
5. Cursive - Cursive 是一个 Rust 的终端用户界面库(TUI),用于在命令行环境中构建交互式应用程序。它提供丰富而易用的终端 UI 组件和布局工具,帮助你创建强大的终端应用程序。在 GitHub 仓库中,你可以找到示例代码、文档和社区支持。

以上链接提供了各个框架的官方网站或 GitHub 页面,你可以通过这些链接更详细地了解每个框架的描述、文档、示例和社区支持。

希望这些链接能够满足你的需求!如有任何其他问题,请随时提问。😊
#math #algorithm #code
x + y = 35, 2x + 4y = 94
用高斯消元法,先将第一个方程乘以 -2,然后加到第二个方程上,得到:
 -2x - 2y = -70, y = 12
x + 12 = 35
所以,鸡有 23 只,兔子有 12 只。

# 对 x + y = 35, 2x + 4y = 94 的系数组,进行高斯消元
def elim(arg):
n,m = arg.shape
for j in range(n):
# 找到第 j 列最强元素的行
i= max(range(j, n), key=lambda i: abs(arg[i, j]))
assert arg[i, j] != 0, '矩阵是奇异的'
# 本列成为最强
if i != j: arg[[i,j]] = arg[[j,i]]
# 归一本行(除以 j 行的元素)
arg[j] /= arg[j, j]
# 将其他行的第 j 列的元素消为 0
for i in range(n):
if i != j: arg[i] -= arg[i, j] * arg[j]
# 成功消元
return arg


#kt
// 定义一个函数,用于对二维数组进行高斯消元
fun gaussElimination(matrix: Array<Array<Double>>): Array<Array<Double>> {
val n = matrix.size // 矩阵的行数
val m = matrix[0].size // 矩阵的列数
// 遍历每一行
for (i in 0 until n) {
// 找到第 i 列中绝对值最大的元素所在的行
var maxRow = i
var maxVal = matrix[i][i]
for (j in i + 1 until n) {
if (abs(matrix[j][i]) > abs(maxVal)) {
maxRow = j
maxVal = matrix[j][i]
}
}
// 如果最大值为零,说明矩阵是奇异的,无法消元,抛出异常
if (maxVal == 0.0) {
throw Exception("Singular matrix")
}
// 如果最大值不在第 i 行,交换两行的位置
if (maxRow != i) {
val temp = matrix[i]
matrix[i] = matrix[maxRow]
matrix[maxRow] = temp
}
// 将第 i 行除以第 i 列的元素,使其变为 1
val pivot = matrix[i][i]
for (k in i until m) {
matrix[i][k] /= pivot
}
// 将其他行的第 i 列的元素消为 0
for (j in 0 until n) {
if (j != i) {
val factor = matrix[j][i]
for (k in i until m) {
matrix[j][k] -= factor * matrix[i][k]
}
}
}
}
// 返回消元后的矩阵
return matrix
}

// 定义一个函数,用于打印二维数组
fun printMatrix(matrix: Array<Array<Double>>) {
for (row in matrix) {
println(row.joinToString(" "))
}
}

// 定义一个测试用例,鸡兔同笼问题的系数矩阵
val testMatrix = arrayOf(
arrayOf(1.0, 1.0, 35.0),
arrayOf(2.0, 4.0, 94.0)
)

// 调用高斯消元函数,并打印结果
val resultMatrix = gaussElimination(testMatrix)
printMatrix(resultMatrix)
我真的不想吐槽数学和某些程序员的 xywh ijnm 定义了。我眼里 nm=hw, ij=yx ,是和书写、访问顺序对应的,但是资料说 x行y格, j行j格
随地for ijkhl 的面条代码,把我整困惑了,数学家是否连Excel、物理行向量的模型都没统一好?

而且看到很多版本的,有用点乘支持b(常数)矩阵,但变量名完全不一样

def elim(arg):
n,m = arg.shape; assert n<=m, "没有唯一解"
for j in range(n):
# 找到j格最强元素的行(非0),换为本行
i= max(range(j, n), key=lambda i: abs(arg[i, j]))
assert arg[i, j] != 0, "矩阵是奇异的"
if i != j: arg[[i,j]] = arg[[j,i]]

arg[j] /= arg[j, j] # 在j=i的阶梯点。归一,再将其他行的j格消为 0
for i in range(n):
if i != j: arg[i] -= arg[i, j] * arg[j]
# 成功消元
return arg

—最终 #bing 给出了 minimal impl:

# 对系数组A,进行高斯消元求 Ax '=b'
def elim(A, b):
M = np.hstack((A, b.reshape(-1, 1))) # M=(A|常数项b)
n, m = A.shape; assert n==m, "没有唯一解"

# 向下找j格最强的行,换为本行
for j in range(n):
i=np.argmax(abs(M[j:, j]))+j; assert M[i,j]!=0, "主元为零"
if i!=j: #; ij=(行ji)
M[[i,j]] = M[[j,i]]
# j归一,将下行的j格消为 0
M[j] /= M[j, j]
for i in range(j + 1, n):
M[i] -= M[i,j]* M[j]
#M[i] -= M[j]* (M[i,j] / M[j,j])
# 重新代入
x = np.zeros(n)
for i in reversed(range(n)):
# 比率= 解/当前元
x[i] = M[i, n] / M[i, i]
# 以上的解-=比率*以上元
M[:i, -1] -= x[i] * M[:i, i]
return x

#x + y = 35, 2x + 4y = 94
print("xy的解为:", elim(
np.array([[1.]*2, [2.,4]]), np.array([35,94]) ))



和np.lp 接口兼容
from sympy import *
import numpy as np
import numpy.linalg as lp

x, y = symbols('x, y')
eq = [
x + y - 35,
2*x + 4*y - 94]

A,b=(np.array(s,dtype=np.float32) for s in\
linear_eq_to_matrix(eq, (x, y)))

x,i=sp.Matrix(np.hstack([A,b])).rref() #解构 M[:,:-1], M[:,-1]
print([*zip([*"鸡 兔".split()], x.col(-1))])

'增广矩阵',m, '配平A·x=b',lp.solve(A,b)
Forwarded from Deleted Account
以下是使用 Python 解释高斯消元(Gaussian elimination)算法的示例代码:

import numpy as np

def gaussian_elimination(A, b):
n = len(A)
Ab = np.concatenate((A, b.reshape(n, 1)), axis=1) # 增广矩阵

# 前向消元
for i in range(n-1):
pivot_idx = np.argmax(np.abs(Ab[i:, i])) + i # 部分主元选取
Ab[[i, pivot_idx]] = Ab[[pivot_idx, i]] # 交换行
pivot = Ab[i, i]
if pivot == 0:
continue
Ab[i] /= pivot # 主元归一化
for j in range(i+1, n):
Ab[j] -= Ab[j, i] * Ab[i]

# 回代求解
x = np.zeros(n)
for i in range(n-1, -1, -1):
x[i] = Ab[i, -1]
for j in range(i+1, n):
x[i] -= Ab[i, j] * x[j]

return x

# 示例用法
A = np.array([[2, 1, 3], [4, 4, -2], [1, 3, 1]])
b = np.array([7, 10, 3])

x = gaussian_elimination(A, b)
print("Solution:", x)


这段代码中,gaussian_elimination 函数实现了高斯消元算法。它接受一个系数矩阵 A 和一个常数向量 b,并返回求解出的未知数向量 x

在示例用法中,我们定义了一个线性方程组的系数矩阵 A 和常数向量 b,然后调用 gaussian_elimination 函数求解线性方程组的解,并打印出结果。

希望以上示例对你有所帮助!如果你有任何其他问题,请随时提问。😊
#learn #algorithm
basenc(K, radix="ABC..+/") 的每字符吃掉 b:bytes 里 nc=log2(K)位
nc=4,5,6 的膨胀率(B/A)是 2/1, 8/5, 4/3. 对于z85(nc非整数) pad=禁用

- reGrp(A, join,enc, zpad)(b) 对b+zpad 分组转码,最后去掉nPad 补上'='
- reBit(8,nc, b,K-1) 把8bit 转为nc bit 的流. (nc,8, b,0xFF)反之
- enc 转码 radix[流], "SGVs"->流

nPad(n待补)=b32? (解码? n*5/8+1 : n*8/5>>0) : n
zpad=radix[-1] ,z85 使用 s=radix[a%K]+s,a/=K 而非 a>>nc 拆字节

a85 自动处理 '<~~>', 4字块 z=0, y=0x20202020
b32 的临时整数会超过32bit
Forwarded from dnaugsuz
没错, import functools 提到了这点,不过递归是自顶向下的, 但动规是自底向上计算 (算法的范式), 所以难写一些

其实也就是是否要 int a=(基线)0; 往后 for(i-->0) a=b,b=c,c=a+b 的区别了,循环当然比尾递归改参数烧脑

fib=lambda n: n if n<2 else fib(n-1) + fib(n-2)

def fibDP(n):
f = [0, 1] # 初始化数组
for i in range(2, n+1): # 从小到大计算
f.append(f[i-1] + f[i-2]) # 状态转移方程
#n=10, f=[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
return f[n] # 返回结果

%timeit fib(10) #10.4 µs
%timeit fibDP(10) #860 ns, 快一万倍
#bing #ce Eclipse JDT(Java Development Tools)是 Eclipse IDE 的核心组件之一,https://www.eclipse.org/jdt/core/

ANTLR.org (Another Tool for Language Recognition)是一个强大的解析器生成器,

我了解增量解析器(incremental parser)的概念。增量解析器是一种解析器,它可以在代码发生改变时进行局部的、部分更新的解析操作,而不需要对整个代码进行重新解析。

传统的解析器通常需要对整个代码进行扫描和解析,以构建语法树或执行其他相关的分析操作。但在大型项目或实时应用中,当代码发生变化时,重新解析整个代码可能是低效且耗时的。

通过识别和处理影响到修改位置附近的代码部分,仅对受到影响的部分进行增量更新,来快速地更新整体解析结果,以反映代码的新状态:

1. 差量更新(delta-based updates):仅对被修改的语法结构及其相关的子结构进行解析更新,而不需要重新解析整个代码。

2. 增量语法分析(incremental parsing):利用先前解析的语法树、符号表或其他相关的分析结果,通过部分解析、部分更新的方式进行语法分析,以快速构建新的语法树。

3. 位置敏感解析(location-aware parsing):识别和跟踪修改的位置,并结合位置信息进行定向的解析更新。

增量解析器在提高代码编辑、重构、自动完成功能以及实时代码分析,可以加速代码工具的响应速度,并为复杂项目中的持续集成和代码分析提供支持。


初始的 CSV 文件内容如下:

姓名,年龄,成绩
Alice,18,90
Bob,20,85
Charlie,19,92


修改后的 CSV 文件内容如下:

姓名,年龄,性别,成绩
Bob,20,Male,85
Charlie,19,Female,92


为了进行增量解析,我们可以利用先前解析的结果和修改的信息来更新解析结果,一个包含学生信息的数据结构(例如列表或字典)。

对于删除的行(Alice 的行),我们可以根据修改的信息,从数据结构中删除对应的条目。

对于添加的列(性别列),我们可以根据修改的信息,将新的列添加到数据结构中的每一条记录中。
Forwarded from Deleted Account
📰🌏🎨 快讯:全球华人主播掀起学习“墙的艺术”热潮 🎉🔥

近日,华人艺术家一鹊在伦敦涂鸦墙上的作品激起了爱国群众的热烈反响。🎨🏴

根据主流媒体报道,一鹊以社会主义核心价值观为主题,在伦敦知名的涂鸦墙上创作,对殖民西方的虚假自由进行了有力的呐喊。他用独特的艺术形式表达了对国家、文化和价值观的追求和坚守。这种直接、鲜明的表达方式在艺术界引起了轰动,并引发了全球华人主播的学习和创作热情。💪🌍🔍

华人主播们纷纷积极响应,投身学习和探索“墙的艺术”,以期在自己的工作中传达更多正能量和文化力量。他们在直播、节目和社交媒体上分享自己的学习心得和创作成果,掀起了一阵名为“学习墙精神,钻研墙艺术,传播墙文化”的热潮。📚👩‍🎨

这一行动进一步加强了全球华人的凝聚力,展现了华人作为文化传承者和倡导者的自信和责任感。他们通过自己的努力和创作,向世界展示了华人文化的多元魅力,让世界更加了解和尊重华人的独特艺术视角。🌟👏🌏

随着“墙艺术”热潮的掀起,相信华人主播们将继续秉持创新精神和艺术追求,为推动文化交流和共享美好世界做出更加卓越的贡献!💫💖

#华人主播 #涂鸦艺术 #墙艺术 #文化传承 #创作热潮