fizz buzz, gcd, and luhn added

This commit is contained in:
Shuzo Katayama 2021-07-14 14:55:23 -04:00
parent 1698c51194
commit 883840a564
6 changed files with 227 additions and 12 deletions

2
.idea/misc.xml generated
View File

@ -7,7 +7,7 @@
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_13" project-jdk-name="openjdk-15" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_13" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -16,18 +16,20 @@
"Reports information each generation."
[pop generation argmap]
(let [best (first pop)]
(clojure.pprint/pprint {:generation generation
:best-plushy (:plushy best)
:best-program (genome/plushy->push (:plushy best) argmap)
:best-total-error (:total-error best)
:best-errors (:errors best)
:best-behaviors (:behaviors best)
:genotypic-diversity (float (/ (count (distinct (map :plushy pop))) (count pop)))
:behavioral-diversity (float (/ (count (distinct (map :behaviors pop))) (count pop)))
:average-genome-length (float (/ (reduce + (map count (map :plushy pop))) (count pop)))
:average-total-error (float (/ (reduce + (map :total-error pop)) (count pop)))})
(println {:generation generation
:best-plushy (:plushy best)
:best-program (genome/plushy->push (:plushy best) argmap)
:best-total-error (:total-error best)
:best-errors (:errors best)
:best-behaviors (:behaviors best)
:genotypic-diversity (float (/ (count (distinct (map :plushy pop))) (count pop)))
:behavioral-diversity (float (/ (count (distinct (map :behaviors pop))) (count pop)))
:average-genome-length (float (/ (reduce + (map count (map :plushy pop))) (count pop)))
:average-total-error (float (/ (reduce + (map :total-error pop)) (count pop)))})
(println)))
;; clojure.pprint/pprint
(defn gp
"Main GP loop."
[{:keys [population-size max-generations error-function instructions

View File

@ -5,7 +5,6 @@
[propeller.utils :as utils]
[propeller.push.utils.helpers :refer [get-stack-instructions]]
[propeller.push.state :as state]
[clojure.pprint :as pprint]
[propeller.tools.math :as math]))
; =========== PROBLEM DESCRIPTION ============================

View File

@ -0,0 +1,70 @@
(ns propeller.problems.PSB2.fizz-buzz
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.utils :as utils]
[propeller.push.utils.helpers :refer [get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.metrics :as metrics]))
; =========== PROBLEM DESCRIPTION =========================
; FIZZ BUZZ from PSB2
; Given an integer x, return "Fizz" if x is
; divisible by 3, "Buzz" if x is divisible by 5, "FizzBuzz" if x
; is divisible by 3 and 5, and a string version of x if none of
; the above hold.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ============================================================
(def train-and-test-data (psb2/fetch-examples "data" "fizz-buzz" 200 2000))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :boolean :string :print})
;;; input instructions
(list :in1)
;;; close
(list 'close)
;;; ERCs (constants)
(list "Fizz" "Buzz" "FizzBuzz" 0 3 5))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data)
correct-outputs (map (fn [i] (get i :output1)) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 input})
(:step-limit argmap))
:string))
inputs)
parsed-outputs (map (fn [output]
(try (read-string output)
#?(:clj (catch Exception e 1000.0)
:cljs (catch js/Error. e 1000.0))))
outputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
10000
(metrics/levenshtein-distance (str correct-output) (str output))))
correct-outputs
parsed-outputs)]
(assoc individual
:behaviors parsed-outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(def arglist
{:instructions instructions
:error-function error-function
:training-data (:train train-and-test-data)
:testing-data (:test train-and-test-data)})

View File

@ -0,0 +1,75 @@
(ns propeller.problems.PSB2.gcd
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.utils :as utils]
[propeller.push.utils.helpers :refer [get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.math :as math]))
; =========== PROBLEM DESCRIPTION ===============================
; GCD [GREATEST COMMON DIVISOR] from PSB2
; Given two integers, return the largest integer that divides each
; of the integers evenly
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ==================================================================
(def train-and-test-data (psb2/fetch-examples "data" "gcd" 200 2000))
(defn random-int [] (- (rand-int 201) 100))
(defn map-vals-input
"Returns all the input values of a map (specific helper method for bouncing-balls)"
[i]
(vals (select-keys i [:input1 :input2])))
(defn map-vals-output
"Returns the output values of a map (specific helper method for bouncing-balls)"
[i]
(get i :output1))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :boolean :print})
;;; input instructions
(list :in1 :in2)
;;; close
(list 'close)
;;; ERCs (constants)
(list random-int))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (map-vals-input i)) data)
correct-outputs (map (fn [i] (map-vals-output i)) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 (nth input 0)
:in2 (nth input 1)})
(:step-limit argmap))
:integer))
inputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
1000000.0
(min 1000.0 (math/abs (- correct-output output)))))
correct-outputs
outputs)]
(assoc individual
:behaviors outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(def arglist
{:instructions instructions
:error-function error-function
:training-data (:train train-and-test-data)
:testing-data (:test train-and-test-data)})

View File

@ -0,0 +1,69 @@
(ns propeller.problems.PSB2.luhn
(:require [psb2.core :as psb2]
[propeller.genome :as genome]
[propeller.push.interpreter :as interpreter]
[propeller.utils :as utils]
[propeller.push.utils.helpers :refer [get-stack-instructions]]
[propeller.push.state :as state]
[propeller.tools.math :as math]))
; =========== PROBLEM DESCRIPTION ============================
; LUHN from PSB2
; Given a vector of 16 digits, implement Luhns
; algorithm to verify a credit card number, such that it follows
; the following rules: double every other digit starting with
; the second digit. If any of the results are over 9, subtract 9
; from them. Return the sum of all of the new digits.
;
; Source: https://arxiv.org/pdf/2106.06086.pdf
; ===============================================================
(def train-and-test-data (psb2/fetch-examples "data" "luhn" 200 2000))
; Random integer between -100 and 100 (from smallest)
(defn random-int [] (- (rand-int 201) 100))
(def instructions
(utils/not-lazy
(concat
;;; stack-specific instructions
(get-stack-instructions #{:exec :integer :boolean :vector_integer :print})
;;; input instructions
(list :in1)
;;; close
(list 'close)
;;; ERCs (constants)
(list 0 2 9 10 random-int))))
(defn error-function
[argmap data individual]
(let [program (genome/plushy->push (:plushy individual) argmap)
inputs (map (fn [i] (get i :input1)) data)
correct-outputs (map (fn [i] (get i :output1)) data)
outputs (map (fn [input]
(state/peek-stack
(interpreter/interpret-program
program
(assoc state/empty-state :input {:in1 input})
(:step-limit argmap))
:integer))
inputs)
errors (map (fn [correct-output output]
(if (= output :no-stack-item)
1000000
(min 1000.0 (math/abs (- correct-output output)))))
correct-outputs
outputs)]
(assoc individual
:behaviors outputs
:errors errors
:total-error #?(:clj (apply +' errors)
:cljs (apply + errors)))))
(def arglist
{:instructions instructions
:error-function error-function
:training-data (:train train-and-test-data)
:testing-data (:test train-and-test-data)})