474d88a2af2e

Refactor to remove some boilerplate
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 23 Feb 2019 12:42:07 -0500
parents ca95211a2d98
children 64aa58880d55
branches/tags (none)
files src/problems/iev.lisp src/problems/iprb.lisp src/problems/lia.lisp src/problems/prob.lisp src/problems/prtm.lisp src/problems/rstr.lisp src/utils.lisp

Changes

--- a/src/problems/iev.lisp	Fri Feb 22 19:32:24 2019 -0500
+++ b/src/problems/iev.lisp	Sat Feb 23 12:42:07 2019 -0500
@@ -9,14 +9,13 @@
          (hh (read data))
          (hr (read data))
          (rr (read data)))
-    (format nil "~,4F"
-            ;; It's just a weighted average…
-            (* 2 (+ (* dd 1)
-                    (* dh 1)
-                    (* dr 1)
-                    (* hh 3/4)
-                    (* hr 1/2)
-                    (* rr 0))))))
+    (float-string
+      ;; It's just a weighted average…
+      (* 2 (+ (* dd 1)
+              (* dh 1)
+              (* dr 1)
+              (* hh 3/4)
+              (* hr 1/2)
+              (* rr 0)))
+      4)))
 
-;; (problem-iev)
-;; (solve iev)
--- a/src/problems/iprb.lisp	Fri Feb 22 19:32:24 2019 -0500
+++ b/src/problems/iprb.lisp	Sat Feb 23 12:42:07 2019 -0500
@@ -24,13 +24,14 @@
              ;;          = 2XY/N²-N
              (/ (* 2 x y)
                 (- (* n n) n))))
-      (format nil "~,5F"
-              (+ (* (p-same d d) 1)      ;; AA AA
-                 (* (p-diff d h) 1)      ;; AA Aa
-                 (* (p-diff d r) 1)      ;; AA aa
-                 (* (p-same h h) 3/4)    ;; Aa Aa
-                 (* (p-diff h r) 1/2)    ;; Aa aa
-                 (* (p-same r r) 0)))))) ;; aa aa
+      (float-string
+        (+ (* (p-same d d) 1)      ;; AA AA
+           (* (p-diff d h) 1)      ;; AA Aa
+           (* (p-diff d r) 1)      ;; AA aa
+           (* (p-same h h) 3/4)    ;; Aa Aa
+           (* (p-diff h r) 1/2)    ;; Aa aa
+           (* (p-same r r) 0))
+        5)))) ;; aa aa
 
 ;; (problem-iprb)
 ;; (solve iprb)
--- a/src/problems/lia.lisp	Fri Feb 22 19:32:24 2019 -0500
+++ b/src/problems/lia.lisp	Sat Feb 23 12:42:07 2019 -0500
@@ -51,4 +51,4 @@
   (let* ((generations (read data))
          (target (read data))
          (population (expt 2 generations)))
-    (format nil "~,3F" (bernoulli-at-least target population 1/4))))
+    (float-string (bernoulli-at-least target population 1/4))))
--- a/src/problems/prob.lisp	Fri Feb 22 19:32:24 2019 -0500
+++ b/src/problems/prob.lisp	Sat Feb 23 12:42:07 2019 -0500
@@ -18,4 +18,4 @@
            (iterate
              (for base :in-string dna)
              (summing (log (base-probability gc-content base) 10)))))
-      (format nil "~{~,3F~^ ~}" (mapcar #'prob gc-contents)))))
+      (float-string (mapcar #'prob gc-contents)))))
--- a/src/problems/prtm.lisp	Fri Feb 22 19:32:24 2019 -0500
+++ b/src/problems/prtm.lisp	Sat Feb 23 12:42:07 2019 -0500
@@ -36,6 +36,6 @@
   (-<> data
     (delete #\newline <>)
     (summation <> :key #'monoisotopic-mass)
-    (format nil "~,3F" <>)))
+    float-string))
 
 
--- a/src/problems/rstr.lisp	Fri Feb 22 19:32:24 2019 -0500
+++ b/src/problems/rstr.lisp	Sat Feb 23 12:42:07 2019 -0500
@@ -12,5 +12,5 @@
   (let* ((n (read data))
          (gc (coerce (read data) 'double-float))
          (dna (read-line data))
-         (prob (product dna :key (curry #'base-probability gc))))
-    (format nil "~,3F" (- 1 (expt (- 1 prob) n)))))
+         (prob (sequence-probability gc dna)))
+    (float-string (- 1 (expt (- 1 prob) n)))))
--- a/src/utils.lisp	Fri Feb 22 19:32:24 2019 -0500
+++ b/src/utils.lisp	Sat Feb 23 12:42:07 2019 -0500
@@ -95,6 +95,10 @@
     (/ gc-content 2)
     (/ (- 1 gc-content) 2)))
 
+(defun sequence-probability (gc-content sequence)
+  "Return the probability of seeing `sequence` when generating a random sequence with the given `gc-content`."
+  (product sequence :key (curry #'base-probability gc-content)))
+
 
 (defun mapcount (predicate sequence &rest more-sequences)
   "Map `predicate` across sequences, counting satisfactory applications."
@@ -107,6 +111,12 @@
     result))
 
 
+(defun ensure-list (value)
+  (if (listp value)
+    value
+    (list value)))
+
+
 ;;;; Math ---------------------------------------------------------------------
 (defmacro do-sum ((var from to) &body body)
   "Sum `body` with `var` iterating over `[from, to]`.
@@ -354,6 +364,13 @@
                 first)))
 
 
+;;;; Output -------------------------------------------------------------------
+(defun float-string (float-or-floats &optional (precision 3))
+  (with-output-to-string (s)
+    (loop :for (float . more) :on (ensure-list float-or-floats)
+          :do (format s "~,VF~:[~; ~]" precision float more))))
+
+
 ;;;; Testing ------------------------------------------------------------------
 (defmacro define-test (problem input output &optional (test 'string=))
   `(test ,(symb 'test- problem)