| @@ -0,0 +1,15 @@ | |||
| module Grains | |||
| let rec safeSqaure n: uint64 = | |||
| if n = 1 then uint64 (1) else uint64 (2) * safeSqaure (n - 1) | |||
| let square (n: int): Result<uint64, string> = | |||
| if n < 1 || n > 64 then Error "square must be between 1 and 64" else Ok(safeSqaure n) | |||
| let total: Result<uint64, string> = | |||
| Ok | |||
| (List.sumBy (fun x -> | |||
| let s = square x | |||
| match s with | |||
| | Ok (n) -> n | |||
| | _ -> uint64 (0)) [ 1 .. 64 ]) | |||
| @@ -0,0 +1,21 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <TargetFramework>netcoreapp3.0</TargetFramework> | |||
| <IsPackable>false</IsPackable> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Compile Include="Grains.fs" /> | |||
| <Compile Include="GrainsTests.fs" /> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" /> | |||
| <PackageReference Include="xunit" Version="2.4.1" /> | |||
| <PackageReference Include="xunit.runner.visualstudio" Version="2.4.2" /> | |||
| <PackageReference Include="FsUnit.xUnit" Version="3.9.0" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -0,0 +1,64 @@ | |||
| // This file was auto-generated based on version 1.2.0 of the canonical data. | |||
| module GrainsTests | |||
| open FsUnit.Xunit | |||
| open Xunit | |||
| open Grains | |||
| [<Fact>] | |||
| let ``1`` () = | |||
| let expected: Result<uint64,string> = Ok 1UL | |||
| square 1 |> should equal expected | |||
| [<Fact>] | |||
| let ``2`` () = | |||
| let expected: Result<uint64,string> = Ok 2UL | |||
| square 2 |> should equal expected | |||
| [<Fact>] | |||
| let ``3`` () = | |||
| let expected: Result<uint64,string> = Ok 4UL | |||
| square 3 |> should equal expected | |||
| [<Fact>] | |||
| let ``4`` () = | |||
| let expected: Result<uint64,string> = Ok 8UL | |||
| square 4 |> should equal expected | |||
| [<Fact>] | |||
| let ``16`` () = | |||
| let expected: Result<uint64,string> = Ok 32768UL | |||
| square 16 |> should equal expected | |||
| [<Fact>] | |||
| let ``32`` () = | |||
| let expected: Result<uint64,string> = Ok 2147483648UL | |||
| square 32 |> should equal expected | |||
| [<Fact>] | |||
| let ``64`` () = | |||
| let expected: Result<uint64,string> = Ok 9223372036854775808UL | |||
| square 64 |> should equal expected | |||
| [<Fact>] | |||
| let ``Square 0 raises an exception`` () = | |||
| let expected: Result<uint64,string> = Error "square must be between 1 and 64" | |||
| square 0 |> should equal expected | |||
| [<Fact>] | |||
| let ``Negative square raises an exception`` () = | |||
| let expected: Result<uint64,string> = Error "square must be between 1 and 64" | |||
| square -1 |> should equal expected | |||
| [<Fact>] | |||
| let ``Square greater than 64 raises an exception`` () = | |||
| let expected: Result<uint64,string> = Error "square must be between 1 and 64" | |||
| square 65 |> should equal expected | |||
| [<Fact>] | |||
| let ``Returns the total number of grains on the board`` () = | |||
| let expected: Result<uint64,string> = Ok 18446744073709551615UL | |||
| total |> should equal expected | |||
| @@ -0,0 +1,52 @@ | |||
| # Grains | |||
| Calculate the number of grains of wheat on a chessboard given that the number | |||
| on each square doubles. | |||
| There once was a wise servant who saved the life of a prince. The king | |||
| promised to pay whatever the servant could dream up. Knowing that the | |||
| king loved chess, the servant told the king he would like to have grains | |||
| of wheat. One grain on the first square of a chess board, with the number | |||
| of grains doubling on each successive square. | |||
| There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on). | |||
| Write code that shows: | |||
| - how many grains were on a given square, and | |||
| - the total number of grains on the chessboard | |||
| ## For bonus points | |||
| Did you get the tests passing and the code clean? If you want to, these | |||
| are some additional things you could try: | |||
| - Optimize for speed. | |||
| - Optimize for readability. | |||
| Then please share your thoughts in a comment on the submission. Did this | |||
| experiment make the code better? Worse? Did you learn anything from it? | |||
| ## Hints | |||
| For this exercise the following F# features come in handy: | |||
| - [BigInt](https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/numerics.biginteger-structure-%5Bfsharp%5D) | |||
| - [Seq.sumBy](https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/seq.sumby%5B't,%5Eu%5D-function-%5Bfsharp%5D) is a condensed format to apply a function to a sequence and then sum the results | |||
| ## Running the tests | |||
| To run the tests, run the command `dotnet test` from within the exercise directory. | |||
| ## Autoformatting the code | |||
| F# source code can be formatted with the [Fantomas](https://github.com/fsprojects/fantomas) tool. | |||
| After installing it with `dotnet tool restore`, run `dotnet fantomas .` to format code within the current directory. | |||
| ## Further information | |||
| For more detailed information about the F# track, including how to get help if | |||
| you're having trouble, please visit the exercism.io [F# language page](http://exercism.io/languages/fsharp/resources). | |||
| ## Source | |||
| JavaRanch Cattle Drive, exercise 6 [http://www.javaranch.com/grains.jsp](http://www.javaranch.com/grains.jsp) | |||