From d337bd2e904d95a02dab3e2cd2c305aadc868852 Mon Sep 17 00:00:00 2001 From: Stuart Halloway Date: Tue, 23 Aug 2011 22:37:57 -0400 Subject: [PATCH 1/3] use the approach taken in the Java version --- element-recursion/josephus.clj | 46 +++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/element-recursion/josephus.clj b/element-recursion/josephus.clj index 5c1c3a5..5dd9a61 100644 --- a/element-recursion/josephus.clj +++ b/element-recursion/josephus.clj @@ -1,18 +1,35 @@ -(defn vec-range [start end] - (loop [start start r (transient [])] - (if (= start end) - (persistent! r) - (recur (inc start) (conj! r start))))) +;; contributed by Stuart Halloway +;; This is not idiomatic Clojure, rather, a simple-minded post of the +;; Java code, in the name of an apples-apples comparison. -(defn shout [people n counter] - (cond - (= (count people) 1) (nth people 0) - (zero? counter) (recur (subvec people 1) n (inc counter)) - :else (let [counter (if (= counter (dec n)) 0 (inc counter))] - (recur (conj (subvec people 1) (nth people 0)) n counter)))) +(import [java.util ArrayList LinkedList List ListIterator]) -(defn josephus [people nth] - (shout (vec-range 1 (inc people)) nth 0)) +(set! *warn-on-reflection* true) + +(defn countoff + [^ListIterator ring ^LinkedList reset kth k] + (loop [ring ring + reset reset + kth (int kth) + k (int k)] + (if (.hasNext ring) + (do + (.next ring) + (if (not= k kth) + (recur ring reset kth (inc k)) + (do + (.remove ring) + (recur ring reset kth (int 1))))) + (if (> (.nextIndex ring) 1) + (recur (.listIterator reset (int 0)) reset kth k) + (.previous ring))))) + +(defn josephus + [n kth] + (let [soldiers (LinkedList.)] + (dotimes [i n] + (.add soldiers (inc i))) + (countoff (.listIterator soldiers) soldiers kth kth))) (defn run-iterations [iterations times] (dotimes [_ times] @@ -23,4 +40,5 @@ (println (float (/ (- end start) (* 1000 iterations)))))))) (println (josephus 40 3)) -(run-iterations 1000000 10) +(run-iterations 100000 10) + From 7ae444818e361e8a8349b93bc79f49e9d58959ee Mon Sep 17 00:00:00 2001 From: Dhananjay Nene Date: Thu, 25 Aug 2011 06:22:13 +0800 Subject: [PATCH 2/3] Javascript and Java Enhancements via Isaac and Clojure java structures version via David --- .../isaac/oo_and_element_recursion/Chain.java | 21 +++++ .../oo_and_element_recursion/Shootout.java | 15 ++++ .../oo_and_element_recursion/Soldier.java | 50 +++++++++++ .../oo_and_element_recursion/josephus.js | 87 +++++++++++++++++++ {combined => element-recursion}/Chain.java | 41 --------- element-recursion/josephus-java.clj | 38 ++++++++ element-recursion/josephus.js | 73 +++++++++------- list-reduction/Chain.java | 51 +++++++++++ list-reduction/josephus-java.clj | 50 +++++++++++ list-reduction/josephus.js | 67 ++++++++------ oo/josephus.js | 87 +++++++++++++++++++ 11 files changed, 481 insertions(+), 99 deletions(-) create mode 100644 contrib/isaac/oo_and_element_recursion/Chain.java create mode 100644 contrib/isaac/oo_and_element_recursion/Shootout.java create mode 100644 contrib/isaac/oo_and_element_recursion/Soldier.java create mode 100644 contrib/isaac/oo_and_element_recursion/josephus.js rename {combined => element-recursion}/Chain.java (63%) create mode 100644 element-recursion/josephus-java.clj create mode 100644 list-reduction/Chain.java create mode 100644 list-reduction/josephus-java.clj create mode 100644 oo/josephus.js diff --git a/contrib/isaac/oo_and_element_recursion/Chain.java b/contrib/isaac/oo_and_element_recursion/Chain.java new file mode 100644 index 0000000..0618c4f --- /dev/null +++ b/contrib/isaac/oo_and_element_recursion/Chain.java @@ -0,0 +1,21 @@ +public class Chain { + + public static void runIterations(int iterations, int times) { + for(int t = 0 ; t < times; t++) { + System.gc(); + long start = System.nanoTime(); + for(int i = 0; i < iterations ; i++) { + Soldier.countoffSoldiers(40,3); + } + long end = System.nanoTime(); + System.out.println(((end - start) * 1.0)/ (iterations * 1000 )); + } + } + + public static void main(String[] args) { + int ITER = 1000000; + System.out.println("Element Recursion Object Oriented"); + System.out.println(Soldier.countoffSoldiers(40,3) ); + runIterations(ITER,10); + } +} diff --git a/contrib/isaac/oo_and_element_recursion/Shootout.java b/contrib/isaac/oo_and_element_recursion/Shootout.java new file mode 100644 index 0000000..21271de --- /dev/null +++ b/contrib/isaac/oo_and_element_recursion/Shootout.java @@ -0,0 +1,15 @@ +final class Shoutout { + + private int k = 1, kth; + + //Shoutout(int n) { kth = n; } // standard Josephus problem + Shoutout(int n) { kth = n; k = n; } + + boolean wasKth(){ + boolean wasKth = k == kth; + if (wasKth) k = 1; else k++; + return wasKth; + } +} + + diff --git a/contrib/isaac/oo_and_element_recursion/Soldier.java b/contrib/isaac/oo_and_element_recursion/Soldier.java new file mode 100644 index 0000000..0f7376a --- /dev/null +++ b/contrib/isaac/oo_and_element_recursion/Soldier.java @@ -0,0 +1,50 @@ +final class Soldier { + + private int number = 0; + private Soldier previous, next; + + Soldier(Soldier previousSoldier, int number) + { + this.number = number; + + if (previousSoldier != null){ + + next = previousSoldier.next; + previousSoldier.next = this; + + previous = previousSoldier; + next.previous = this; + + } else { + next = this; + previous = this; + } + } + + + int countoff(Shoutout shout) + { + if (next != this){ + + if (shout.wasKth()) { + previous.next = next; + next.previous = previous; + } + return next.countoff(shout); + + } else { + return number; + } + } + + + static int countoffSoldiers(int n, int kth){ + Soldier soldier = null; + for (int i = 1; i <= n; i++) soldier = new Soldier(soldier,i); + + soldier = soldier.next; // set to the first Soldier constructed + + return soldier.countoff( new Shoutout(kth) ); + } +} + diff --git a/contrib/isaac/oo_and_element_recursion/josephus.js b/contrib/isaac/oo_and_element_recursion/josephus.js new file mode 100644 index 0000000..9cf1839 --- /dev/null +++ b/contrib/isaac/oo_and_element_recursion/josephus.js @@ -0,0 +1,87 @@ +/* +$ /usr/local/src/v8/d8 josephus.js +26 +element recursion object oriented +3.266 +3.264 +3.283 +3.286 +3.286 +3.286 +3.285 +3.286 +3.285 +3.284 +*/ + +function Soldier(previousSoldier,number){ + this.number = number + + if (previousSoldier != null){ + + this.next = previousSoldier.next + previousSoldier.next = this + + this.previous = previousSoldier + this.next.previous = this + + } else { + this.next = this + this.previous = this + } +} + + +Soldier.prototype.countoff = function(shout){ + if (this.next != this){ + + if (shout.wasKth()) { + this.previous.next = this.next + this.next.previous = this.previous + } + return this.next.countoff(shout) + + } else { + return this.number + } +} + + +function countoffSoldiers(n,kth) { + var soldier = null + for (var i = 1; i <= n; i++) soldier = new Soldier(soldier,i) + + soldier = soldier.next // set to the first Soldier constructed + + return soldier.countoff( new Shoutout(kth) ) +} + + + +//function Shoutout(n) { this.kth = n; this.k = 1 } // standard Josephus problem +function Shoutout(n) { this.kth = n; this.k = n } + +Shoutout.prototype.wasKth = function(){ + var wasKth = this.k == this.kth + if (wasKth) this.k = 1; else this.k++; + return wasKth +} + + +//----------------------------------------------------------------------------- + +function run_iterations(iterations, times) { + for (var t = 0 ; t < times ; t++) { + var start = new Date() + for(var i = 0 ; i < iterations ; i++) { + countoffSoldiers(40,3) + } + var end = new Date() + print ((end.getTime() - start.getTime()) * 1000 / ITERS) + } +} + +print(countoffSoldiers(40,3)) +ITERS = 1000000 +print ("element recursion object oriented") +run_iterations(ITERS,10) diff --git a/combined/Chain.java b/element-recursion/Chain.java similarity index 63% rename from combined/Chain.java rename to element-recursion/Chain.java index 89c1f74..f78ed5d 100644 --- a/combined/Chain.java +++ b/element-recursion/Chain.java @@ -13,32 +13,6 @@ private static int[] soldiers(int n) return a; } - public static int countoffSoldiersReduction(int n, int kth) - { - int[] s = soldiers(n); - int[] survivors = new int[n]; - int[] swap; - int k = 0, count = n; - - while (count > 1) { - int m = 0; - - for (int i = 0 ; i < count; i++) - if (i != k) { - survivors[m++] = s[i]; - - } else { - k += kth; - } - - k -= count; // wrap around - - swap = s; s = survivors; survivors = swap; - count = m; - } - - return s[0]; - } public static int countoffSoldiersRecursion(int n, int kth) { LinkedList soldiers = new LinkedList(); @@ -75,18 +49,6 @@ private static int countoff( } } - public static void runIterationsReduction(int iterations, int times) { - for(int t = 0 ; t < times; t++) { - System.gc(); - long start = System.nanoTime(); - for(int i = 0; i < iterations ; i++) { - countoffSoldiersReduction(40,3); - } - long end = System.nanoTime(); - System.out.println(((end - start) * 1.0)/ (iterations * 1000 )); - } - } - public static void runIterationsRecursive(int iterations, int times) { for(int t = 0 ; t < times; t++) { System.gc(); @@ -101,9 +63,6 @@ public static void runIterationsRecursive(int iterations, int times) { public static void main(String[] args) { int ITER = 1000000; - System.out.println("List Reduction"); - System.out.println(countoffSoldiersReduction(40,3)); - runIterationsReduction(ITER,10); System.out.println("Element Recursion"); System.out.println(countoffSoldiersRecursion(40,3) ); runIterationsRecursive(ITER,10); diff --git a/element-recursion/josephus-java.clj b/element-recursion/josephus-java.clj new file mode 100644 index 0000000..d9a50f7 --- /dev/null +++ b/element-recursion/josephus-java.clj @@ -0,0 +1,38 @@ +(set! *warn-on-reflection* true) +(set! *unchecked-math* true) + +(defn shout [^java.util.ArrayList people ^long n ^long counter] + (cond + (= (.size people) 1) (.get people 0) + (zero? counter) (do + (.remove people 0) + (recur people n (inc counter))) + :else (let [counter (if (= counter (dec n)) + 0 (inc counter)) + f (.get people 0)] + (.remove people 0) + (.add people f) + (recur people n counter)))) + +(defn josephus [people nth] + (let [al (java.util.ArrayList.)] + (dotimes [x people] + (.add al (inc x))) + (shout al nth 0))) + +;(defn run-el-recur-al [] + ;(println (josephus 40 3)) + ;(time + ;(dotimes [_ 1000000] + ;(josephus 40 3)))) + +(defn run-iterations [iterations times] + (dotimes [_ times] + (let [start (System/nanoTime)] + (dotimes[_ iterations] + (josephus 40 3)) + (let [end (System/nanoTime)] + (println (float (/ (- end start) (* 1000 iterations)))))))) + +(println (josephus 40 3)) +(run-iterations 1000000 10) diff --git a/element-recursion/josephus.js b/element-recursion/josephus.js index a68f2e4..27e3452 100644 --- a/element-recursion/josephus.js +++ b/element-recursion/josephus.js @@ -1,50 +1,61 @@ -function array_init(size) { - people = [] - for (var i = 0; i < size; i++) { - people[i] = i + 1; - } +/* +$ /usr/local/src/v8/d8 josephus.js +26 +element recursion +7.496 +7.517 +7.522 +7.527 +7.526 +7.524 +7.526 +7.527 +7.524 +7.526 +*/ - return people -} - -function shout(people, nth, counter) { - if (people.length == 1) { - return people[0] - } else { - if (counter == 0) { - people.shift() - counter = counter + 1 - } else { - if (counter == nth - 1) { - counter = 0 - } else { - counter = counter + 1 - } - val = people.shift() - people.push(val) - } - return shout(people,nth,counter) - } +function countoff(soldiers, kth, k) { + var i = soldiers.shift() + + if (soldiers.length > 0){ + if (k != kth){ + k++ + soldiers.push(i) + } else { + k = 1 + } + return countoff(soldiers, kth, k) + + } else { + return i + } } -function josephus(size, nth) { - people = array_init(size) - return shout(people, nth, 0); + +function countoffSoldiers(n, kth) { + var soldiers = [] + for (var i = 0; i < n; i++) soldiers[i] = i+1 + + //return countoff(soldiers, kth, 1); // standard Josephus problem + return countoff(soldiers, kth, kth) } + +//----------------------------------------------------------------------------- + function run_iterations(iterations, times) { for (var t = 0 ; t < times ; t++) { var start = new Date() for(var i = 0 ; i < iterations ; i++) { - josephus(40,3) + countoffSoldiers(40,3) } var end = new Date() print ((end.getTime() - start.getTime()) * 1000 / ITERS) } } -print(josephus(40,3)) +print(countoffSoldiers(40,3)) ITERS = 1000000 print ("element recursion") run_iterations(ITERS,10) diff --git a/list-reduction/Chain.java b/list-reduction/Chain.java new file mode 100644 index 0000000..f7963b0 --- /dev/null +++ b/list-reduction/Chain.java @@ -0,0 +1,51 @@ +public class Chain { + + public static int countoffSoldiers(int n, int kth) + { + int[] soldiers = new int[n]; + for (int i = 0 ; i < n ; i++) soldiers[i] = i+1; + + //int k = kth-1, survivedLastRound = n; // standard Josephus problem, 0th indexing + int k = 0, survivedLastRound = n; + + while (survivedLastRound > 1) { + int survived = 0; + + for (int i = 0 ; i < survivedLastRound; i++) + if (i != k) { + soldiers[survived++] = soldiers[i]; + + } else { + k += kth; + } + + k -= survivedLastRound; // wrap around + survivedLastRound = survived; + } + + return soldiers[0]; + } + + +//----------------------------------------------------------------------------- + + public static void runIterations(int iterations, int times) { + for(int t = 0 ; t < times; t++) { + System.gc(); + long start = System.nanoTime(); + for(int i = 0; i < iterations ; i++) { + countoffSoldiers(40,3); + } + long end = System.nanoTime(); + System.out.println(((end - start) * 1.0)/ (iterations * 1000 )); + } + } + + public static void main(String[] args) { + int ITER = 1000000; + System.out.println("List Reduction Array"); + System.out.println(countoffSoldiers(40,3) ); + runIterations(ITER,10); + } +} + diff --git a/list-reduction/josephus-java.clj b/list-reduction/josephus-java.clj new file mode 100644 index 0000000..84b87ec --- /dev/null +++ b/list-reduction/josephus-java.clj @@ -0,0 +1,50 @@ +(set! *warn-on-reflection* true) +(set! *unchecked-math* true) + +(definterface IChain + (kill [^long nth]) + (getFirst ^long []) + (shout [^long nth])) + +(deftype Chain [^java.util.ArrayList persons + ^{:unsynchronized-mutable true :tag long} index + ^{:unsynchronized-mutable true :tag long} size] + IChain + (getFirst [this] + (.get persons 0)) + (kill [this nth] + (set! index 0) + (while (> size 1) + (.shout this nth)) + (.getFirst this)) + (shout [this nth] + (while (< index size) + (.remove persons index) + (set! index (+ index (dec nth))) + (set! size (dec size))) + (set! index (- index size)))) + +(defn run [] + (let [al (java.util.ArrayList.) + n 40] + (dotimes [x n] + (.add al (inc x))) + (let [chain (Chain. al 0 n)] + (.kill chain 3)))) + +;(comment +; (dotimes [_ 10] +; (time +; (dotimes [_ 1e6] +; (run))))) + +(defn run-iterations [iterations times] + (dotimes [_ times] + (let [start (System/nanoTime)] + (dotimes[_ iterations] + (run)) + (let [end (System/nanoTime)] + (println (float (/ (- end start) (* 1000 iterations)))))))) + +(println (run)) +(run-iterations 1000000 10) diff --git a/list-reduction/josephus.js b/list-reduction/josephus.js index 1fceb81..bf85d8c 100644 --- a/list-reduction/josephus.js +++ b/list-reduction/josephus.js @@ -1,44 +1,57 @@ -function array_init(size) { - people = [] - for (var i = 0; i < size; i++) { - people[i] = i + 1; - } +/* +$ /usr/local/src/v8/d8 josephus.js +26 +list reduction array +1.232 +1.217 +1.217 +1.224 +1.22 +1.227 +1.224 +1.226 +1.219 +1.217 +*/ + +function countoffSoldiers(n,kth) { + var soldiers = [] + for (var i = 0; i < n; i++) soldiers[i] = i+1 + + //var k = kth-1, survivedLastRound = n; // standard Josephus problem + var k = 0, survivedLastRound = n + + while (survivedLastRound > 1) { + var survived = 0 + + for (var i = 0 ; i < survivedLastRound; i++) + if (i != k) + soldiers[survived++] = soldiers[i] + else + k += kth - return people + k -= survivedLastRound // wrap around + survivedLastRound = survived + } + + return soldiers[0] } -function shout(people, nth, counter) { - new_people = [] - if (people.length == 1) { - return people[0] - } else { - for (var i = 0 ; i < people.length ; i++) { - if ((i + counter) % nth != 0) { - new_people.push(people[i]) - } - } - counter = (counter + people.length) % nth - return shout(new_people, nth, counter) - } -} -function josephus(size, nth) { - people = array_init(size) - return shout(people, nth, 0); -} +//----------------------------------------------------------------------------- function run_iterations(iterations, times) { for (var t = 0 ; t < times ; t++) { var start = new Date() for(var i = 0 ; i < iterations ; i++) { - josephus(40,3) + countoffSoldiers(40,3) } var end = new Date() print ((end.getTime() - start.getTime()) * 1000 / ITERS) } } -print(josephus(40,3)) +print(countoffSoldiers(40,3)) ITERS = 1000000 -print ("list reduction") +print ("list reduction array") run_iterations(ITERS,10) diff --git a/oo/josephus.js b/oo/josephus.js new file mode 100644 index 0000000..c810e05 --- /dev/null +++ b/oo/josephus.js @@ -0,0 +1,87 @@ +/* +$ /usr/local/src/v8/d8 josephus.js +26 +object oriented +2.557 +2.572 +2.577 +2.578 +2.578 +2.578 +2.578 +2.572 +2.572 +2.571 +*/ + +function Soldier(previousSoldier,number){ + this.number = number + + if (previousSoldier != null){ + + this.next = previousSoldier.next + previousSoldier.next = this + + this.previous = previousSoldier + this.next.previous = this + + } else { + this.next = this + this.previous = this + } +} + + +Soldier.prototype.countoff = function(shout){ + if (shout.wasKth()) { + + this.previous.next = this.next + this.next.previous = this.previous + } + return this.next +} + + +function countoffSoldiers(n,kth) { + var soldier = null + for (var i = 1; i <= n; i++) soldier = new Soldier(soldier,i) + + soldier = soldier.next // set to the first Soldier constructed + + var shout = new Shoutout(kth) + + while (soldier.next != soldier) + soldier = soldier.countoff(shout) + + return soldier.number +} + + + +//function Shoutout(n) { this.kth = n; this.k = 1 } // standard Josephus problem +function Shoutout(n) { this.kth = n; this.k = n } + +Shoutout.prototype.wasKth = function(){ + var wasKth = this.k == this.kth + if (wasKth) this.k = 1; else this.k++; + return wasKth +} + + +//----------------------------------------------------------------------------- + +function run_iterations(iterations, times) { + for (var t = 0 ; t < times ; t++) { + var start = new Date() + for(var i = 0 ; i < iterations ; i++) { + countoffSoldiers(40,3) + } + var end = new Date() + print ((end.getTime() - start.getTime()) * 1000 / ITERS) + } +} + +print(countoffSoldiers(40,3)) +ITERS = 1000000 +print ("object oriented") +run_iterations(ITERS,10) From 4987479a7dd1694408df810006752b11db70bbc9 Mon Sep 17 00:00:00 2001 From: Stuart Halloway Date: Sun, 28 Aug 2011 09:57:07 -0400 Subject: [PATCH 3/3] fast, thread-safe, referentially transparent Clojure version --- element-recursion/josephus-java.clj | 38 --------------------- element-recursion/josephus.clj | 53 ++++++++++++----------------- 2 files changed, 22 insertions(+), 69 deletions(-) delete mode 100644 element-recursion/josephus-java.clj diff --git a/element-recursion/josephus-java.clj b/element-recursion/josephus-java.clj deleted file mode 100644 index d9a50f7..0000000 --- a/element-recursion/josephus-java.clj +++ /dev/null @@ -1,38 +0,0 @@ -(set! *warn-on-reflection* true) -(set! *unchecked-math* true) - -(defn shout [^java.util.ArrayList people ^long n ^long counter] - (cond - (= (.size people) 1) (.get people 0) - (zero? counter) (do - (.remove people 0) - (recur people n (inc counter))) - :else (let [counter (if (= counter (dec n)) - 0 (inc counter)) - f (.get people 0)] - (.remove people 0) - (.add people f) - (recur people n counter)))) - -(defn josephus [people nth] - (let [al (java.util.ArrayList.)] - (dotimes [x people] - (.add al (inc x))) - (shout al nth 0))) - -;(defn run-el-recur-al [] - ;(println (josephus 40 3)) - ;(time - ;(dotimes [_ 1000000] - ;(josephus 40 3)))) - -(defn run-iterations [iterations times] - (dotimes [_ times] - (let [start (System/nanoTime)] - (dotimes[_ iterations] - (josephus 40 3)) - (let [end (System/nanoTime)] - (println (float (/ (- end start) (* 1000 iterations)))))))) - -(println (josephus 40 3)) -(run-iterations 1000000 10) diff --git a/element-recursion/josephus.clj b/element-recursion/josephus.clj index 5dd9a61..2ff3cc3 100644 --- a/element-recursion/josephus.clj +++ b/element-recursion/josephus.clj @@ -1,35 +1,27 @@ -;; contributed by Stuart Halloway -;; This is not idiomatic Clojure, rather, a simple-minded post of the -;; Java code, in the name of an apples-apples comparison. - -(import [java.util ArrayList LinkedList List ListIterator]) - (set! *warn-on-reflection* true) +(set! *unchecked-math* true) -(defn countoff - [^ListIterator ring ^LinkedList reset kth k] - (loop [ring ring - reset reset - kth (int kth) - k (int k)] - (if (.hasNext ring) - (do - (.next ring) - (if (not= k kth) - (recur ring reset kth (inc k)) - (do - (.remove ring) - (recur ring reset kth (int 1))))) - (if (> (.nextIndex ring) 1) - (recur (.listIterator reset (int 0)) reset kth k) - (.previous ring))))) - +;; N.B. referentially transparent and threadsafe even with internal +;; use of mutation. (defn josephus - [n kth] - (let [soldiers (LinkedList.)] - (dotimes [i n] - (.add soldiers (inc i))) - (countoff (.listIterator soldiers) soldiers kth kth))) + [people nth] + (let [shout + (fn [^java.util.LinkedList people ^long n ^long counter] + (cond + (= (.size people) 1) (.get people 0) + (zero? counter) (do + (.remove people 0) + (recur people n (inc counter))) + :else (let [counter (if (= counter (dec n)) + 0 (inc counter)) + f (.get people 0)] + (.remove people 0) + (.add people f) + (recur people n counter)))) + al (java.util.LinkedList.)] + (dotimes [x people] + (.add al (inc x))) + (shout al nth 0))) (defn run-iterations [iterations times] (dotimes [_ times] @@ -40,5 +32,4 @@ (println (float (/ (- end start) (* 1000 iterations)))))))) (println (josephus 40 3)) -(run-iterations 100000 10) - +(run-iterations 1000000 10)