| @@ -0,0 +1,6 @@ | |||
| { | |||
| "cells": [], | |||
| "metadata": {}, | |||
| "nbformat": 4, | |||
| "nbformat_minor": 4 | |||
| } | |||
| @@ -0,0 +1,18 @@ | |||
| module Proverb | |||
| let finalLine (input: string list) = "And all for the want of a " + (List.head input) + "." | |||
| let getLists (input: string list) = (List.take ((List.length input) - 1) input, List.tail input) | |||
| let getItemPairs (input: string list) = | |||
| let lists = getLists input | |||
| let a = lists |> fst | |||
| let b = lists |> snd | |||
| List.zip a b | |||
| let getLines (input: string list) = List.map (fun i -> | |||
| let a = i |> fst | |||
| let b = i |> snd | |||
| "For want of a " + a + " the " + b + " was lost.") (getItemPairs input) | |||
| let recite (input: string list): string list = if not (List.isEmpty input) then getLines input @ [finalLine input] else [] | |||
| @@ -0,0 +1,21 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk"> | |||
| <PropertyGroup> | |||
| <TargetFramework>netcoreapp3.0</TargetFramework> | |||
| <IsPackable>false</IsPackable> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <Compile Include="Proverb.fs" /> | |||
| <Compile Include="ProverbTests.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,61 @@ | |||
| // This file was auto-generated based on version 1.1.0 of the canonical data. | |||
| module ProverbTests | |||
| open FsUnit.Xunit | |||
| open Xunit | |||
| open Proverb | |||
| [<Fact>] | |||
| let ``Zero pieces`` () = | |||
| let strings: string list = [] | |||
| let expected: string list = [] | |||
| recite strings |> should equal expected | |||
| [<Fact>] | |||
| let ``One piece`` () = | |||
| let strings = ["nail"] | |||
| let expected = ["And all for the want of a nail."] | |||
| recite strings |> should equal expected | |||
| [<Fact>] | |||
| let ``Two pieces`` () = | |||
| let strings = ["nail"; "shoe"] | |||
| let expected = | |||
| [ "For want of a nail the shoe was lost."; | |||
| "And all for the want of a nail." ] | |||
| recite strings |> should equal expected | |||
| [<Fact>] | |||
| let ``Three pieces`` () = | |||
| let strings = ["nail"; "shoe"; "horse"] | |||
| let expected = | |||
| [ "For want of a nail the shoe was lost."; | |||
| "For want of a shoe the horse was lost."; | |||
| "And all for the want of a nail." ] | |||
| recite strings |> should equal expected | |||
| [<Fact>] | |||
| let ``Full proverb`` () = | |||
| let strings = ["nail"; "shoe"; "horse"; "rider"; "message"; "battle"; "kingdom"] | |||
| let expected = | |||
| [ "For want of a nail the shoe was lost."; | |||
| "For want of a shoe the horse was lost."; | |||
| "For want of a horse the rider was lost."; | |||
| "For want of a rider the message was lost."; | |||
| "For want of a message the battle was lost."; | |||
| "For want of a battle the kingdom was lost."; | |||
| "And all for the want of a nail." ] | |||
| recite strings |> should equal expected | |||
| [<Fact>] | |||
| let ``Four pieces modernized`` () = | |||
| let strings = ["pin"; "gun"; "soldier"; "battle"] | |||
| let expected = | |||
| [ "For want of a pin the gun was lost."; | |||
| "For want of a gun the soldier was lost."; | |||
| "For want of a soldier the battle was lost."; | |||
| "And all for the want of a pin." ] | |||
| recite strings |> should equal expected | |||
| @@ -0,0 +1,41 @@ | |||
| # Proverb | |||
| For want of a horseshoe nail, a kingdom was lost, or so the saying goes. | |||
| Given a list of inputs, generate the relevant proverb. For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme: | |||
| ```text | |||
| For want of a nail the shoe was lost. | |||
| For want of a shoe the horse was lost. | |||
| For want of a horse the rider was lost. | |||
| For want of a rider the message was lost. | |||
| For want of a message the battle was lost. | |||
| For want of a battle the kingdom was lost. | |||
| And all for the want of a nail. | |||
| ``` | |||
| Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content. No line of the output text should be a static, unchanging string; all should vary according to the input given. | |||
| ## Hints | |||
| - Try to capture the structure of the song in your code, where you build up the song by composing its parts. | |||
| ## 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 | |||
| Wikipedia [http://en.wikipedia.org/wiki/For_Want_of_a_Nail](http://en.wikipedia.org/wiki/For_Want_of_a_Nail) | |||