diff --git a/.gitignore b/.gitignore index dc7141bba1..4d7f4fa653 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ tmp bin/configlet bin/configlet.exe +.fake/ +.vs/ +tools/ +build/ +TestResult.xml \ No newline at end of file diff --git a/build.fsx b/build.fsx new file mode 100644 index 0000000000..919a5dab8c --- /dev/null +++ b/build.fsx @@ -0,0 +1,58 @@ +// Include Fake library +#r "tools/FAKE/tools/FakeLib.dll" + +open Fake +open Fake.CscHelper +open Fake.Testing.NUnit3 + +// Properties +let buildDir = getBuildParamOrDefault "buildDir" "./build/" +let sourceDir = "./exercises/" +let testDll = buildDir @@ "Tests.dll" +let nunitFrameworkDll = "tools/NUnit/lib/net45/nunit.framework.dll" + +let sourceFiles() = !! (buildDir @@ "./**/*.cs") |> List.ofSeq + +// Targets +Target "Clean" (fun _ -> + CleanDir buildDir +) + +Target "CopySource" (fun _ -> + CopyDir buildDir sourceDir allFiles +) + +Target "ModifySource" (fun _ -> + sourceFiles() + |> ReplaceInFiles [("[Ignore(\"Remove to run test\")]", ""); ("; Ignore", ""); (", Ignore = \"Remove to run test case\"", "")] +) + +Target "Build" (fun _ -> + sourceFiles() + |> List.ofSeq + |> Csc (fun p -> + { p with Output = testDll + References = [nunitFrameworkDll] + Target = Library }) +) + +Target "Test" (fun _ -> + Copy buildDir [nunitFrameworkDll] + + [testDll] + |> NUnit3 (fun p -> + { p with + ShadowCopy = false }) +) + +Target "Default" (fun _ -> ()) + +// Dependencies +"Clean" + ==> "CopySource" + ==> "ModifySource" + ==> "Build" + ==> "Test" + ==> "Default" + +RunTargetOrDefault "Default" \ No newline at end of file diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000000..6f17b6da10 --- /dev/null +++ b/build.ps1 @@ -0,0 +1,36 @@ +$toolsDirectory = Join-Path $PSScriptRoot "tools" +$nugetDirectory = Join-Path $toolsDirectory "nuget" +$nugetExe = Join-Path $nugetDirectory "nuget.exe" +$fakeExe = Join-Path $toolsDirectory "fake/tools/fake.exe" +$nunitFrameworkDll = Join-Path $toolsDirectory "nunit/lib/net45/nunit.framework.dll" +$nunitConsoleExe = Join-Path $toolsDirectory "nunit.console/tools/nunit3-console.exe" + +If (!(Test-Path $nugetExe)) { + # Ensure the directory exists (which is required by DownloadFile) + New-Item $nugetDirectory -Type Directory | Out-Null + + $nugetUrl = "https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe" + (New-Object System.Net.WebClient).DownloadFile($nugetUrl, $nugetExe) +} + +If (!(Test-Path $nugetExe)) { + Throw "Could not find nuget.exe" +} + +& $nugetExe install FAKE -Version 4.17.1 -ExcludeVersion -OutputDirectory $toolsDirectory +If (!(Test-Path $fakeExe)) { + Throw "Could not find fake.exe" +} + +& $nugetExe install NUnit -Version 3.0.1 -ExcludeVersion -OutputDirectory $toolsDirectory +If (!(Test-Path $nunitFrameworkDll)) { + Throw "Could not find nunit.framework.dll" +} + +& $nugetExe install NUnit.Console -Version 3.0.1 -ExcludeVersion -OutputDirectory $toolsDirectory +If (!(Test-Path $nunitConsoleExe)) { + Throw "Could not find nunit3-console.exe" +} + +# Use FAKE to execute the build script +& $fakeExe $args \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100644 index 0000000000..445152c968 --- /dev/null +++ b/build.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +currentDirectory="$( cd "$( dirname "$0" )" && pwd )" +toolsDirectory=$currentDirectory/tools +nugetDirectory=$toolsDirectory/nuget +nugetExe=$nugetDirectory/nuget.exe +fakeExe=$toolsDirectory/FAKE/tools/FAKE.exe +nunitFrameworkDll=$toolsDirectory/NUnit/lib/nunit.framework.dll +nunitConsoleExe=$toolsDirectory/NUnit.Console/tools/nunit3-console.exe + +if test ! -d $nugetDirectory; then + mkdir -p $nugetDirectory +fi + +if test ! -f $nugetExe; then + nugetUrl="https://dist.nuget.org/win-x86-commandline/v3.3.0/nuget.exe" + wget -O $nugetExe $nugetUrl 2> /dev/null || curl -o $nugetExe --location $nugetUrl /dev/null + + if test ! -f $nugetExe; then + echo "Could not find nuget.exe" + exit 1 + fi + + chmod 755 $nugetExe +fi + +mono $nugetExe install FAKE -Version 4.17.1 -ExcludeVersion -OutputDirectory $toolsDirectory +if test ! -f $fakeExe; then + echo "Could not find fake.exe" + exit 1 +fi + +mono $nugetExe install NUnit -Version 2.6.4 -ExcludeVersion -OutputDirectory $toolsDirectory +if test ! -f $nunitFrameworkDll; then + echo "Could not find nunit.framework.dll" + exit 1 +fi + +mono $nugetExe install NUnit.Console -Version 3.0.1 -ExcludeVersion -OutputDirectory $toolsDirectory +if test ! -f $nunitConsoleExe; then + echo "Could not find nunit3-console.exe" + exit 1 +fi + +# Use FAKE to execute the build script +mono $fakeExe build.fsx $@ \ No newline at end of file diff --git a/exercises/crypto-square/CryptoSquareTest.cs b/exercises/crypto-square/CryptoSquareTest.cs index 3b4e673271..5348ff0337 100644 --- a/exercises/crypto-square/CryptoSquareTest.cs +++ b/exercises/crypto-square/CryptoSquareTest.cs @@ -103,7 +103,7 @@ public void Normalized_ciphertext_is_split_by_height_of_square() public void Normalized_ciphertext_not_exactly_divisible_by_5_spills_into_a_smaller_segment() { var crypto = new Crypto("Madness, and then illumination."); - Assert.That(crypto.NormalizeCiphertext(), Is.EqualTo("msemo aanin dninn dlaet ltshu i")); + Assert.That(crypto.NormalizeCiphertext(), Is.EqualTo("msemo aanin dnin ndla etlt shui")); } [Ignore("Remove to run test")] @@ -111,7 +111,7 @@ public void Normalized_ciphertext_not_exactly_divisible_by_5_spills_into_a_small public void Normalized_ciphertext_is_split_into_segements_of_correct_size() { var crypto = new Crypto("If man was meant to stay on the ground god would have given us roots"); - Assert.That(crypto.NormalizeCiphertext(), Is.EqualTo("imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghns seoau")); + Assert.That(crypto.NormalizeCiphertext(), Is.EqualTo("imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau")); } [Ignore("Remove to run test")] diff --git a/exercises/crypto-square/Example.cs b/exercises/crypto-square/Example.cs index 472497534b..d06e7f8957 100644 --- a/exercises/crypto-square/Example.cs +++ b/exercises/crypto-square/Example.cs @@ -1,68 +1,54 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; public class Crypto { - public string NormalizePlaintext { get; private set; } + public Crypto(string input) + { + this.NormalizePlaintext = GetNormalizedPlaintext(input); + this.Size = this.CalculateSize(); + } + public int Size { get; private set; } - public Crypto(string value) + public string NormalizePlaintext { get; private set; } + + public string NormalizeCiphertext() { - NormalizePlaintext = NormalizeText(value); - Size = GetSquareSize(NormalizePlaintext); + return string.Join(" ", Transpose(this.PlaintextSegments())); } - private static string NormalizeText(string text) + public string Ciphertext() { - return string.Concat(text.ToLower().Where(char.IsLetterOrDigit)); + return string.Join("", Transpose(this.PlaintextSegments())); } - private static int GetSquareSize(string text) + public IEnumerable PlaintextSegments() { - return (int)Math.Ceiling(Math.Sqrt(text.Length)); + return Chunks(this.NormalizePlaintext, this.Size); } - public string[] PlaintextSegments() + private int CalculateSize() { - return SegmentText(NormalizePlaintext, Size); + return (int) Math.Ceiling(Math.Sqrt(this.NormalizePlaintext.Length)); } - private static string[] SegmentText(string text, int size) + private static string GetNormalizedPlaintext(string input) { - var segments = new List(); - var idx = 0; - while (idx < text.Length) - { - if (idx + size < text.Length) - segments.Add(text.Substring(idx, size)); - else - segments.Add(text.Substring(idx)); - idx += size; - } - return segments.ToArray(); + return new string(input.ToLowerInvariant().Where(char.IsLetterOrDigit).ToArray()); } - public string Ciphertext() + private static IEnumerable Chunks(string str, int chunkSize) { - var ciphertext = new StringBuilder(NormalizePlaintext.Length); - - for (int i = 0; i < Size; i++) - { - foreach (var segment in PlaintextSegments()) - { - if (i < segment.Length) - ciphertext.Append(segment[i]); - } - } - return ciphertext.ToString(); + return Enumerable.Range(0, (int)Math.Ceiling(str.Length / (double)chunkSize)) + .Select(i => str.Substring(i * chunkSize, Math.Min(str.Length - i * chunkSize, chunkSize))); } - - public string NormalizeCiphertext() + + private static IEnumerable Transpose(IEnumerable input) { - string cipher = Ciphertext(); - int size = cipher.Length == Size * Size - Size ? Size : Size - 1; - return string.Join(" ", SegmentText(cipher, size) ); + return input.SelectMany(s => s.Select((c, i) => Tuple.Create(i, c))) + .GroupBy(x => x.Item1) + .Select(g => new string(g.Select(t => t.Item2).ToArray())); } } \ No newline at end of file diff --git a/exercises/largest-series-product/LargestSeriesProductTest.cs b/exercises/largest-series-product/LargestSeriesProductTest.cs index cc48a77daf..63b8446ee0 100644 --- a/exercises/largest-series-product/LargestSeriesProductTest.cs +++ b/exercises/largest-series-product/LargestSeriesProductTest.cs @@ -89,7 +89,7 @@ public int Largest_product_for_empty_span_is_1(string digits) [Ignore("Remove to run test")] [Test] - public void Cannot_slice_empty_string_with_nonzero_span(string digits) + public void Cannot_slice_empty_string_with_nonzero_span() { Assert.Throws(() => new LargestSeriesProduct("").GetSlices(1)); }