#lang racket
(require csc151)
(require rackunit)
(require rackunit/text-ui)

;;; File:
;;;   000000.rkt
;;; Authors:
;;;   The student currently referred to as 000000
;;;   Titus Klinge
;;;   Samuel A. Rebelsky
;;; Contents:
;;;   Code and solutions for Exam 3 2017F
;;; Citations:
;;;

;; +---------+--------------------------------------------------------
;; | Grading |
;; +---------+

;; This section is for the grader's use.

;; Problem 1: 
;; Problem 2:
;; Problem 3:
;; Problem 4:
;; Problem 5:
;; Problem 6:
;;           ----
;;     Total:

;;    Scaled:
;;    Errors:
;;     Times:
;;          :
;;          :
;;          :
;;           ----
;;     Total:

;; +----------+-------------------------------------------------------
;; | Prologue |
;; +----------+

; Time Log:
;   Date        Start   Finish  Elapsed Activity

; Time Spent: 

;; +-----------+------------------------------------------------------
;; | Problem 1 |
;; +-----------+

; Time Log:
;   Date        Start   Finish  Elapsed Activity

; Time Spent: 

; Citations:

; Solution:

;;; Procedure:
;;;   
;;; Parameters:
;;;   
;;; Purpose:
;;;   
;;; Produces:
;;;   
;;; Preconditions:
;;;   
;;; Postconditions:
;;;   
(define list-tally
  (lambda (lst pred?)
    0)) ; STUB
 
; Examples/Tests:


;; +-----------+------------------------------------------------------
;; | Problem 2 |
;; +-----------+

; Time Log:
;   Date        Start   Finish  Elapsed Activity

; Time Spent: 

; Citations:

; Solution:

;;; Procedure:
;;;   
;;; Parameters:
;;;   
;;; Purpose:
;;;   
;;; Produces:
;;;   
;;; Preconditions:
;;;   
;;; Postconditions:
;;;   
(define list-set
  (lambda (lst pos val)
    lst)) ; STUB

; Examples/Tests:


;; +-----------+------------------------------------------------------
;; | Problem 3 |
;; +-----------+

; Time Log:
;   Date        Start   Finish  Elapsed Activity

; Time Spent: 

; Citations:

; Provided code:

;;; Procedure:
;;;   alphabetically-first-in-bst
;;; Parameters:
;;;   bst, a non-empty bst [unverified] 
;;; Purpose:
;;;   Find the alphabetically first string in a binary search tree
;;; Produces:
;;;   first, a string
;;; Preconditions:
;;;   bst contains only strings
;;; Postconditions:
;;;   For all strings, str, in bst, (string<=? first str)
;;; Practica:
;;;   > (alphabetically-first-in-bst (node "dog" (leaf "cat") (leaf "squirrel")))
;;;   "cat"
;;;   > (alphabetically-first-in-bst (node "dog" empty (leaf "squirrel")))
;;;   ;"dog"
;;;   > (alphabetically-first-in-bst (node "dog" (node "cat"
;;;                                                    (leaf "aardvark")
;;;                                                    (leaf "chincilla"))
;;;                                        (leaf "squirrel")))
;;;   "aardvark"
(define alphabetically-first-in-bst
  (lambda (bst)
    (if (empty? (left bst))
        (contents bst)
        (alphabetically-first-in-bst (left bst)))))

;;; Procedure:
;;;   alphabetically-last-in-bst
;;; Parameters:
;;;   bst, a non-empty bst [unverified] 
;;; Purpose:
;;;   Find the alphabetically last string in a binary search tree
;;; Produces:
;;;   last, a string
;;; Preconditions:
;;;   bst contains only strings
;;; Postconditions:
;;;   For all strings, str, in bst, (string<=? str last)
;;; Practica:
;;;   > (alphabetically-last-in-bst (leaf "dog"))
;;;   "dog"
;;;   > (alphabetically-last-in-bst (node "dog"
;;;                                       (leaf "cat")
;;;                                       (leaf "squirrel")))
;;;   "squirrel"
;;;   > (alphabetically-last-in-bst (node "dog"
;;;                                       (leaf "cat")
;;;                                       (node "squirrel"
;;;                                             (leaf "emu")
;;;                                             (leaf "turtle"))))
;;;   "turtle"
;;;   > (alphabetically-last-in-bst (node "dog"
;;;                                       (leaf "cat")
;;;                                       empty))
;;;   "dog"
(define alphabetically-last-in-bst
  (lambda (bst)
    (if (empty? (right bst))
        (contents bst)
        (alphabetically-last-in-bst (right bst)))))

; More tree code appears at the end of the exam.  

; Solution:

(define bst?
  (lambda (val)
    #f)) ; STUB

; Examples/Tests:


;; +-----------+------------------------------------------------------
;; | Problem 4 |
;; +-----------+

; Time Log:
;   Date        Start   Finish  Elapsed Activity

; Time Spent: 

; Citations:

; Solution:
(define vector-selective-map!
  (lambda (vec pred? proc)
    vec)) ; STUB

; Examples/Tests:


;; +-----------+------------------------------------------------------
;; | Problem 5 |
;; +-----------+

; Time Log:
;   Date        Start   Finish  Elapsed Activity

; Time Spent: 

; Citations:

; Supplied code:

;;; Procedure:
;;;   letter->number
;;; Parameters:
;;;   letter, a character
;;; Purpose:
;;;   Convert a letter to a number in the range 0..25
;;; Produces:
;;;   number, an integer in the range 0..25, inclusive.
;;; Preconditions:
;;;   * letter is a lowercase or uppercase letter in US English
;;;   * the encoding system numbers letters in the sensible way, with
;;;     each letter's encoding one greater than the encoding of the previous
;;;     letter.  
;;; Postconditions:
;;;   if letter is #\a or #\A, number is 0
;;;   if letter is #\b or #\B, number is 1
;;;   if letter is #\c or #\C, number is 2
;;;   and so on and so forth
(define letter->number
  (let ([a-num (char->integer #\a)])
    (lambda (letter)
      (- (char->integer (char-downcase letter)) a-num))))

;;; Procedure:
;;;   increment-at!
;;; Parameters:
;;;   vec, a vector of numbers
;;;   pos, an integer
;;; Purpose:
;;;   Increment the value at position pos.
;;; Produces:
;;;   [Nothing; called for the side effect]
;;; Preconditions:
;;;   0 <= pos < (vector-length vec)
;;; Postconditions:
;;;   * Let oldval be the value of (vector-ref vec pos) before this procedure
;;;     is called.
;;;   * (vector-ref vec pos) = (increment oldval) after this procedure is
;;;     called.
(define increment-at!
  (lambda (vec pos)
    (vector-set! vec pos (increment (vector-ref vec pos)))))

;;; Procedure:
;;;   display-tallies
;;; Parameters:
;;;   tallies, a vector of 26 integers
;;; Purpose:
;;;   Display the result of tally-letters-from-port
;;; Produces:
;;;   [Nothing; called for the side effect]
(define display-tallies
  (let ([eh (char->integer #\a)])
    (lambda (tallies)
      (let kernel ([pos 0])
        (when (< pos 26)
          (display (integer->char (+ pos eh)))
          (display ": ")
          (display (vector-ref tallies pos))
          (newline)
          (kernel (+ pos 1)))))))

; Solution:

(define tally-letters-from-port
  (lambda (inport)
    (let ([tallies (make-vector 26 0)])
      tallies)))        ; STUB

; Examples/Tests:

;; +-----------+------------------------------------------------------
;; | Problem 6 |
;; +-----------+

; Time Log:
;   Date        Start   Finish  Elapsed Activity

; Time Spent: 

; Citations:

; Supplied code

; Solution:

;;; Procedure:
;;;   
;;; Parameters:
;;;   
;;; Purpose:
;;;   
;;; Produces:
;;;   
;;; Preconditions:
;;;   
;;; Postconditions:
;;;   
(define    daffy
(lambda (  puddles        )
  (let ([  darkwing       (lambda (
           donald
           huey
           count-duckula  ) (let ([
           louie          (vector-ref
           donald
           huey           )][
           dewey          (vector-ref
           donald
           count-duckula  )]) (vector-set!
           donald
           huey
           dewey          )(vector-set!
           donald
           count-duckula
           louie          )))]) (map (l-s
    apply  darkwing       )(map list (make-list (quotient (vector-length
           puddles        ) 2)
           puddles        )(iota (quotient (vector-length
           puddles        ) 2))(map (r-s - 1) (map (l-s - (vector-length
           puddles        )) (iota (quotient (vector-length
           puddles        ) 2)))))))
           puddles        ))

; Examples/Tests:

; ===================================================================

; +-------------------+----------------------------------------------
; | Tree Constructors |
; +-------------------+

;;; Name:
;;;   empty
;;; Type:
;;;   tree
;;; Value:
;;;   The empty tree
(define empty 'empty)

;;; Procedure:
;;;   leaf
;;; Parameters:
;;;   val, a value
;;; Purpose:
;;;   Make a leaf node.
;;; Produces:
;;;   tree, a tree
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   (contents tree) = val
;;;   (left tree) = empty
;;;   (right tree) = empty
(define leaf
  (lambda (val)
    (node val empty empty)))

;;; Procedure:
;;;   node
;;; Parameters:
;;;   val, a value
;;;   left-subtree, a tree
;;;   right-subtree, a tree
;;; Purpose:
;;;   Create a node in a binary tree.
;;; Produces:
;;;   tree, a tree
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   (node? tree) holds.
;;;   (left tree) = left-subtree.
;;;   (right tree) = right-subtree.
;;;   (contents tree) = val.
(define node
  (lambda (val left right)
    (vector 'node val left right)))

; +----------------+-------------------------------------------------
; | Tree Observers |
; +----------------+

;;; Procedure:
;;;   contents
;;; Parameters:
;;;   nod, a binary tree node
;;; Purpose:
;;;   Extract the contents of node.
;;; Produces:
;;;   val, a value
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   (contents (node val l r)) = val
(define contents
  (lambda (nod)
    (cond
      [(not (node? nod))
       (error "contents requires a node, received" nod)]
      [else
       (vector-ref nod 1)])))

;;; Procedure:
;;;   left
;;; Parameters:
;;;   nod, a binary tree node
;;; Purpose:
;;;   Extract the left subtree of nod.
;;; Produces:
;;;   l, a tree
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   (left (node val l r)) = l
(define left
  (lambda (nod)
    (cond
      [(not (node? nod))
       (error "left requires a node, received" nod)]
      [else
       (vector-ref nod 2)])))

;;; Procedure:
;;;   right
;;; Parameters:
;;;   nod, a binary tree node
;;; Purpose:
;;;   Extract the right subtree of nod.
;;; Produces:
;;;   r, a tree
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   (right (node val l r)) = r
(define right
  (lambda (nod)
    (cond
      [(not (node? nod))
       (error "right requires a node, received" nod)]
      [else
       (vector-ref nod 3)])))

; +-----------------+------------------------------------------------
; | Tree Predicates |
; +-----------------+

;;; Procedure:
;;;   empty?
;;; Parameters:
;;;   val, a Scheme value
;;; Purpose:
;;;   Determine if val represents an empty tree.
;;; Produces:
;;;   is-empty?, a Boolean 
;;; Preconditions:
;;;   [No additional]
;;; Postconditions:
;;;   is-empty? is true (#t) if and only if val can be interpreted as
;;;   the empty tree.
(define empty? 
  (section eq? <> empty))

;;; Procedure:
;;;   leaf?
;;; Parameters:
;;;   val, a Scheme value
;;; Purpose:
;;;   Determine if val is a tree leaf
;;; Produces:
;;;   is-leaf?, a Boolean
(define leaf?
  (lambda (val)
    (and (node? val)
         (empty? (left val))
         (empty? (right val)))))

;;; Procedure:
;;;   node?
;;; Parameters:
;;;   val, a Scheme value
;;; Purpose:
;;;   Determine if val can be used as a tree node.
;;; Produces:
;;;   is-node?, a Boolean
(define node?
  (lambda (val)
    (and (vector? val)
         (= (vector-length val) 4)
         (eq? (vector-ref val 0) 'node))))


