trackler 2.0.8.19 → 2.0.8.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/common/exercises/phone-number/canonical-data.json +2 -2
 - data/lib/trackler/version.rb +1 -1
 - data/tracks/c/config.json +7 -0
 - data/tracks/c/exercises/react/makefile +16 -0
 - data/tracks/c/exercises/react/src/example.c +185 -0
 - data/tracks/c/exercises/react/src/react.h +29 -0
 - data/tracks/c/exercises/react/test/test_react.c +324 -0
 - data/tracks/c/exercises/react/test/vendor/unity.c +1300 -0
 - data/tracks/c/exercises/react/test/vendor/unity.h +274 -0
 - data/tracks/c/exercises/react/test/vendor/unity_internals.h +701 -0
 - data/tracks/csharp/.travis.yml +2 -9
 - data/tracks/csharp/appveyor.yml +3 -3
 - data/tracks/csharp/build.cake +13 -4
 - data/tracks/csharp/build.ps1 +56 -164
 - data/tracks/csharp/build.sh +33 -78
 - data/tracks/csharp/circle.yml +2 -4
 - data/tracks/csharp/config.json +2 -1
 - data/tracks/csharp/exercises/leap/LeapTest.cs +8 -8
 - data/tracks/csharp/generators/CanonicalData.cs +19 -0
 - data/tracks/csharp/generators/CanonicalDataCase.cs +24 -0
 - data/tracks/csharp/generators/CanonicalDataCaseJsonConverter.cs +32 -0
 - data/tracks/csharp/generators/CanonicalDataCasesJsonConverter.cs +30 -0
 - data/tracks/csharp/generators/CanonicalDataParser.cs +28 -0
 - data/tracks/csharp/generators/ExerciseCollection.cs +23 -0
 - data/tracks/csharp/generators/Exercises/Exercise.cs +14 -0
 - data/tracks/csharp/generators/Exercises/LeapExercise.cs +35 -0
 - data/tracks/csharp/generators/Generators.csproj +12 -0
 - data/tracks/csharp/generators/Generators.csproj.user +6 -0
 - data/tracks/csharp/generators/Generators.sln +22 -0
 - data/tracks/csharp/generators/Program.cs +59 -0
 - data/tracks/csharp/generators/TestClass.cs +13 -0
 - data/tracks/csharp/generators/TestClassRenderer.cs +36 -0
 - data/tracks/csharp/generators/TestMethod.cs +9 -0
 - data/tracks/csharp/generators/TestMethodNameTransformer.cs +11 -0
 - data/tracks/csharp/generators/TestMethodRenderer.cs +18 -0
 - data/tracks/csharp/generators/To.cs +7 -0
 - data/tracks/csharp/generators/generate.ps1 +2 -0
 - data/tracks/csharp/generators/generate.sh +4 -0
 - data/tracks/delphi/config.json +8 -0
 - data/tracks/delphi/exercises/phone-number/uPhoneNumberExample.pas +6 -6
 - data/tracks/delphi/exercises/phone-number/uPhoneNumberTests.pas +28 -17
 - data/tracks/delphi/exercises/roman-numerals/RomanNumerals.dpr +60 -0
 - data/tracks/delphi/exercises/roman-numerals/uRomanNumeralsExample.pas +49 -0
 - data/tracks/delphi/exercises/roman-numerals/uRomanNumeralsTest.pas +216 -0
 - data/tracks/elixir/config.json +22 -0
 - data/tracks/elixir/exercises/poker/example.exs +136 -0
 - data/tracks/elixir/exercises/poker/poker.exs +34 -0
 - data/tracks/elixir/exercises/poker/poker_test.exs +217 -0
 - data/tracks/elixir/exercises/protein-translation/example.exs +62 -0
 - data/tracks/elixir/exercises/protein-translation/protein_translation.exs +34 -0
 - data/tracks/elixir/exercises/protein-translation/protein_translation_test.exs +87 -0
 - data/tracks/elixir/exercises/say/example.exs +139 -0
 - data/tracks/elixir/exercises/say/say.exs +8 -0
 - data/tracks/elixir/exercises/say/say_test.exs +85 -0
 - data/tracks/go/exercises/robot-name/example.go +2 -0
 - data/tracks/go/exercises/robot-name/robot_name_test.go +9 -1
 - data/tracks/go/exercises/roman-numerals/roman_numerals_test.go +4 -1
 - data/tracks/go/exercises/saddle-points/saddle_points_test.go +6 -6
 - data/tracks/php/config.json +7 -0
 - data/tracks/php/exercises/grade-school/example.php +35 -0
 - data/tracks/php/exercises/grade-school/grade-school_test.php +84 -0
 - metadata +43 -2
 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            defmodule ProteinTranslation do
         
     | 
| 
      
 2 
     | 
    
         
            +
              @doc """
         
     | 
| 
      
 3 
     | 
    
         
            +
              Given an RNA string, return a list of proteins specified by codons, in order.
         
     | 
| 
      
 4 
     | 
    
         
            +
              """
         
     | 
| 
      
 5 
     | 
    
         
            +
              @spec of_rna(String.t()) :: { atom,  list(String.t()) }
         
     | 
| 
      
 6 
     | 
    
         
            +
              def of_rna(rna) do
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              @doc """
         
     | 
| 
      
 10 
     | 
    
         
            +
              Given a codon, return the corresponding protein
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              UGU -> Cysteine
         
     | 
| 
      
 13 
     | 
    
         
            +
              UGC -> Cysteine
         
     | 
| 
      
 14 
     | 
    
         
            +
              UUA -> Leucine
         
     | 
| 
      
 15 
     | 
    
         
            +
              UUG -> Leucine
         
     | 
| 
      
 16 
     | 
    
         
            +
              AUG -> Methionine
         
     | 
| 
      
 17 
     | 
    
         
            +
              UUU -> Phenylalanine
         
     | 
| 
      
 18 
     | 
    
         
            +
              UUC -> Phenylalanine
         
     | 
| 
      
 19 
     | 
    
         
            +
              UCU -> Serine
         
     | 
| 
      
 20 
     | 
    
         
            +
              UCC -> Serine
         
     | 
| 
      
 21 
     | 
    
         
            +
              UCA -> Serine
         
     | 
| 
      
 22 
     | 
    
         
            +
              UCG -> Serine
         
     | 
| 
      
 23 
     | 
    
         
            +
              UGG -> Tryptophan
         
     | 
| 
      
 24 
     | 
    
         
            +
              UAU -> Tyrosine
         
     | 
| 
      
 25 
     | 
    
         
            +
              UAC -> Tyrosine
         
     | 
| 
      
 26 
     | 
    
         
            +
              UAA -> STOP
         
     | 
| 
      
 27 
     | 
    
         
            +
              UAG -> STOP
         
     | 
| 
      
 28 
     | 
    
         
            +
              UGA -> STOP
         
     | 
| 
      
 29 
     | 
    
         
            +
              """
         
     | 
| 
      
 30 
     | 
    
         
            +
              @spec of_codon(String.t()) :: { atom, String.t() }
         
     | 
| 
      
 31 
     | 
    
         
            +
              def of_codon(codon) do
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,87 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            if !System.get_env("EXERCISM_TEST_EXAMPLES") do
         
     | 
| 
      
 2 
     | 
    
         
            +
              Code.load_file("protein_translation.exs", __DIR__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            end
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ExUnit.start
         
     | 
| 
      
 6 
     | 
    
         
            +
            ExUnit.configure exclude: :pending, trace: true
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            defmodule ProteinTranslationTest do
         
     | 
| 
      
 9 
     | 
    
         
            +
              use ExUnit.Case
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              #@tag :pending
         
     | 
| 
      
 12 
     | 
    
         
            +
              test "AUG translates to methionine" do
         
     | 
| 
      
 13 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("AUG") == { :ok, "Methionine" }
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 17 
     | 
    
         
            +
              test "identifies Phenylalanine codons" do
         
     | 
| 
      
 18 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UUU") == { :ok, "Phenylalanine" }
         
     | 
| 
      
 19 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UUC") == { :ok, "Phenylalanine" }
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 23 
     | 
    
         
            +
              test "identifies Leucine codons" do
         
     | 
| 
      
 24 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UUA") == { :ok, "Leucine" }
         
     | 
| 
      
 25 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UUG") == { :ok, "Leucine" }
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 29 
     | 
    
         
            +
              test "identifies Serine codons" do
         
     | 
| 
      
 30 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UCU") == { :ok, "Serine" }
         
     | 
| 
      
 31 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UCC") == { :ok, "Serine" }
         
     | 
| 
      
 32 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UCA") == { :ok, "Serine" }
         
     | 
| 
      
 33 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UCG") == { :ok, "Serine" }
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 37 
     | 
    
         
            +
              test "identifies Tyrosine codons" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UAU") == { :ok, "Tyrosine" }
         
     | 
| 
      
 39 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UAC") == { :ok, "Tyrosine" }
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 43 
     | 
    
         
            +
              test "identifies Cysteine codons" do
         
     | 
| 
      
 44 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UGU") == { :ok, "Cysteine" }
         
     | 
| 
      
 45 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UGC") == { :ok, "Cysteine" }
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 49 
     | 
    
         
            +
              test "identifies Tryptophan codons" do
         
     | 
| 
      
 50 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UGG") == { :ok, "Tryptophan" }
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 54 
     | 
    
         
            +
              test "identifies stop codons" do
         
     | 
| 
      
 55 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UAA") == { :ok, "STOP" }
         
     | 
| 
      
 56 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UAG") == { :ok, "STOP" }
         
     | 
| 
      
 57 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("UGA") == { :ok, "STOP" }
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 61 
     | 
    
         
            +
              test "translates rna strand into correct protein" do
         
     | 
| 
      
 62 
     | 
    
         
            +
                strand = "AUGUUUUGG"
         
     | 
| 
      
 63 
     | 
    
         
            +
                assert ProteinTranslation.of_rna(strand) == { :ok, ~w(Methionine Phenylalanine Tryptophan) }
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 67 
     | 
    
         
            +
              test "stops translation if stop codon present" do
         
     | 
| 
      
 68 
     | 
    
         
            +
                strand = "AUGUUUUAA"
         
     | 
| 
      
 69 
     | 
    
         
            +
                assert ProteinTranslation.of_rna(strand) == { :ok, ~w(Methionine Phenylalanine) }
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 73 
     | 
    
         
            +
              test "stops translation of longer strand" do
         
     | 
| 
      
 74 
     | 
    
         
            +
                strand = "UGGUGUUAUUAAUGGUUU"
         
     | 
| 
      
 75 
     | 
    
         
            +
                assert ProteinTranslation.of_rna(strand) == { :ok, ~w(Tryptophan Cysteine Tyrosine) }
         
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 79 
     | 
    
         
            +
              test "invalid RNA" do
         
     | 
| 
      
 80 
     | 
    
         
            +
                assert ProteinTranslation.of_rna("CARROT") == { :error, "invalid RNA" }
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 84 
     | 
    
         
            +
              test "invalid codon" do
         
     | 
| 
      
 85 
     | 
    
         
            +
                assert ProteinTranslation.of_codon("INVALID") == { :error, "invalid codon" }
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,139 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            defmodule Say do
         
     | 
| 
      
 2 
     | 
    
         
            +
              @moduledoc """
         
     | 
| 
      
 3 
     | 
    
         
            +
              This example solution takes an integer and breaks it into chunks of 3 and
         
     | 
| 
      
 4 
     | 
    
         
            +
              translates those chunks the same. The larger denominations (e.g. 'thousand')
         
     | 
| 
      
 5 
     | 
    
         
            +
              are added if there are multiple chunks to translate.  Here are a few examples:
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              - `Say.in_english(23)` creates the chunk of `[0, 2, 3]` and invokes
         
     | 
| 
      
 8 
     | 
    
         
            +
                `translate_chunk` on that to produce "twenty-three".
         
     | 
| 
      
 9 
     | 
    
         
            +
              - `Say.in_english(1_234)` creates the chunks of `[0, 0, 1]` and `[2, 3, 4]`,
         
     | 
| 
      
 10 
     | 
    
         
            +
                 which `translate_chunk` will translate to "one" and
         
     | 
| 
      
 11 
     | 
    
         
            +
                 "two hundred thirty-four" and `translate_chunks` will combine them for
         
     | 
| 
      
 12 
     | 
    
         
            +
                 `one thousand two hundred thirty-four`.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              Padding the chunks with leading zeroes gives us nice and even chunks of 3
         
     | 
| 
      
 15 
     | 
    
         
            +
              digits to translate.
         
     | 
| 
      
 16 
     | 
    
         
            +
              """
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              @small_numbers ~w(
         
     | 
| 
      
 19 
     | 
    
         
            +
                one two three four five six seven eight nine ten
         
     | 
| 
      
 20 
     | 
    
         
            +
                eleven twelve thirteen fourteen fifteen sixteen
         
     | 
| 
      
 21 
     | 
    
         
            +
                seventeen eighteen nineteen
         
     | 
| 
      
 22 
     | 
    
         
            +
              )
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              @decades ~w(
         
     | 
| 
      
 25 
     | 
    
         
            +
                twenty thirty forty fifty sixty seventy eighty ninety
         
     | 
| 
      
 26 
     | 
    
         
            +
              )
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              @separators ~w(thousand million billion)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              @doc """
         
     | 
| 
      
 31 
     | 
    
         
            +
              Translate a positive integer into English.
         
     | 
| 
      
 32 
     | 
    
         
            +
              """
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              @spec in_english(Integer.t) :: {atom, String.t}
         
     | 
| 
      
 35 
     | 
    
         
            +
              def in_english(number) when number < 0 or number >= 1_000_000_000_000 do
         
     | 
| 
      
 36 
     | 
    
         
            +
                {:error, "number is out of range"}
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
              def in_english(0), do: {:ok, "zero"}
         
     | 
| 
      
 39 
     | 
    
         
            +
              def in_english(number) do
         
     | 
| 
      
 40 
     | 
    
         
            +
                result = Integer.digits(number)
         
     | 
| 
      
 41 
     | 
    
         
            +
                |> padded_chunk(3, 0)
         
     | 
| 
      
 42 
     | 
    
         
            +
                |> translate_chunks
         
     | 
| 
      
 43 
     | 
    
         
            +
                |> clean_join(" ")
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                {:ok, result}
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              @spec translate_chunks(List.t) :: [String.t]
         
     | 
| 
      
 50 
     | 
    
         
            +
              defp translate_chunks(chunks) do
         
     | 
| 
      
 51 
     | 
    
         
            +
                translate_chunks(chunks, Enum.count(chunks))
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              @spec translate_chunks(List.t, Integer.t) :: [String.t]
         
     | 
| 
      
 56 
     | 
    
         
            +
              defp translate_chunks([chunk], 1), do: [translate_chunk(chunk)]
         
     | 
| 
      
 57 
     | 
    
         
            +
              defp translate_chunks([[0, 0, 0] | remaining], n) do
         
     | 
| 
      
 58 
     | 
    
         
            +
                translate_chunks(remaining, n - 1)
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
              defp translate_chunks([chunk | remaining], n) do
         
     | 
| 
      
 61 
     | 
    
         
            +
                chunk_in_english = [
         
     | 
| 
      
 62 
     | 
    
         
            +
                  translate_chunk(chunk),
         
     | 
| 
      
 63 
     | 
    
         
            +
                  Enum.at(@separators, n - 2)
         
     | 
| 
      
 64 
     | 
    
         
            +
                ]
         
     | 
| 
      
 65 
     | 
    
         
            +
                |> clean_join(" ")
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                [ chunk_in_english | translate_chunks(remaining, n - 1) ]
         
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              @spec translate_chunk([Integer.t]) :: String.t
         
     | 
| 
      
 72 
     | 
    
         
            +
              defp translate_chunk([0, 0, 0]), do: ""
         
     | 
| 
      
 73 
     | 
    
         
            +
              defp translate_chunk([0, 0, ones]), do: ones_in_english(ones)
         
     | 
| 
      
 74 
     | 
    
         
            +
              defp translate_chunk([0, 1, ones]) do
         
     | 
| 
      
 75 
     | 
    
         
            +
                ones_in_english(ones + 10)
         
     | 
| 
      
 76 
     | 
    
         
            +
              end
         
     | 
| 
      
 77 
     | 
    
         
            +
              defp translate_chunk([0, tens, 0]), do: tens_in_english(tens)
         
     | 
| 
      
 78 
     | 
    
         
            +
              defp translate_chunk([0, tens, ones]) do
         
     | 
| 
      
 79 
     | 
    
         
            +
                [
         
     | 
| 
      
 80 
     | 
    
         
            +
                  tens_in_english(tens),
         
     | 
| 
      
 81 
     | 
    
         
            +
                  ones_in_english(ones)
         
     | 
| 
      
 82 
     | 
    
         
            +
                ]
         
     | 
| 
      
 83 
     | 
    
         
            +
                |> clean_join("-")
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
              defp translate_chunk([hundreds, 0, 0]) do
         
     | 
| 
      
 86 
     | 
    
         
            +
                "#{ones_in_english(hundreds)} hundred"
         
     | 
| 
      
 87 
     | 
    
         
            +
              end
         
     | 
| 
      
 88 
     | 
    
         
            +
              defp translate_chunk([hundreds, tens, ones]) do
         
     | 
| 
      
 89 
     | 
    
         
            +
                [
         
     | 
| 
      
 90 
     | 
    
         
            +
                  translate_chunk([hundreds, 0, 0]),
         
     | 
| 
      
 91 
     | 
    
         
            +
                  translate_chunk([0, tens, ones])
         
     | 
| 
      
 92 
     | 
    
         
            +
                ]
         
     | 
| 
      
 93 
     | 
    
         
            +
                |> clean_join(" ")
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
              @spec ones_in_english(Integer.t) :: String.t
         
     | 
| 
      
 98 
     | 
    
         
            +
              defp ones_in_english(index), do: Enum.at(@small_numbers, index - 1)
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
              @spec tens_in_english(Integer.t) :: String.t
         
     | 
| 
      
 102 
     | 
    
         
            +
              defp tens_in_english(index), do: Enum.at(@decades, index - 2)
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              @spec clean_join([any], String.t) :: String.t
         
     | 
| 
      
 106 
     | 
    
         
            +
              defp clean_join(collection, separator) do
         
     | 
| 
      
 107 
     | 
    
         
            +
                collection
         
     | 
| 
      
 108 
     | 
    
         
            +
                |> reject_blank
         
     | 
| 
      
 109 
     | 
    
         
            +
                |> Enum.join(separator)
         
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
              @spec reject_blank([any]) :: [any]
         
     | 
| 
      
 114 
     | 
    
         
            +
              defp reject_blank(col) do
         
     | 
| 
      
 115 
     | 
    
         
            +
                col
         
     | 
| 
      
 116 
     | 
    
         
            +
                |> Enum.reject(&(&1 == nil || &1 == ""))
         
     | 
| 
      
 117 
     | 
    
         
            +
              end
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
              @spec padded_chunk([any], Integer.t, any) :: [any]
         
     | 
| 
      
 121 
     | 
    
         
            +
              defp padded_chunk(list, chunk_size, pad) do
         
     | 
| 
      
 122 
     | 
    
         
            +
                pad_size = pad_size(chunk_size, rem(Enum.count(list), chunk_size))
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                pad(list, pad, pad_size)
         
     | 
| 
      
 125 
     | 
    
         
            +
                |> Enum.chunk(chunk_size)
         
     | 
| 
      
 126 
     | 
    
         
            +
              end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
              @spec pad_size(Integer.t, Integer.t) :: Integer.t
         
     | 
| 
      
 130 
     | 
    
         
            +
              defp pad_size(_, 0), do: 0
         
     | 
| 
      
 131 
     | 
    
         
            +
              defp pad_size(total, rem), do: total - rem
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
              @spec pad([any], any, Integer.t) :: [any]
         
     | 
| 
      
 135 
     | 
    
         
            +
              defp pad(list, _, 0), do: list
         
     | 
| 
      
 136 
     | 
    
         
            +
              defp pad(list, pad, count) do
         
     | 
| 
      
 137 
     | 
    
         
            +
                [pad] ++ pad(list, pad, count - 1)
         
     | 
| 
      
 138 
     | 
    
         
            +
              end
         
     | 
| 
      
 139 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,85 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            if !System.get_env("EXERCISM_TEST_EXAMPLES") do
         
     | 
| 
      
 2 
     | 
    
         
            +
              Code.load_file("say.exs", __DIR__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            end
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ExUnit.start
         
     | 
| 
      
 6 
     | 
    
         
            +
            ExUnit.configure exclude: :pending, trace: true
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            defmodule SayTest do
         
     | 
| 
      
 9 
     | 
    
         
            +
              use ExUnit.Case
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              # @tag :pending
         
     | 
| 
      
 12 
     | 
    
         
            +
              test "zero" do
         
     | 
| 
      
 13 
     | 
    
         
            +
                assert Say.in_english(0) == {:ok, "zero"}
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 17 
     | 
    
         
            +
              test "one" do
         
     | 
| 
      
 18 
     | 
    
         
            +
                assert Say.in_english(1) == {:ok, "one"}
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 22 
     | 
    
         
            +
              test "fourteen" do
         
     | 
| 
      
 23 
     | 
    
         
            +
                assert Say.in_english(14) == {:ok, "fourteen"}
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 27 
     | 
    
         
            +
              test "twenty" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                assert Say.in_english(20) == {:ok, "twenty"}
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 32 
     | 
    
         
            +
              test "twenty-two" do
         
     | 
| 
      
 33 
     | 
    
         
            +
                assert Say.in_english(22) == {:ok, "twenty-two"}
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 37 
     | 
    
         
            +
              test "one hundred" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                assert Say.in_english(100) == {:ok, "one hundred"}
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 42 
     | 
    
         
            +
              test "one hundred twenty-three" do
         
     | 
| 
      
 43 
     | 
    
         
            +
                assert Say.in_english(123) == {:ok, "one hundred twenty-three"}
         
     | 
| 
      
 44 
     | 
    
         
            +
              end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 47 
     | 
    
         
            +
              test "one thousand" do
         
     | 
| 
      
 48 
     | 
    
         
            +
                assert Say.in_english(1_000) == {:ok, "one thousand"}
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 52 
     | 
    
         
            +
              test "one thousand two hundred thirty-four" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                assert Say.in_english(1_234) == {:ok, "one thousand two hundred thirty-four"}
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 57 
     | 
    
         
            +
              test "one million" do
         
     | 
| 
      
 58 
     | 
    
         
            +
                assert Say.in_english(1_000_000) == {:ok, "one million"}
         
     | 
| 
      
 59 
     | 
    
         
            +
              end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 62 
     | 
    
         
            +
              test "one million two thousand three hundred forty-five" do
         
     | 
| 
      
 63 
     | 
    
         
            +
                assert Say.in_english(1_002_345) == {:ok, "one million two thousand three hundred forty-five"}
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 67 
     | 
    
         
            +
              test "one billion" do
         
     | 
| 
      
 68 
     | 
    
         
            +
                assert Say.in_english(1_000_000_000) == {:ok, "one billion"}
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 72 
     | 
    
         
            +
              test "a big number" do
         
     | 
| 
      
 73 
     | 
    
         
            +
                assert Say.in_english(987_654_321_123) == {:ok, "nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three"}
         
     | 
| 
      
 74 
     | 
    
         
            +
              end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 77 
     | 
    
         
            +
              test "numbers below zero are out of range" do
         
     | 
| 
      
 78 
     | 
    
         
            +
                assert Say.in_english(-1) == {:error, "number is out of range"}
         
     | 
| 
      
 79 
     | 
    
         
            +
              end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
              @tag :pending
         
     | 
| 
      
 82 
     | 
    
         
            +
              test "numbers above 999,999,999,999 are out of range" do
         
     | 
| 
      
 83 
     | 
    
         
            +
                assert Say.in_english(1_000_000_000_000) == {:error, "number is out of range"}
         
     | 
| 
      
 84 
     | 
    
         
            +
              end
         
     | 
| 
      
 85 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -5,10 +5,18 @@ import ( 
     | 
|
| 
       5 
5 
     | 
    
         
             
            	"testing"
         
     | 
| 
       6 
6 
     | 
    
         
             
            )
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 8 
     | 
    
         
            +
            const targetTestVersion = 1
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
       10 
10 
     | 
    
         
             
            var namePat = regexp.MustCompile(`^[A-Z]{2}\d{3}$`)
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
      
 12 
     | 
    
         
            +
            func New() *Robot { return new(Robot) }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            func TestTestVersion(t *testing.T) {
         
     | 
| 
      
 15 
     | 
    
         
            +
            	if testVersion != targetTestVersion {
         
     | 
| 
      
 16 
     | 
    
         
            +
            		t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
         
     | 
| 
      
 17 
     | 
    
         
            +
            	}
         
     | 
| 
      
 18 
     | 
    
         
            +
            }
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       12 
20 
     | 
    
         
             
            func TestNameValid(t *testing.T) {
         
     | 
| 
       13 
21 
     | 
    
         
             
            	n := New().Name()
         
     | 
| 
       14 
22 
     | 
    
         
             
            	if !namePat.MatchString(n) {
         
     | 
| 
         @@ -4,10 +4,13 @@ import "testing" 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            const targetTestVersion = 3
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
            func  
     | 
| 
      
 7 
     | 
    
         
            +
            func TestTestVersion(t *testing.T) {
         
     | 
| 
       8 
8 
     | 
    
         
             
            	if testVersion != targetTestVersion {
         
     | 
| 
       9 
9 
     | 
    
         
             
            		t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
         
     | 
| 
       10 
10 
     | 
    
         
             
            	}
         
     | 
| 
      
 11 
     | 
    
         
            +
            }
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            func TestRomanNumerals(t *testing.T) {
         
     | 
| 
       11 
14 
     | 
    
         
             
            	tc := append(romanNumeralTests, []romanNumeralTest{
         
     | 
| 
       12 
15 
     | 
    
         
             
            		{0, "", true},
         
     | 
| 
       13 
16 
     | 
    
         
             
            		{-1, "", true},
         
     | 
| 
         @@ -20,6 +20,12 @@ var tests = []struct { 
     | 
|
| 
       20 
20 
     | 
    
         
             
            	{"4 5 4\n3 5 5\n1 5 4", []Pair{{0, 1}, {1, 1}, {2, 1}}},
         
     | 
| 
       21 
21 
     | 
    
         
             
            }
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
      
 23 
     | 
    
         
            +
            func TestTestVersion(t *testing.T) {
         
     | 
| 
      
 24 
     | 
    
         
            +
            	if testVersion != targetTestVersion {
         
     | 
| 
      
 25 
     | 
    
         
            +
            		t.Fatalf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
         
     | 
| 
      
 26 
     | 
    
         
            +
            	}
         
     | 
| 
      
 27 
     | 
    
         
            +
            }
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
       23 
29 
     | 
    
         
             
            func TestSaddle(t *testing.T) {
         
     | 
| 
       24 
30 
     | 
    
         
             
            	for _, test := range tests {
         
     | 
| 
       25 
31 
     | 
    
         
             
            		m, err := New(test.m)
         
     | 
| 
         @@ -51,12 +57,6 @@ exp: 
     | 
|
| 
       51 
57 
     | 
    
         
             
            	return true
         
     | 
| 
       52 
58 
     | 
    
         
             
            }
         
     | 
| 
       53 
59 
     | 
    
         | 
| 
       54 
     | 
    
         
            -
            func TestTestVersion(t *testing.T) {
         
     | 
| 
       55 
     | 
    
         
            -
            	if testVersion != targetTestVersion {
         
     | 
| 
       56 
     | 
    
         
            -
            		t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
         
     | 
| 
       57 
     | 
    
         
            -
            	}
         
     | 
| 
       58 
     | 
    
         
            -
            }
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
60 
     | 
    
         
             
            func BenchmarkSaddle(b *testing.B) {
         
     | 
| 
       61 
61 
     | 
    
         
             
            	ms := make([]*Matrix, len(tests))
         
     | 
| 
       62 
62 
     | 
    
         
             
            	var err error
         
     |