From 5f0bd1e0829339fa0c0dcabd9fc14176eac56e99 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Wed, 14 Mar 2018 21:46:56 -0400 Subject: [PATCH] Update code. --- examples/3sum.dst | 14 ++++++++++++++ src/compiler/boot.dst | 42 ++++++++++++++++++++++++++++++++---------- src/core/struct.c | 9 ++++----- 3 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 examples/3sum.dst diff --git a/examples/3sum.dst b/examples/3sum.dst new file mode 100644 index 00000000..2cc75a6f --- /dev/null +++ b/examples/3sum.dst @@ -0,0 +1,14 @@ +(defn sum3 + "Solve the 3SUM problem O(n^2) time." + [s] + (def tab @{}) + (def solutions []) + (def len (length s)) + (for [k 0 len] + (put tab (get s k) k)) + (for [i 0 len] + (for [j 0 len] + (def k (get tab (- 0 (get s i) (get s j)))) + (when (and k (not= k i) (not= k j) (not= i j)) + (array-push solutions [i j k])))) + solutions) diff --git a/src/compiler/boot.dst b/src/compiler/boot.dst index 4fbaf971..43f47c31 100644 --- a/src/compiler/boot.dst +++ b/src/compiler/boot.dst @@ -32,6 +32,14 @@ (apply tuple (array-concat ['defn name :private] more))) +(defn even? [x] (== 0 (% x 2))) +(defn odd? [x] (== 1 (% x 2))) +(defn nil? [x] (= x nil)) +(defn zero? [x] (== x 0)) +(defn one? [x] (== x 1)) +(defn inc [x] (+ x 1)) +(defn dec [x] (- x 1)) + (defmacro comment "Ignores the body of the comment." []) @@ -83,8 +91,19 @@ If no match is found, returns nil" (tuple 'def sym dispatch) (aux 0))) -(defmacro or [x y] (tuple 'if x true y)) -(defmacro and [x y] (tuple 'if x y false)) +(defmacro and [& forms] + (def len (length forms)) + (if (= len 0) true ((fn aux [i] + (cond + (>= (inc i) len) (get forms i) + (tuple 'if (get forms i) (aux (inc i)) false))) 0))) + +(defmacro or [& forms] + (def len (length forms)) + (if (= len 0) false ((fn aux [i] + (cond + (>= (inc i) len) (get forms i) + (tuple 'if (get forms i) true (aux (inc i))))) 0))) (defn identity "A function that returns its first argument." @@ -136,6 +155,12 @@ If no match is found, returns nil" (def {:more more :next next} (seq s)) (while (more) (f (next)))) +(defn seq-array [s] + (def {:more more :next next} (seq s)) + (def a []) + (while (more) (array-push a (next))) + a) + (defn map [f s] (def {:more more :next next} (seq s)) {:more more :next (fn [] (f (next)))}) @@ -164,14 +189,6 @@ If no match is found, returns nil" (defn nmore [] (when isnew (varset! isnew false) (nnext)) alive) {:more nmore :next nnext}) -(defn even? [x] (== 0 (% x 2))) -(defn odd? [x] (== 1 (% x 2))) -(defn nil? [x] (= x nil)) -(defn zero? [x] (== x 0)) -(defn one? [x] (== x 1)) -(defn inc [x] (+ x 1)) -(defn dec [x] (- x 1)) - (defmacro let [bindings & body] (def head (ast-unwrap1 bindings)) (when (odd? (length head)) (error "expected even number of bindings to let")) @@ -303,6 +320,11 @@ If no match is found, returns nil" (fn [x] (print (pp1 @{} @"" x))))) # End pretty printer +(defn unique [s] + (def tab @{}) + (domap (fn [x] (put tab x true)) s) + (keys tab)) + (defn make-env [parent] (def parent (if parent parent _env)) (def newenv (setproto @{} parent)) diff --git a/src/core/struct.c b/src/core/struct.c index c6955ded..9ab9a64a 100644 --- a/src/core/struct.c +++ b/src/core/struct.c @@ -61,11 +61,10 @@ const DstKV *dst_struct_find(const DstKV *st, Dst key) { * Nil keys and values are ignored, extra keys are ignore, and duplicate keys are * ignored. * - * Much of this complexity is in the robinhood hashing scheme, an - * attempt to make structs that are created with arguments in a different - * order to have the same internal representation. If this turns out to be - * incorrect or too complicated, another scheme that would definitely work - * is inserting all keys in sorted order with any deterministic hashing scheme. */ + * Runs will be in sorted order, as the collisions resolver essentially + * preforms an in-place insertion sort. This ensures the internal structure of the + * hash map is independant of insertion order. + */ void dst_struct_put(DstKV *st, Dst key, Dst value) { int32_t cap = dst_struct_capacity(st); int32_t hash = dst_hash(key);