things
This commit is contained in:
parent
14005e4a12
commit
3a6f481571
|
@ -0,0 +1,69 @@
|
|||
# All Your Base
|
||||
|
||||
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](https://en.wikipedia.org/wiki/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!*
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir all_your_base_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,114 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("all-your-base.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(exclude: :pending, trace: true)
|
||||
|
||||
defmodule AllYourBaseTest do
|
||||
use ExUnit.Case
|
||||
|
||||
test "convert single bit one to decimal" do
|
||||
assert AllYourBase.convert([1], 2, 10) == [1]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert binary to single decimal" do
|
||||
assert AllYourBase.convert([1, 0, 1], 2, 10) == [5]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert single decimal to binary" do
|
||||
assert AllYourBase.convert([5], 10, 2) == [1, 0, 1]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert binary to multiple decimal" do
|
||||
assert AllYourBase.convert([1, 0, 1, 0, 1, 0], 2, 10) == [4, 2]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert decimal to binary" do
|
||||
assert AllYourBase.convert([4, 2], 10, 2) == [1, 0, 1, 0, 1, 0]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert trinary to hexadecimal" do
|
||||
assert AllYourBase.convert([1, 1, 2, 0], 3, 16) == [2, 10]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert hexadecimal to trinary" do
|
||||
assert AllYourBase.convert([2, 10], 16, 3) == [1, 1, 2, 0]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert 15-bit integer" do
|
||||
assert AllYourBase.convert([3, 46, 60], 97, 73) == [6, 10, 45]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert empty list" do
|
||||
assert AllYourBase.convert([], 2, 10) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert single zero" do
|
||||
assert AllYourBase.convert([0], 10, 2) == [0]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert multiple zeros" do
|
||||
assert AllYourBase.convert([0, 0, 0], 10, 2) == [0]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert leading zeros" do
|
||||
assert AllYourBase.convert([0, 6, 0], 7, 10) == [4, 2]
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert negative digit" do
|
||||
assert AllYourBase.convert([1, -1, 1, 0, 1, 0], 2, 10) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert invalid positive digit" do
|
||||
assert AllYourBase.convert([1, 2, 1, 0, 1, 0], 2, 10) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert first base is one" do
|
||||
assert AllYourBase.convert([0], 1, 10) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert second base is one" do
|
||||
assert AllYourBase.convert([1, 0, 1, 0, 1, 0], 2, 1) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert first base is zero" do
|
||||
assert AllYourBase.convert([], 0, 10) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert second base is zero" do
|
||||
assert AllYourBase.convert([7], 10, 0) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert first base is negative" do
|
||||
assert AllYourBase.convert([1], -2, 10) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert second base is negative" do
|
||||
assert AllYourBase.convert([1], 2, -7) == nil
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "convert both bases are negative" do
|
||||
assert AllYourBase.convert([1], -2, -7) == nil
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
defmodule AllYourBase do
|
||||
@doc """
|
||||
Given a number in base a, represented as a sequence of digits, converts it to base b,
|
||||
or returns nil if either of the bases are less than 2
|
||||
"""
|
||||
|
||||
@spec convert(list, integer, integer) :: list
|
||||
def convert(digits, base_a, base_b) do
|
||||
cond do
|
||||
base_a < 2 || base_b < 2 ->
|
||||
nil
|
||||
|
||||
true ->
|
||||
""
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,50 @@
|
|||
# Nth Prime
|
||||
|
||||
Given a number n, determine what the nth prime is.
|
||||
|
||||
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that
|
||||
the 6th prime is 13.
|
||||
|
||||
If your language provides methods in the standard library to deal with prime
|
||||
numbers, pretend they don't exist and implement them yourself.
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir nth_prime_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
A variation on Problem 7 at Project Euler [http://projecteuler.net/problem=7](http://projecteuler.net/problem=7)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,26 @@
|
|||
defmodule Prime do
|
||||
@doc """
|
||||
Generates the nth prime.
|
||||
"""
|
||||
@spec nth(non_neg_integer) :: non_neg_integer
|
||||
def nth(count) when count > 0 do
|
||||
Stream.iterate(1, &(&1 + 1))
|
||||
|> Stream.filter(&prime?/1)
|
||||
|> Enum.at(count - 1)
|
||||
end
|
||||
|
||||
defp prime?(n) do
|
||||
case n do
|
||||
_n when n <= 1 ->
|
||||
false
|
||||
|
||||
2 ->
|
||||
true
|
||||
|
||||
_ ->
|
||||
2..round(:math.sqrt(n))
|
||||
|> Enum.filter(&(rem(n, &1) == 0))
|
||||
|> Enum.empty?()
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,35 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("nth_prime.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(trace: true)
|
||||
|
||||
defmodule NthPrimeTest do
|
||||
use ExUnit.Case
|
||||
|
||||
# @tag :pending
|
||||
test "first prime" do
|
||||
assert Prime.nth(1) == 2
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "second prime" do
|
||||
assert Prime.nth(2) == 3
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "sixth prime" do
|
||||
assert Prime.nth(6) == 13
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "100th prime" do
|
||||
assert Prime.nth(100) == 541
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "weird case" do
|
||||
catch_error(Prime.nth(0))
|
||||
end
|
||||
end
|
|
@ -24,6 +24,17 @@ defmodule Phone do
|
|||
"""
|
||||
@spec number(String.t()) :: String.t()
|
||||
def number(raw) do
|
||||
n =
|
||||
Regex.scan(~r/\d/, raw)
|
||||
|> Enum.join()
|
||||
|> String.replace_prefix("1", "")
|
||||
|
||||
if String.length(n) == 10 && not Regex.match?(~r/[01]/, String.at(n, 3)) &&
|
||||
not Regex.match?(~r/[01]/, String.at(n, 0)) && not Regex.match?(~r/[a-z]/i, raw) do
|
||||
n
|
||||
else
|
||||
"0000000000"
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -48,6 +59,7 @@ defmodule Phone do
|
|||
"""
|
||||
@spec area_code(String.t()) :: String.t()
|
||||
def area_code(raw) do
|
||||
String.slice(number(raw), 0..2)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -72,5 +84,7 @@ defmodule Phone do
|
|||
"""
|
||||
@spec pretty(String.t()) :: String.t()
|
||||
def pretty(raw) do
|
||||
n = number(raw)
|
||||
"(#{String.slice(n, 0..2)}) #{String.slice(n, 3..5)}-#{String.slice(n, 6..9)}"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
|||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(exclude: :pending, trace: true)
|
||||
ExUnit.configure(trace: true)
|
||||
|
||||
defmodule PhoneTest do
|
||||
use ExUnit.Case
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
# Roman Numerals
|
||||
|
||||
Write a function to convert from normal numbers to Roman Numerals.
|
||||
|
||||
The Romans were a clever bunch. They conquered most of Europe and ruled
|
||||
it for hundreds of years. They invented concrete and straight roads and
|
||||
even bikinis. One thing they never discovered though was the number
|
||||
zero. This made writing and dating extensive histories of their exploits
|
||||
slightly more challenging, but the system of numbers they came up with
|
||||
is still in use today. For example the BBC uses Roman numerals to date
|
||||
their programmes.
|
||||
|
||||
The Romans wrote numbers using letters - I, V, X, L, C, D, M. (notice
|
||||
these letters have lots of straight lines and are hence easy to hack
|
||||
into stone tablets).
|
||||
|
||||
```text
|
||||
1 => I
|
||||
10 => X
|
||||
7 => VII
|
||||
```
|
||||
|
||||
There is no need to be able to convert numbers larger than about 3000.
|
||||
(The Romans themselves didn't tend to go any higher)
|
||||
|
||||
Wikipedia says: Modern Roman numerals ... are written by expressing each
|
||||
digit separately starting with the left most digit and skipping any
|
||||
digit with a value of zero.
|
||||
|
||||
To see this in practice, consider the example of 1990.
|
||||
|
||||
In Roman numerals 1990 is MCMXC:
|
||||
|
||||
1000=M
|
||||
900=CM
|
||||
90=XC
|
||||
|
||||
2008 is written as MMVIII:
|
||||
|
||||
2000=MM
|
||||
8=VIII
|
||||
|
||||
See also: http://www.novaroma.org/via_romana/numbers.html
|
||||
|
||||
## Running tests
|
||||
|
||||
Execute the tests with:
|
||||
|
||||
```bash
|
||||
$ elixir roman_numerals_test.exs
|
||||
```
|
||||
|
||||
### Pending tests
|
||||
|
||||
In the test suites, all but the first test have been skipped.
|
||||
|
||||
Once you get a test passing, you can unskip the next one by
|
||||
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||
|
||||
For example:
|
||||
|
||||
```elixir
|
||||
# @tag :pending
|
||||
test "shouting" do
|
||||
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||
end
|
||||
```
|
||||
|
||||
Or, you can enable all the tests by commenting out the
|
||||
`ExUnit.configure` line in the test suite.
|
||||
|
||||
```elixir
|
||||
# ExUnit.configure exclude: :pending, trace: true
|
||||
```
|
||||
|
||||
For more detailed information about the Elixir track, please
|
||||
see the [help page](http://exercism.io/languages/elixir).
|
||||
|
||||
## Source
|
||||
|
||||
The Roman Numeral Kata [http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals](http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals)
|
||||
|
||||
## Submitting Incomplete Solutions
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
|
@ -0,0 +1,35 @@
|
|||
defmodule Roman do
|
||||
@romans [
|
||||
{"M", 1000},
|
||||
{"CM", 900},
|
||||
{"D", 500},
|
||||
{"CD", 400},
|
||||
{"C", 100},
|
||||
{"XC", 90},
|
||||
{"L", 50},
|
||||
{"XL", 40},
|
||||
{"X", 10},
|
||||
{"IX", 9},
|
||||
{"V", 5},
|
||||
{"IV", 4},
|
||||
{"I", 1}
|
||||
]
|
||||
|
||||
@doc """
|
||||
Convert the number to a roman number.
|
||||
"""
|
||||
@spec numerals(pos_integer) :: String.t()
|
||||
def numerals(number) do
|
||||
numerals(@romans, number, "")
|
||||
end
|
||||
|
||||
defp numerals(_romans, 0, res), do: res
|
||||
|
||||
defp numerals([{_letter, number} | t], c, res) when c < number do
|
||||
numerals(t, c, res)
|
||||
end
|
||||
|
||||
defp numerals([{letter, number} | _t] = list, c, res) do
|
||||
numerals(list, c - number, res <> letter)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,100 @@
|
|||
if !System.get_env("EXERCISM_TEST_EXAMPLES") do
|
||||
Code.load_file("roman.exs", __DIR__)
|
||||
end
|
||||
|
||||
ExUnit.start()
|
||||
ExUnit.configure(trace: true)
|
||||
|
||||
defmodule RomanTest do
|
||||
use ExUnit.Case
|
||||
|
||||
# @tag :pending
|
||||
test "1" do
|
||||
assert Roman.numerals(1) == "I"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "2" do
|
||||
assert Roman.numerals(2) == "II"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "3" do
|
||||
assert Roman.numerals(3) == "III"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "4" do
|
||||
assert Roman.numerals(4) == "IV"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "5" do
|
||||
assert Roman.numerals(5) == "V"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "6" do
|
||||
assert Roman.numerals(6) == "VI"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "9" do
|
||||
assert Roman.numerals(9) == "IX"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "27" do
|
||||
assert Roman.numerals(27) == "XXVII"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "48" do
|
||||
assert Roman.numerals(48) == "XLVIII"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "59" do
|
||||
assert Roman.numerals(59) == "LIX"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "93" do
|
||||
assert Roman.numerals(93) == "XCIII"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "141" do
|
||||
assert Roman.numerals(141) == "CXLI"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "163" do
|
||||
assert Roman.numerals(163) == "CLXIII"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "402" do
|
||||
assert Roman.numerals(402) == "CDII"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "575" do
|
||||
assert Roman.numerals(575) == "DLXXV"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "911" do
|
||||
assert Roman.numerals(911) == "CMXI"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "1024" do
|
||||
assert Roman.numerals(1024) == "MXXIV"
|
||||
end
|
||||
|
||||
@tag :pending
|
||||
test "3000" do
|
||||
assert Roman.numerals(3000) == "MMM"
|
||||
end
|
||||
end
|
|
@ -3,16 +3,13 @@ class Prime
|
|||
|
||||
def self.nth(n)
|
||||
raise ArgumentError.new('N must be positive') if n < 1
|
||||
primes ||= [2, 3]
|
||||
curr = primes.last
|
||||
while n > primes.length
|
||||
curr += 2
|
||||
unless primes.any? { |p| curr % p == 0 }
|
||||
# very naive and slow :(
|
||||
primes.push(curr)
|
||||
sieve(50 * n)[n - 1]
|
||||
end
|
||||
end
|
||||
primes[n - 1]
|
||||
|
||||
def self.sieve(n)
|
||||
(2..Math.sqrt(n)).each_with_object([nil, nil, *2..n]) do |p, res|
|
||||
(p*p).step(n, p) { |m| res[m] = nil }
|
||||
end.compact
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
class Sieve
|
||||
@num
|
||||
|
||||
def initialize(base)
|
||||
@num = base
|
||||
end
|
||||
|
||||
def primes
|
||||
primes = (0..@num).to_a
|
||||
primes[0] = primes[1] = nil
|
||||
primes.select{|p| p && p*p < @num}.each do |p|
|
||||
(p*p).step(@num, p) {|m| primes[m] = nil}
|
||||
end
|
||||
primes.compact
|
||||
(2..Math.sqrt(@num)).each_with_object([nil, nil, *2..@num]) do |p, res|
|
||||
(p*p).step(@num, p) { |m| res[m] = nil }
|
||||
end.compact
|
||||
end
|
||||
end
|
||||
|
||||
module BookKeeping
|
||||
VERSION = 1
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue