Cum se calcula în mod corespunzător diferențele din schema de perechi?

voturi
2

Având în vedere o listă de numere, să zicem, (1 3 6 10 0), cum calcula diferențele (x i - x i-1 ), cu condiția să aveți x -1 = 0?

(rezultatul în acest exemplu ar trebui să fie (1 2 3 4 -10))

Am găsit această soluție să fie corectă:

(Defini (pairwise-2 f init l)
  (primul 
   (foldl
    (Λ (x acc date)
      (Lasa ([rezultat-list (prima acc-date)]
            [Prev-x (a doua acc date)])
        (listă 
         (Anexați rezultat lista (lista (fx prev-x)))
         X))) 
    (Listă goală 0)
    l)))

(Pairwise-2 - 0 „(1 3 6 10 0))
;; => (1 2 3 4 -10)

Cu toate acestea, cred că ar trebui să fie mai elegant, deși soluția nu mai puțin flexibilă. E doar urât.

Sunt nou la programarea funcțională și ar dori să aud orice sugestii cu privire la acest cod.

Mulțumiri.

Întrebat 12/03/2009 la 13:46
sursa de către utilizator
În alte limbi...                            


7 răspunsuri

voturi
1

Eu nu am făcut schema în ani de câine, dar acest lucru mi se pare o problemă tipic pic de tip lisper.

Am început cu o definiție de bază (vă rugăm să ignorați rătăcirea Parens - Eu nu am un interpret Schemă la îndemână:

(define pairwise-diff
    (lambda (list)
      (cond
       ((null? list) '())
       ((atom? list) list)
       (t (pairwise-helper 0 list)))))

Aceasta se ocupă de cazurile de rahat de delegați și nule atom și atunci cazul de carne la un ajutor:

(define pairwise-helper
    (lambda (n list)
       (cond
         ((null? list) '())
         (t
            (let ([one (car list)])
               (cons (- one n) (pairwise-helper one (cdr list))))
         ))))

Ai putea rescrie acest lucru folosind „dacă“, dar eu sunt cablată de a utiliza Cond.

Există două cazuri aici: lista null - care este ușor și orice altceva. Pentru orice altceva, am apuca capul listei și contra acestei dif pe cazul recursiv. Nu cred că devine mult mai simplu.

Publicat 12/03/2009 la 14:12
sursa de către utilizator

voturi
1

După rafinarea și adaptarea la Schema PLT plinte „s cod , cred că soluția aproape perfectă ar fi:

(Defini (pairwise-aplica f l l0)
  (În cazul în care (gol? L)
      „()
      (Lasa ([l1 (primul l)])
        (Contra (f l1 l0) (pairwise-aplica f l1 (repaus l))))))
Publicat 12/03/2009 la 14:49
sursa de către utilizator

voturi
2

mapia mai multe argumente. Deci, aș face doar

(define (butlast l)
  (reverse (cdr (reverse l))))
(let ((l '(0 1 3 6 10)))
  (map - l (cons 0 (butlast l)))

Dacă doriți să-l încheie într-o funcție, să zicem

(define (pairwise-call f init l)
  (map f l (cons init (butlast l))))

Aceasta este, desigur , nu Little Schemer Calea, dar modul în care evită scrierea recursivitate - te. Alegeți modul în care vă place cel mai bun.

Publicat 13/03/2009 la 13:36
sursa de către utilizator

voturi
1

Haskell mi -a spus să folosească zip;)

(define (zip-with f xs ys)
  (cond ((or (null? xs) (null? ys)) null)
        (else (cons (f (car xs) (car ys))
                    (zip-with f (cdr xs) (cdr ys))))))
(define (pairwise-diff lst) (zip-with - (cdr lst) lst))

(pairwise-diff (list 1 3 6 10 0))
; gives (2 3 4 -10)
Publicat 13/03/2009 la 13:51
sursa de către utilizator

voturi
1

nu sunt mapate termina imediat ce cel mai scurt lista de argumente este epuizat, oricum?

(Defini (Pairwise-apel distractiv init-element de LST)
  (Hartă LST distractiv (contra-init element de LST)))

edita : jleedev mă informează că acest lucru nu este cazul în cel puțin o Schema de implementare. Acesta este un pic enervant, deoarece nu există nici o O (1) operațiune pentru a taie capătul unei liste.

Poate putem folosi reduce:

(Defini (Pairwise-apel distractiv init-element de LST)
  (Invers (cdr (reduce (lambda (ab)
                          (Atașați (lista b (- b (masina a))) (cdr a)))
                        (Contra (lista de inițializare element) LST)))))

(Disclaimer: rapid hack, netestat)

Publicat 13/03/2009 la 13:53
sursa de către utilizator

voturi
0

Acesta este cel mai simplu mod:

(define (solution ls)
  (let loop ((ls (cons 0 ls)))
    (let ((x (cadr ls)) (x_1 (car ls)))
      (if (null? (cddr ls)) (list (- x x_1))
          (cons (- x x_1) (loop (cdr ls)))))))

(display (equal? (solution '(1)) '(1))) (newline)
(display (equal? (solution '(1 5)) '(1 4))) (newline)
(display (equal? (solution '(1 3 6 10 0)) '(1 2 3 4 -10))) (newline)

Scrie extinderea cod pentru fiecare exemplu pentru a vedea cum funcționează.

Dacă sunteți interesat în obținerea a început cu FP, asigurați - vă că pentru a verifica modul de a proiecta programul. Sigur că este scris pentru oameni de brand noi la programare, dar are de tone de idiomuri bune FP în cadrul.

Publicat 27/03/2009 la 17:36
sursa de către utilizator

voturi
0
(define (f l res cur)
  (if (null? l)
    res
    (let ((next (car l)))
      (f (cdr l) (cons (- next cur) res) next))))

(define (do-work l)
  (reverse (f l '() 0)))

(do-work '(1 3 6 10 0))

==> (1 2 3 4 -10)
Publicat 06/04/2009 la 11:43
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more