Skip to content

Commit

Permalink
Merge pull request #23 from TheAlgorithms/fr33m0nk/add-immutable-stac…
Browse files Browse the repository at this point in the history
…k-impl

Adds immutable stack implementation
  • Loading branch information
fr33m0nk authored Apr 4, 2024
2 parents d4196d4 + c3d09db commit 10de49d
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* [Run length encoding](https://github.com/TheAlgorithms/Clojure/blob/main/src/data_structures/lists/run_length_encoding.clj)

* [Dynamic Array implementation](/src/data_structures/dynamic_array/core.clj)
* [Immutable Stack implementation](/src/data_structures/stack/core.clj)

## Sorting
* [Merge Sort](https://github.com/TheAlgorithms/Clojure/blob/main/src/sorts/merge_sort.clj)
Expand Down
49 changes: 49 additions & 0 deletions src/data_structures/stack/core.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
(ns data-structures.stack.core)

(defn ->Stack
[length]
[length []])

(defn length
[stack]
(first stack))

(defn empty-stack?
[stack]
(let [[_ store] stack]
(= (count store) 0)))

(defn full-stack?
[stack]
(let [[length store] stack]
(= (count store) length)))

(defn push-in-stack
[stack val]
(assert (not (full-stack? stack)) "Stack is full")
(let [[length store] stack]
[length (conj store val)]))

(defn pop-from-stack
[stack]
(if (empty-stack? stack)
stack
(let [[length store] stack]
[length (pop store)])))

(defn peek-at-stack
[stack]
(when-not (empty-stack? stack)
(let [[_ store] stack]
(nth store (dec (count store))))))

(defn to-string
[stack]
(let [sb (StringBuilder.)]
(.append sb "[ ")
(let [[_ store] stack]
(doseq [el store]
(.append sb el)
(.append sb " ")))
(.append sb "]")
(.toString sb)))
84 changes: 84 additions & 0 deletions test/data_structures/stack/core_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
(ns data-structures.stack.core-test
(:require
[clojure.test :refer [deftest testing is]]
[data-structures.stack.core :as s]))

(deftest ->Stack-test
(testing "returns stack of desired size"
(is (= [10 []] (s/->Stack 10)))))

(deftest length-test
(testing "returns length of the stack"
(is (= 10 (-> (s/->Stack 10)
(s/length))))))

(deftest empty-stack?-test
(testing "returns true when stack is empty"
(is (true? (s/empty-stack? (s/->Stack 10)))))
(testing "returns false when stack is not empty"
(is (false? (-> (s/->Stack 10)
(s/push-in-stack "a-value")
(s/empty-stack?))))))

(deftest full-stack?-test
(testing "returns false when the stack is not full"
(is (false? (s/full-stack? (s/push-in-stack (s/->Stack 3) "a-value")))))
(testing "returns true when the stack is full"
(is (true? (-> (s/->Stack 3)
(s/push-in-stack "a-value")
(s/push-in-stack "other-value")
(s/push-in-stack "another-other-value")
(s/full-stack?))))))

(deftest push-in-stack-test
(testing "pushes element in a not full stack"
(is (= [3 ["a-value" "other-value" "another-other-value"]]
(-> (s/->Stack 3)
(s/push-in-stack "a-value")
(s/push-in-stack "other-value")
(s/push-in-stack "another-other-value")))))

(testing "throws error when trying to push element in a full stack"
(is (thrown? AssertionError
(-> (s/->Stack 3)
(s/push-in-stack "a-value")
(s/push-in-stack "other-value")
(s/push-in-stack "another-other-value")
(s/push-in-stack "yet-another-other-value"))))))

(deftest peek-at-stack-test
(testing "returns peeking at an empty stack"
(is (nil? (-> (s/->Stack 3)
(s/peek-at-stack)))))

(testing "returns the last pushed value if stack is not empty"
(is (= "another-other-value" (-> (s/->Stack 3)
(s/push-in-stack "a-value")
(s/push-in-stack "other-value")
(s/push-in-stack "another-other-value")
(s/peek-at-stack))))))

(deftest pop-from-stack-test
(testing "returns original stack when popping from empty stack"
(is (= [3 []] (-> (s/->Stack 3)
(s/pop-from-stack)))))

(testing "returns modified stack when popping from non empty stack"
(is (= [3 ["a-value" "other-value"]]
(-> (s/->Stack 3)
(s/push-in-stack "a-value")
(s/push-in-stack "other-value")
(s/push-in-stack "another-other-value")
(s/pop-from-stack))))))

(deftest to-string-test
(testing "returns string for a stack"
(is (= "[ ]" (-> (s/->Stack 3)
(s/to-string))))

(is (= "[ a-value other-value another-other-value ]"
(-> (s/->Stack 3)
(s/push-in-stack "a-value")
(s/push-in-stack "other-value")
(s/push-in-stack "another-other-value")
(s/to-string))))))

0 comments on commit 10de49d

Please sign in to comment.