Как да внедрим рекурсивна функция в Racket?

Опитвам се да създам функция, наречена lcm-from-factors, която изчислява най-малкото общо кратно на две числа (m и n). Входящите данни за функцията са m-co-groups и n-co-groups, които изброяват всички прости фактори и техните правомощия. Например за m= 2970 и n= 163 800 ще имаме:

m-ко-групи= '((2 1) (3 3) (5 1) (7 0) (11 1) (13 0)) n-ко-групи= '((2 3) (3 2) ( 5 2) (7 1) (11 0) (13 1))

Те се връщат от функция, наречена кофактор, която ми беше дадена. Написах кода, но функцията не се компилира, защото смятам, че не съм внедрил правилно рекурсията. Ще се радвам на всякаква помощ, за да разбера какво правя погрешно. Моят код е както следва.

    (define (lcm-from-factors m n)
        (let-values (((m-co-groups n-co-groups) (co-factor m n)))
            (define (recurse m-co-groups n-co-groups)
                (let* ((a (first(m-co-groups)))
                      (b (first(n-co-groups))))
                   (cond ((>= (rest(a)) (rest(b)))
                         (+ (expt (first(a)) (rest(a))) (recurse (rest(m-co-groups)) (rest(n-co-groups)))))
                         (else (+ (expt (first(b)) (rest(b))) (recurse (rest(m-co-groups)) (rest(n-co-groups))))))))))

person user2904796    schedule 10.02.2015    source източник
comment
От това, което виждам, (co-factor m n) трябва да се направи оценка на два списъка с процедури, тъй като прилагате елементи ((a) и (b)) и тези процедури трябва да произведат двойки, тъй като се опитвате да first резултатите?   -  person Sylwester    schedule 10.02.2015
comment
Да, функцията, която ми беше дадена, връща два списъка, както е показано за m=2970 и n=163 800.   -  person user2904796    schedule 10.02.2015
comment
Въпреки това не мога да попълня (първо (m-co-groups)) по някаква причина?   -  person user2904796    schedule 10.02.2015
comment
(m-co-groups) означава извикване на m-co-groups като процедура. Ако това не е процедура, ще получите грешка. Нито една от променливите никога не трябва да се извиква като процедури.   -  person Sylwester    schedule 10.02.2015
comment
Върнатият списък не е m-co-groups. Кофакторът е процедурата, която вярвам.   -  person user2904796    schedule 10.02.2015
comment
m-ко-групи= ’((2 1) (3 3) (5 1) (7 0) (11 1) (13 0)). Връща списък, където всеки елемент е двойка.   -  person user2904796    schedule 10.02.2015
comment
Отново.. Когато оградите променлива в скоби i Scheme, вие я третирате като процедура без аргументи.. Напр. ако a е (lambda () 10), тогава (a) става 10. Ако a е (2 1), получавате грешка, че (2 1) не е процедура, тъй като всъщност извиквате ('(2 1)) Предполагам, че губите много грешки, като премахвате излишните скоби. например (first m-co-groups) вместо (first (m-co-groups)), което би трябвало да изисква m-co-groups да бъде процедура, както + е .   -  person Sylwester    schedule 10.02.2015
comment
Благодаря ви, премахнах всички допълнителни скоби. Грешката все още е там. Съобщението за грешка е както следва:   -  person user2904796    schedule 10.02.2015
comment
начало (възможно имплицитно): няма израз след поредица от вътрешни дефиниции   -  person user2904796    schedule 10.02.2015
comment
Това е така, защото дефинирате рекурсивна процедура, но не я използвате, като извиквате (recurse m-co-groups n-co-groups) като последен израз в let-values. Можете да направите и двете в една форма с име let (let recurse ((m-co-groups m-co-groups) (n-co-groups n-co-groups) ... )   -  person Sylwester    schedule 10.02.2015


Отговори (1)


Следното е стъпало, за да започнете. Кодът обработва конкретната ситуация, при която m и n имат еднакви прости множители. Ваша работа е да разберете как да се справите с другите случаи.

#lang racket
(require math/number-theory)

(define (co-factor m n) (values (factorize m) (factorize n)))
(define (exponent power) (second power))
(define (base power)     (first power))

(define (lcm-from-factors m n)
  (let-values ([(m-co-groups n-co-groups) (co-factor m n)])
    (define (recurse m-co-groups n-co-groups)
      (cond
        [(and (empty? m-co-groups) (empty? n-co-groups))  1]
        [(empty? m-co-groups)                             'something-1]
        [(empty? n-co-groups)                             'something-2]
        [else
         (define a-power (first m-co-groups))
         (define b-power (first n-co-groups))
         (define a-base  (base a-power))
         (define b-base  (base b-power))
         (define a-exp   (exponent a-power))
         (define b-exp   (exponent b-power))
         (cond 
           [(= a-base b-base)   (* (expt a-base (max a-exp b-exp))
                                   (recurse (rest m-co-groups) (rest n-co-groups)))]
           [(< a-base b-base)   'something-3]
           [(> a-base b-base)   'something-4])]))
    (recurse m-co-groups n-co-groups)))

(define x (* (expt 2 3) (expt 3 4)))
(define y (* (expt 2 1) (expt 3 5)))

(lcm-from-factors x y) ; gives 1944
(lcm x y)              ; gives 1944
person soegaard    schedule 10.02.2015