Merge pull request GH-1 from gh/roman-numerals-kata
roman numerals kata
This commit is contained in:
commit
8c18b21121
2 changed files with 129 additions and 3 deletions
|
|
@ -1,3 +1,46 @@
|
|||
String integerToRoman(int number) {
|
||||
throw UnimplementedError();
|
||||
class RomanNumeralInput {
|
||||
static const _minValue = 1;
|
||||
static const _maxValue = 3999;
|
||||
|
||||
final int value;
|
||||
|
||||
RomanNumeralInput(this.value) {
|
||||
if (value < _minValue || value > _maxValue) {
|
||||
throw ArgumentError(
|
||||
'Roman numeral input must be between $_minValue and $_maxValue',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String integerToRoman(int number) {
|
||||
final input = RomanNumeralInput(number);
|
||||
|
||||
const conversionRules = [
|
||||
(1000, 'M'),
|
||||
(900, 'CM'),
|
||||
(500, 'D'),
|
||||
(400, 'CD'),
|
||||
(100, 'C'),
|
||||
(90, 'XC'),
|
||||
(50, 'L'),
|
||||
(40, 'XL'),
|
||||
(10, 'X'),
|
||||
(9, 'IX'),
|
||||
(5, 'V'),
|
||||
(4, 'IV'),
|
||||
(1, 'I'),
|
||||
];
|
||||
|
||||
final result = StringBuffer();
|
||||
var remaining = input.value;
|
||||
|
||||
for (final (value, symbol) in conversionRules) {
|
||||
while (remaining >= value) {
|
||||
result.write(symbol);
|
||||
remaining -= value;
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,84 @@
|
|||
void main() {}
|
||||
import 'package:tdd_katas/roman_numerals.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('Roman Numerals Conversion', () {
|
||||
group('Basic Symbols', () {
|
||||
test('smallest unit', () => expect(integerToRoman(1), 'I'));
|
||||
test('five', () => expect(integerToRoman(5), 'V'));
|
||||
test('ten', () => expect(integerToRoman(10), 'X'));
|
||||
test('fifty', () => expect(integerToRoman(50), 'L'));
|
||||
test('hundred', () => expect(integerToRoman(100), 'C'));
|
||||
test('five hundred', () => expect(integerToRoman(500), 'D'));
|
||||
test('thousand', () => expect(integerToRoman(1000), 'M'));
|
||||
});
|
||||
|
||||
group('Subtractive Notation', () {
|
||||
test('four (one before five)', () => expect(integerToRoman(4), 'IV'));
|
||||
test('nine (one before ten)', () => expect(integerToRoman(9), 'IX'));
|
||||
test('forty (ten before fifty)', () => expect(integerToRoman(40), 'XL'));
|
||||
test(
|
||||
'ninety (ten before hundred)',
|
||||
() => expect(integerToRoman(90), 'XC'),
|
||||
);
|
||||
test(
|
||||
'four hundred (hundred before five hundred)',
|
||||
() => expect(integerToRoman(400), 'CD'),
|
||||
);
|
||||
test(
|
||||
'nine hundred (hundred before thousand)',
|
||||
() => expect(integerToRoman(900), 'CM'),
|
||||
);
|
||||
});
|
||||
|
||||
group('Additive Combinations', () {
|
||||
test('two (repeated symbol)', () => expect(integerToRoman(2), 'II'));
|
||||
test(
|
||||
'three (maximum repetition)',
|
||||
() => expect(integerToRoman(3), 'III'),
|
||||
);
|
||||
test('six (additive after five)', () => expect(integerToRoman(6), 'VI'));
|
||||
test(
|
||||
'twenty-seven (multiple symbols)',
|
||||
() => expect(integerToRoman(27), 'XXVII'),
|
||||
);
|
||||
});
|
||||
|
||||
group('Complex Edge Cases', () {
|
||||
test(
|
||||
'forty-nine (combines subtractive symbols)',
|
||||
() => expect(integerToRoman(49), 'XLIX'),
|
||||
);
|
||||
test(
|
||||
'ninety-nine (maximum two-digit complexity)',
|
||||
() => expect(integerToRoman(99), 'XCIX'),
|
||||
);
|
||||
test(
|
||||
'four hundred forty-four (all subtractive positions)',
|
||||
() => expect(integerToRoman(444), 'CDXLIV'),
|
||||
);
|
||||
test(
|
||||
'1994 (year notation stress test)',
|
||||
() => expect(integerToRoman(1994), 'MCMXCIV'),
|
||||
);
|
||||
test(
|
||||
'3999 (maximum valid Roman numeral)',
|
||||
() => expect(integerToRoman(3999), 'MMMCMXCIX'),
|
||||
);
|
||||
});
|
||||
|
||||
group('Error Handling', () {
|
||||
test('rejects zero', () {
|
||||
expect(() => integerToRoman(0), throwsArgumentError);
|
||||
});
|
||||
|
||||
test('rejects negative numbers', () {
|
||||
expect(() => integerToRoman(-5), throwsArgumentError);
|
||||
});
|
||||
|
||||
test('rejects numbers above 3999', () {
|
||||
expect(() => integerToRoman(4000), throwsArgumentError);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue