北緯35.65858東経139.745433という緯度経度データと、E9139659937288という1つの文字列で表すGeo3x3(ジオ・スリーバイスリー)との相互変換をIchigoJamだけでできます!
IchigoJam R と IchigoJam S で実行している様子。Rだとエンコードとデコードがそれぞれ4秒/3秒、Sで30秒/17秒、がんばって変換している様子がかわいいですね!SでもVIDEO0を使うと3倍速になるので、悪くない速度です。
今回扱う緯度経度は360を超えないので、正数部を3桁、小数部を17桁とする20桁の固定小数として扱うことにしました。102コの配列を使って5つの固定小数を変数として保持します。 A,B,Cで変数を指定して呼び出すプログラムを作ってGSB(ゴーサブ)で呼び出す形にするとスッキリ書けます。
足し算(@ADD)、引き算(@SUB)、表示(@SHOW)、一桁の掛け算(@XMUL)、一桁の割り算(@XDIV)、割り算(@DIVX)、コピー(@A2B)をまとめました(プログラミングの世界で、ライブラリと呼びます)
100 @ADD:FORI=0TON-1:[C+I]=[A+I]+[B+I]:NEXT:A=C 110 @NORM:FORI=N-1TO1STEP-1:[A+I-1]=[A+I-1]+[A+I]/10:[A+I]=[A+I]%10:NEXT:RTN 150 @SUB:FORI=N-1TO0STEP-1:IF[A+I]<[B+I]&&I>0[A+I-1]=[A+I-1]-1:[A+I]=[A+I]+10 170 [C+I]=[A+I]-[B+I]:NEXT:RTN 200 @SHOW:?[S];[S+1];[S+2];".";:FORI=3TON-1:?[S+I];:NEXT:?:RTN 400 @XMUL:FORI=N-1TO0STEP-1:[A+I]=[A+I]*X:NEXT:GOTO@NORM 450 @XDIV:FORI=0TON-1:D=[A+I]%X:[A+I]=[A+I]/X:IFI<N-1[A+I+1]=[A+I+1]+D*10 460 NEXT:RTN 470 @DIVX:X=0 480 GSB@SUB:IF[C]<0:RTNELSEX=X+1:A=C:CONT 500 @A2B:FORI=0TON-1:[B+I]=[A+I]:NEXT:RTN
N: 桁数を指定
I, D: 内部で使用する
あとは、このライブラリを使ったエンコードとデコードを実装するだけです!
1 'GEO3x3 encode 10 CLV:N=20:L=14 20 LET[20],0,3,5,6,5,8,5,8 25 LET[40],1,3,9,7,4,5,4,3,3 'main 30 LET[0],1,8,0:[21]=[21]+9:A=20:GSB@NORM 35 IF[40]>=0?"E";ELSE?"W";:LET[60],1,8,0:[40]=-[40]:A=60:B=40:C=40:GSB@SUB 40 FORJ=1TOL-1 50 A=0:X=3:GSB@XDIV 60 A=20:B=60:GSB@A2B:A=60:B=0:C=80:GSB@DIVX:Y=X 70 A=40:B=60:GSB@A2B:A=60:B=0:GSB@DIVX 80 ?X+Y*3+1; 90 A=0:B=60:GSB@A2B:A=60:GSB@XMUL:A=40:B=60:C=40:GSB@SUB 95 A=0:B=60:GSB@A2B:A=60:X=Y:GSB@XMUL:A=20:B=60:C=20:GSB@SUB 99 NEXT:?:END
10行でレベル(Geo3x3の桁数)、20行、25行で緯度経度を配列へ設定するとGeo3x3が表示されます。ちょっと読みづらいですが、ライブラリを呼び出してる感が伝わると思います。
アルゴリズム(手順)は同じなので、JavaScript版やその他49言語のと同じなので、見比べてみましょう!(src on GitHub)
こちらはデコードプログラム
1 'GEO3x3 decode 10 CLV:N=20 12 S="E9139659937288" 'main 14 F=ASC(S)=87 16 LET[0],1,8,0 18 FORJ=1TOLEN(S)-1 20 M=ASC(S+J)-49:?M+1 22 X=3:A=0:GSB@XDIV 24 A=0:B=60:GSB@A2B:X=M%3:A=60:GSB@XMUL:B=40:C=40:GSB@ADD 26 A=0:B=60:GSB@A2B:X=M/3:A=60:GSB@XMUL:B=20:C=20:GSB@ADD 28 NEXT 30 X=2:A=0:GSB@XDIV 40 A=0:B=20:C=20:GSB@ADD 50 A=0:B=40:C=40:GSB@ADD 60 LET[80],0,9,0:A=20:B=80:C=20:GSB@SUB 70 IF F LET[80],1,8,0:A=40:B=80:C=40:GSB@SUB 80 S=20:GSB@SHOW:S=40:GSB@SHOW 90 END
どちらのプログラムもライブラリと合わせて1KBに収まっています!
固定小数ライブラリをマシン語化して高速化、効率化してみるのも楽しそう!(Armマシン語入門 / RISC-Vマシン語入門)
サポートプログラミング言語、50言語達成!
と思った矢先、なんと、COBOL実装のプルリク!
変数の桁数指定や、COMPUTEとEND-COMPUTEで終わる計算がシビレます!
プログラミングの世界は広大ですよ。