如何创建一个列表(3 3 3 2 2 1)

时间:2017-04-14 00:04:49

标签: scheme racket

我正在尝试创建像(3 3 3 2 2 1)这样的列表。 我的代码:

(define Func
  (lambda (n F)
    (define L
      (lambda (n)
        (if (< n 0)
          (list)
          (cons n (L (- n 1))) )))
    (L n) ))

我需要添加什么才能获得它? 谢谢

4 个答案:

答案 0 :(得分:0)

我会将其分解为三个功能。

(define (repeat e n) (if (= n 0) '() (cons e (repeat e (- n 1)))))
(define (count-down n) (if (= n 0) '() (cons n (count-down (- n 1)))))
(define (f n) (apply append (map (lambda (n) (repeat n n)) (count-down n))))

(f 3); => '(3 3 3 2 2 1)

将其展平为单个函数需要这样的事情:

(define (g a b) 
      (if (= a 0) '() 
          (if (= b 0) 
              (g (- a 1) (- a 1)) 
              (cons a (g a (- b 1))))))

(define (f n) (g n n))

(f 3) ;=> '(3 3 3 2 2 1)

答案 1 :(得分:0)

(define (range n m)
  (if (< n m)
    (let up ((n n))        ; `n` shadowed in body of named let `up`
      (if (= n m) (list n)
                  (cons n (up (+ n 1))) ))
    (let down ((n n))
      (if (= n m) (list n)
                  (cons n (down (- n 1))) ))))

(define (replicate n x)
  (let rep ((m n))         ; Named let eliminating wrapper recursion
    (if (= m 0) '()        ; `replicate` partial function defined for
      (cons x              ; zero-inclusive natural numbers
        (rep (- m 1)) ))))

(define (concat lst)
  (if (null? lst) '()
    (append (car lst)
            (concat (cdr lst)) )))

(display
  (concat                             ; `(3 3 3 2 2 1)`
    (map (lambda (x) (replicate x x)) ; `((3 3 3) (2 2) (1))`
         (range 3 1) )))              ; `(3 2 1)`

concat的替代方案:

(define (flatten lst)
  (if (null? lst) '()
    (let ((x (car lst)))    ; Memoization of `(car lst)`
      (if (list? x)
        (append x (flatten (cdr lst)))
        (cons x (flatten (cdr lst))) ))))

(display
  (flatten '(1 2 (3 (4 5) 6) ((7)) 8)) ) ; `(1 2 3 (4 5) 6 (7) 8)`

答案 2 :(得分:0)

这是一个尾递归版本。它以相反的方式进行迭代!

(define (numbers from to)
  (define step (if (< from to) -1 1))
  (define final (+ from step))
  (let loop ((to to) (down to) (acc '()))
    (cond ((= final to) acc)
          ((zero? down)
           (let ((n (+ to step)))
             (loop n n acc)))
          (else
           (loop to (- down 1) (cons to acc))))))

(numbers 3 1)
; ==> (3 3 3 2 2 1)

要在标准Scheme中使用此功能,您可能需要将define更改为let*,因为当前step确定final不可用得到评估。

答案 3 :(得分:0)

我会使用build-list

的简单递归程序
(define (main n)
  (if (= n 0)
      empty
      (append (build-list n (const n)) (main (sub1 n)))))

(main 3) ;; '(3 3 3 2 2 1)
(main 6) ;; '(6 6 6 6 6 6 5 5 5 5 5 4 4 4 4 3 3 3 2 2 1)

这是一个尾递归版

(define (main n)
  (let loop ((m n) (k identity))
    (if (= m 0)
        (k empty)
        (loop (sub1 m) (λ (xs) (k (append (build-list m (const m)) xs)))))))

(main 3) ;; '(3 3 3 2 2 1)
(main 6) ;; '(6 6 6 6 6 6 5 5 5 5 5 4 4 4 4 3 3 3 2 2 1)