Skip to content

Commit

Permalink
roman numerals
Browse files Browse the repository at this point in the history
  • Loading branch information
handcraftsman committed Jun 20, 2016
1 parent b7a799b commit 0562d1d
Show file tree
Hide file tree
Showing 2 changed files with 194 additions and 0 deletions.
191 changes: 191 additions & 0 deletions src/Scratch/RomanNumerals/RomanTests.cs
@@ -0,0 +1,191 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssert;
using NUnit.Framework;

namespace Scratch.RomanNumerals
{
/// <summary>
/// inspired by: http://www.sandimetz.com/blog/2016/6/9/make-everything-the-same
/// </summary>
public static class Roman
{
private static readonly IDictionary<int, string> Numerals = new Dictionary<int, string>
{
{1, "I"},
{4, "IV"},
{5, "V"},
{9, "IX"},
{10, "X"},
{40, "XL"},
{50, "L"},
{90, "XC"},
{100, "C"},
{400, "CD"},
{500, "D"},
{900, "CM"},
{1000, "M"}
};

public static int FromRoman(this string roman)
{
var value = 0;
foreach (var kvp in Numerals.OrderByDescending(x => x.Key))
{
while (roman.StartsWith(kvp.Value))
{
value += kvp.Key;
roman = roman.Substring(kvp.Value.Length);
}
}
return value;
}

public static string ToRoman(this int i)
{
var result = "";
while (i > 0)
{
foreach (var kvp in Numerals.OrderByDescending(x => x.Key))
{
while (i >= kvp.Key)
{
result += kvp.Value;
i -= kvp.Key;
}
}
}
return result;
}
}

public class RomanTests
{
[TestFixture]
public class When_asked_to_convert_and_integer_value_to_roman_numerals
{
[Test]
public void Given_1_should_get_I()
{
1.ToRoman().ShouldBeEqualTo("I");
}


[Test]
public void Given_2_should_get_II()
{
2.ToRoman().ShouldBeEqualTo("II");
}

[Test]
public void Given_4_should_get_IV()
{
4.ToRoman().ShouldBeEqualTo("IV");
}

[Test]
public void Given_5_should_get_V()
{
5.ToRoman().ShouldBeEqualTo("V");
}

[Test]
public void Given_9_should_get_IX()
{
9.ToRoman().ShouldBeEqualTo("IX");
}

[Test]
public void Given_10_should_get_X()
{
10.ToRoman().ShouldBeEqualTo("X");
}

[Test]
public void Given_40_should_get_XL()
{
40.ToRoman().ShouldBeEqualTo("XL");
}

[Test]
public void Given_50_should_get_L()
{
50.ToRoman().ShouldBeEqualTo("L");
}

[Test]
public void Given_90_should_get_XC()
{
90.ToRoman().ShouldBeEqualTo("XC");
}

[Test]
public void Given_100_should_get_C()
{
100.ToRoman().ShouldBeEqualTo("C");
}

[Test]
public void Given_400_should_get_CD()
{
400.ToRoman().ShouldBeEqualTo("CD");
}

[Test]
public void Given_500_should_get_D()
{
500.ToRoman().ShouldBeEqualTo("D");
}

[Test]
public void Given_900_should_get_CM()
{
900.ToRoman().ShouldBeEqualTo("CM");
}

[Test]
public void Given_1000_should_get_M()
{
1000.ToRoman().ShouldBeEqualTo("M");
}
}

[TestFixture]
public class When_asked_to_convert_roman_numerals_to_an_integer
{
[Test]
public void Given_I_should_get_1()
{
"I".FromRoman().ShouldBeEqualTo(1);
}

[Test]
public void Given_II_should_get_2()
{
"II".FromRoman().ShouldBeEqualTo(2);
}

[Test]
public void Given_IV_should_get_4()
{
"IV".FromRoman().ShouldBeEqualTo(4);
}
}

[TestFixture]
public class When_asked_to_round_trip_integer_to_roman_numerals_to_integer
{
[Test]
public void Should_be_able_to_convert_all_integers_between_1_and_10000()
{
for (int input = 1; input <= 10000; input++)
{
var result = input.ToRoman();
var roundTripped = result.FromRoman();
input.ShouldBeEqualTo(roundTripped);
}
}
}
}
}
3 changes: 3 additions & 0 deletions src/Scratch/Scratch.csproj
Expand Up @@ -102,6 +102,9 @@
<Compile Include="Parse\CommaSeparatedList.cs" />
<Compile Include="Parse\TabDelimitedSerialized.cs" />
<Compile Include="Rectangle\Demo.cs" />
<Compile Include="RomanNumerals\RomanTests.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="SequentialLinq\SplitByBreakInSequence.cs" />
<Compile Include="SequentialLinq\Tests.cs" />
<Compile Include="Sorting\QuickSortWithInsertionSort\Class1.cs" />
Expand Down

0 comments on commit 0562d1d

Please sign in to comment.