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) | |||||