| { | |||||
| "cells": [], | |||||
| "metadata": {}, | |||||
| "nbformat": 4, | |||||
| "nbformat_minor": 4 | |||||
| } |
| 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 [] |
| <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> |
| // 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 | |||||
| # 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) | |||||