-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Instructions | ||
|
||
Convert an octal number, represented as a string (e.g. '1735263'), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion). | ||
|
||
Implement octal to decimal conversion. | ||
Given an octal input string, your program should produce a decimal output. | ||
|
||
## Note | ||
|
||
- Implement the conversion yourself. | ||
Do not use something else to perform the conversion for you. | ||
- Treat invalid input as octal 0. | ||
|
||
## About Octal (Base-8) | ||
|
||
Decimal is a base-10 system. | ||
|
||
A number 233 in base 10 notation can be understood | ||
as a linear combination of powers of 10: | ||
|
||
- The rightmost digit gets multiplied by 10^0 = 1 | ||
- The next number gets multiplied by 10^1 = 10 | ||
- ... | ||
- The nth number gets multiplied by 10^_(n-1)_. | ||
- All these values are summed. | ||
|
||
So: | ||
|
||
```text | ||
233 # decimal | ||
= 2*10^2 + 3*10^1 + 3*10^0 | ||
= 2*100 + 3*10 + 3*1 | ||
``` | ||
|
||
Octal is similar, but uses powers of 8 rather than powers of 10. | ||
|
||
So: | ||
|
||
```text | ||
233 # octal | ||
= 2*8^2 + 3*8^1 + 3*8^0 | ||
= 2*64 + 3*8 + 3*1 | ||
= 128 + 24 + 3 | ||
= 155 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
module [parse] | ||
|
||
parseOctalDigit = \char -> | ||
if char >= '0' && char <= '7' then | ||
Ok (char - '0' |> Num.toU64) | ||
else | ||
Err InvalidNumStr | ||
|
||
parse : Str -> Result U64 _ | ||
parse = \string -> | ||
if string == "" then | ||
Err InvalidNumStr | ||
else | ||
|
||
string | ||
|> Str.toUtf8 | ||
|> List.walkTry 0 \number, char -> | ||
octalDigit = parseOctalDigit? char | ||
if number > 0x1fffffffffffffff then | ||
Err InvalidNumStr | ||
else | ||
number |> Num.shiftLeftBy 3 |> Num.add octalDigit |> Ok |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"authors": [ | ||
"ageron" | ||
], | ||
"files": { | ||
"solution": [ | ||
"Octal.roc" | ||
], | ||
"test": [ | ||
"octal-test.roc" | ||
], | ||
"example": [ | ||
".meta/Example.roc" | ||
] | ||
}, | ||
"blurb": "Convert a octal number, represented as a string (e.g. '1735263'), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).", | ||
"source": "All of Computer Science", | ||
"source_url": "https://www.wolframalpha.com/examples/mathematics/numbers/base-conversions" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module [parse] | ||
|
||
parse : Str -> Result U64 _ | ||
parse = \string -> | ||
crash "Please implement the 'parse' function" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
app [main] { | ||
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.15.0/SlwdbJ-3GR7uBWQo6zlmYWNYOxnvo8r6YABXD-45UOw.tar.br", | ||
} | ||
|
||
main = | ||
Task.ok {} | ||
|
||
import Octal exposing [parse] | ||
|
||
# Parse "0" | ||
expect | ||
result = parse "0" | ||
result == Ok 0 | ||
|
||
# Parse "1" | ||
expect | ||
result = parse "1" | ||
result == Ok 1 | ||
|
||
# Parse "2" | ||
expect | ||
result = parse "2" | ||
result == Ok 2 | ||
|
||
# Parse "3" | ||
expect | ||
result = parse "3" | ||
result == Ok 3 | ||
|
||
# Parse "4" | ||
expect | ||
result = parse "4" | ||
result == Ok 4 | ||
|
||
# Parse "5" | ||
expect | ||
result = parse "5" | ||
result == Ok 5 | ||
|
||
# Parse "6" | ||
expect | ||
result = parse "6" | ||
result == Ok 6 | ||
|
||
# Parse "7" | ||
expect | ||
result = parse "7" | ||
result == Ok 7 | ||
|
||
# Parse "10" | ||
expect | ||
result = parse "10" | ||
result == Ok 8 | ||
|
||
# Parse "11" | ||
expect | ||
result = parse "11" | ||
result == Ok 9 | ||
|
||
# Parse "12" | ||
expect | ||
result = parse "12" | ||
result == Ok 10 | ||
|
||
# Parse "13" | ||
expect | ||
result = parse "13" | ||
result == Ok 11 | ||
|
||
# Parse "14" | ||
expect | ||
result = parse "14" | ||
result == Ok 12 | ||
|
||
# Parse "15" | ||
expect | ||
result = parse "15" | ||
result == Ok 13 | ||
|
||
# Parse "16" | ||
expect | ||
result = parse "16" | ||
result == Ok 14 | ||
|
||
# Parse "17" | ||
expect | ||
result = parse "17" | ||
result == Ok 15 | ||
|
||
# Parse "20" | ||
expect | ||
result = parse "20" | ||
result == Ok 16 | ||
|
||
# Parse "21" | ||
expect | ||
result = parse "21" | ||
result == Ok 17 | ||
|
||
# Parse "22" | ||
expect | ||
result = parse "22" | ||
result == Ok 18 | ||
|
||
# Parse "77" | ||
expect | ||
result = parse "77" | ||
result == Ok 63 | ||
|
||
# Parse "100" | ||
expect | ||
result = parse "100" | ||
result == Ok 64 | ||
|
||
# Parse "1234567654321" | ||
expect | ||
result = parse "1234567654321" | ||
result == Ok 89755965649 | ||
|
||
# Parse "1777777777777777777777", the largest U64 value | ||
expect | ||
result = parse "1777777777777777777777" | ||
result == Ok 18446744073709551615 | ||
|
||
# Ignore leading zeros in "00000" | ||
expect | ||
result = parse "00000" | ||
result == Ok 0 | ||
|
||
# Ignore leading zeros in "00001" | ||
expect | ||
result = parse "00001" | ||
result == Ok 1 | ||
|
||
# Ignore leading zeros in "00007" | ||
expect | ||
result = parse "00007" | ||
result == Ok 7 | ||
|
||
# Ignore leading zeros in "000010" | ||
expect | ||
result = parse "000010" | ||
result == Ok 8 | ||
|
||
# Ignore leading zeros in "000077" | ||
expect | ||
result = parse "000077" | ||
result == Ok 63 | ||
|
||
# Ignore leading zeros in "000070000" | ||
expect | ||
result = parse "000070000" | ||
result == Ok 28672 | ||
|
||
# Ignore leading zeros even before the largest U64 value | ||
expect | ||
result = parse "00001777777777777777777777" | ||
result == Ok 18446744073709551615 | ||
|
||
# Empty strings are invalid | ||
expect | ||
result = parse "" | ||
result |> Result.isErr | ||
|
||
# A string with only spaces is invalid | ||
expect | ||
result = parse " " | ||
result |> Result.isErr | ||
|
||
# Leading spaces are invalid | ||
expect | ||
result = parse " 1234567" | ||
result |> Result.isErr | ||
|
||
# Trailing spaces are invalid | ||
expect | ||
result = parse "1234567 " | ||
result |> Result.isErr | ||
|
||
# Spaces anywhere are invalid | ||
expect | ||
result = parse "123 4567" | ||
result |> Result.isErr | ||
|
||
# Invalid character in "1*234" | ||
expect | ||
result = parse "1*234" | ||
result |> Result.isErr | ||
|
||
# Invalid character in "12abc" | ||
expect | ||
result = parse "12abc" | ||
result |> Result.isErr | ||
|
||
# Invalid character in "12/34" | ||
expect | ||
result = parse "12/34" | ||
result |> Result.isErr | ||
|
||
# Invalid character in "1234\n" | ||
expect | ||
result = parse "1234\n" | ||
result |> Result.isErr | ||
|
||
# Invalid character in "-1234" | ||
expect | ||
result = parse "-1234" | ||
result |> Result.isErr | ||
|
||
# Invalid character in "+1234" | ||
expect | ||
result = parse "+1234" | ||
result |> Result.isErr | ||
|
||
# For numbers that don't fit in an U64, `parse` should return an error | ||
# instead of crashing | ||
expect | ||
result = parse "2000000000000000000000" | ||
result |> Result.isErr |