| 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 ]) |
| <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> |
| // 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 | |||||
| # 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) | |||||