Home on obviy.us
https://obviy.us/
Recent content in Home on obviy.usHugo -- gohugo.ioen-usThu, 09 Sep 2021 00:00:00 +0000GSoC 2020 @ CERN
https://obviy.us/posts/gsoc/
Sun, 01 Nov 2020 00:00:00 +0000https://obviy.us/posts/gsoc/Google Summer of Code (GSoC) is :
A global program that matches students up with open source, free software and technology-related organizations to write code and get paid to do it! The organizations provide mentors who act as guides through the entire process, from learning about the community to contributing code. The idea is to get students involved in and familiar with the open source community and help them to put their summer break to good use.My Experience with GSoC 2020 @ CERN - Part 0
https://obviy.us/gsoc/cern-0/
Thu, 15 Oct 2020 00:00:00 +0000https://obviy.us/gsoc/cern-0/My Experience with Google Summer of Code 2020 @ CERN - Part 0 GSoC is a fantastic way to learn about open-source from one of the best engineers in the world. I knew I wanted to participate in 2020 which in hindsight was a fantastic decision due to everything closing down due to COVID-19.
I was accepted into Google Summer of Code 2020 at CERN-HSF. In this post I’ll talk about how I went about shortlisting organisations, contacting mentors and preparing my final proposal.My Experience with GSoC 2020 @ CERN - Part II
https://obviy.us/gsoc/cern-2/
Fri, 28 Aug 2020 00:00:00 +0000https://obviy.us/gsoc/cern-2/Workflow configuration import and validation for AliECS Mentored By: Teo Mrnjavac Links Google Summer of Code Page GitHub Project Page PR#171 General Overview The ALICE Experiment Control System (AliECS) is a distributed system based on state of the art cluster management and microservices which have recently emerged in the distributed computing ecosystem. AliECS is being built from scratch in Go and takes advantage of Apache Mesos for its cluster resource management capabilities, with the goal of controlling tens of thousands of processes over hundreds of nodes.My Experience with GSoC 2020 @ CERN - Part I
https://obviy.us/gsoc/cern-1/
Mon, 29 Jun 2020 00:00:00 +0000https://obviy.us/gsoc/cern-1/My Experience with Google Summer of Code 2020 @ CERN - Part I Being Selected I was confident, yet nervous. I had been in light communication with the project mentor during the selection period but you never know for sure. I had only applied to one project so I’m glad it worked out.
The Project The official title for the project is:
AliECS Workflow configuration import and validation for AliECSBookmarks
https://obviy.us/posts/bookmarks/
Sun, 08 Sep 2019 00:00:00 +0000https://obviy.us/posts/bookmarks/Some of my favorite links Missing Semester of your CS Education: one of the best online courses I have had the pleasure of studying. I highly recommend this to everyone early in their careers Existentialism Is a Humanism: this essay had a big impact on me during my formative years at university. Thanks jvoisin! How to remember anything forever-ish: an excellent explanation of Anki, the flashcards software I’ve used every day for the last ~3 years The Best Picture I Ever Clicked
https://obviy.us/posts/tibet/
Thu, 20 Jun 2019 00:00:00 +0000https://obviy.us/posts/tibet/This stack of images was shot on the 4th of June. I used a Canon 600D and a 18mm lens with ISO 3200, Aperture f/3.5 and an exposure of 18s.
Location The image above was shot at Sangla, a bit north of Shimla. I knew I needed to go somewhere with very little light pollution. DarkSiteFinder to the rescue.
The sky there was clear. I chose a spot close to our room with minimal light pollution and a view of the mountains during the day.1.1
https://obviy.us/sicp/ch01/1.10/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.10/SICP Exercise 1.10 Run the Ackermann’s function in the block below:
The functions compute to:
(f n) : 2n (g n) : 2^n (h n) : 2^2^2…(n-1) times 1.11
https://obviy.us/sicp/ch01/1.11/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.11/SICP Exercise 1.11 Recursive:
(define (f n) (cond ((< n 3) n) (else (+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))))) Iterative:
(define (f n) (define (iter a b c count) (if (= count 0) a (iter b c (+ c (* 2 b) (* 3 a)) (- count 1)))) (iter 0 1 2 n)) 1.12
https://obviy.us/sicp/ch01/1.12/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.12/SICP Exercise 1.12 Add the values of the adjacent coolumn elements in the row above.
(define (pascal-triangle row col) (cond ((> col row) 0) ((< col 0) 0) ((= col 1) 1) ((+ (pascal-triangle (- row 1) (- col 1)) (pascal-triangle (- row 1) col))))) 1.15
https://obviy.us/sicp/ch01/1.15/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.15/SICP Exercise 1.15 The formula for calculating $$ \sin x $$ is:
$$ \sin x = 3 \sin \frac{x}{3} - 4 \sin^3 \frac{x}{3} $$
Applying the procedure to (sin 12.15):
(sine 12.15) (p (sine 4.05)) (p (p (sine 1.35))) (p (p (p (sine 0.45)))) (p (p (p (p (sine 0.15))))) (p (p (p (p (p (sine 0.05)))))) (p (p (p (p (p 0.05))))) Clearly, the procedure is called 5 times.1.16
https://obviy.us/sicp/ch01/1.16/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.16/SICP Exercise 1.16 (define (square x) (* x x)) (define (expt-iter b n a) (cond ((= n 0) a) ((even? n) (expt-iter (square b) (/ n 2) a)) (else (expt-iter b (- n 1) (* a b))))) (define (fast-expt b n) (expt-iter b n 1)) The Hint suggests keeping an additional state variable such that the product $$ a b^n $$ remains unchanged from state to state. Therefore:
when n is even, $$ ab^n = a(b^{2})^{n/2} $$ when n is odd, $$ ab^n = ab(b^{n-1}) $$ 1.17
https://obviy.us/sicp/ch01/1.17/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.17/SICP Exercise 1.17 (define (fast-mult a b) (cond ((= b 0) 0) ((= b 1) a) ((even? b) (double (fast-mult a (halve b)))) (else (+ a (fast-mult a (- b 1)))))) And here’s the recursive process:
(fast-mult 3 7) (+ 3 (fast-mult 3 6)) (+ 3 (double (fast-mult 3 3)) (+ 3 (double (+ 3 (fast-mult 3 2)))) (+ 3 (double (+ 3 (double (fast-mult 3 1))))) (+ 3 (double (+ 3 (double (+ 3 (fast-mult 3 0)))))) (+ 3 (double (+ 3 (double (+ 3 0))))) (+ 3 (double (+ 3 (double 3)))) (+ 3 (double (+ 3 6))) (+ 3 (double 9)) (+ 3 18) 21 1.18
https://obviy.us/sicp/ch01/1.18/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.18/SICP Exercise 1.18 Initially I solved it the same way as fast-exp. Just remember that an iterative process can be completely defined, at any point, by its state variables.
(define (mul-iter a b) (define (iter counter a b) (cond ((= b 0) counter) ((even? b) (iter counter (double a) (halve b))) (else (iter (+ counter a) a (- b 1))))) (iter 0 a b)) (define (double x) (+ x x)) (define (halve x) (/ x 2)) 1.19
https://obviy.us/sicp/ch01/1.19/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.19/SICP Exercise 1.19 This was my favourite exercise so far. Calculating values of p' and q' was fairly easy. Applying the $$T_{pq}$$ transformation twice and factoring out a and b in each case did the trick.
$$ T_{pq} $$ is defined as:
$$ a \leftarrow bq + aq + ap $$ $$ b \leftarrow bp + aq $$
We’re told applying $$T_{pq}$$ twice has the same effect as applying $$T_{p’q'}$$ once.1.2
https://obviy.us/sicp/ch01/1.20/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.20/SICP Exercise 1.20 Normal Order: Fully expand then reduce
remainder is called 18 times
(gcd 206 40) (gcd 40 (remainder 206 40)) (gcd (remainder 206 40) (remainder 40 (remainder 206 40)) (gcd (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) (gcd (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))))) (gcd (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40)))) (remainder (remainder (remainder 206 40) (remainder 40 (remainder 206 40))) (remainder (remainder 40 (remainder 206 40)) (remainder (remainder 206 40) (remainder 40 (remainder 206 40))))))) 2 Applicative Order: Evaluate then apply1.21
https://obviy.us/sicp/ch01/1.21/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.21/SICP Exercise 1.21 > (smallest-divisor 199) 199 > (smallest-divisor 1999) 1999 > (smallest-divisor 19999) 7 1.22
https://obviy.us/sicp/ch01/1.22/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.22/SICP Exercise 1.22 I had a bit of trouble trying to figure out search-for-primes until I realised I can invoke two procedures in a single cond statement.
(define (smallest-divisor n) (find-divisor n 2)) (define (find-divisor n test-divisor) (cond ((> (square test-divisor) n) n) ((divides? test-divisor n) test-divisor) (else (find-divisor n (+ test-divisor 1))))) (define (divides? a b) (= (remainder b a) 0)) (define (square x) (* x x)) (define (prime? n) (= n (smallest-divisor n))) (define (timed-prime-test n) (start-prime-test n (runtime))) (define (start-prime-test n start-time) (if (prime?1.23
https://obviy.us/sicp/ch01/1.23/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.23/SICP Exercise 1.23 Exact same as last problem except you remove redundant checks for even numbers.
#lang sicp (define (smallest-divisor n) (find-divisor n 2)) (define (find-divisor n test-divisor) (cond ((> (square test-divisor) n) n) ((divides? test-divisor n) test-divisor) (else (find-divisor n (next test-divisor))))) (define (divides? a b) (= (remainder b a) 0)) (define (square x) (* x x)) (define (prime? n) (= n (smallest-divisor n))) (define (timed-prime-test n) (start-prime-test n (runtime))) (define (start-prime-test n start-time) (if (prime?1.24
https://obviy.us/sicp/ch01/1.24/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.24/SICP Exercise 1.24 This time prime? procedure has been replaced by fast-prime?.
(define (divides? a b) (= (remainder b a) 0)) (define (square x) (* x x)) (define (expmod base exp m) (cond ((= exp 0)1) ((even? exp) (remainder (square (expmod base (/ exp 2) m)) m)) (else (remainder (* base (expmod base (- exp 1) m)) m)))) (define (fermat-test n) (define (try-it a) (= (expmod a n n) a)) (try-it (+ 1 (random (- n 1))))) (define (fast-prime?1.25
https://obviy.us/sicp/ch01/1.25/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.25/SICP Exercise 1.25 Using fast-exp inside the expmod procedure gives us the same results but takes much longer.
This happens because good old expmod keeps squares less than the number whose primality is being checked for. fast-exp does not do that and keeps squaring the numbers to as high as $$a^m$$.
A better explanation is present at: http://community.schemewiki.org/?sicp-ex-1.251.26
https://obviy.us/sicp/ch01/1.26/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.26/SICP Exercise 1.26 (remainder (* (expmod base (/ exp 2) m) (expmod base (/ exp 2) m)) m) Using multiplication like this rather than calling square causes the expmod function to be called twice. Instead of linear recursion, the procedure now becomes a recursion tree whose execution time increases exponentially as it’s depth increases as a logarithm of N.1.27
https://obviy.us/sicp/ch01/1.27/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.27/SICP Exercise 1.27 The fermat-test procedure has been modified to test using every single number from 1 to (n-1), rather than using random numbers. The procedure prime? stays to check whether the number actually is prime using the smallest-divisor method.
(define (carmichael n) (and (fermat-test-all n) (not (prime? n)))) (define (expmod base exp m) (cond ((= exp 0) 1) ((even? exp) (remainder (square (expmod base (/ exp 2) m)) m)) (else (remainder (* base (expmod base (- exp 1) m)) m)))) (define (fermat-test-all n) (define (try-it a) (cond ((= a n) #t) ((= (expmod a n n) a) (try-it (+ a 1))) (else #f))) (try-it 1)) (define (square x) (* x x)) (define (smallest-divisor n) (find-divisor n 2)) (define (find-divisor n test-divisor) (cond ((> (square test-divisor) n) n) ((divides?1.28
https://obviy.us/sicp/ch01/1.28/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.28/SICP Exercise 1.28 By Miller-Rabin test, we should check for: $$ a^{n-1} \equiv 1(mod n) $$
The procedures themselves were easy to build. The question has a big hint:
Modify the expmod procedure to signal if it discovers a nontrivial square root of 1, and use this to implement the Miller-Rabin test with a procedure analogous to fermat-test. Check your procedure by testing various known primes and non-primes. Hint: One convenient way to make expmod signal is to have it return 0.1.29
https://obviy.us/sicp/ch01/1.29/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.29/SICP Exercise 1.29 The power of sigma notation is that it allows mathematicians to deal with the concept of summation itself rather than only with particular sums-for example, to formulate a general result about sums that are independant of the particular series being summed.
Building a procedure for the Simpson’s Rule:
$$ \int^a_b f(x) dx = \frac{h}{3} (y_0 + 4y_1 + 2y_2 + 4y_3 + 2y_4 + \dots + 2y_{n-2} + 4y_{n-1} + y_n) \$$1.3
https://obviy.us/sicp/ch01/1.3/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.3/SICP Exercise 1.3 Find the smallest, then add the other two.
(define (sum a b c) (cond ((and (< a b) (< a c)) (+ (square b) (square c))) ((and (< b a) (< b c)) (+ (square a) (square c))) (else (+ (square a) (square b))))) (define (square x) (* x x)) 1.3
https://obviy.us/sicp/ch01/1.30/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.30/SICP Exercise 1.30 The sum procedure is given as:
(define (sum term a next b) (if (> ab) 0 (+ (term a) (sum term (next a) next b)))) It can be changed to act iteratively as:
(define (sum term a next b) (define (iter a result) (if (> a b) result (iter (next a) (+ result (term a))))) (iter a 0)) 1.31
https://obviy.us/sicp/ch01/1.31/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.31/SICP Exercise 1.31 Building a procedure product analogous to sum:
(define (product term a next b) (if (> a b) 1 (* (term a) (product term (next a) next b)))) Factorial using product:
(define (product term a next b) (if (> a b) 1 (* (term a) (product term (next a) next b)))) (define (identity x) x) (define (inc x) (+ x 1)) (define (factorial n) (product identity 1 inc n)) And now using the same to calculate $$\pi$$:1.32
https://obviy.us/sicp/ch01/1.32/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.32/SICP Exercise 1.32 Defining accumulator:
(define (accumulate combiner null-value term a next b) (if (> a b) null value (combiner ((term a) (accumulate combiner null-value term (next a) next b))))) Using the above definition for building sum and product:
(define (sum term a next b) (accumulate + 0 term a next b)) (define (product term a next b) (accumulate * 1 term a next b)) And changing accumulator to be iterative:1.33
https://obviy.us/sicp/ch01/1.33/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.33/SICP Exercise 1.33 The procedure filtered-accumulator:
(define (filtered-accumulate combiner null-value term a next b filter) (if (> a b) null-value combiner (if (filter a) (term a) null-value) (filtered-accumulate combiner null-value term (next a) next b filter))) Part A: Borrowing prime? from earlier:
(define (sum-of-prime-squares a b) (filtered-accumulate + 0 square a inc b prime?)) Part B:
(define (gcd m n) (cond ((< m n) (gcd (n m))) ((= n 0) m) (else (gcd n (remainder m n))))) (define (relatively-prime?1.34
https://obviy.us/sicp/ch01/1.34/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.34/SICP Exercise 1.34 Out f procedure is defined as:
(define (f g) (g 2)) Trying to ask the interpreter to evaluate (f f):
> (f f) . . application: not a procedure; expected a procedure that can be applied to arguments given: 2 arguments...: The first time f is invoked, it will apply its argument (f) to 2. The second time it will try to apply its argument (2) to 2.1.35
https://obviy.us/sicp/ch01/1.35/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.35/SICP Exercise 1.35 Given:
$$ x \leftarrow 1 + \frac{1}{x} $$
Multiply by $$x$$ on both sides:
$$ x^2 \leftarrow x + 1 $$
Which is the defination of $$\phi$$ from 1.2.2. Now solving the quadratic gives:
$$ \phi = \frac{1 + \sqrt{5}}{2} \approx 1.6180 $$
Using fixed-point to calculate this:
(fixed-point (lambda (x) (+ 1 (/ 1 x))) 1.0) 1.36
https://obviy.us/sicp/ch01/1.36/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.36/SICP Exercise 1.36 Modified fixed-point procedure:
(define (fixed-point f first-guess) (define (close-enough? v1 v2) (display "x=") (display v1) (display " and f(x)=") (display v2) (newline) (< (abs (- v1 v2)) tolerance)) (define (try guess) (let ((next (f guess))) (if (close-enough? guess next) next (try next)))) (try first-guess)) Without average damping:
> (fixed-point (lambda (x) (/ (log 1000) (log x))) 1.1) This gives us the answer in 33 iterations.1.37
https://obviy.us/sicp/ch01/1.37/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.37/SICP Exercise 1.37 Recursive:
(define (cont-frac n d k) (cond ((= k 0) 0) (else (/ (n k) (+ (d k) (cont-frac n d (- k 1))))))) Iterative:
(define (cont-frac n dk) (define (loop result term) (if (= term 0) result (loop (/ (n term) (+ (d term) result)) (- term 1)))) (loop 0 k)) 1.38
https://obviy.us/sicp/ch01/1.38/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.38/SICP Exercise 1.38 The math was a bit tedious in this one, trying to calculate the pattern took me a while.
(define (e-euler k) (+ 2.0 (cont-frac (lambda (i) 1.0) (lambda (i) (if (= (remainder i 3) 2) (/ (+ i 1) 1.5) 1)) k))) 1.39
https://obviy.us/sicp/ch01/1.39/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.39/SICP Exercise 1.39 (define (tan-cf x k) (cont-frac (lambda (i) (if (= i 1) x (- (* x x)))) (lambda (i) (- (* i 2) 1)) k)) 1.4
https://obviy.us/sicp/ch01/1.40/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.40/SICP Exercise 1.40 (define (cubic a b c) (lambda (x) (+ (* x x x) (* a x x) (* b x) c))) 1.41
https://obviy.us/sicp/ch01/1.41/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.41/SICP Exercise 1.41 (define (double f) (lambda (x) (f ( f x)))) 1.42
https://obviy.us/sicp/ch01/1.42/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.42/SICP Exercise 1.42 (define (compose f g) (lambda (x) (f (g x)))) 1.43
https://obviy.us/sicp/ch01/1.43/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.43/SICP Exercise 1.43 (define (repeat f n) (if (= n 0) (lambda (x) x) (compose f (repeat f (- n 1))))) 1.44
https://obviy.us/sicp/ch01/1.44/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.44/SICP Exercise 1.44 (define (smooth f) (lambda (x) (/ (+ (f (- x dx)) (f x) (f (+ x dx))) 3))) (define (n-fold f n) ((repeat smooth n) f)) 1.46
https://obviy.us/sicp/ch01/1.46/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.46/SICP Exercise 1.46 (define (iterative-improve good-enough? improve) (lambda (x) (define (iter n) (if (good-enough? n) n (iter (improve n)))) (iter x))) (define (good-enough? x y) (< (abs (- x y) 0.0001))) (define (sqrt x) ((iterative-improve (lambda (y) (< (abs (- (square y) x)) 0.0001)) (lambda (y) (average y (/ x y)))) 1.0)) 1.5
https://obviy.us/sicp/ch01/1.5/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.5/SICP Exercise 1.5 Using applicative order, the code for (test 0 (p)) never terminates because it infinitely expands into itself.
(test 0 (p)) (test 0 (p)) (test 0 (p)) However, for normal eval it evaluates step-by-step to 0.
(test 0 (p)) (if (= 0 0) 0 (p)) (if #t 0 (p)) 0 1.6
https://obviy.us/sicp/ch01/1.6/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.6/SICP Exercise 1.6 Scheme uses Applicative Order Evaluation. The procedure new-if is a procedure. When it’s called all the arguments are executed.
A later augument is recursion, calling the new-if again which causes an infinite loop.
(define (sqrt-iter guess x) (new-if (good-enough? guess x) guess (sqrt-iter (improve guess x) x))) 1.7
https://obviy.us/sicp/ch01/1.7/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.7/SICP Exercise 1.7 Using absolute difference as a criteria for good-enough? will not work for calculating square roots of smaller numbers. Changing it to be a ratio instead would work for both larger and smaller numbers.
(define (sqrt-iter guess x) (if (good-enough? guess) guess (sqrt-iter (improve guess x) x))) (define (improve guess x) (average guess (/ x guess))) (define (average x y) (/ (+ x y) 2)) (define (good-enough? guess old-guess) (< (/ old-guess guess) 0.1.8
https://obviy.us/sicp/ch01/1.8/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.8/SICP Exercise 1.8 Simply implementing Newton’s method of calculating cube roots.
(define (cube-iter guess x) (if (good-enough? guess x) guess (cube-iter (improve guess x) x))) (define (improve y x) (/ (+ (/ x (* y y)) (* 2 y)) 3)) (define (good-enough? guess x) (< (abs (- (cube guess) x)) 0.0001)) (define (cube x) (* x x x)) (define (cbrt x) (cube-iter 1.0 x)) Although this program suffers from the same issue we faced in SICP Exercise 1.1.9
https://obviy.us/sicp/ch01/1.9/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch01/1.9/SICP Exercise 1.9 The first procedure is recursive and expands as:
(+ 4 5) (inc (+ (dec 4) 5)) (inc (+ 3 5)) (inc (inc (+ (dec 3) 5))) (inc (inc (+ 2 5))) (inc (inc (inc (+ (dec 2) 5)))) (inc (inc (inc (+ 1 5)))) (inc (inc (inc (inc (+ (dec 1) 5))))) (inc (inc (inc (inc (+ 0 5))))) (inc (inc (inc (inc 5)))) (inc (inc (inc 6))) (inc (inc 7)) (inc 8) 9 The second is iterative and expands like so:2.1
https://obviy.us/sicp/ch02/2.1/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.1/SICP Exercise 2.1 (define (make-rat n d) (cond ((and (< n 0) (< d 0)) (let ((g (gcd (* -1 n) (* -1 d)))) (cons (/ n g) (/ d g)))) ((< d 0) (let ((g (gcd (* -1 n) (* -1 d)))) (cons (/ n g) (/ d g)))) (else (let ((g (gcd n d)) (cons (/ n g) (/ d g)))))) 2.1
https://obviy.us/sicp/ch02/2.10/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.10/SICP Exercise 2.10 Interval spanning zero means one end is less than 0 and the other is greater than 0.
(define (div-interval x y) (if (and (<= (lower-bound y) 0) (>= (upper-bound y) 0)) (error "Interval spans 0") (mul-interval x (make-interval (/ 1.0 (upper-bound y)) (/ 1.0 (lower-bound y)))))) 2.11
https://obviy.us/sicp/ch02/2.11/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.11/SICP Exercise 2.11 The table for the min and max for each combination is as folows:
| $$L_x$$ | $$U_x$$ | $$L_y$$ | $$U_y$$ | $$L_x L_y$$ | $$L_x U_y$$ | $$U_x L_y$$ | $$U_x U_y$$ | min | max | | + | + | + | + | + | + | + | + | $$L_x L_y$$ | $$U_x U_y$$ | | + | + | - | + | - | + | + | + | $$U_x L_y$$ | $$U_x U_y$$ | | + | + | - | - | - | - | - | - | $$U_x L_y$$ | $$L_x U_y$$ | | - | + | + | + | - | - | + | + | $$L_x U_y$$ | $$U_x U_y$$ | | - | + | + | - | + | - | - | + | $$min(L_xU_y, U_x L_y)$$ | $$max (L_x L_y, U_x U_y)$$ | | - | + | - | - | + | + | - | - | $$U_x L_y$$ | $$L_x L_y$$ | | - | - | + | + | - | - | - | - | $$L_x U_y$$ | $$U_x L_y$$ | | - | - | - | + | + | - | + | - | $$L_x L_y$$ | $$L_x U_y$$ | | - | - | - | - | + | + | + | + | $$U_x U_y$$ | $$L_x L_y$$ |2.13
https://obviy.us/sicp/ch02/2.12/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.12/SICP Exercise 2.13 Straightforward solution:
(define (make-center-percent c p) (let ((tolerance (* c (/ p 100)))) (make-interval (+ c tolerance) (- c tolerance)))) (define (percent x) (* (/ abs(- (center x) (car x)) (center x)) 100)) 2.13
https://obviy.us/sicp/ch02/2.13/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.13/SICP Exercise 2.13 Let $C_a$$ be the center of an interval and $$T_a$$ be the tolerance of ‘a’. Then the interval ‘a’ spans:
$$ a = [C_a \times (1 - 0.5 T_a), C_a \times (1 + 0.5 T_a)] $$
Similarly for ‘b’:
$$ b = [C_b \times (1 - 0.5 T_b), C_b \times (1 + 0.5 T_b)] $$
The interval of ‘a*b’:
$$ \begin {align} a * b = [&C_a C_b (1 - 0.2.14
https://obviy.us/sicp/ch02/2.14/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.14/SICP Exercise 2.14 Added 3 intervals to test:
(define (par1 r1 r2) (div-interval (mul-interval r1 r2) (add-interval r1 r2))) (define (par2 r1 r2) (let ((one (make-interval 1 1))) (div-interval one (add-interval (div-interval one r1) (div-interval one r2))))) (define ina (make-center-percent 20 5)) (define inb (make-center-percent 30 1)) (define inc (make-center-percent 10 0)) Now running:
> (display (par1 ina inb)) (11.0 . 13.06570841889117) > (display (par2 ina inb)) (11.587268993839837 . 12.2.15
https://obviy.us/sicp/ch02/2.15/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.15/SICP Exercise 2.15 Eva is correct. Procedure par1 would produce tighter bounds than par2. Using the uncertain values r1 and r2 (having a non-zero width), multiple times increases the uncertainity. Therefore par1 overcompensates.
Using both the uncertain values only once, par2 avoid overcompensating and therefore returns tighter bounds.2.16
https://obviy.us/sicp/ch02/2.16/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.16/SICP Exercise 2.16 No.2.17
https://obviy.us/sicp/ch02/2.17/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.17/SICP Exercise 2.17 (define (last-pair items) (let ((l (length items))) (list-ref items (- l 1)))) (define (length items) (if (null? items) 0 (+ 1 (length (cdr items))))) (define (list-ref items n) (if (= n 0) (car items) (list-ref (cdr items) (- n 1)))) There exists a better solution without using either list-ref or length:
(define (better-last-pair items) (let ((rest (cdr items))) (if (null? rest) items (last-pair rest)))) 2.18
https://obviy.us/sicp/ch02/2.18/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.18/SICP Exercise 2.18 This one works without using either length or list-ref.
(define (reverse items) (define (iter items result) (if (null? items) result (iter (cdr items) (cons (car items) result)))) (iter items nil)) 2.19
https://obviy.us/sicp/ch02/2.19/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.19/SICP Exercise 2.19 Simple-straightforward solution.
(define (first-denomination coin-values) (car coin-values)) (define (except-first-denomination coin-values) (cdr coin-values)) (define (no-more? coin-values) (null? coin-values)) 2.2
https://obviy.us/sicp/ch02/2.2/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.2/SICP Exercise 2.2 (define (make-point x y) (cons x y)) (define (x-point p) (car p)) (define (y-point p) (cdr p)) (define (print-point p) (newline) (display "(") (display (x-point p)) (display ",") (display (y-point p)) (display ")")) (define (make-segment start-point end-point) (cons start-point end-point)) (define (start-segment segment) (car segment)) (define (end-segment segment) (cdr segment)) (define (midpoint-segment segment) (define (average a b) (/ (+ a b) 2)) (let ((a (start-segment segment)) (b (end-segment segment))) (make-point (average (x-point a) (x-point b)) (average (y-point a) (y-point b))))) 2.2
https://obviy.us/sicp/ch02/2.20/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.20/SICP Exercise 2.20 (define (same-parity first . rest) (define (same-parity-as-first? n) (or (and (even? first) (even? n)) (and (not (even? first)) (not (even? n))))) (define (build-list rest) (cond ((null? rest) nil) ((same-parity-as-first? (car rest)) (cons (car rest) (build-list (cdr rest)))) (else (build-list (cdr rest))))) (cons first (build-list rest))) 2.21
https://obviy.us/sicp/ch02/2.21/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.21/SICP Exercise 2.21 Here’s square-list made with and without using map.
(define (square-list items) (if (null? items) nil (cons (square (car items)) (square-list (cdr items))))) (define (map-square-list items) (map square items)) 2.22
https://obviy.us/sicp/ch02/2.22/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.22/SICP Exercise 2.22 This implementation of square-list is basically an extension of the reverse procedure. The difference being that the elements are squared before consed.
(define (square-list items) (define (iter things answer) (if (null? things) answer (iter (cdr things) (cons (square (car things)) answer)))) (iter items nil)) The procedure begins with an empty list. The first item in things is squared and consed as the last element of result.2.23
https://obviy.us/sicp/ch02/2.23/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.23/SICP Exercise 2.23 An easy question except I don’t know how to handle the final void returned.
(define (for-each f items) (if (not (null? items)) ((f (car items)) (for-each f (cdr items))))) 2.24
https://obviy.us/sicp/ch02/2.24/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.24/SICP Exercise 2.24 The expression (list 1 (list 2 (list 3 4))) is basically (1 (2 (3 4))). The tree structure is:
text { text-anchor: middle; font-size: small; font-weight: regular; } rect { fill: lightblue; stroke: black; opacity: 0.5; stroke-width: 1.5; }
line { stroke: black; opacity: 0.5; stroke-width: 1.5; } (1 (2 (3 4)))1(2 (3 4))2(3 4)34
2.25
https://obviy.us/sicp/ch02/2.25/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.25/SICP Exercise 2.25 This exercise is mostly hit and trial.
A.
(define items (list 1 2 (list 5 7) 9)) > (car (cdr (cdr (cdr items)))) 9 > (car (cdr (cdr items))) (5 7) > (car (cdr (car (cdr (cdr items))))) 7 B.
(define items2 (list (list 7))) > (car (car items2)) 7 C.
> (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr (car (cdr items3)))))))))))) 7 2.26
https://obviy.us/sicp/ch02/2.26/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.26/SICP Exercise 2.26 Simply running the expressions:
> (append x y) (1 2 3 4 5 6) > (cons x y) ((1 2 3) 4 5 6) > (list x y) ((1 2 3) (4 5 6)) 2.27
https://obviy.us/sicp/ch02/2.27/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.27/SICP Exercise 2.27 This implementation makes use of the reverse procedure defined earlier in 2.18.
(define (deep-reverse x) (if (pair? x) (append (deep-reverse (cdr x)) (list (deep-reverse (car x)))) x)) 2.28
https://obviy.us/sicp/ch02/2.28/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.28/SICP Exercise 2.28 (define (fringe x) (cond ((null? x) nil) ((pair? x) (append (fringe (car x)) (fringe (cdr x)))) (else (list x)))) 2.29
https://obviy.us/sicp/ch02/2.29/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.29/SICP Exercise 2.29 This was a long but fun problem.
(define (make-mobile left right) (list left right)) (define (make-branch length structure) (list length structure)) (define (left-branch mobile) (car mobile)) (define (right-branch mobile) (car (cdr mobile))) (define (branch-length branch) (car branch)) (define (branch-structure branch) (car (cdr branch))) (define (total-weight mobile) (cond ((null? mobile) 0) ((not (pair? mobile)) mobile) (else (+ (total-weight (branch-structure (left-branch mobile))) (total-weight (branch-structure (right-branch mobile))))))) (define (torque branch) (* (branch-length branch) (total-weight (branch-structure branch)))) (define (is-balanced?2.3
https://obviy.us/sicp/ch02/2.3/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.3/SICP Exercise 2.3 These are getting really long and tedious now.
(define (make-point x y) (cons x y)) (define (x-point p) (car p)) (define (y-point p) (cdr p)) (define (make-rect bottom-left top-right) (cons bottom-left top-right)) (define (bottom-left rect) (car rect)) (define (bottom-right rect) (make-point (x-point (cdr rect)) (y-point (car rect)))) (define (top-left rect) (make-point (x-point (car rect)) (y-point (cdr rect)))) (define (top-right rect) (cdr rect)) (define (width-rect rect) (abs (- (x-point (bottom-left rect)) (x-point (bottom-right rect))))) (define (height-rect rect) (abs (- (y-point (bottom-left rect)) (y-point (top-left rect))))) (define (area-rect rect) (* (width-rect rect) (height-rect rect))) (define (perimeter-rect rect) (* (+ (width-rect rect) (height-rect rect)) 2)) 2.3
https://obviy.us/sicp/ch02/2.30/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.30/SICP Exercise 2.30 Fun problem!
(define (scale-tree tree factor) (cond ((null? tree) nil) ((not (pair? tree)) (* tree factor)) (else (cons (scale-tree (car tree) factor) (scale-tree (cdr tree) factor))))) (define (scale-tree-map tree factor) (map (lambda (sub-tree) (if (pair? sub-tree) (scale-tree-map sub-tree factor) (* sub-tree factor))) tree)) (define (square-tree tree) (cond ((null? tree) nil) ((not (pair? tree)) (square tree)) (else (cons (square-tree (car tree)) (square-tree (cdr tree)))))) (define (square-tree-map tree) (map (lambda (sub-tree) (if (pair?2.31
https://obviy.us/sicp/ch02/2.31/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.31/SICP Exercise 2.31 Abstracting away the previous procedure to use any function is pretty neat. The hardest part for me is not letting random paranthesis' ruin my program.
(define (tree-map f tree) (map (lambda (sub-tree) (if (pair? sub-tree) (tree-map f sub-tree) (f sub-tree))) tree)) Here’s a few test cases:
> (tree-map square (list 1 2 3 4 (list 5 6 7) (list 7 8 9))) (1 4 9 16 (25 36 49) (49 64 81)) > (tree-map cube (list 1 2 3 4 (list 5 6 7) (list 7 8 9))) (1 8 27 64 (125 216 343) (343 512 729)) 2.32
https://obviy.us/sicp/ch02/2.32/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.32/SICP Exercise 2.32 This problem is similar to the count-change problem. The set of all subsets is the union of:
the set of all subsets without the first number the set of all subsets without the first number, with the first number inserted into each subset The obviyus answer is recursion.
(define (subsets s) (if (null? s) (list nil) (let ((rest (subsets (cdr s)))) (append rest (map (lambda (x) (cons (car s) x)) rest))))) Here’s a test case:2.33
https://obviy.us/sicp/ch02/2.33/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.33/SICP Exercise 2.33 A.
(define (map p sequence) (accumulate (lambda (x y) (if (null? y) nil (cons (x (car y)) (lambda x (cdr y))))) nil sequence)) B.
(define (append seq1 seq2) (accumulate cons seq2 seq1)) C.
(define (length sequence) (accumulate (lambda (x y) ((+ 1 y))) 0 sequence)) 2.34
https://obviy.us/sicp/ch02/2.34/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.34/SICP Exercise 2.34 In the example we have: $$ 1 + 3x + 5x^3 + x^5 $$. We can rewrite this as:
$$ 1 + 3x + 0x^2 + 5x^3 + 0x^4 + x^5 $$
Where:
$$ a_0 \rightarrow 1 \
a_1 \rightarrow 3 \
a_2 \rightarrow 0 \
a_3 \rightarrow 5 \
a_4 \rightarrow 0 \
a_5 \rightarrow 1 $$
Horner’s rule states:
$$ \begin{align} p(x) &= a_0 + a_1x + a_2x^2 + a_3x^3 + \dots + a_nx^n \2.35
https://obviy.us/sicp/ch02/2.35/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.35/SICP Exercise 2.35 Using recusrion to solve without using enumerate:
(define (count-leaves t) (accumulate + 0 (map (lambda (sub-tree) (if (pair? sub-tree) (count-leaves sub-tree) 1)) t))) 2.36
https://obviy.us/sicp/ch02/2.36/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.36/SICP Exercise 2.36 (define (accumulate-n op init seqs) (if (null? (car seqs)) nil (cons (accumulate op init (map car seqs)) (accumulate-n op init (map cdr seqs))))) 2.37
https://obviy.us/sicp/ch02/2.37/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.37/SICP Exercise 2.37 This was one of the hardest problems yet.
(define (dot-product v w) (accumulate + 0 (map * v w))) (define (matrix-*-vector m v) (map (lambda (row-m) (dot-product row-m v)) m)) (define (transpose mat) (accumulate-n cons nil mat)) (define (matrix-*-matrix m n) (let ((cols (transpose n))) (map (lambda (row-m) (matrix-*-vector cols row-m)) m))) 2.38
https://obviy.us/sicp/ch02/2.38/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.38/SICP Exercise 2.38 Comparing:
> (accumulate / 1.0 (list 1 2 3)) 1.5 > (fold-left / 1.0 (list 1 2 3)) 0.16666666666666666 > (accumulate list nil (list 1 2 3)) (1 (2 (3 ()))) > (fold-left list nil (list 1 2 3)) (((() 1) 2) 3) The op must be commutative and associative.2.39
https://obviy.us/sicp/ch02/2.39/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.39/SICP Exercise 2.39 The procedure reverse-fl is simply consing the elemets.
(define (reverse-fl sequence) (fold-left (lambda (x y) (cons y x)) nil sequence)) For reverse-fr, simply using cns ruins the structure of the list. Using append is a better approach.
(define (reverse-fr sequence) (fold-right (lambda (x y) (append y (list x))) nil sequence)) 2.4
https://obviy.us/sicp/ch02/2.4/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.4/SICP Exercise 2.4 Using applicative-order evaluation on car:
(car (cons x y)) (car (lambda (m) (m x y))) ((lambda (m) (m x y)) (lambda (p q) p)) ((lambda (p q) p) x y) x Similarly, cdr is:
(define (cdr z) (z (lambda (p q) q))) 2.4
https://obviy.us/sicp/ch02/2.40/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.40/SICP Exercise 2.40 Unique pairs is simply the portion of the procedure earlier that builds our lists.
(define (unique-pairs n) (flatmap (lambda (i) (map (lambda (j) (list i j)) (enumerate-interval 1 (- i 1)))) (enumerate-interval 1 n))) (define (prime-sum-pairs n) (map make-pair-sum (filter prime-sum? (unique-pairs n)))) 2.41
https://obviy.us/sicp/ch02/2.41/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.41/SICP Exercise 2.41 (define (triple-sum s n) (define (sum-to-s? triple) (= s (+ (car triple) (cadr triple) (caddr triple)))) (define (unique-triples n) (flatmap (lambda (i) (flatmap (lambda (j) (map (lambda (k) (list i j k)) (enumerate-interval 1 (- j 1)))) (enumerate-interval 1 (- i 1)))) (enumerate-interval 1 n)) (filter sum-to-s? (unique-triples n)))) 2.5
https://obviy.us/sicp/ch02/2.5/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.5/SICP Exercise 2.5 Great exercise! The procedure cons is defined as:
(define (cons a b) (* (exp 2 a) (exp 3 b))) Using exp procedure from earlier. And for car and cdr:
(define (car x) (define (iter x count) (if (= (remainder x 2) 0) (iter (/ x 2) (+ count 1)) count)) (iter x 0)) (define (cdr x) (define (iter x count) (if (= (remainder x 3) 0) (iter (/ x 3) (+ count 1)) count)) (iter x 0)) Simple explanation:2.6
https://obviy.us/sicp/ch02/2.6/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.6/SICP Exercise 2.6 zero and add-1 are defined as:
(define zero (lambda (f) (lambda (x) x))) (define (add-1 n) (lambda (f) (lambda (x) (f ((n f) x))))) With these definitions we can calculate one and two.
one is add-1 applied to zero:
> (add-1 zero) > (lambda (f) (lambda (x) (f ((zero f) x)))) As zero is an identity function (i.e. (f x) returns x) one reduces to:2.7
https://obviy.us/sicp/ch02/2.7/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.7/SICP Exercise 2.7 (define (upper-bound x) (cdr x)) (define (lower-bound x) (car x)) 2.8
https://obviy.us/sicp/ch02/2.8/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.8/SICP Exercise 2.8 (define (sub-interval x y) (make-interval (- (lower-bound x) (lower-bound y)) (- (upper-bound x) (upper-bound y)))) 2.9
https://obviy.us/sicp/ch02/2.9/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/sicp/ch02/2.9/SICP Exercise 2.9 We know:
$$ width = \frac{(upper bound) - (lower bound)}{2} $$
The add-interval procedure adds the lower-bound and upper-bound of both the intervals passed to it. Let the two intervals be $$x$$ and $$y$$:
$$ width (x) = \frac{U_x - L_x}{2} \
width (y) = \frac{U_y - L_y}{2} $$
Running:
(add-interval x y) Let’s call this new interval sum. The width is:
$$ width (sum) = \frac{U_s - L_s}{2} $$Structure and Interpretation of Computer Programs
https://obviy.us/posts/sicp/
Mon, 01 Jan 0001 00:00:00 +0000https://obviy.us/posts/sicp/Introduction Why? Structure and Interpretation of Computer Programs has been recommended to me time and time again. I’ve seen it being praised on Reddit and HackerNews a million times. I think it’s worth giving it a try.
Those who hate SICP think it doesn’t deliver enough tips and tricks for the amount of time it takes to read. But if you’re like me, you’re not looking for one more trick, rather you’re looking for a way of synthesizing what you already know, and building a rich framework onto which you can add new learning over a career.