Skip to content

Commit

Permalink
Exercise 1.23 (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
SmetDenis authored Oct 20, 2023
1 parent 9d22560 commit aea2c85
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 6 deletions.
10 changes: 5 additions & 5 deletions src/sicp/chapter_1/part_2/ex_1_22.clj
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@
; to the number of steps required for the computation?

(defn find-primes
[from to]
[from to print-log]
(cond (>= from to) (do
; (println "finish")
(when print-log (println "finish"))
from)
(even? from) (find-primes (+ from 1) to) ; Just skip to the next odd
(even? from) (find-primes (+ from 1) to print-log) ; Just skip to the next odd
:else (do
; (println from)
(find-primes (+ from 2) to)))) ; Takes only odds
(when print-log (println from))
(find-primes (+ from 2) to print-log)))) ; Takes only odds
43 changes: 43 additions & 0 deletions src/sicp/chapter_1/part_2/ex_1_23.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(ns sicp.chapter-1.part_2.ex-1-23)

; Exercise 1.23
; The smallest-divisor procedure shown at the start of this section does lots of needless testing:
; After it checks to see if the number is divisible by 2 there is no point in checking to see
; if it is divisible by any larger even numbers.
;
; This suggests that the values used for test-divisor should not be 2, 3, 4, 5, 6, …, but rather 2, 3, 5, 7, 9, ….
;
; To implement this change, define a procedure next that returns 3 if its input is equal to 2
; and otherwise returns its input plus 2.
;
; Modify the smallest-divisor procedure to use (next test-divisor) instead of (+ test-divisor 1).
;
; With timed-prime-test incorporating this modified version of smallest-divisor,
; run the test for each of the 12 primes found in Exercise 1.22.
;
; Since this modification halves the number of test steps, you should expect it to run about twice as fast.
;
; Is this expectation confirmed? If not, what is the observed ratio of the speeds of the two algorithms,
; and how do you explain the fact that it is different from 2?

(defn next-odd
[x]
(if (= x 2) 3 (+ x 2)))

(defn divides?
[a b]
(= (mod b a) 0))

(defn find-divisor
[num test-divisor]
(cond (> (* test-divisor test-divisor) num) num
(divides? test-divisor num) test-divisor
:else (find-divisor num (next-odd test-divisor))))

(defn smallest-divisor
[num]
(find-divisor num 2))

(defn prime?
[n]
(= n (smallest-divisor n)))
2 changes: 1 addition & 1 deletion test/sicp/chapter_1/part_2/ex_1_22_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
[sicp.chapter-1.part_2.ex-1-22 :refer [find-primes]]))

(deftest find-primes-test
(is (= 5 (find-primes 1 5)))) ; Change arguments and see the output
(is (= 5 (find-primes 1 5 false)))) ; Change arguments and see the output
40 changes: 40 additions & 0 deletions test/sicp/chapter_1/part_2/ex_1_23_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
(ns sicp.chapter-1.part_2.ex-1-23-test
(:require [clojure.test :refer [deftest is]]
[sicp.chapter-1.part_2.ex-1-23 :refer [find-divisor next-odd prime? smallest-divisor]]))

(deftest next-odd-test
(is (= 3 (next-odd 1)))
(is (= 3 (next-odd 2)))
(is (= 5 (next-odd 3)))
(is (= 6 (next-odd 4)))
(is (= 7 (next-odd 5))))

(deftest smallest-divisor-test
(is (= 2 (smallest-divisor 2)))
(is (= 3 (smallest-divisor 3)))
(is (= 2 (smallest-divisor 6)))
(is (= 2 (smallest-divisor 30)))
(is (= 11 (smallest-divisor 11)))
(is (= 31 (smallest-divisor 31))))

(deftest find-divisor-test
(is (= 2 (find-divisor 2 4)))
(is (= 5 (find-divisor 5 35)))
(is (= 7 (find-divisor 7 35)))
(is (= 100 (find-divisor 100 100)))
(is (= 10 (find-divisor 10 100))))

(deftest prime?-test
; Prime
(is (= true (prime? 1)))
(is (= true (prime? 2)))
(is (= true (prime? 3)))
(is (= true (prime? 5)))
(is (= true (prime? 7)))
(is (= true (prime? 11)))
(is (= true (prime? 23)))
; Not prime
(is (= false (prime? 4)))
(is (= false (prime? 6)))
(is (= false (prime? 8)))
(is (= false (prime? 20))))

0 comments on commit aea2c85

Please sign in to comment.