3
(2&*~) 15 7 3 1 

以上が台詞です。最後はトレースと最終結果です。このフレーズがモナドであることは理解しています。〜のおかげで、左と右の引数があることも理解しています。'15 7 3 1(2&*) 15 7 3 1' を実行すると、同じ出力が発生します。また、右の表は 1、3、7、15 の 2 の累乗であり、他のエントリは 2 の累乗の基数倍であることがわかりますが、その理由がわかりません。

関連する注意事項として、これは Rosetta Code Web サイトのエトピア乗算からのフレーズです (実際、これも同様に、私がそれを理解しようとしてここまでたどり着きました) および '(1>.<.@-:)^: a:' はフレーズです。

(1>.<.@-:)^:a: 27
27 13 6 3 1

しかし、 (1>.<.@-:)^: 27 はそれ自体のボックス化されたバージョンを返し、27 回実行されると予想します。

関連する 3 つの質問の最後 (これらはすべてエトピア乗算コードの分解に関連しています) では、完全なコードは次のように与えられます。

double =:  2&*
halve  =:  %&2           NB.  or the primitive  -:
odd    =:  2&|

ethiop =:  +/@(odd@] # (double~ <@#)) (1>.<.@halve)^:a:

そしてそれは次のように自明に置き換えることができます:

ethiop =:  +/@(2&|@] # (2&*~ <@#)) (1>.<.@-:)^:a:

そして、それはうまくいきます!成功に打ちのめされた私は、コマンド ラインで動作するモナド double があると思ったとき、完全に崖から落ちました。

+: 98
196

また、double 演算子は、定数が付加された double よりも高速である必要があります。おそらく、double は単にシフトするだけなので、

ethiop =:  +/@(2&|@] # (+:~ <@#)) (1>.<.@-:)^:a:

うまくいくでしょう...しかし、そうではありません。

大文字や接続詞などを試しましたが、何も機能せず、常に「ドメイン エラー」と表示されます。私が得られない方法で倍増テーブルを作成するために、コードが動的に呼び出されるモナドに依存していると考え始めています。

唯一の良い点は、J 動詞の奇数が奇数のテストとは何の関係もないことです。

プログラムがどのように機能するかについての英語の説明を付けて、誰かが私にこれらのことを説明できますか? アルゴリズムがどのように機能するかではなく、アルゴリズムをどのように実装するかです。1970 年に IBM 1130 APL で遊んでいたときのことを思い出します。これは、8k ワードで実行される APL インタープリターであり、言うまでもなく、制限がありました。たとえば、ロールはありましたが、取引はありませんでした。インタープリターは、メモリから段階的に出入りし、1130 はコード オーバーレイをサポートし、サブルーチンをグループに分割し、あるグループが別のグループを呼び出すと、新しいグループをディスクからロードします (はい、8k での疑似スワッピング)。そこで、さまざまなスキームを使用して、deal のバージョンを作成しました。ランダムに、シークせずにフェーズ インおよびフェーズ アウトできるバージョンを見つけました。他と同じように高速です。自分が何をしているのかわからなかったので、シークせずに実行されるものになるまで、ラヴェルや無意味な代入を追加し、行をまたがってステートメントを分割したり、それらを組み合わせたりし続けました。(シークしていた 52 取引 52 には 45 秒かかる場合があります)。

そして昨夜、J で 150,000 番目のフィボナッチ数を計算しました。これは 64 ビット バージョンでなければならず、1 時間 17 分かかりました。私は正確な算術演算を使用しました。数字は 31349 桁で、1012838344936638038 で始まります...そして、1130 ではこれを計算することはできなかったことに気付きました。数字は適合しないため、そのうちの 3 つが必要であり、最大のものを作成しました。 32kの16ビットワードがありました。これができる言語を学びたいのですが、ドキュメントに欠けているものがあります。

 trace '(2&*) 15 7 3 1' 
 --------------- 4 Conj -------
 2
 &
 *
 2&*
 --------------- 3 Adverb -----
 2&*
 ~
 2&*~
 --------------- 8 Paren ------
 (
 2&*~
 )
 2&*~
 --------------- 0 Monad ------
 2&*~
 15 7 3 1
 491520 229376 98304 32768
   1920    896   384   128
    120     56    24     8
     30     14     6     2
 ==============================
 491520 229376 98304 32768
   1920    896   384   128
    120     56    24     8
     30     14     6     2

フィボナッチ 脚注:

]t150k=:6!:2 'a150k =: $ ":r150k=: {:  (,+/@(_2&{.) )^:150000 (0x 1x)'
4631.62

0 60 60 #: t150k
1 17 11.6167
r150k
10128383449366380384728502706681008427227914006240871521944866167854579423510169
50198752571599303492471943589300904953648270811064370506598260395645679940891823
17307901573781852234222080308236027906733606532470814177610613237408102006595571
1949713927351702...
a150k
31349
4

2 に答える 2

5

答えはBond (&)の下に文書化されており、2項使用のために次の ID が示されています。

x m&v y ↔ m&v^:xy

あなたの例では、m は2、v は*であり、x と y は両方とも 4 つの数値のリストです15 7 3 1

等式の右側の言い回しには^:x("to the power x") が含まれます。これは、動詞を x 回適用することと同じです。動詞 is 2&*so 15回適用されます。しかも七回。しかも三回。また、一度。これら 4 つのアプリケーションの結果は、出力の 4 つの行を構成します。

3 番目に注目し、括弧を使用して強調すると、次のようになります。

   (2&* (2&* (2&* (15 7 3 1))))
  120 56 24 8

これはと同じです

   (2&*)^:3 (15 7 3 1)
120 56 24 8

これはと同じです

   (3) 2&* (15 7 3 1)
120 56 24 8

3 までの非負の整数をすべて適用してパターンを見てみましょう。

   (0 1 2 3) 2&* (15 7 3 1)
 15  7  3 1
 30 14  6 2
 60 28 12 4
120 56 24 8

この時点で、元のテーブルとの類似性により、そのテーブルの意味が理解できるようになる場合があります。

   (15 7 3 1) 2&* (15 7 3 1)
491520 229376 98304 32768
  1920    896   384   128
   120     56    24     8
    30     14     6     2

同じことが起こっています。より高い数値を指定したため、より頻繁に発生しています。

于 2011-10-17T03:22:09.707 に答える
2

これまでに誰も回答していないため、これはあなたの質問への最初の刺し傷です。

副詞には長い左スコープがあります。

(2&*~) <-> ((2&*)~)

bond によって返される関数の 2 項ケースは、poweredです。

(x m&v y) <-> ((m&v)^:x y)

2&*適用されるたびに引数が 2 倍になるため、powered2&*はその引数に の累乗を掛けます2

(1>.<.@-:)^: 27動詞を定義します (^:接続詞であるため) が、実行しません。元の句foo^:a:には動詞と27引数がありました。収束するまで実行するだけですa:^:

モナ+:ディックはその引数を倍増しますが、 と の二項ケース2&*+:まったく関係がなく、交換することはできません。double~はフックの左側であり、常にダイアディカルに呼び出されることに注意してください。

唯一の良い点は、J 動詞の奇数が奇数のテストとは何の関係もないことです。

実際に2&| yはが奇数の場合、偶数の1場合は奇数のテストです。y0

12 ethiop 27さて、アルゴリズムが何をしているのかを平易な英語で説明するために、例としてフレーズごとに見ていきましょう:

+/@(2&|@] # (2&*~ <@#)) (1>.<.@-:)^:a:

フックです。フックでは、右部分は常にモナドであり、左部分は常にダイアドです。

(1 >. (<. @ -:)) ^: a:

Monad (<. @ -:)=floor @ halfは、その引数を半分にして切り捨て1 >. (<. @ -:その最小値を返します1^:a:収束するまで継続し、結果のリストを作成します。したがって、(1 >. (<. @ -:)) ^: a: 2727達するまで繰り返し半分になり1、降伏します。27 13 6 3 1

次に、フックの左半分を見てみましょう。 (2&|@] # (2&*~ <@#))は二項分岐であり、引数は前述のフックの左側の引数とethiop右側の部分の結果です。

2&|@]1、その右の引数が奇数の場合、0そうでない場合です。引数27 13 6 3 1の結果は1 1 0 1 1

(2&*~ <@#)再びフックです。<@# は単項的に に適用され27 13 6 3 1、長さをボックス化して を返し(<5)ます。次に、 に到達します2&*~。これは、見たように、2 進法で強化されているため、これは (~引数を切り替えた後)+:^:(<5) 12です。

f^:mmボックス化されている場合、回を実行し、長さの結果リストをf <: >m生成します (が空の場合を除き、収束するまで実行されます)。したがって、これは得られますmm12 * 2 ^ i.5

次に、フォークの中央部分は単に#であり、ブール値の左引数を使用して右引数を単純にフィルター処理します。この場合、12 * 27 が奇数である 2 のべき乗を残します。

   1 1 0 1 1 # 12 24 48 96 192
12 24 96 192

最後+/sum

   +/12 24 96 192
324
于 2011-09-19T14:33:54.423 に答える