Last active
August 29, 2015 14:02
-
-
Save ralfw/89640f71e95f23ab2927 to your computer and use it in GitHub Desktop.
Informed TDD - JUGHH 17.6.2014
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Ralf Westphal, Hamburg | |
* [email protected], @ralfw, http://blog.ralfw.de | |
*/ | |
using System; | |
using System.Linq; | |
using System.Collections.Generic; | |
namespace kata | |
{ | |
public class RomanConverter | |
{ | |
public int ConvertFromRoman(string roman) | |
{ | |
Validate(roman); | |
var reversedRoman = Reverse_roman(roman); | |
var values = Map_roman_digits_to_values(reversedRoman); | |
return Sum_values(values); | |
} | |
private void Validate(string roman) | |
{ | |
// validate 1 | |
if (roman.IndexOf("VV") >= 0 || | |
roman.IndexOf("LL") >= 0 || | |
roman.IndexOf("DD") >= 0) | |
throw new InvalidOperationException("So gehts nicht!"); | |
// validate 2 | |
// validate 3 | |
} | |
private IEnumerable<char> Reverse_roman(string roman) | |
{ | |
var digits = roman.ToCharArray(); | |
Array.Reverse(digits); | |
return digits; | |
} | |
private IEnumerable<int> Map_roman_digits_to_values(IEnumerable<char> reversedRoman) | |
{ | |
var map = new Dictionary<char, int>{ | |
{'I', 1}, | |
{'V', 5}, | |
{'X', 10}, | |
{'L', 50}, | |
{'C', 100}, | |
{'D', 500}, | |
{'M', 1000}, | |
}; | |
return reversedRoman.Select(d => map[d]); | |
} | |
private int Sum_values(IEnumerable<int> values) | |
{ | |
var sum = 0; | |
var prevValue = 0; | |
foreach (var v in values) { | |
if (v < prevValue) | |
sum -= v; | |
else | |
sum += v; | |
prevValue = v; | |
} | |
return sum; | |
} | |
} | |
public static class RomanExtensions | |
{ | |
public static int ToArabic(this string roman) | |
{ | |
var conv = new RomanConverter(); | |
return conv.ConvertFromRoman(roman); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Ralf Westphal, Hamburg | |
* [email protected], @ralfw, http://blog.ralfw.de | |
*/ | |
using System; | |
using NUnit.Framework; | |
namespace kata | |
{ | |
// Informed TDD | |
// TDD as if you meant | |
// From Roman Numerals | |
// XLII -> 42 | |
// XV -> 15 | |
// MCXL -> 1140 | |
// MMXIV -> 2014 | |
// 1. Analyse | |
// I, V, X, L, C, D, M: römische Ziffern | |
// >0, <= 3000 | |
// Römische Ziffern in monoton absteigender Folge - außer manchmal. | |
// Zehnerpotenzen können vorangestellt werden, um "negativ zu wirken", | |
// aber nur die jeweils nächst kleinere. Und nur 1x. | |
// Bsp: XL, XC - erlaubt, aber nicht: XD, XM | |
// Nicht mehr als 3x dieselbe röm. Zi nacheinander. | |
// Dieselbe Zi darf nur nacheinander stehen. | |
// Jede röm. Zi hat einen Wert. | |
// Nicht-10erpotenzen dürfen nicht mehrfach auftauchen. | |
// API? | |
// u.a. Extension Method | |
// Inkremente: | |
// #1: nur korrekte Zahlen | |
// #2: wir erkennen Syntaxfehler | |
// 2. Lösungsansatz entwerfen | |
// XVI | |
// 1. X -> 10 | |
// 2. V -> 5 | |
// 3. I -> 1 | |
// 4. Summe bilden | |
// Röm. umdrehen: XIV -> VIX | |
// Röm. Ziffern bewerten: VIX -> 5, 1, 10 | |
// Werte addieren - solange Wert nicht kleiner als Vorgänger. | |
// Wenn kleiner, dann subtrahieren. | |
// 5, 0 -> 0+5 = 5 | |
// 1, 5 -> 5-1 = 4 | |
// 10, 5 -> 4 + 10 = 14 | |
[TestFixture] | |
public class Tests | |
{ | |
[TestCase("XLII", 42)] | |
[TestCase("XV", 15)] | |
[TestCase("MCXL", 1140)] | |
[TestCase("MMXIV", 2014)] | |
[TestCase("I", 1)] | |
[TestCase("V", 5)] | |
[TestCase("X", 10)] | |
[TestCase("L", 50)] | |
[TestCase("C", 100)] | |
[TestCase("D", 500)] | |
[TestCase("M", 1000)] | |
public void Akzeptanztestfälle(string roman, int expectedArabic) | |
{ | |
var result = roman.ToArabic(); | |
Assert.AreEqual(expectedArabic, result); | |
} | |
[TestCase("VV")] | |
public void Rainy_day_Testfälle(string roman) | |
{ | |
Assert.Throws<InvalidOperationException>( | |
() => roman.ToArabic()); | |
} | |
[Test] | |
public void API_finden() | |
{ | |
var sut = new RomanConverter(); | |
var arabic = "XLII".ToArabic(); | |
Assert.AreEqual(42, arabic); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment