(require 2htdp/image)
; Problem 2:
; Consider a test tube filled with solid blobs and bubbles. Over time the
; solids sink to the bottom of the test tube, and as a consequence the bubbles
; percolate to the top. Let’s capture this idea in BSL.
;
; Complete the design of a function that takes a list of blobs and sinks each
; solid blob by one. It’s okay to assume that a solid blob sinks past any
; neighbor just below it.
;
; To assist you, we supply the relevant data definitions.


;; Blob is one of:
;; - “solid”
;; - “bubble”
;; interp. a gelatinous blob, either a solid or a bubble
;; Examples are redundant for enumerations
#;
(define (fn-for-blob b)
(cond [(string=? b “solid”) (…)]
[(string=? b “bubble”) (…)]))

;; Template rules used:
;; - one-of: 2 cases
;; - atomic distinct: “solid”
;; - atomic distinct: “bubble”


;; ListOfBlob is one of:
;; - empty
;; - (cons Blob ListOfBlob)
;; interp. a sequence of blobs in a test tube, listed from top to bottom.
(define LOB0 empty) ; empty test tube
(define LOB2 (cons “solid” (cons “bubble” empty))) ; solid blob above a bubble

#;
(define (fn-for-lob lob)
(cond [(empty? lob) (…)]
[else
(… (fn-for-blob (first lob))
(fn-for-lob (rest lob)))]))

;; Template rules used
;; - one-of: 2 cases
;; - atomic distinct: empty
;; - compound: 2 fields
;; - reference: (first lob) is Blob
;; - self-reference: (rest lob) is ListOfBlob

;; ListOfBlob -> ListOfBlob
;; produce a list of blobs that sinks the given solid blobs by one

(check-expect (sink empty) empty)
(check-expect (sink (cons “bubble” (cons “solid” (cons “bubble” empty))))
(cons “bubble” (cons “bubble” (cons “solid” empty))))
(check-expect (sink (cons “solid” (cons “solid” (cons “bubble” empty))))
(cons “bubble” (cons “solid” (cons “solid” empty))))
(check-expect (sink (cons “solid” (cons “bubble” (cons “bubble” empty))))
(cons “bubble” (cons “solid” (cons “bubble” empty))))
(check-expect (sink (cons “solid” (cons “bubble” (cons “solid” empty))))
(cons “bubble” (cons “solid” (cons “solid” empty))))
(check-expect (sink (cons “bubble” (cons “solid” (cons “solid” empty))))
(cons “bubble” (cons “solid” (cons “solid” empty))))
(check-expect (sink (cons “solid”
(cons “solid”
(cons “bubble” (cons “bubble” empty)))))
(cons “bubble” (cons “solid”
(cons “solid” (cons “bubble” empty)))))
;(define (sink lob) empty) ; stub

(define (sink lob)
  (cond [(empty? lob) empty] ; base case: empty list
        [(string=? (first lob) "solid") 
         (append (rest lob) (list "solid") (sink (rest lob)))]
        [else (cons (first lob) (sink (rest lob)))]))
Ran 10 tests.
6 of the 10 tests failed.

Check failures:
Actual value (list “bubble” “bubble”) differs from (list “bubble” “bubble” “solid”), the expected value.
in Naturals-and-Helpers-Design-Quiz (1).rkt, line 101, column 0
Actual value (list “solid” “bubble”) differs from (list “bubble” “solid” “solid”), the expected value.
in Naturals-and-Helpers-Design-Quiz (1).rkt, line 103, column 0
Actual value (list “bubble” “bubble”) differs from (list “bubble” “solid” “bubble”), the expected value.
in Naturals-and-Helpers-Design-Quiz (1).rkt, line 105, column 0
check-expect encountered the following error instead of the expected value, (list “bubble” “solid” “solid”).
:: first: expects a non-empty list; given: '()
in Naturals-and-Helpers-Design-Quiz (1).rkt, line 107, column 0 caused by expression in Naturals-and-Helpers-Design-Quiz (1).rkt, line 121, column 15
Actual value (list “bubble” “solid”) differs from (list “bubble” “solid” “solid”), the expected value.
in Naturals-and-Helpers-Design-Quiz (1).rkt, line 109, column 0
Actual value (list “solid” “bubble” “bubble”) differs from (list “bubble” “solid” “solid” “bubble”), the expected value.
in Naturals-and-Helpers-Design-Quiz (1).rkt, line 111, column 0
(cons (first lob) (sink (rest lob)))]))