[SICP] ch-2习题堆

2.4

用函数的参数作为pair的representation

;2.4
;m是一个双参函数,cons是一个以m为参数的函数
( define ( cons x y )
         ( lambda ( m ) ( m x y ) ))
;给m赋值为返回p的函数
( define ( car z ) 
         ( z ( lambda ( p q ) p ) ))
( define ( cdr z )
         ( z ( lambda ( p q ) q ) ))
! 2.6

Church numerals

;2.6
;church numerals DEF
( define zero ( lambda ( f ) ( lambda ( x ) x ) ) )

( define ( add-1 n )
         ( lambda ( f )( lambda ( x ) ( f ( ( n f ) x ) ))))

;从0开始,每多一个f就+1
( define ( church-to-int ch )
         ( ( ch ( lambda ( n ) ( + n 1 ) ) ) 0 ) )

( define one ( lambda ( f ) ( lambda ( x ) ( f x ) ) ) )

( define two ( lambda ( f ) ( lambda ( x ) ( f ( f x ) ) ) ) )

;a,b: function of zero, one, two...
;b以x为参数经过b次apply f
;a以x经过b次apply后的结果为参数(( b f ) x ),在此基础上再apply f a次
( define ( add a b )
         ( lambda ( f )
                  ( lambda ( x ) ( ( a f ) ( ( b f ) x ) ) ) ) )

;调用
( define ( square x )
         ( * x x ))

; f = square x = 2 
( ( two square ) 2 )
2.1.4 Interval Arithmetic
( define ( add-interval x y )
         ( make-interval ( + ( lower-bound x ) ( lower-bound y ) )
                         ( + ( upper-bound x ) ( upper-bound y ) ) ) )

(define ( make-interval a b) ( cons a b))

(define (upper-bound interval) (max (car interval) (cdr interval))) 
(define (lower-bound interval) (min (car interval) (cdr interval))) 

( define ( div-interval x y )
         ;y区间包含0
         ( if ( >= 0 ( * ( lower-bound y ) ( upper-bound y ) ) )
              ( error "Division error ( interval spans 0 )" y )
              ( mul-interval x 
                             ( make-interval ( / 1. ( upper-bound y ) )
                                             ( / 1/ ( lower-bound y ) )))) )  

( define ( mul-interval x y )

         ( define ( endpoint-sign i )
                         ; + +
                  ( cond ( ( and ( >= ( lower-bound i ) 0 ) ( >= ( upper-bound i ) 0 ) ) 1 )
                         ; - -
                         ( ( and ( < ( lower-bound i ) 0 ) ( < ( upper-bound i ) 0 ) ) -1)
                         ; - +
                         ( else 0 )))

         ( let ( ( es-x ( endpoint-sign x ) )
                 ( es-y ( endpoint-sign y ) )
                 ( x-up ( upper-bound x ) )
                 ( x-lo ( lower-bound x ) )
                 ( y-up ( upper-bound y ) )
                 ( y-lo ( lower-bound y ) ) ) 

              (if (and (= es-x 0) (= es-y 0)) 
          ; Take care of the exceptional condition where we have to test 
          (make-interval (min (* x-lo y-up) (* x-up y-lo)) 
                         (max (* x-lo y-lo) (* x-up y-up))) 

          ; Otherwise, select which value goes in which "slot". I'm not sure 
          ; whether there is an intuitive way to explain *why* these 
          ; selections work. 
          (let ((a1 (if (and (<= es-y 0) (<= (- es-y es-x) 0)) x-up x-lo)) (a2 (if (and (<= es-x 0) (<= (- es-x es-y) 0)) y-up y-lo)) (b1 (if (and (<= es-y 0) (<= (+ es-y es-x) 0)) x-lo x-up)) (b2 (if (and (<= es-x 0) (<= (+ es-x es-y) 0)) y-lo y-up))) 
            (make-interval (* a1 a2) (* b1 b2))))))  

( define ( make-interval-center-percentage c pct )
         ( let ( ( width ( * c ( / pct 100.0 ) ) ) )
               ( make-interval ( - c width ) ( + c width ) )))

( define ( percentage-tolerance i )          
         ( let ( ( center ( / ( + ( upper-bound i ) ( lower-bound i ) ) 2.0 ) )
                 ( width  ( / ( - ( upper-bound i ) ( lower-bound i ) ) 2.0 ) ) )
               ( * ( / width center ) 100 )))
List Operations
;2.17
; procedure last-pair
( define ( last-pair items )
         ( if ( null? ( cdr items ) )
              ( car items ) 
              ( last-pair ( cdr items ) ) ) )

( last-pair ( list 23 72 149 34 ) )

;2.18
; procedure reverse
( define ( reverse items )
         ( if ( null? ( cdr items ) )
              items
              ( append ( reverse ( cdr items ) ) ( list ( car items ) ) ) ) )

(reverse (list 1 4 9 16 25))

;2.19
; 用list重写countchange
( define ( cc amount coin-values )
         ( cond ( ( = amount 0 ) 1 )
                ( ( or ( < amount 0 ) ( no-more? coin-values ) ) 0 ) 
                ( else 
                   ( + ( cc amount ( except-first-denomination coin-values ) )
                       ( cc ( - amount ( first-denomination coin-values ) ) coin-values )))))

( define ( no-more? coin-values )
         ( null? coin-values ) )

( define ( except-first-denomination deno )
         ( cdr deno ))

( define ( first-denomination deno )
         ( car deno ))

(cc 100 (list 50 25 10 5 1)) 

( define ( same-parity fst . rst )
         ( define ( same-parity-iter src dist remain )
                  ( if ( null? src )
                       dist 
                       ( same-parity-iter ( cdr src )
                                          ( if ( = ( remainder ( car src ) 2 ) remain ) ( append dist ( list ( car src ) ) ) dist )
                                          remain )
                       ))
         ( same-parity-iter rst ( list fst ) ( remainder fst 2 ) ) )
mapping over list
( define ( square-list items )
         ( if ( null? items )
              nil 
              ( cons ( square ( car items ) ) ( square-list ( cdr items ) ) )))

( define ( square-list items )
         ( map square items ))
Trees
( define ( count-leaves x )
         ( cond ( ( null? x ) 0 )
                ( ( not ( pair? x ) ) 1 )
                ( else ( + ( count-leaves ( car x ) )
                           ( count-leaves ( cdr x ) ) ) )))

( define x ( list ( list 1 2 ) ( list 3 4 ) ) )

;2.27
;tree reverse
( define ( deep-reverse x )
         ( if ( pair? x )
              ( append ( deep-reverse ( cdr x ) )
                       ( list ( deep-reverse ( car x ) ) ))
              x ))

( deep-reverse x )

;2.28
;list all leaves
( define ( fringe x )
         ( if ( not ( pair? x ) )
              (list x)
              ( append ( fringe ( car x ) ) ( fringe ( cdr x ) ) )))

( fringe ( list x x ) )

;2.29
;mobile == two branches
( define ( make-mobile left right )
         ( list left right ) )

;branch == length + struct ( weight / mobile )
( define ( make-branch length structure )
         ( list length structure ))

;a
( define (left-branch mb )
         ( car mb ))

( define ( right-branch mb )
         ( car (cdr mb ) ))

( define ( branch-length bc )
         ( car bc ))

( define (branch-structure bc )
         (car ( cdr bc )))

;b
;define total-weight
( define ( branch-weight bc )
         ( if ( pair? ( branch-structure bc ) )
              ( total-weight ( branch-structure bc ) )
              ( branch-structure bc )))

( define ( total-weight mb )
         ( + ( branch-weight ( left-branch mb ) )
             ( branch-weight ( right-branch mb) )))

;c
;define balenced
( define (branch-balanced? bc)
         ( if ( pair? ( branch-structure bc ) )
              ( balanced? ( branch-structure bc ) )
              true ))

( define ( branch-torque bc )
         ( * ( branch-weight bc ) ( branch-length bc ) ))

( define ( balanced? mb )
         ( let ( ( lft ( left-branch mb ) ) 
                 ( rht ( right-branch mb ) ) ) 
         ( and ( =  ( branch-torque lft ) ( branch-torque rht ))
               ( branch-balanced? lft )
               ( branch-balanced? rht ))))

(balanced? (make-mobile (make-branch 5 3) 
                         (make-branch 3 2))) 

mapping over trees
;2.30
; define square-tree
( define ( square-tree tre )
         ( cond (( null? tre ) nil )
            ( ( not ( pair? ( car tre ))) ( cons ( square ( car tre ) ) ( square-tree ( cdr tre ) ) ) )
            ( else ( cons ( square-tree ( car tre ) ) 
                       ( square-tree ( cdr tre ) ) ) )))

( define ( square x )
         ( * x x ))

;square tree using map
( define ( sqr-tree-mp tree )
         ( map ( lambda ( sub-tree )
                        ( if ( pair? sub-tree )
                             ( sqr-tree-mp sub-tree )
                             ( square sub-tree ) ) )
               tree ))

;2.31 abstract square to procedure
( define ( tree-map proc tree )
         ( map ( lambda ( sub-tree )
                        ( if ( pair? sub-tree )
                             ( tree-map proc sub-tree ) 
                             ( proc sub-tree ) ) )
               tree ))


(tree-map square
(list 1
(list 2 (list 3 4) 5)
(list 6 7)))
! 2.32

http://community.schemewiki.org/?sicp-ex-2.32

nested map

棋盘的那个一脸懵逼
智商持续下线中

(define x ( list ( list 1 2 3 ) ( list 3 4 5 ) ( list 6 7 8 ) ))

( define ( filter predicate seq )
         ( cond ( ( null? seq ) nil )
                ( ( predicate ( car seq ) )
                  ( cons ( car seq )
                         ( filter predicate ( cdr seq ) )) )
                ( else ( filter predicate ( cdr seq ) ) )) ) 

;( enumerate-interval 2 7 ) == ( 2 3 4 5 6 7 )
( define ( enumerate-interval low high )
         ( if ( > low high )
              nil
              ( cons low ( enumerate-interval ( + low 1 ) high ) ) ))

( define ( accumulate op init seq )
         ( if ( null? seq )
              init
              ( op ( car seq )
                   ( accumulate op init ( cdr seq) ))))

( define ( flatmap proc seq )
         ( accumulate append nil ( map proc seq ) ))

( define ( all-triple n ) 
( flatmap 
  ( lambda ( i )
           ( map ( lambda ( j ) ( map ( lambda ( k ) ( list i j k ) ) ( enumerate-interval 1 ( - j 1 ) ) ) ) 
                 ( enumerate-interval 1 ( - i 1 ) ) ) )
  ( enumerate-interval 1 n ) ) )

( define ( sum-tri n s )
         ( filter 
            ( lambda ( lst ) 
                     ( = ( accumulate + 0 lst ) s ))
            ( flatmap 
                    ( lambda ( i )
                             ( map ( lambda ( j ) ( map ( lambda ( k ) ( list i j k ) ) ( enumerate-interval 1 ( - j 1 ) ) ) ) ( enumerate-interval 1 ( - i 1 ) ) ) )
                    ( enumerate-interval 1 n ) ) ))


;2.42
( define ( queens board-size ) 
         ( define ( queen-cols k )
                  ( if ( = k 0 )
                       ( list empty-board ) 
                       ( filter 
                          ( lambda ( positions ) ( safe? k positions ))
                          ( flatmap ( lambda ( rest-of-queens ) ( map ( lambda ( new-row ) ( adjoin-position new-row k rest-of-queens ) ) ( enumerate-interval 1 board-size ))) ( queen-cols ( - k 1 ) )))))
         ( queen-cols board-size ))

( define empty-board nil )

;in chess: rank == row, file == col
( define ( place-queen rank file )
         ( cons rank file ))

( define ( queen-rank queen )
         ( car queen ))

( define ( queen-file queen )
         ( cdr queen ))

;ADJOIN-POSITION
( define ( adjoin-position rank file board )
         ( cons ( place-queen rank file ) board ))

;找到items里第一个符合pred条件的
( define ( find-first pred items )
         ( cond ( ( null? items ) nil )
                ( ( pred ( car items ) ) ( car items) )
                ( else ( find-first pred ( cdr items ) ) ) ))

( define ( safe? file board )
         ;在棋盘上找到所判断列(file)上的queen
         ( define ( get-queen-by-file file board )
                  ( find-first ( lambda ( queen )
                                        ( = ( queen-file queen ) file ) )
                               board ) )

         ;定义了两个,the-queen和other-queens
         ;the-queen是当前新增的,要判断是否safe的
         ( let* ( ( the-queen
                    ( get-queen-by-file file board ) )

                 ;other-queens 是和q行列不同的
                  ( other-queens
                    ;filter predicate seq 
                    ( filter ( lambda ( q ) ( not ( and ( = ( queen-rank the-queen ) ( queen-rank q ) ) ( = ( queen-file the-queen ) ( queen-file q ) ) ) ) ) board )))

                ;accumulate op init seq
                ;任何other-queens 和q没有相同行(rank)
                ( and ( not ( accumulate ( lambda ( p q ) ;or ( or q ( = ( queen-rank p ) ( queen-rank the-queen ) ) ) ) #f other-queens ) )
                      ( not ( accumulate ( lambda ( p q ) ( or q ( = ( abs ( - ( queen-rank the-queen ) ( queen-rank p ) ) ) ( abs ( - ( queen-file the-queen ) ( queen-file p ) ) ) ) ) ) #f other-queens )))))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值