perm函数

工作上遇到一个问题,好奇goalng的排列数Perm是怎么实现的,看了下源代码,写的很简洁。 使用了随机交换算法来得到一个排列组合。 1 2 3 4 5 package rand // import "math/rand" func Perm(n int) []int Perm returns, as a slice of n ints, a pseudo-random permutation of the integers in the half-open interval [0,n) from the default Source. 交换 本质上说就是交换m[i]和m[j],且i> j。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 func Perm(n int) []int { m := make([]int, n) for i := 0; i < n; i++ { j := rand.Intn(i + 1) // std implement // m[i] = m[j] // m[j] = i // swap m[i], m[j] = m[j], i // same effect // m[i] = i // m[i], m[j] = m[j], m[i] } return m }

December 28, 2021 · datewu

排列组合

上礼拜有人问我,如何从数组中选择和为n,长度为m的所有的子数组? 问题 输入 a = []int{10, 7, -5, 4, 8, 16, 70, -30, 91} m = 3, n = 15 输出 1 [[10 35 -30] [-5 4 16]] 答案 算法 这是一个典型的排列组合的问题,只要把Cn算出来然后做过滤就好,核心是数组组合的算法。 我使用的是递归算法: 选取包含第一个元素的组合:拼接第一个元素和剔除第一个元素后数组的所有的m-1的组合; 选取不含第二个元素的长度为m的组合; 将上面两个组合合并起来即可;(不用去重,因为没有重复的) 递归结束条件:当m=1的时候,直接放回所有数组元素;当m=len(input)时,直接返回[][]int{input};当m>len(input)时,返回空; golang实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 package main import ( "flag" "fmt" ) var ( size = flag.Int("size", 3, "size of array") sum = flag.Int("sum", 0, "sum of two numbers") ) func main() { flag.Parse() input := []int{10, 7, -5, 4, 8, 16, 35, -30, 91} // for _, v := range chooseM(input, 8) { // fmt.Println(v) // } fmt.Println(input) fmt.Println(chooseSumN(input, *size, *sum)) } func chooseM(data []int, m int) [][]int { if len(data) < m { return nil } if len(data) == m { return [][]int{data} } if m == 1 { var res [][]int for _, v := range data { res = append(res, []int{v}) } return res } one := [][]int{} rest := chooseM(data[1:], m-1) for _, v := range rest { m := append([]int{data[0]}, v...) one = append(one, m) } return append(one, chooseM(data[1:], m)...) } func chooseSumN(data []int, m, n int) [][]int { out := [][]int{} for _, v := range chooseM(data, m) { sum := 0 for _, i := range v { sum += i } if sum == n { out = append(out, v) } } return out } 调试输出 1 2 3 4 5 6 7 ❯ ./c3 -sum 15 -size 2 [10 7 -5 4 8 16 35 -30 91] [[7 8]] ❯ ./c3 -sum 15 [10 7 -5 4 8 16 35 -30 91] [[10 35 -30] [-5 4 16]] 工程优化 上面是算法的解释,工程实现的时候可以把选择和过滤结合在一起做,提升代码的时间/空间性能。 ...

December 13, 2021 · datewu

合并图片

填写某政府表格时候,需要把多个图片合并为一张图片。 用Photoshop应该很好解决,但是本地没有安装。于是网上查了一下用imageMagick也可以解决。 meat Appending images vertically in ImageMagick 1 2 3 4 5 # vertical stacking (top to bottom): convert -append 1.jpeg 2.jpeg 3.jpeg out.jpg # horizontal stacking (left to right): convert +append 1.jpg 2.jpg out.jpg ps 另外这篇循环播放gif图片也用到了imageMagick。

December 5, 2021 · datewu

查看Wi-Fi密码

在苹果电脑上使用终端security命令查看Wi-Fi密码: 1 security find-generic-password -wa 'your wifi-ssid' 在弹出的系统对话框中输入正确的用户名和密码,终端即可以看到Wi-Fi密码。 ps. 除了当前连接的Wi-Fi,系统所有保存过的Wi-Fi密码都可以通过security命令查到。

December 1, 2021 · datewu

 重新安装macport

updated: 好像是因为我安装了ripgrep所以会一直更新cargo-c依赖。 不知道为啥每次sudo port -v upgrade outdated 都会重新安装cargo-c, 进而会安装编译rust。 编译rust很费时间和CPU风扇。 所以我就卸载了rust和一众依赖,后面特意又卸载了cargo-c。但是每次upgrade outdated cargo-c又回来了,很是烦人。 google一圈后,决定重新安装macport 清理安装包 尝试clean 所有的安装包: 1 2 3 4 5 6 7 8 9 10 11 12 sudo port uninstall cargo-c sudo port -v selfupdate sudo port -f clean --all all sudo rm -rf /opt/local/var/macports/packages/* sudo rm -rf /opt/local/var/macports/distfiles/* sudo rm -rf /opt/local/var/macports/build/* port echo leaves sudo port uninstall leaves sudo port -f uninstall inactive ## SURPRISE! after upgrade, `cargo-c` come back. sudo port upgrade outdated 卸载macport 参考官网协助步骤: ...

November 29, 2021 · datewu

fish shell

今天在hacker news上闲逛,又看到有人推销fish。心想马上就2022年了,不如换个shell耍耍。 其实早在2013年就接触过fish,那个时候自己比较菜,工作的时候很多bash脚本在fish上都不能使用,所以就放弃fish。 安装 安装fish 1 2 3 sudo port install fish sudo chpass -s /opt/local/bin/fish ${USER} cat /etc/shells 退出zsh,重启terminal 安装插件 oh-my-fish / fisher 1 2 3 4 5 6 curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install > install fish install --path=~/.local/share/omf --config=~/.config/omf # 可能出现 https://git.io无法访问的问题 curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher autojump/ j 1 2 3 4 5 6 7 8 sudo port uninstall autojump git clone https://github.com/wting/autojump.git cd autojump/ ./install.py cd repo/github/autojump/ vi .config/fish/config.fish j home nvm 1 2 3 4 5 6 7 8 sudo port uninstall nvm fisher install jorgebucaran/nvm.fish nvm install latest nvm list nvm --version #nvm use v17.1.0 # Now using Node v17.1.0 (npm 8.1.2) ~/.local/share/nvm/v17.1.0/bin/node node --version fisher plugins 1 2 3 4 5 fisher install IlanCosman/tide@v5 fisher install PatrickF1/fzf.fish fisher install franciscolourenco/done 配置 PATH 1 2 3 echo $PATH fish_add_path /Users/r/go/bin fish_add_path /opt/local/bin alias 默认ls命令对文件和目录没有做颜色的区分,可以使用alias ls='ls -G'加上颜色选项:) ...

November 26, 2021 · datewu

clickhouse初始化

总体来看clickhouse的ddl操作方式和mysql很像。比如use database_name, create user ... identified by ''等。 server docker run 启动clickhouse服务: 1 docker run -d --name clickhouse-server -p 8123:8123 -p 9000:9000 --ulimit nofile=262144:262144 yandex/clickhouse-server:21.8.10.19 default user权限 默认defualt 用户不能添加新的用户,需要修改default权限,否则会报错Code: 497. DB::Exception: Received from localhost:9000. DB::Exception: default: Not enough privileges. To execute this query it's necessary to have the grant CREATE USER ON *.*. : 1 2 3 4 5 6 7 docker exec -it clickhouse-server bash apt update -y apt install vim vi /etc/clickhouse-server/users.xml # update <access_management>1</access_management> exit docker restart clickhouse-server ...

November 22, 2021 · datewu

用户线程调度模型

一般来说多线程3种并发模型: N:1, 把n个用户线程(Green threed)映射到一个操作系统的线程(OS Threed)上。 这种模型的优点是 用户线程之间的上下文切换(context switch)会非常快, 缺点是不能充分的运用多核CPU资源(一个OS Thread只能在一个CPU上); 2. 1:1, 每个用户线程映射到一个操作系统线程上。 这种和第一种的优缺点正好相反。1:1 可以充分利用多核处理器资源,但是上下文切换很慢。 M:N,把M个用户线程映射到N个操作系统线程上。 这种结合了前面两种模型的优点,同时规避了他们的缺点。 M/G/P golang runtime主要通过抽象出Machine/Processor/Groutine三种对象,和一些算法(steal)实现了M:N模型。 Machine M对应操作系统线程,代表被操作系统管理的线程资源。 Goroutine G对应用户线程(Goroutine),包含了stack,指令指针,还有一些会影响这个Goroutine调度的关键信息,比如有关的channel。 Processor P对应本地逻辑调度器上下文(context),是调度算法具体的执行对象,主要用来处理steal和hand-off等算法。 demo normal 上图中,我们有2个M(OS Thread),每个M都有一个本地的context(P),都在运行一个goroutine(G)。 有几点需要说明一下: M必须得到一个P才能运行goroutine里面的指令; P的数量等于环境变量GOMAXPROCS的值, 一般等于宿主机的处理器核心数; 灰色的goroutine没有在running,但是已经准备好被调度了。他们所处的队列叫runqueues,每当执行的go statement指令时,新的goroutine就会加到runqueue的尾部; 每个P都有自己本地runqueue。 (sys)call / hand-off M0把自己的context给了M1,流程是这样的: M0执行G0上的某条syscall指令; M0放弃P进入block状态,M1得到并继续执行P调度算法,可能去执行另外某一个goroutine; syscall返回,M0因为没有P所以不能继续执行G0。现在M0需要去偷一个P执行G0,否则就把G0放到global runqueue里面然后把自己放回thread cahe去sleep。 也有几点需要单独说明: M1可能是scheduler为了处理syscall特意创建的,也可能是来自thread cache; 当P本地的runqueue为空时,P会从global runqueue拉取G;即使本地runqueue没有空,P也会定期的检查global runqueue里的goroutine。 正是因为要处理syscal/hand-off,所以即使GOMAXPROCS等于1,Go还是会启动多个OS线程。 stealing work 当P自己本地的runqueue空了,而且global runqueue也是空的时候, P就会去其他P偷掉对方一半的G,从而使得自己和其它P都能高效工作,提高整体性能。 参考文档

November 19, 2021 · datewu

纸巾和盆栽

月初的时候同事抱怨公司没有纸巾了,有点儿不方便。 八卦一阵后,原来是说上个月团建超预算了,下个月才有经费采购纸巾。估计还要等20多天。 慢慢的大家的纸巾都用完了,私下的抱怨也越来越多。 到了月中也就不怎么抱怨了,毕竟才几块钱的东西,大家基本上都自己买了。 本来事情很简单过去了。不想前几天公司的老大在办公室逛的时候说了一句,这些盆栽有的已经枯了,要找人修一修了。 然后今天办公室的盆栽就都换新了: 有一说一,这些盆栽挺漂亮的。 不过公司要是能把没有纸巾的问题解决了,赏花的时候心里会更舒服些,不要辜负了绿油油漂亮的盆栽。 ps. 我也不敢提纸巾的时候,忍一忍就过去了哈。 pps. 下午接到通知,大老板要从上海过来。公司还请了保洁阿姨搞卫生。可能是特批了一笔经费吧。

November 19, 2021 · datewu

循环播放gif图片

install 首先使用macport安装 imagemagick软件包,因为macport是编译安装软件包,所以安装过程会比较久(~9min)。 更加习惯homebrew的可以参考 官网imagemagick download 安装。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ❯ sudo port install imagemagick Password: ---> Computing dependencies for ImageMagickWarning: cltversion: The Command Line Tools are installed, but MacPorts cannot determine the version. Warning: cltversion: For a possible fix, please see: https://trac.macports.org/wiki/ProblemHotlist#reinstall-clt The following dependencies will be installed: aom brotli .... .... . . ---> Activating webp @1.2.1_0 ---> Cleaning webp ---> Fetching archive for ImageMagick ---> Attempting to fetch ImageMagick-6.9.11-60_1+x11.darwin_21.x86_64.tbz2 from https://packages.macports.org/ImageMagick ---> Attempting to fetch ImageMagick-6.9.11-60_1+x11.darwin_21.x86_64.tbz2 from https://pek.cn.packages.macports.org/macports/packages/ImageMagick ---> Attempting to fetch ImageMagick-6.9.11-60_1+x11.darwin_21.x86_64.tbz2 from https://kmq.jp.packages.macports.org/ImageMagick ---> Fetching distfiles for ImageMagick ---> Attempting to fetch ImageMagick-6.9.11-60.tar.xz from https://distfiles.macports.org/ImageMagick ---> Verifying checksums for ImageMagick ---> Extracting ImageMagick ---> Configuring ImageMagick ---> Building ImageMagick ---> Staging ImageMagick into destroot ---> Installing ImageMagick @6.9.11-60_1+x11 ---> Activating ImageMagick @6.9.11-60_1+x11 ---> Cleaning ImageMagick ---> Updating database of binaries ---> Scanning binaries for linking errors ---> No broken files found. ---> No broken ports found. ~ took 8m49s convert 修改gif循环次数,当loop为0时则关闭了gif的循环播放。 ...

November 18, 2021 · datewu