From 6b454451d7d8d415c40dd14dcc8a608cbc21794b Mon Sep 17 00:00:00 2001 From: Nic McPhee Date: Fri, 11 Feb 2022 17:27:33 -0600 Subject: [PATCH 1/4] Fix the `_from_string` instruction This replaces the dangerous use of `read-string`with `parseInt` and `parseFloat`, and returns `ignore-instruction` if an exception is thrown when trying to do the parsing. Hopefully this will fix the stack overflow problems with the PSB2 Middle Character and Twitter problems. --- src/propeller/push/instructions/numeric.cljc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/propeller/push/instructions/numeric.cljc b/src/propeller/push/instructions/numeric.cljc index b9cbf1f..455dad4 100755 --- a/src/propeller/push/instructions/numeric.cljc +++ b/src/propeller/push/instructions/numeric.cljc @@ -121,9 +121,13 @@ :name "_from_string"} (fn [stack state] (make-instruction state - #(try ((if (= stack :integer) int float) (read-string %)) - #?(:clj (catch Exception e) - :cljs (catch js/Error. e))) + #(try (if (= stack :integer) + #?(:clj (Integer/parseInt %) + :cljs (js/parseInt %)) + #?(:clj (Float/parseFloat %) + :cljs (js/parseFloat %))) + #?(:clj (catch Exception e :ignore-instruction) + :cljs (catch js/Error e :ignore-instruction))) [:string] stack))) From cb33af755a775770d67eb4645e287a7170458a58 Mon Sep 17 00:00:00 2001 From: Nic McPhee Date: Fri, 25 Feb 2022 16:29:02 -0600 Subject: [PATCH 2/4] Remove unnecessary use of `read-string` in Middle Character For some reason `read-string` was being called to parse a string to a string in Middle Character, along with a totally unnecessary try/catch block. This cleans that up. It looks like most if not all of the PSB2 problems have this issue and we'll need to go through and update all of those to not use `read-string`. --- src/propeller/problems/PSB2/middle_character.cljc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/propeller/problems/PSB2/middle_character.cljc b/src/propeller/problems/PSB2/middle_character.cljc index f9a4b18..ee2378b 100644 --- a/src/propeller/problems/PSB2/middle_character.cljc +++ b/src/propeller/problems/PSB2/middle_character.cljc @@ -48,9 +48,9 @@ :string)) inputs) parsed-outputs (map (fn [output] - (try (read-string output) - #?(:clj (catch Exception e 1000.0) - :cljs (catch js/Error. e 1000.0)))) + (if (= output :no-stack-item) + 1000.0 + output)) outputs) errors (map (fn [correct-output output] (if (= output :no-stack-item) From 404e640cfb19c64f9dfee0aa73eb9a37fbf9f4a8 Mon Sep 17 00:00:00 2001 From: Nic McPhee Date: Fri, 25 Feb 2022 16:49:45 -0600 Subject: [PATCH 3/4] Further improve Middle Character and Twitter Upon further inspection, Richard and I realized that we didn't need to have `parsed-outputs` at all in problems that just return a string (take the top value from the `:string` stack). So we removed all that from the Middle Character and Twitter problems, and removed the unnecessary calls to `str` in the `levenshtein-distance` calls. Co-authored-by: RichardLussier --- src/propeller/problems/PSB2/middle_character.cljc | 11 +++-------- src/propeller/problems/PSB2/twitter.cljc | 11 +++-------- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/propeller/problems/PSB2/middle_character.cljc b/src/propeller/problems/PSB2/middle_character.cljc index ee2378b..a665d9b 100644 --- a/src/propeller/problems/PSB2/middle_character.cljc +++ b/src/propeller/problems/PSB2/middle_character.cljc @@ -47,19 +47,14 @@ (:step-limit argmap)) :string)) inputs) - parsed-outputs (map (fn [output] - (if (= output :no-stack-item) - 1000.0 - output)) - outputs) errors (map (fn [correct-output output] (if (= output :no-stack-item) 10000 - (metrics/levenshtein-distance (str correct-output) (str output)))) + (metrics/levenshtein-distance correct-output output))) correct-outputs - parsed-outputs)] + outputs)] (assoc individual - :behaviors parsed-outputs + :behaviors outputs :errors errors :total-error #?(:clj (apply +' errors) :cljs (apply + errors))))) diff --git a/src/propeller/problems/PSB2/twitter.cljc b/src/propeller/problems/PSB2/twitter.cljc index 3d70851..95273e2 100644 --- a/src/propeller/problems/PSB2/twitter.cljc +++ b/src/propeller/problems/PSB2/twitter.cljc @@ -50,19 +50,14 @@ (: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)))) + (metrics/levenshtein-distance correct-output output))) correct-outputs - parsed-outputs)] + outputs)] (assoc individual - :behaviors parsed-outputs + :behaviors outputs :errors errors :total-error #?(:clj (apply +' errors) :cljs (apply + errors))))) From c6f08d4ca30154cd8166aaa37810cf7257657d16 Mon Sep 17 00:00:00 2001 From: RichardLussier Date: Thu, 3 Mar 2022 14:44:09 -0600 Subject: [PATCH 4/4] Fix other read-string uses in PSB2 problems Since removing 'read-string' and 'str' from middle-character and twitter seemed to help diversify the outputs, we chose to replace all other occurrences of this pattern from the other PSB2 problems. Additionally, this conversion with 'read-string' and 'str' was completely unnecessary since the program was already taking from the top of the string stack. --- src/propeller/problems/PSB2/camel_case.cljc | 9 ++------- src/propeller/problems/PSB2/fizz_buzz.cljc | 11 +++-------- src/propeller/problems/PSB2/spin_words.cljc | 9 ++------- src/propeller/problems/PSB2/square_digits.cljc | 11 +++-------- src/propeller/problems/PSB2/substitution_cipher.cljc | 11 +++-------- 5 files changed, 13 insertions(+), 38 deletions(-) diff --git a/src/propeller/problems/PSB2/camel_case.cljc b/src/propeller/problems/PSB2/camel_case.cljc index 99b20be..ba80c6b 100644 --- a/src/propeller/problems/PSB2/camel_case.cljc +++ b/src/propeller/problems/PSB2/camel_case.cljc @@ -78,19 +78,14 @@ (: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 correct-output output))) correct-outputs - parsed-outputs)] + outputs)] (assoc individual - :behaviors parsed-outputs + :behaviors outputs :errors errors :total-error #?(:clj (apply +' errors) :cljs (apply + errors))))) diff --git a/src/propeller/problems/PSB2/fizz_buzz.cljc b/src/propeller/problems/PSB2/fizz_buzz.cljc index 4b892e7..ee1f536 100644 --- a/src/propeller/problems/PSB2/fizz_buzz.cljc +++ b/src/propeller/problems/PSB2/fizz_buzz.cljc @@ -46,19 +46,14 @@ (: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)))) + (metrics/levenshtein-distance correct-output output))) correct-outputs - parsed-outputs)] + outputs)] (assoc individual - :behaviors parsed-outputs + :behaviors outputs :errors errors :total-error #?(:clj (apply +' errors) :cljs (apply + errors))))) diff --git a/src/propeller/problems/PSB2/spin_words.cljc b/src/propeller/problems/PSB2/spin_words.cljc index 5698f7a..b25386a 100644 --- a/src/propeller/problems/PSB2/spin_words.cljc +++ b/src/propeller/problems/PSB2/spin_words.cljc @@ -74,19 +74,14 @@ (: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 correct-output output))) correct-outputs - parsed-outputs)] + outputs)] (assoc individual - :behaviors parsed-outputs + :behaviors outputs :errors errors :total-error #?(:clj (apply +' errors) :cljs (apply + errors))))) diff --git a/src/propeller/problems/PSB2/square_digits.cljc b/src/propeller/problems/PSB2/square_digits.cljc index bc3bc61..76b1a24 100644 --- a/src/propeller/problems/PSB2/square_digits.cljc +++ b/src/propeller/problems/PSB2/square_digits.cljc @@ -46,19 +46,14 @@ (: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)))) + (metrics/levenshtein-distance correct-output output))) correct-outputs - parsed-outputs)] + outputs)] (assoc individual - :behaviors parsed-outputs + :behaviors outputs :errors errors :total-error #?(:clj (apply +' errors) :cljs (apply + errors))))) diff --git a/src/propeller/problems/PSB2/substitution_cipher.cljc b/src/propeller/problems/PSB2/substitution_cipher.cljc index 3f83e64..f6b5d49 100644 --- a/src/propeller/problems/PSB2/substitution_cipher.cljc +++ b/src/propeller/problems/PSB2/substitution_cipher.cljc @@ -59,19 +59,14 @@ (: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)))) + (metrics/levenshtein-distance correct-output output))) correct-outputs - parsed-outputs)] + outputs)] (assoc individual - :behaviors parsed-outputs + :behaviors outputs :errors errors :total-error #?(:clj (apply +' errors) :cljs (apply + errors)))))