The Way 2 Inner Peace.


#lang racket

;give a n 
;output the outermost diagonal numbers of the n x n spiral form
(define (outermost n)
  (if (= n 1)
      (list 1)
      (build-list 4 (λ(x) 
                        (+ (* (sub1 n)(add1 x))
                           (sqr(- n 2)))))))

(define (build-diagonal n)
  (define (iter i r)
    (if (> i n)
        (iter (+ 2 i)
              (append r (outermost i)))))
  (iter 1 '()))

(display (apply + (build-diagonal 1001)))




#lang racket

(define (triangle x)
  (quotient (* x (add1 x)) 2))

(define (prime-factors n)
  (let loop ([n n] [m 2] [factors (list)])
    (cond [(= n 1) factors]
          [(= 0 (modulo n m)) (loop (/ n m) 2 (cons m factors))]
          [else (loop n (add1 m) factors)]))) 

;;cont n in l
(define (count-n l n)
  (cons n (count (lambda (x) (= n x)) l)))

;;count all n in l
(define (count-all l)
  (let loop ([l l] [visited '()] [r '()])
      [(null? l) r]
      [(member (car l) visited) (loop (cdr l) visited r)]
      [else (loop (cdr l) 
                  (cons (car l) visited)
                  (cons (count-n l (car l)) r))])))

;;count all divisors of a number
;more in
(define (count-factor n)
  (let loop ([l (count-all(prime-factors n))] [r 1])
      [(null? l) (cons r n)]
      [else (loop (cdr l) (* r (add1(cdar l))))])))

(define (tri-count-factor n)
  (count-factor (triangle n)))

(time(car(filter (lambda (x) (< 500 (car x))) 
                 (map tri-count-factor (range 10000 20000)))))



racekt.. 大概9秒.

#lang racket
(require racket/trace)
(define (col x)
    [(> 0 x)x]
    [(even? x) (/ x 2)]
    [else (add1(* 3 x))]))
(define (gene-col x ht)
    [(number? (hash-ref ht x null)) (hash-ref ht x)]
    [(= 1 x) (begin(hash-set! ht x 1)(hash-ref ht x))]
    [else (begin(hash-set! ht x (add1 (gene-col (col x) ht)))
                (hash-ref ht x))]))
;;alop is a list of pairs
(define (find-cdr alop h)
  (if(= h (cdr(car alop)))
     (car alop)
     (find-cdr (cdr alop) h)))
(define ht (make-hash))
(define answers(map (lambda (x) (gene-col x ht))(build-list 1000000 (lambda (x) (add1 x)))))
(find-cdr (hash->list ht) (apply max answers))


来自The seasoned schemer

The Next Ten Commandments


The Eleventh Commandment

Use additional arguments when a function needs to know what other arguments to the function have been like so far.



The Twelfth Commandment

Use (letrec ...) to remove arguments that do not change for recursive applications.



The Thirteenth Commandment

Use(letrec ...) to hide and to protect functions.



The Fourteenth Commandment

Use(letcc1 ...) to return values abruptly and promptly.



The Fifteenth Commandment

Use (let ...) to name the values of repeated expressions in a function definition if they may be evaluated twice for one and t he same use of the function. And use (let...) to name the values of expressions(without set!) that are re-evaluated every time a function is used.



The Sixteenth Commandment

Use (set! ...)only with names defined in (let ...)s.



The Seventeenth Commandment

Use(set! x ...) for (let((x ...)) ...) only if there is at least one (lambda ... between it and the(let ...),or if the new value for x is a function that refers to x .



The Eighteenth Commandment

Use (set! x ...) only when the value that x refers to is no longer needed.



The Nineteenth Commandment

Use (set! ...) to remember valuable things between two distinct uses of a function.



The Twentieth Commandment

When thinking about a value created with (letcc ...),write down the function that is equivalent but does not forget. Then, when you use it, remember to forget.


1:letcc is call-with-current-continuation or call/cc in scheme


在scheme中.let,let*和letrec的形式均写做:(id val-expr).即:

(let ([id val-expr] ...) body ...+),(let* ([id val-expr] ...) body ...+),(letrec ([id val-expr] ...) body ...+)



在let*中.先计算一个val-expr,将其赋值给id.在进行下一个(id val-expr)的计算.



(define foo 5)
;; foo 現在取值 5
(let ((foo 10))
  ;; foo 現在取值 10
;; foo 現在取值 5


(let* ((var1 10)
       (var2 (+ var1 5)))
;; 返回 15
;; 如果僅使用 let,程式會出錯。


(letrec ((female (lambda(n)
                   (if (= n 0) 1
                       (- n (male (female (- n 1)))))))
         (male (lambda(n)
                 (if (= n 0) 0
                     (- n (female (male (- n 1))))))))
  (display "i male(i) female(i)")(newline)
  (do ((i 0 (+ i 1)))
      ((> i 8) #f)
    (display i) (display "   ")(display (male i))(display "         ")(display (female i))

(via wikipedia)


同时 剥去语法糖.

(let ((x 1))
  (print x))
((lambda (x) (print x)) 1)

(letrec ((fact (lambda (x)
                 (if (= x 1)
                    (* x (fact (- x 1)))))))
  (fact 5))

((lambda (fact x)
   (fact x fact))
(lambda (x fact)
   (if (= x 1)
      (* x (fact (- x 1) fact))))



(letrec ((f (lambda ...))) ...)


(let ((f <undefined>))   (set! f (lambda ...)) ...)