2

*から+、そして最終的には からどのように構築できるかを考えていました。次に、より低い関数 b を使用するという同じパターンを適用して、ハイパーネスが増加し続ける超乗算関数の階段を得るという同じパターンを適用する別の方向に+進みます。そこで私は、増え続けるハイパーオペレーターの無限リストをコーディングしてみることにしました。私はこれを思いつきました、これはかなり近いです!:inc(f a b)

(defn operator-staircase
  []
  (iterate
   (fn [f]
     (fn [a b]
       (loop [bottom b
              result a]
         (if (>= 0 bottom)
           result
           (recur
            (dec bottom)
            (f a result))))))
   (fn [a b]
     (inc b))))

(def ops (operator-staircase))
((nth ops 0) 3 5) ;; -->  6  (inc is arity one so it must ignore one of the args?)
((nth ops 1) 3 5) ;; -->  8  (correct addition)
((nth ops 2) 3 5) ;; -->  18  (oops, one off!  otherwise correctly multiplies.)  
                                Basically implements (fn [a b] (* a (inc b)))
((nth ops 3) 3 5) ;; ---->  1092 (Wow)

どうすればいいのかわからないのは、イニシャルresultを一般的な方法で定義することだけです! ちょっとうまくいくので作っただけaですが、たとえば足し算は0、掛け算は1でなければなりません。

result上記のループでの初期値を定義して、すべてのケースで一般的な方法で機能するようにするにはどうすればよいですか?

前もって感謝します!

4

2 に答える 2

1

から始めたい場合はinc、単項演算子のみを意味のある形で定義できると思います。したがって、0番目のステップは「1つ追加」です。最初のステップは「N回:1つ追加」です。これは基本的に#(+ % %);です。2番目のステップは「N回:Nを追加」です。これは#(* % %);です。3番目のステップは「N回:Nを掛ける」です。これは#(pow % %)...などです。

二項演算子を定義したい場合は、から+ではなく、から始めincて、残りは同じように導出すると思います。

于 2013-03-21T06:05:09.647 に答える
0

アマロイの言うことは正しいと思います。これがあなたのシーケンスの私のバージョンです+。 amalloy によって提案された から始まります。あなたのものとの他の違いは、カウンター変数が at(dec b)ではなく at で始まることですb。その理由は、たとえばa*3a自分自身に 3 回足す」と考えても、これはまだ足し算機能 (すなわちa+a+a) の 2 回の適用に過ぎないからです。これらの変更により、期待どおりの結果が得られます。

(def operator-staircase
  (iterate
    (fn [f]
      (fn [a b]
        (loop [acc a
               counter (dec b)]
        (if (>= 0 counter)
          acc
          (recur (f a acc) (dec counter))))))
    +))

;; in comments, * is multiplication, ** is exponentiation (chained multiplication), *** is chained exponentiation, etc
(println ((nth operator-staircase 0) 3 2)) ; 5 = 3+2 = (inc (inc 3)))
(println ((nth operator-staircase 1) 3 2)) ; 6 = 3*2 = 3+3
(println ((nth operator-staircase 2) 3 2)) ; 9 = 3**2 = 3*3 = 3+3+3
(println ((nth operator-staircase 3) 3 2)) ; 27 = 3***2 = 3**3 = 3*3*3
;(println ((nth operator-staircase 4) 3 2)) ; takes too long to compute, but presumably 7625597484987 = 3****2 = 3***3 = 3**(3**3)
(println ((nth operator-staircase 0) 2 3)) ; 5 = 2+3 = (inc (inc (inc 2)))
(println ((nth operator-staircase 1) 2 3)) ; 6 = 2*3 = 2+2+2
(println ((nth operator-staircase 2) 2 3)) ; 8 = 2**3 = 2*2*2 = 2+2+2+2
(println ((nth operator-staircase 3) 2 3)) ; 16 = 2***3 = 2**(2**2) = 2*2*2*2

最初の数回の反復を少し分解してみましょう。

(defn apply-n-times [f n arg]
  (if (= n 0) arg
    (recur f (dec n) (f arg))))

(defn plus [m n]
  (apply-n-times inc n m))

(defn times [m n]
  (apply-n-times (partial plus m) (dec n) m))

(defn exp [m n]
  (apply-n-times (partial times m) (dec n) m))

(defn expexp [m n]
  (apply-n-times (partial exp m) (dec n) m))

(dec n)繰り返しますが、ではなく時間を適用する必要がありますn。時間を適用した場合n、3 番目の引数はすべてではなく、 の場合は 0、 のtimes場合は 1 である必要があるため、均一性はありません。expm

このapply-n-times関数を使用すると、オペレーターの階段をもう少し簡潔に定義できます。

(def os2
  (iterate
    (fn [f]
      (fn [m n]
        (apply-n-times (partial f m) (dec n) m)))
    +))

これにより、前の定義と同じ結果が得られます。しかし、私はまだ一歩下がって、同じ順序+でを定義することはできませんでした。と上記の他の関数( 、、 )incの違いを見ると、構造が同じではないことがわかると思います。plustimesexpexpexp

于 2013-03-22T14:26:42.853 に答える