2017-02-20 2 views
2

(f 4)が、私は2つの変数を使用してみましたが、それはルール違反も256Lispの再帰的な正方形の利用1つの変数

を返す必要があり、27を返す必要があります。

再帰的に1つの変数しか使用できませんか?任意のアイデアを

おかげ

答えて

0

はい、これは可能です:

(defun f (n) 
    (cond 
    ((numberp n) 
     (f (cons n n))) 
    ((zerop (car n)) 
     1) 
    (t 
     (* (cdr n) 
     (f (cons (1- (car n)) 
        (cdr n))))))) 

トリックを使用すると、単一の変数に(数値の組を含む)任意のデータ構造を格納できるということです。また


、あなたは標準ライブラリからヘルパーを使用することができます。

(defun f (n) 
    (apply #'* 
     (loop repeat n collect n))) 

しかし、それは再帰を使用していません。あるいは単に:

(defun f (n) 
    (expt n n)) 
+1

alistで数値を乗算する場合は、APPLYではなくREDUCEを使用することをお勧めします。 APPLYは、最大長CALL-ARGUMENTS-LIMITのリストのみをサポートします。 –

1

私はCLを知らないが、私はClojureのと再帰を使用する他の言語を知っていますか。

1つのパラメータがアキュムレータとして機能するが、最初の呼び出しでのみ設定されるパラメータの場合、通常は別の関数でfをラップします。より簡潔に

(defun g (a n) 
    (if (zerop n) 
     1 
     (* a (g a (- n 1))))) 

(defun f (n) 
    ; I'm assuming you want the initial value of "a" to be 1 
    (g 1 n)) 

または、::

(defun f (n) 
    (let (g (fn (n) 
      (if (zerop n) 
       1 
       (* a (g a (- n 1)))))))) 
    ; Instead of f being recursive, f calls g, which is recursive 
    (g 1 n)) 

言い訳構文エラーこれを行う2(基本的に同じ)の方法があります。

+1

答えをありがとう。構文については、CL(http(http)で '(let((g(fn(n)...))...)'に '(labels((g(n)...) ://www.lispworks.com/documentation/HyperSpec/Body/s_flet_.htm) – coredump

+0

@coredump 'labels'?それは決して推測できませんでした。私はラップトップに乗るときにそれを修正します。ヘッドアップをありがとう。 – Carcigenicate

+0

はい。それは驚くべきことですが、歴史的な理由は面白いですし、コンテキストでも意味をなさないです:https://www.reddit.com/r/lisp/comments/k1tnl/where_does_the_special_form_labels_come_from/ – coredump

1

正気の選択となるカウントダウンを追加変数を使用していますが、これだけのためにただ一つの数値引数入力の契約を変更する必要はありません。あなたはそれを行うためのヘルパーを行うことができます。

(defun exptnn (n) 
    "Get the (expt n n)" 
    (check-type n integer) 
    (labels ((helper (acc count) 
      (if (zerop count) 
       acc 
       (helper (* acc n) (1- count))))) 
    (if (< n 0) 
     (/ 1 (helper 1 (- n))) 
     (helper 1 n)))) 

任意のヘルパーなしで解決するために、すでにそれを行うソリューションがあるので、一つの引数は可能ですが、私はそれがなくてBrainf*ckでのプログラミングのようなものであると言わなければならないだけで喜び!

1
CL-USER 15 > (defun f (n) 
       (labels ((g (m) 
         (if (zerop m) 
          1 
          (* n (g (1- m)))))) 
       (g n))) 
F 

CL-USER 16 > (f 0) 
1 

CL-USER 17 > (f 1) 
1 

CL-USER 18 > (f 2) 
4 

CL-USER 19 > (f 3) 
27 

CL-USER 20 > (f 4) 
256 

CL-USER 21 > (loop for i below 10 collect (f i)) 
(1 1 4 27 256 3125 46656 823543 16777216 387420489) 
1

これは、複数のパラメータとは機能が=+*logandashを除いて(使用されない溶液であり、それらができるようにlogandashは常に2番目のパラメータとして定数を取ることにも留意されたいです単項関数としても実装できます)。

考え方は、奇数/偶数ビットを使用して、明白な再帰的アプローチに必要な2つのパラメータを1つの整数で「隠す」ことです。

(defun pair (n) 
    (if (= n 0) 
     0 
     (+ (* 3 (logand n 1)) 
     (ash (pair (ash n -1)) 2)))) 

(defun pair-first (p) 
    (if (= p 0) 
     0 
     (+ (logand p 1) 
     (ash (pair-first (ash p -2)) 1)))) 

(defun pair-second (p) 
    (pair-first (ash p -1))) 

(defun subsec (p) 
    (if (= 2 (logand p 2)) 
     (- p 2) 
     (+ (logand p 1) 2 (ash (subsec (ash p -2)) 2)))) 

(defun pairpow (p) 
    (if (= (pair-second p) 1) 
     (pair-first p) 
     (* (pair-first p) 
     (pairpow (subsec p))))) 

(defun f (n) 
    (pairpow (pair n))) 

妥当な使用法はもちろんありません。確かに面白い運動。

関連する問題