Header

∇RDECODE N
  R2N

∇RX ENCODE N
  R(X2)N

∇RENCODE32 N
  R(322)N

∇RENCODE64 N
  R(642)N

⍝ example
AENCODE64 865940890845960854
0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 1 1 0 1 1 1 1 1 0 1 1
      0 1 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0
      DECODE A
8.659408908E17 ⍝ GG

正常情況下都会这么用 loop 写吧

∇RA ADD B;C
  ⍝ BINARY ADDITION
  NOTEST/BEGIN
  DERR/(A=A=1)B=B=1
BEGIN:
  ⍝ RESET OVERFLOW
  OVERFLOW0
LOOP:AA+B
  ⍝ FIND CARRY
  C2=A
  (0=+/C)/END
  A[C/⍳⍴C]0
  ⍝ CHECK OVERFLOW
  OVERFLOWOVERFLOW1=''C
  B(C)1C
  LOOP
END:
  RA

说白了就是进位法。

不过发现了一个规律沒有

      A1 0 0 1 0 1 1 0 1 1 1 0 1 1 1 1
      B1 0 1 0 1 1 0 0 0 0 1 0 0 0 0 1
      A+B
2 0 1 1 1 2 1 0 1 1 2 0 1 1 1 2
      A ADD B
0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0

单个的 “2” 会变成 “10”,“12” 变成 “100”,“1112” 会变成 “10000”,“22” 则是 “110”。

这样看來根本不用 loop 麻。

      C
1 0 0 1 1 2 0 2 0 1 1 1 2
      1 1 0 1 0 0 1 1 1 1 0 0 0C
┌─┬───┬─────┬─┬─┬─┬───────┐
10 01 1 20201 1 1 2
└─┴───┴─────┴─┴─┴─┴───────┘
      ZC>0
      Z
1 0 0 1 1 1 0 1 0 1 1 1 1
      (1Z)-Z
¯1 0 1 0 0 ¯1 1 ¯1 1 0 0 0 0
      (¯1Z)-Z
0 1 0 ¯1 0 0 1 ¯1 1 ¯1 0 0 0
      |(¯1Z)-Z
0 1 0 1 0 0 1 1 1 1 0 0 0
      1,1↓|(¯1Z)-Z
1 1 0 1 0 0 1 1 1 1 0 0 0
      (1,1↓|(¯1Z)-Z)C
┌─┬───┬─────┬─┬─┬─┬───────┐
10 01 1 20201 1 1 2
└─┴───┴─────┴─┴─┴─┴───────┘
      ¨(1,1↓|(¯1Z)-Z)C
┌─┬───┬─────┬─┬─┬─┬───────┐
10 02 1 10202 1 1 1
└─┴───┴─────┴─┴─┴─┴───────┘
      A ADD B
1 0 1 0 0 0 1 0 1 0 0 0 0
      ¨¨(1,1↓|(¯1Z)-Z)C
1 0 2 0 2 0 2
      2=⊃¨¨(1,1↓|(¯1Z)-Z)C
0 0 1 0 1 0 1
      K¨(1,1↓|(¯1Z)-Z)C
      2=⊃¨K
0 0 1 0 1 0 1
      (2=⊃¨K)/K
┌─────┬─┬───────┐
2 1 122 1 1 1
└─────┴─┴───────┘
      {(⍵)0}¨(2=⊃¨K)/K
┌─────┬─┬───────┐
0 0 000 0 0 0
└─────┴─┴───────┘
      Z{(⍵)0}¨(2=⊃¨K)/K
      Z
┌─────┬─┬───────┐
0 0 000 0 0 0
└─────┴─┴───────┘
      K
┌─┬───┬─────┬─┬─┬─┬───────┐
10 02 1 10202 1 1 1
└─┴───┴─────┴─┴─┴─┴───────┘
      K[2=⊃¨K]Z
      K
┌─┬───┬─────┬─┬─┬─┬───────┐
10 00 0 00000 0 0 0
└─┴───┴─────┴─┴─┴─┴───────┘
      K
1 0 0 0 0 0 0 0 0 0 0 0 0

于是有 version1

∇RA ADDK B;C;B;T;K
  CA+B
  NC>0
  K¨(1,1↓|(¯1N)-N)C
  T2=⊃¨K
  K[T]{(⍵)0}¨T/K
  T(T)1T
  K[T]{1,((⍵)-1)0}¨T/K
  K∊⌽¨K
  RK

试一试

      A ADDK B
1 0 1 0 0 0 1 0 1 0 0 0 0 ⍝ seems ok
1 1 1 ADDK 1 1 1      
0 0 0

GG, WTF?

      AB  1 1 1
      A+B
2 2 2
      CA+B
      K¨(1,1↓|(¯1N)-NC>0)C
      K
┌─────┐
2 2 2
└─────┘

額⋯⋯

说明 2 要額外做 partition。

那么干脆就一开始先 reverse 好了

于是最后版本

∇RA ADD B;C;N;I
  CA+B
  NC>0
  R((C=2)1,1↓|(¯1N)-N)C ⍝ Partition
  I2=⊃¨R ⍝ Find pattern "1*2"
  R[I]{(⍵)0}¨I/R ⍝ substitution
  OVERFLOW''⍴⌽I
  I(-⍴I)¯1I ⍝ carry
  R[I]{1,((⍵)-1)0}¨I/R
  R⌽∊R

试试

      1 1 1 ADD 1 1 1
1 1 0
      OVERFLOW
1