diff --git a/config.json b/config.json index 45d681ab..985eb75c 100644 --- a/config.json +++ b/config.json @@ -520,6 +520,17 @@ "matrices" ] }, + { + "slug": "nth-prime", + "uuid": "8600a843-ec71-4f1a-b9fe-2ed515035101", + "core": false, + "unlocked_by": "hamming", + "difficulty": 4, + "topics": [ + "algorithms", + "math" + ] + }, { "slug": "largest-series-product", "uuid": "b312ff0e-90e3-4dd8-99dc-df4a9deb1907", diff --git a/exercises/nth-prime/README.md b/exercises/nth-prime/README.md new file mode 100644 index 00000000..b4291e50 --- /dev/null +++ b/exercises/nth-prime/README.md @@ -0,0 +1,39 @@ +# 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 + +In order to run the tests, issue the following command from the exercise +directory: + +For running the tests provided, `rebar3` is used as it is the official build and +dependency management tool for erlang now. Please refer to [the tracks installation +instructions](http://exercism.io/languages/erlang/installation) on how to do that. + +In order to run the tests, you can issue the following command from the exercise +directory. + +```bash +$ rebar3 eunit +``` + +## Questions? + +For detailed information about the Erlang track, please refer to the +[help page](http://exercism.io/languages/erlang) on the Exercism site. +This covers the basic information on setting up the development +environment expected by the exercises. + +## 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. diff --git a/exercises/nth-prime/rebar.config b/exercises/nth-prime/rebar.config new file mode 100644 index 00000000..db5d9076 --- /dev/null +++ b/exercises/nth-prime/rebar.config @@ -0,0 +1,30 @@ +%% Erlang compiler options +{erl_opts, [debug_info, warnings_as_errors]}. + +{deps, [{erl_exercism, "0.1.2"}]}. + +{dialyzer, [ + {warnings, [underspecs, no_return]}, + {get_warnings, true}, + {plt_apps, top_level_deps}, % top_level_deps | all_deps + {plt_extra_apps, []}, + {plt_location, local}, % local | "/my/file/name" + {plt_prefix, "rebar3"}, + {base_plt_apps, [stdlib, kernel, crypto]}, + {base_plt_location, global}, % global | "/my/file/name" + {base_plt_prefix, "rebar3"} +]}. + +%% eunit:test(Tests) +{eunit_tests, []}. +%% Options for eunit:test(Tests, Opts) +{eunit_opts, [verbose]}. + +%% == xref == + +{xref_warnings, true}. + +%% xref checks to run +{xref_checks, [undefined_function_calls, undefined_functions, + locals_not_used, exports_not_used, + deprecated_function_calls, deprecated_functions]}. diff --git a/exercises/nth-prime/src/example.erl b/exercises/nth-prime/src/example.erl new file mode 100644 index 00000000..7ffc6035 --- /dev/null +++ b/exercises/nth-prime/src/example.erl @@ -0,0 +1,57 @@ +-module(example). + +-export([prime/1]). + + +prime(N) when is_integer(N), N>0 -> + Generator=prime_generator(), + prime(Generator, N, []). + +prime(Generator, N, KnownPrimes0) when length(KnownPrimes0) + Next=next_candidate(Generator), + KnownPrimes1=case is_prime(Next, KnownPrimes0) of + true -> KnownPrimes0++[Next]; + false -> KnownPrimes0 + end, + prime(Generator, N, KnownPrimes1); +prime(_, _, Primes) -> + lists:last(Primes). + +is_prime(Candidate, KnownPrimes) -> + SqrtCandidate=math:sqrt(Candidate), + is_prime(Candidate, SqrtCandidate, KnownPrimes). + +is_prime(_, _, []) -> + true; +is_prime(_, SqrtCandidate, [KnownPrime|_]) when KnownPrime>SqrtCandidate -> + true; +is_prime(Candidate, _, [KnownPrime|_]) when Candidate rem KnownPrime=:=0 -> + false; +is_prime(Candidate, SqrtCandidate, [_|KnownPrimes]) -> + is_prime(Candidate, SqrtCandidate, KnownPrimes). + +next_candidate(Generator) -> + Candidate=receive {Generator, Candidate1} -> Candidate1 end, + Generator ! {self(), next}, + Candidate. + +prime_generator() -> + Generator=spawn_link( + fun () -> prime_generator_loop() end + ), + Generator ! {self(), next}, + Generator. + +prime_generator_loop() -> + prime_generator_loop(2). + +prime_generator_loop(2) -> + receive {Reply, next} -> Reply ! {self(), 2} end, + prime_generator_loop(3); +prime_generator_loop(3) -> + receive {Reply, next} -> Reply ! {self(), 3} end, + prime_generator_loop(6); +prime_generator_loop(N) -> + receive {Reply1, next} -> Reply1 ! {self(), N-1} end, + receive {Reply2, next} -> Reply2 ! {self(), N+1} end, + prime_generator_loop(N+6). diff --git a/exercises/nth-prime/src/nth_prime.app.src b/exercises/nth-prime/src/nth_prime.app.src new file mode 100644 index 00000000..c8d2b814 --- /dev/null +++ b/exercises/nth-prime/src/nth_prime.app.src @@ -0,0 +1,9 @@ +{application, nth_prime, + [{description, "exercism.io - nth-prime"}, + {vsn, "0.0.1"}, + {modules, []}, + {registered, []}, + {applications, [kernel, + stdlib]}, + {env, []} +]}. diff --git a/exercises/nth-prime/src/nth_prime.erl b/exercises/nth-prime/src/nth_prime.erl new file mode 100644 index 00000000..3247066e --- /dev/null +++ b/exercises/nth-prime/src/nth_prime.erl @@ -0,0 +1,6 @@ +-module(nth_prime). + +-export([prime/1]). + + +prime(_N) -> undefined. diff --git a/exercises/nth-prime/test/nth_prime_tests.erl b/exercises/nth-prime/test/nth_prime_tests.erl new file mode 100644 index 00000000..11e502bf --- /dev/null +++ b/exercises/nth-prime/test/nth_prime_tests.erl @@ -0,0 +1,29 @@ +%% Based on canonical data version 2.1.0.1 +%% Generated with 'testgen v0.1.0' +%% https://github.com/exercism/problem-specifications/raw/4a3ba76cf247f83f2417b35df68404279942df07/exercises/nth-prime/canonical-data.json +%% This file is automatically generated from the exercises canonical data. + +-module(nth_prime_tests). + +-include_lib("erl_exercism/include/exercism.hrl"). +-include_lib("eunit/include/eunit.hrl"). + + + + +'1_first_prime_test_'() -> + {"first prime", ?_assertEqual(2, nth_prime:prime(1))}. + +'2_second_prime_test_'() -> + {"second prime", ?_assertEqual(3, nth_prime:prime(2))}. + +'3_sixth_prime_test_'() -> + {"sixth prime", ?_assertEqual(13, nth_prime:prime(6))}. + +'4_big_prime_test_'() -> + {"big prime", + ?_assertEqual(104743, nth_prime:prime(10001))}. + +'5_there_is_no_zeroth_prime_test_'() -> + {"there is no zeroth prime", + ?_assertError(_, nth_prime:prime(0))}.