lispy.el demo 4: Project Euler p100 and Clojure

Back to github This file in org-mode Function reference

Intro

This demo will showcase expanding Clojure's iterate with Emacs macros.

Task summary

See a step-by-step solution of https://projecteuler.net/problem=100.

Screencast

The screencast for this demo is here: http://youtu.be/tcI4gZ3eHaw

Step-by-step

step 1

Start with this code (sorry for spoiling):

;; If a box contains twenty-one coloured discs, composed of fifteen blue
;; discs and six red discs, and two discs were taken at random, it can be
;; seen that the probability of taking two blue discs, P(BB) =
;; (15/21)×(14/20) = 1/2.

;; The next such arrangement, for which there is exactly 50% chance of
;; taking two blue discs at random, is a box containing eighty-five blue
;; discs and thirty-five red discs.

;; By finding the first arrangement to contain over 1012 =
;; 1,000,000,000,000 discs in total, determine the number of blue discs
;; that the box would contain.

;; 1+4*r+√(8*r^2+1)>2e12=x
;; 8*r^2+1>(x-1)^2+16*r^2-8*r*(x-1)
;; 8*r*r-8*r(x-1)+(x-1)^2-1<0
;; solve=> r> 292893218813
;; for blue to be integer, the req is 8*r*r+1 is square
(defn blue [red]
  (BigInteger/valueOf (/ (+ 1 (* 2 red) (Math/sqrt (+ 1 (* 8 red red)))) 2)))
(defn next-red [[a b]]
  [b (- (* b 6) a)])
(defn solution []
  (->> (filter #(> (+ % (blue %)) 1e12)
               (map first (iterate next-red [6N 35N]))) first blue))
(solution)

step 2

Fire up cider and eval everything with ejeje.

step 3

  • k3f to jump to the filter statement
  • 2m to select the lambda
  • n to copy
  • A jump to beginning of defun
  • j C-n C-n navigate to some empty space

step 4

  • ( C-y C-j
  • (first}6N 35N

You should now have:

(#(> (+ % (blue %)) 1e12)
 (first [6N 35N]))

step 5

  • C-f A navigate to the start
  • e eval to get false

step 6

  • <f3> to start recording a macro
  • fjf to navigate to the array
  • 2(next-red to wrap the array
  • [xr to eval and replace
  • A to navigate to the start
  • E to eval and insert
  • <f4> to finish the macro

step 7

Keep spamming <f4> until you get true.

step 8

  • fj2(blue[E to get the solution
  • hkE to double-check