2015年6月28日日曜日

短いコードの「お中元」

先日来、JulyさんでHP50G, HP Primeほかの入荷があった様で、徐々に販売されて居ります。
Amazonのレビューに、neuro_drive 様がレビューを投じておりました。

HP Primeは未だ、「日本語クイックリファレンス付き」ではありませんが、既に日本語マニュアルPDFがwebでも取り寄せる事が出来、冊子としての日本語クイックリファレンスが添付されるのは、もう暫く先になるのかも知れません (もっとも、あと5日でJuly、もしかして、何か動きがありや ?)。
一方、アベノタレナガシミクスで円安も進行、10月には消費税も上がるので、輸入製品の価格が高騰する事も予想されており、こうした製品が欲しい向きは、今のうちに買っておくのが良いのかも知れませんが、それはさておきます。

6月もそろそろ終わりですが、HP Prime使用の方に、ささやかながら「お中元」を。Clifford attractor というグラフィクスのコードです。
4つのパラメタ A,B,C,D を色々と変えてプログラムを実行すると、様々な意匠を表示します。

// title : Clifford attractor for HP Prime
// begin : 2015-06-22 19:29:08  
// note  : 

EXPORT Clifford(a, b, c, d)
BEGIN
// Clean the screen (G0)
RECT();

LOCAL i;
LOCAL x, y, xp, yp;
LOCAL xmin, xmax, ymin, ymax;
//LOCAL a, b, c, d;

//a := -1.4; 
//b :=  1.6; 
//c :=  1.0; 
//d :=  0.7;

Xmin := -3.2;
Xmax :=  3.2;
Ymin := -2.4;
Ymax :=  2.4;

x := 0.5;
y := 0.5;

FOR i FROM 1 TO 10000 DO
  PIXON(x, y, RGB(25, 128, 240));
  xp := SIN(a*y)+c*COS(a*x);
  yp := SIN(b*x)+d*COS(b*y);
  x  := xp;
  y  := yp;
END;

//  key wait loop
REPEAT UNTIL GETKEY() == -1;
FREEZE;

END;

ホーム画面から
Clifford(1.38, 1.65, 1.2, 0.7)
の様に打ち込んでやると、実行されます。 
 
HP Primeは、QVGAのカラー画面を持っていて、グラフ電卓のなかでは比較的高いグラフィクス機能を持っています。そして、pコードJITコンパイラでプログラムが実行されているらしく、プログラムの実行速度は割合早いものです。

エミュレータで実行すると、すぐにも実行結果が得られるのですが、それはPCのパワーが強力だからなので、実機で実行すると、どの程度になるのか、お知らせ戴くと有難く思います。

2015年6月14日日曜日

素晴らしい !「CLASSWIZ」の記事

先ずは、以下の記事をお読み戴き度。

異様に欲しくなった電卓の話 カシオCLASSWIZ - 週刊ASCII
http://weekly.ascii.jp/elem/000/000/339/339010/

開発者のホンネがみっちり詰まった、とても読み応えのある良い記事です。

そういや、CLASSWIZって、2 way powerでした。ここまで省電力で動くために回路設計を限界まで作りこんでいた、素晴らしい成果だった、と !
何故、2 way powerに拘ったのか ? それは、世界で広く使われる事を意識しているからです。「乾電池なんて近所のコンビニで買えるでしょうよ」という国は、実の所、そんなに多くはないのです。一方、太陽光ならば、広く世界を照らし出している。常に手元に置いて、すぐに使えるという理想を実現するのは、2 way power、だった。ウーン。流石は世界企業 !

で、大変素晴らしい取り組みであり、記事でありますが、当blogとしては、つぎのお言葉がチョット気になってしまいました。
 帰国してカシオの新入社員に聞いてみたところ「難しくて使いこなしていない。使っていたのはせいぜいLOGと三角関数だけだ」という返事が戻ってきたことに落胆し、どうにかせんといかんと討議をはじめた。

「電卓のいいところは、手軽で大事に扱わなくても大丈夫で、ポンと押したらすぐ出てくること。ものさしや鉛筆みたいに使えなければならない。そこを忘れて多機能に入ってしまうと、スマホに全部食われてしまう。電卓のいいところを残して、プラスアルファを作っていく必要があると思うんです」
ウーン。なるほど「高機能電卓」はウケが悪い ... 。
道理で、なかなかfx-5800Pの後継機が出ない、のか ?

どうせ鄙びた辺りの当blog、見ていないだろうから以下、好き勝手な事を書きます。

「多機能になるとスマホに喰われてしまう」いうのは、確かにそう感じる所もありますが、一方、高機能電卓にしても、スマホのタッチスクリーンよりも使いやすいボタン操作ですから、スマホとは別モノとして普及する余地はあるのだと思うのですヨ。

「難しくて使いこなしていない。使っていたのはせいぜいLOGと三角関数だけだ」という返事が戻ってきたことに落胆し、の所ですが、これは如何ともしがたい、遺憾な状況であります。
今日に至るも、関数電卓は未だに「エレキ計算尺」という位置付けに過ぎず、高機能電卓の存在意義は無くなってしまったのか ?
その昔、世界に初めて登場したグラフ電卓はCASIOのもので、液晶パネルの高解像度化が進む中で投入された、実にエポックな製品だった。ポケコンの次の製品世代であり、グラフ機能を盛り付ける事で、計算に対するリテラシイの向上につながるものかと期待されたため、発売に至ったのではないか。
グラフ電卓が、より高機能電卓の開発に拍車をかける事になったのですが、今日では「普及が見込めない」という理由からか、開発に積極性が無くなってきてしまった。

確かに、高機能電卓を欲しがる人なんて、ごく少数ではあります。しかし、TI, HPはそれでも作っているじゃありませんか !
そこで、CASIOにも、高機能電卓を出して欲しく思うのです。
計算リテラシイの向上に寄与するとなれば、例えばfx-5800Pの様にプログラム機能を盛り付けるとか (fx-5800Pも単4電池1本で動くスグレモノでした !)。そして、今日的には外部ストレージのパスを用意し、プログラム・データのPCとの共有を図る。fx-FD10 proがそうだった様に。

普及価格帯の関数電卓でもやることは沢山あるのは判りますが、高機能電卓もやって欲しいのです。

「頼むから、そんな悲しい事を言わないでくれよ ... 」

HP50GでZINTによる階乗計算が9999! まで計算できるという話なので、実行してみました

エミュレータでは割合早いそうですが、実機は結構掛かります。
ちなみに、9999!の「桁数」がどうなるのか。こんな事で求まる筈です。
50Gが計算中なので、TI83+でのプログラムを。

PROGRAM:LIMIT
:0→S
:For(I,1,9999)
:S+log(I)→S
:End
:Disp "FACTO",S

1から9999までの足し算ですが、流石に実行時間が掛かり、最終的に得られた値は、35655.45427 という値。これは log(9999!) の値なので、概算では 2.846259e35655 という値になります。桁数は、35656桁。なるほど、これではすぐに結果は出そうもありません。
今もって、50Gは計算中です。ホントに終わるのか心配になってきたヨ ... 。

で、最終的に 01時間28分 で計算が終わりました !

追記
実行時間の表記を変えました。

2015年6月11日木曜日

「Leapfrogs !」

「Leapfrogs」というゲーム(というかパズル ?)があります。

# ゲームの目的

一本の木の上に、右を向いたカエル(A)と左を向いたカエル(B)が4匹ずつ、並んでいます。カエルA, B の間には、カエル1匹が入るだけの狭い空間(_)があります。

    BBBB_AAAA

カエルA, B は、お互いに「向こう側」に行きたがっているのですが、細長い木の上なので、身動きが取れません。そこで、カエルをつついて移動させ、つぎの状態に持っていくのが、このゲームの目的です。

    AAAA_BBBB

1本の木の上なので、カエルをつつく事で、

  • のそのそと、となりのコマに移動できます
  • 一匹分のスペースをジャンプして、移動できます
どのカエルをつついて動かすか、その指示を与えるには、カエルの場所にある番号を指定します。

    123456789            ←場所 (インデクス)
    BBBB_AAAA        ←カエルの配置状態 (ステージ)

最初は、3, 4, 6, 7 のカエルのみが移動できます。例えば、ここで3のカエルをつついて移動させると、3に居たカエルは4のカエルをジャンプで飛び越し、5へ移動します。

    123456789            ←場所 (インデクス)
    BB_BBAAAA        ←カエルの配置状態 (ステージ)

こうしてカエルをつついて移動させ、最終的に

    123456789            ←場所 (インデクス)
    AAAA_BBBB        ←カエルの配置状態 (ステージ)

の状態に持って行きます。
慣れてきましたら、カエルを移動させる回数を出来るだけ少ない手順で行う方法を探求してみるのが面白いでしょう。
簡単なパズル・プログラムなので、高機能電卓でも十分楽しめるプログラムが作成できると思います。

この記事では、久しぶりにHP35Sで動くプログラムを作成しました。


# 使い方

HP35S では、文字列の加工が出来ないので、苦肉の策として16進数表示を使ってみました。空白の表示は「C」となっています。
  1.  [XEQ] L [ENTER] で起動
  2. C = 1 の様に、試行回数を表示
  3. つぎの書式でステージを表示

    123456789h    ←インデクス
    BBBBCAAAAh    ←「カエル」表示
  4. 移動対象のカエルをインデクスにて指定し、[R/S] を押して入力します
  5. 「上がり」状態になれば「CLEAR !」と表示され、最後に操作回数を表示して、プログラムは終了します
  6. 上がりでなければ、2. へ戻り、繰り返しになります
#  変数

C        試行回数
I, J    配列変数操作インデクス
M        移動するカエルの位置
S        空白の位置

Reg(1)...R(9)        ステージ状態


# プログラム

L001    LBL L
L002    DEC
L003    1
L004    STO I
L005    4
L006    STO(I)
L007    1
L008    STO+ I
L009    4
L010    STO(I)
L011    1
L012    STO+ I
L013    4
L014    STO(I)
L015    1
L016    STO+ I
L017    4
L018    STO(I)
L019    1
L020    STO+ I
L021    3
L022    STO(I)
L023    1
L024    STO+ I
L025    5
L026    STO(I)
L027    1
L028    STO+ I
L029    5
L030    STO(I)
L031    1
L032    STO+ I
L033    5
L034    STO(I)
L035    1
L036    STO+ I
L037    5
L038    STO(I)
L039    1
L040    STO C
L041    5
L042    STO S
L043    VIEW C
L044    PSE
L045    1.009
L046    STO I
L047    0
L048    16
L049    *
L050    RCL(I)
L051    +
L052    ISG I
L053    GTO L048
L054    1
L055    +
L056    +/-
L057    ENTER
L058    ENTER
L059    AAAACBBBBh
L060    x=y?
L061    GTO L092      ; 上がり判定
L062    R↓
L063    123456789h
L064    x<>y
L065    HEX
L066    STOP          ; 入力部分
L067    DEC
L068    STO M         ; 
L069    RCL S
L070    -
L071    ABS
L072    2
L073    xL074    GTO    L089      ; 入力が範囲外か ?
L075    RCL M
L076    RCL S
L077    x=y?
L078    GTO L089      ; 空き位置の指定 ?
L079    RCL M
L080    STO I
L081    RCL S
L082    STO J
L083    RCL(I)
L084    STO(I)
L085    3
L086    STO(I)
L087    RCL M
L088    STO S
L089    1
L090    STO+ C
L091    GTO L043
L092    1
L093    STO- C
L094    SF 10
L095    CLEAR !
L096    PSE
L097    CLEAR !
L098    PSE
L099    CLEAR !
L100    PSE
L101    CF 10
L102    VIEW C
L103    RCL C
L104    RTN

このプログラムでは両側に4匹ずつのカエルが配されています。この場合、最小の手数が24手になるとの事です。
詳しくは、次のサイト様で色々な解説がありますので、御参考下さい。

『カエル跳びゲーム』解答
http://math.a.la9.jp/akaeru.htm

かなり昔に、ポケコンでプログラムを作ったのですが、その時は「最小の手数が24手」というのが、どうにも判らんかったのでした。

グラフ電卓の愉しみ #2 - Pickover Attractor

グラフ電卓には、それなりのグラフィクス機能があります。簡単なプログラムで興味深いグラフィクスを描き出す「Clifford Attractors」のプログラムを作成してみました。

Clifford A. Pickover 氏によるアトラクタで、en wiki には、2DのClifford attractor、3Dの「Pickover attractor」がある、と書かれています。3Dの表示はPCでも少々手数が掛かってしまうので、2D表示で出来るClifford attractor について、行ってみました。
Clifford attractorについては、以下のサイトで例が示されています。

Clifford Attractor
http://paulbourke.net/fractals/clifford/

ここで紹介されているグラフィクスは高性能のコンピュータを使って描き出されたものですから、これがそのままグラフ電卓で再現できるわけではないのですが、大まかな所は十分に描き出される筈です。

先ずは、TI-83+ で描いてみました。プログラム自体は実に簡単ですが、結構時間が掛かります。

PROGRAM:ATTRCT
:AxesOff
:ClrDraw
:0.5→X:0.5→Y
:For(I,1,1000)
:Pt-On(X,Y)
:sin(AY)+Ccos(AX)→Z
:sin(BX)+Dcos(BY)→Y
:Z→X
:End

プログラムを実行する前に、細かい指定を行っておかないとなりません。

1. Clifford attractor では、A, B, C, Dの4つのパラメタを変換させる事で、様々な意匠が得られます。プログラム実行前に、変数A, B, C, Dを予め指定しておきます。

例)
1.32→A : 0.804→B : 2.568→C : 1.824→D

2. つぎに、グラフを描く範囲を指定しておきます。TI83+の場合、グラフ電卓の機能として描図領域の設定等を電卓のメニューから行います。X, Y共に、-4~+4の範囲で描くと、いい感じです。

ついでにHP50GのSysRPLで作成したものを掲載しておきます。UserRPLより断然早いのですが、それでも1分以上掛かってしまいますネ。
こちらの場合は、スタックにA, B, C, Dの数値を積み、プログラムを実行します。
描図範囲は PPAR を参照するので、プログラム実行前に[WIN]キー([Left-Shift]+[F2])で描図範囲を設定して下さい。

!NO CODE
!RPL

::

0LASTOWDOB!
CK2NOLASTWD
CK&DISPATCH1
#1111

  ::

  GETXMIN GETXMAX GETXMIN %-
  GETYMAX GETYMAX GETYMIN %-

  { LAM a LAM b LAM c LAM d LAM xmin LAM xrng LAM ymax LAM yrng } BIND

  CLEARLCD
  TURNMENUOFF

  80 131 MAKEGROB
  GROB>GDISP
  TOGDISP

  ' ID X PURGE
  %0.5 ' ID X CREATE
  ' ID Y PURGE
  %0.5 ' ID Y CREATE

  1000 0 DO
    LAM a ID Y %* %SIN LAM c LAM a ID X %* %COS %* %+
    LAM b ID X %* %SIN LAM d LAM b ID Y %* %COS %* %+
    ' ID Y STO ' ID X STO

    ID X LAM xmin %- LAM xrng %/ %131 %* COERCE
    LAM ymax ID Y %- LAM yrng %/ %80  %* COERCE
    PIXON3
  LOOP

  ABND
  ;
;
@


グラフ電卓の愉しみ #1 - Sierpinski gaskets

プログラムで描くグラフィクスという事で、今回は「Sierpinski gaskets」を御紹介。

TI-83+のマニュアルには、Sierpinski gaskets を「乱数を使う手法」で描くプログラムが掲載されています。
Sierpinski gasketsは「再帰図形」なので、再帰処理によって描く事が出来るのですが、TI-83+には再帰処理のメカがないため、乱数を使う手法を例示していたのでした。

HP50GでRPLを使うと、再帰処理のプログラムを作成できます。今回も懲りずにSysRPLで書いたプログラムを示します (もちろん、UserRPLでも書けます)。

ユーザーが使える「スタック」を用意する事で、BASICでも再帰処理のプログラムは書けると思います。Androidの「BASIC !」には、スタックのメカが用意されておりました。3DSのプチコンにもスタックのメカがあるそうです(藤堂様、多謝 !)から、再帰処理プログラムの作成は可能です、多分。
(こちゃこちゃしてしまい、当方、着手出来ず。申し訳ない。loadがガンガン上がって、頭から湯気が出ております ...)

!NO CODE
!RPL

::
  '
  ::
    {
      LAM ax LAM ay LAM bx LAM by LAM cx LAM cy LAM d
    } BIND

    LAM d #0= ITE
    :: 
      LAM ax 80 LAM ay #- LAM bx 80 LAM by #- DRAWLINE#3
      LAM ax 80 LAM ay #- LAM cx 80 LAM cy #- DRAWLINE#3
      LAM bx 80 LAM by #- LAM cx 80 LAM cy #- DRAWLINE#3
    ;

    ::  
      LAM ax LAM ay 
      LAM ax LAM bx #+ #2/ LAM ay LAM by #+ #2/ 
      LAM ax LAM cx #+ #2/ LAM ay LAM cy #+ #2/ 
      LAM d #1- LAM sier EVAL

      LAM ax LAM bx #+ #2/ LAM ay LAM by #+ #2/ 
      LAM bx LAM by 
      LAM bx LAM cx #+ #2/ LAM by LAM cy #+ #2/ 
      LAM d #1- LAM sier EVAL

      LAM ax LAM cx #+ #2/ LAM ay LAM cy #+ #2/ 
      LAM bx LAM cx #+ #2/ LAM by LAM cy #+ #2/ 
      LAM cx LAM cy 
      LAM d #1- LAM sier EVAL
    ;
    ABND
  ;

  { LAM sier } BIND

  CLEARLCD
  TURNMENUOFF

  80 131 MAKEGROB
  GROB>GDISP
  TOGDISP

  65 80 25 1 105 1 4
  LAM sier EVAL
  SetDAsTemp

  ABND
;
@



SysRPLで再帰大作戦

SysRPLで再帰処理を書くにはどうするのか、気になって居りました。

ここでは、再帰処理による階乗計算の例を示しておきます。

!NO CODE
!RPL

::
  { LAM n } BIND

  LAM n %0 %> 
  ITE 
    ::  LAM n DUP %1 %- ID facto %*  ;
    ::  %1 ;
  ABND
;
@


これをASM でコンパイルし、スタックに載っているSysRPLコードを「'facto' STO 」とやって保存すると使える様になります。CK2とか使っていないので、パラメタは決め打ちです。実数として明確にスタックに数を置き、引き続いてfacto と打ち込みます。
例えば、70の階乗を求めるには、「70. facto」とやってやります。70の後に少数点をつけて実数とするのです。

実は、局所変数に関数定義を束縛し、呼び出すという技法があります。

SysRPL Recursion Question - comp.sys.hp48
https://groups.google.com/forum/#!topic/comp.sys.hp48/JrtXN0bz1QU

上記ではAckermann functionの例が出ておりますが、こちらでは上と同じく階乗の例を示しておきます。

!NO CODE
!RPL

::
  '
  :: 
    { LAM n } BIND
    LAM n %0=
    ITE
      :: %1 ;
      :: LAM n %1- LAM facto EVAL LAM n %* ;
    ABND
  ;
  { LAM facto } BIND
  LAM facto EVAL
  ABND
;
@

冒頭の「'」は、以降のプログラム節 (「::」と「;」で括られたもの) をQuoteする、というものです。これにより、

  :: 
    { LAM n } BIND
    LAM n %0=
    ITE
      :: %1 ;
      :: LAM n %1- LAM facto EVAL LAM n %* ;
    ABND
  ;

の部分を実行(評価)せずに、「そのまま」の状態でスタックに置く、というイメージです。続く「{ LAM facto } BIND」によって局所変数(シンボル)facto に束縛します。
更に「LAM facto EVAL」で、factoシンボルに束縛されたプログラム節をEVALにて評価する事で、実行します。
最後は「ABND」で、BINDで束縛した局所シンボルスコープを脱し、プログラムの終了という具合です。