Skip to content
This repository has been archived by the owner on May 30, 2023. It is now read-only.

Commit

Permalink
Add all-your-base exercise (#113)
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom authored May 6, 2023
1 parent 747a087 commit 3ab0feb
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 0 deletions.
13 changes: 13 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,19 @@
"topics": null
},
{
"slug": "all-your-base",
"name": "All Your Base",
"uuid": "5f736494-1f66-4711-aa22-6d2133bc641d",
"practices": [
"numbers"
],
"prerequisites": [
"numbers",
"vectors"
],
"difficulty": 2
},
{
"slug": "acronym",
"name": "Acronym",
"uuid": "e6147a0d-3000-4b3c-9a60-3f8800730691",
Expand Down
33 changes: 33 additions & 0 deletions exercises/practice/all-your-base/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Instructions

Convert a number, represented as a sequence of digits in one base, to any other base.

Implement general base conversion.
Given a number in base **a**, represented as a sequence of digits, convert it to base **b**.

## Note

- Try to implement the conversion yourself.
Do not use something else to perform the conversion for you.

## About [Positional Notation][positional-notation]

In positional notation, a number in base **b** can be understood as a linear combination of powers of **b**.

The number 42, *in base 10*, means:

`(4 * 10^1) + (2 * 10^0)`

The number 101010, *in base 2*, means:

`(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0)`

The number 1120, *in base 3*, means:

`(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0)`

I think you got the idea!

*Yes. Those three numbers above are exactly the same. Congratulations!*

[positional-notation]: https://en.wikipedia.org/wiki/Positional_notation
17 changes: 17 additions & 0 deletions exercises/practice/all-your-base/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"authors": [
"ErikSchierboom"
],
"files": {
"solution": [
"src/all_your_base.cljs"
],
"test": [
"test/all_your_base_test.cljs"
],
"example": [
".meta/src/example.cljs"
]
},
"blurb": "Convert a number, represented as a sequence of digits in one base, to any other base."
}
31 changes: 31 additions & 0 deletions exercises/practice/all-your-base/.meta/src/example.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
(ns all-your-base)

(defn- digits->decimal
"Converts a sequence of digits given in input-base into decimal format."
[input-base digits]
(loop [sum 0
[num & nums] digits]
(if num
(recur (+ (* sum input-base) num) nums)
sum)))

(defn- decimal->digits
"Converts a decimal number into a sequence of digits in the desired output base."
[output-base number]
(loop [digits nil
num number]
(if (zero? num)
digits
(recur (conj digits (mod num output-base)) (quot num output-base)))))

(defn convert
"Converts a sequence of digits given in input-base into a sequence of digits in the desired output-base."
[input-base digits output-base]
(cond
(some #(< % 2) (list input-base output-base)) nil
(not-every? #(and (not (neg? %)) (< % input-base)) digits) nil
(empty? digits) ()
(every? #(zero? %) digits) '(0)
:else (->> digits
(digits->decimal input-base)
(decimal->digits output-base))))
66 changes: 66 additions & 0 deletions exercises/practice/all-your-base/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# This is an auto-generated file. Regular comments will be removed when this
# file is regenerated. Regenerating will not touch any manually added keys,
# so comments can be added in a "comment" key.

[5ce422f9-7a4b-4f44-ad29-49c67cb32d2c]
description = "single bit one to decimal"

[0cc3fea8-bb79-46ac-a2ab-5a2c93051033]
description = "binary to single decimal"

[f12db0f9-0d3d-42c2-b3ba-e38cb375a2b8]
description = "single decimal to binary"

[2c45cf54-6da3-4748-9733-5a3c765d925b]
description = "binary to multiple decimal"

[65ddb8b4-8899-4fcc-8618-181b2cf0002d]
description = "decimal to binary"

[8d418419-02a7-4824-8b7a-352d33c6987e]
description = "trinary to hexadecimal"

[d3901c80-8190-41b9-bd86-38d988efa956]
description = "hexadecimal to trinary"

[5d42f85e-21ad-41bd-b9be-a3e8e4258bbf]
description = "15-bit integer"

[d68788f7-66dd-43f8-a543-f15b6d233f83]
description = "empty list"

[5e27e8da-5862-4c5f-b2a9-26c0382b6be7]
description = "single zero"

[2e1c2573-77e4-4b9c-8517-6c56c5bcfdf2]
description = "multiple zeros"

[3530cd9f-8d6d-43f5-bc6e-b30b1db9629b]
description = "leading zeros"

[a6b476a1-1901-4f2a-92c4-4d91917ae023]
description = "input base is one"

[e21a693a-7a69-450b-b393-27415c26a016]
description = "input base is zero"

[54a23be5-d99e-41cc-88e0-a650ffe5fcc2]
description = "input base is negative"

[9eccf60c-dcc9-407b-95d8-c37b8be56bb6]
description = "negative digit"

[232fa4a5-e761-4939-ba0c-ed046cd0676a]
description = "invalid positive digit"

[14238f95-45da-41dc-95ce-18f860b30ad3]
description = "output base is one"

[73dac367-da5c-4a37-95fe-c87fad0a4047]
description = "output base is zero"

[13f81f42-ff53-4e24-89d9-37603a48ebd9]
description = "output base is negative"

[0e6c895d-8a5d-4868-a345-309d094cfe8d]
description = "both bases are negative"
10 changes: 10 additions & 0 deletions exercises/practice/all-your-base/deps.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{:deps
{org.clojure/clojure {:mvn/version "1.10.1"}
org.clojure/clojurescript {:mvn/version "1.10.773"}}

:aliases
{:test
{:extra-paths ["test"]
:extra-deps
{olical/cljs-test-runner {:mvn/version "3.8.0"}}
:main-opts ["-m" "cljs-test-runner.main"]}}}
5 changes: 5 additions & 0 deletions exercises/practice/all-your-base/src/all_your_base.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
(ns all-your-base)

(defn convert [] ;; <- arglist goes here
;; your code goes here
)
87 changes: 87 additions & 0 deletions exercises/practice/all-your-base/test/all_your_base_test.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
(ns all-your-base-test
(:require [clojure.test :refer [deftest testing is]]
[all-your-base]))

(deftest test-single-bit-to-one-decimal
(testing "Base 2 '1' converts to base 10 '1'"
(is (= '(1) (all-your-base/convert 2 '(1) 10)))))

(deftest test-binary-to-single-decimal
(testing "Base 2 '1 0 1' converts to base 10 '5'"
(is (= '(5) (all-your-base/convert 2 '(1 0 1) 10)))))

(deftest test-single-decimal-to-binary
(testing "Base 10 '5' converts to base 2 '1 0 1'"
(is (= '(1 0 1) (all-your-base/convert 10 '(5) 2)))))

(deftest test-binary-to-multiple-decimal
(testing "Base 2 '1 0 1 0 1 0' converts to base 10 '4 2'"
(is (= '(4 2) (all-your-base/convert 2 '(1 0 1 0 1 0) 10)))))

(deftest test-decimal-to-binary
(testing "Base 10 '4 2' conves to base 2 '1 0 1 0 1 0'"
(is (= '(1 0 1 0 1 0) (all-your-base/convert 10 '(4 2) 2)))))

(deftest test-trinary-to-hexadecimal
(testing "Base 3 '1 1 2 0' converts to base 16 '2 10'"
(is (= '(2 10) (all-your-base/convert 3 '(1 1 2 0) 16)))))

(deftest test-hexadecimal-to-trinary
(testing "Base 16 '2 10' converts to base 3 '1 1 2 0'"
(is (= '(1 1 2 0) (all-your-base/convert 16 '(2 10) 3)))))

(deftest test-15-bit-integer
(testing "Base 97 '3 46 60' converts to base 73 '6 10 45'"
(is (= '(6 10 45) (all-your-base/convert 97 '(3 46 60) 73)))))

(deftest test-empty-list
(testing "Empty input digits returns empty sequence"
(is (empty? (all-your-base/convert 2 () 10)))))

(deftest test-single-zero
(testing "0 converts to 0, no matter the base"
(is (= '(0) (all-your-base/convert 10 '(0) 2)))))

(deftest test-multiple-zeroes
(testing "0 converts to 0, no matter the how many zeroes"
(is (= '(0) (all-your-base/convert 10 '(0 0 0) 2)))))

(deftest test-leading-zeros
(testing "Leading zeroes don't affect conversion"
(is (= '(4 2) (all-your-base/convert 7 '(0 6 0) 10)))))

(deftest test-negative-digit
(testing "Negative digits result in nil"
(is (nil? (all-your-base/convert 2 '(1 -1 1 0 1 0) 10)))))

(deftest test-invalid-positive-digit
(testing "Invalid digits return nil"
(is (nil? (all-your-base/convert 2 '(1 2 1 0 1 0) 10)))))

(deftest test-first-base-is-one
(testing "Input base of 1 returns nil"
(is (nil? (all-your-base/convert 1 () 10)))))

(deftest test-second-base-is-one
(testing "Output base of 1 returns nil"
(is (nil? (all-your-base/convert 2 '(1 0 1 0 1 0) 1)))))

(deftest test-first-base-is-zero
(testing "Input base of 0 returns nil"
(is (nil? (all-your-base/convert 0 () 10)))))

(deftest test-second-base-is-zero
(testing "Output base of 0 returns nil"
(is (nil? (all-your-base/convert 10 '(7) 0)))))

(deftest test-first-base-is-negative
(testing "Negative input base returns nil"
(is (nil? (all-your-base/convert -2 '(1) 10)))))

(deftest test-second-base-is-negative
(testing "Negative output base returns nil"
(is (nil? (all-your-base/convert 2 '(1) -7)))))

(deftest test-both-bases-are-negative
(testing "When both bases are negative, nil is returned"
(is (nil? (all-your-base/convert -2 '(1) -7)))))

0 comments on commit 3ab0feb

Please sign in to comment.