1
0
Fork 0

Day 18: Simplify logic a little without using symbols.

This commit is contained in:
Jonathan Chan 2021-12-18 03:08:02 -08:00 committed by Jonathan Chan
parent 258249f4de
commit dbe632d7dc
1 changed files with 21 additions and 40 deletions

View File

@ -97,86 +97,67 @@
['right (left-add-rightmost! n (pair-parent p))] ['right (left-add-rightmost! n (pair-parent p))]
['left (up-add-rightmost! n (pair-parent p))])) ['left (up-add-rightmost! n (pair-parent p))]))
;; number? pair? -> (or/c 'exploded 'continue) ;; number? pair? -> (or/c void? #f)
;; Explodes pairs at depth 4 or greater ;; Explodes pairs at depth 4 or greater or returns false
(define (explode depth p) (define (explode depth p)
(match p (match p
[(pair 'left parent (? number? left) (? number? right)) [(pair 'left parent (? number? left) (? number? right))
#:when (>= depth 4) #:when (>= depth 4)
(right-add-leftmost! right parent) (right-add-leftmost! right parent)
(up-add-rightmost! left parent) (up-add-rightmost! left parent)
(set-pair-left! parent 0) (set-pair-left! parent 0)]
'exploded]
[(pair 'right parent (? number? left) (? number? right)) [(pair 'right parent (? number? left) (? number? right))
#:when (>= depth 4) #:when (>= depth 4)
(left-add-rightmost! left parent) (left-add-rightmost! left parent)
(up-add-leftmost! right parent) (up-add-leftmost! right parent)
(set-pair-right! parent 0) (set-pair-right! parent 0)]
'exploded] [(pair type parent (? number? left) (? number? right)) #f]
[(pair type parent (? number? left) (? number? right))
'continue]
[(pair type parent (? number? left) (? pair? right)) [(pair type parent (? number? left) (? pair? right))
(explode (add1 depth) right)] (explode (add1 depth) right)]
[(pair type parent (? pair? left) (? number? right?)) [(pair type parent (? pair? left) (? number? right?))
(explode (add1 depth) left)] (explode (add1 depth) left)]
[(pair type parent (? pair? left) (? pair? right)) [(pair type parent (? pair? left) (? pair? right))
(define results (or (explode (add1 depth) left)
(list (explode (add1 depth) left) (explode (add1 depth) right))]))
(explode (add1 depth) right)))
(if (member 'exploded results) 'exploded 'continue)]))
;; SPLIT ;; ;; SPLIT ;;
;; number? pair? -> void? ;; number? pair? -> void?
;; Effect: Sets left node to new pair consisting of halved number ;; Effect: Sets left node to new pair consisting of halved number rounded down and up
;; rounded down and up
(define (split-left! left p) (define (split-left! left p)
(define halved (/ left 2)) (define halved (/ left 2))
(set-pair-left! p (pair 'left p (floor halved) (ceiling halved)))) (set-pair-left! p (pair 'left p (floor halved) (ceiling halved))))
;; number? pair? -> void? ;; number? pair? -> void?
;; Effect: Sets right node to new pair consisting of halved number ;; Effect: Sets right node to new pair consisting of halved number rounded down and up
;; rounded down and up
(define (split-right! right p) (define (split-right! right p)
(define halved (/ right 2)) (define halved (/ right 2))
(set-pair-right! p (pair 'right p (floor halved) (ceiling halved)))) (set-pair-right! p (pair 'right p (floor halved) (ceiling halved))))
;; pair? -> (or/c 'split 'continue) ;; pair? -> (or/c void? #f)
;; Splits leftmost number greater than 10 into a pair of halved numbers ;; Splits leftmost number greater than 10 into a pair of halved numbers or returns false
(define (split p) (define (split p)
(match p (match p
[(pair type parent (? number? left) (? number? right)) [(pair type parent (? number? left) (? number? right))
(if (>= left 10) (or (and (>= left 10) (split-left! left p))
(begin (split-left! left p) 'split) (and (>= right 10) (split-right! right p)))]
(if (>= right 10)
(begin (split-right! right p) 'split)
'continue))]
[(pair type parent (? number? left) (? pair? right)) [(pair type parent (? number? left) (? pair? right))
(if (>= left 10) (if (>= left 10) (split-left! left p) (split right))]
(begin (split-left! left p) 'split)
(split right))]
[(pair type parent (? pair? left) (? number? right)) [(pair type parent (? pair? left) (? number? right))
(match (split left) (or (split left) (and (>= right 10) (split-right! right p)))]
['split 'split]
['continue
(if (>= right 10)
(begin (split-right! right p) 'split)
'continue)])]
[(pair type parent (? pair? left) (? pair? right)) [(pair type parent (? pair? left) (? pair? right))
(match (split left) (or (split left) (split right))]))
['split 'split]
['continue (split right)])]))
;; REDUCE ;; ;; REDUCE ;;
;; pair? -> void? ;; pair? -> void?
;; Effect: Explodes then splits pair until a fixed point is reached ;; Effect: Explodes then splits pair until a fixed point is reached
(define (reduce p) (define (reduce p)
(let loop ([status 'exploded]) (let loop ([exploded #t])
(if (symbol=? status 'continue) (if exploded
(unless (symbol=? (split p) 'continue) (loop (explode 0 p))
(loop (explode 0 p))) (when (split p)
(loop (explode 0 p))))) (loop (explode 0 p))))))
;; MAGNITUDE ;; ;; MAGNITUDE ;;