Sunday, June 05, 2022

SICP in Clojure: Chapter 2, Exercise 3

This is my Clojure solution to Chapter 2, Exercise 3:

(ns sicp.ch2.ex03
  (:require [sicp.ch2.ex02 :as ch2-ex02]))

(defn- seg-length
  [seg]
  (let [s (ch2-ex02/seg-start seg)
        e (ch2-ex02/seg-end seg)
        x (- (ch2-ex02/point-x e) (ch2-ex02/point-x s))
        y (- (ch2-ex02/point-y e) (ch2-ex02/point-y s))]
    (Math/sqrt (+ (* x x) (* y y)))))

(defn- make-rect-1
  [left-seg bottom-seg]
  [left-seg bottom-seg])

(def ^:private rect-1-left-seg first)

(def ^:private rect-1-bottom-seg second)

(defn- rect-1-width
  [rect-1]
  (seg-length (rect-1-bottom-seg rect-1)))

(defn- rect-1-height
  [rect-1]
  (seg-length (rect-1-left-seg rect-1)))

(defn- rect-1-perimeter
  [rect-1]
  (* 2 (+ (rect-1-width rect-1) (rect-1-height rect-1))))

(defn rect-1-area
  [rect-1]
  (* (rect-1-width rect-1) (rect-1-height rect-1)))

(def ^:private rect-1
  (make-rect-1
   (ch2-ex02/make-seg (ch2-ex02/make-point 1 0)
                      (ch2-ex02/make-point 5 0))
   (ch2-ex02/make-seg (ch2-ex02/make-point 1 0)
                      (ch2-ex02/make-point 1 42))))

(comment
  (rect-1-perimeter rect-1) ; => 92.0

  (rect-1-area rect-1) ; => 168.0
  )

(defn- make-rect-2
  [bottom-left-pt top-right-pt]
  [bottom-left-pt top-right-pt])

(def ^:private rect-2-bottom-left first)

(def ^:private rect-2-top-right second)

(defn- rect-2-bottom-right
  [rect-2]
  (ch2-ex02/make-point
   (ch2-ex02/point-x (rect-2-top-right rect-2))
   (ch2-ex02/point-y (rect-2-bottom-left rect-2))))

(defn- rect-2-width
  [rect-2]
  (seg-length
   (ch2-ex02/make-seg (rect-2-bottom-left rect-2)
                      (rect-2-bottom-right rect-2))))

(defn- rect-2-height
  [rect-2]
  (seg-length
   (ch2-ex02/make-seg (rect-2-bottom-right rect-2)
                      (rect-2-top-right rect-2))))

(defn- rect-2-perimeter
  [rect-2]
  (* 2 (+ (rect-2-width rect-2) (rect-2-height rect-2))))

(defn- rect-2-area
  [rect-2]
  (* (rect-2-width rect-2) (rect-2-height rect-2)))

(comment
  (def rect-2 (make-rect-2 (ch2-ex02/make-point 1 0)
                           (ch2-ex02/make-point 5 42)))

  (rect-2-perimeter rect-2) ; => 92.0

  (rect-2-area rect-2) ; => 168.0
  )

 

No comments: