| author | Christian Urban <urbanc@in.tum.de> | 
| Fri, 09 Nov 2018 07:30:02 +0000 | |
| changeset 201 | dc505025ce15 | 
| parent 111 | 7cefb821ee20 | 
| child 265 | 2692329287bb | 
| permissions | -rw-r--r-- | 
| 108 | 1 | // Part 1 about Roman Numerals | 
| 2 | //============================= | |
| 3 | ||
| 104 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 4 | abstract class RomanDigit | 
| 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 5 | case object I extends RomanDigit | 
| 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 6 | case object V extends RomanDigit | 
| 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 7 | case object X extends RomanDigit | 
| 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 8 | case object L extends RomanDigit | 
| 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 9 | case object C extends RomanDigit | 
| 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 10 | case object D extends RomanDigit | 
| 
a7ce74d89085
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: diff
changeset | 11 | case object M extends RomanDigit | 
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 12 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 13 | type RomanNumeral = List[RomanDigit] | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 14 | |
| 108 | 15 | |
| 16 | // (1) First write a polymorphic function that recursively | |
| 17 | // transforms a list of options into an option of a list. | |
| 18 | // As soon as a None is inside the list, the result is None. | |
| 19 | // Otherwise produce a list of all Some's appended. | |
| 20 | ||
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 21 | def optionlist[A](xs: List[Option[A]]): Option[List[A]] = xs match {
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 22 | case Nil => Some(Nil) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 23 |   case x::xs => (x, optionlist(xs)) match {
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 24 | case (None, _) => None | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 25 | case (_, None) => None | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 26 | case (Some(y), Some(ys)) => Some(y::ys) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 27 | } | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 28 | } | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 29 | |
| 108 | 30 | optionlist(List(Some(1), Some(2), Some(3))) | 
| 31 | optionlist(List(Some(1), None, Some(3))) | |
| 32 | optionlist(List()) | |
| 33 | ||
| 34 | // (2) Write a function first a function that converts a character | |
| 35 | // into a roman digit (if possible). Then convert a string into | |
| 36 | // a roman numeral (if possible). If this is not possible, the functions | |
| 37 | // should return None. | |
| 38 | ||
| 39 | def Char2RomanDigit(c: Char): Option[RomanDigit] = c match {
 | |
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 40 | case 'I' => Some(I) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 41 | case 'V' => Some(V) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 42 | case 'X' => Some(X) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 43 | case 'L' => Some(L) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 44 | case 'C' => Some(C) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 45 | case 'D' => Some(D) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 46 | case 'M' => Some(M) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 47 | case _ => None | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 48 | } | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 49 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 50 | def String2RomanNumeral(s: String) : Option[RomanNumeral] = | 
| 108 | 51 | optionlist(s.toList.map(Char2RomanDigit)) | 
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 52 | |
| 108 | 53 | // some test cases | 
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 54 | String2RomanNumeral("IIII")
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 55 | String2RomanNumeral("IV")
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 56 | String2RomanNumeral("VI")
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 57 | String2RomanNumeral("IX")
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 58 | String2RomanNumeral("MCMLXXIX")
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 59 | String2RomanNumeral("MCMXLIV") 
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 60 | String2RomanNumeral("M C M X L I V")  // None
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 61 | |
| 108 | 62 | |
| 63 | // (3) Write a recursive function RomanNumral2Int that converts a | |
| 64 | // RomanNumeral into an integer. | |
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 65 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 66 | def RomanNumeral2Int(rs: RomanNumeral): Int = rs match { 
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 67 | case Nil => 0 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 68 | case M::r => 1000 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 69 | case C::M::r => 900 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 70 | case D::r => 500 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 71 | case C::D::r => 400 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 72 | case C::r => 100 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 73 | case X::C::r => 90 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 74 | case L::r => 50 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 75 | case X::L::r => 40 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 76 | case X::r => 10 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 77 | case I::X::r => 9 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 78 | case V::r => 5 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 79 | case I::V::r => 4 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 80 | case I::r => 1 + RomanNumeral2Int(r) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 81 | } | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 82 | |
| 108 | 83 | // some test cases | 
| 109 | 84 | RomanNumeral2Int(List(I,I,I,I)) // 4 (invalid roman number) | 
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 85 | RomanNumeral2Int(List(I,V)) // 4 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 86 | RomanNumeral2Int(List(V,I)) // 6 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 87 | RomanNumeral2Int(List(I,X)) // 9 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 88 | RomanNumeral2Int(List(M,C,M,L,X,X,I,X)) // 1979 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 89 | RomanNumeral2Int(List(M,C,M,X,L,I,V)) // 1944 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 90 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 91 | |
| 108 | 92 | // (4) Write a function that converts a string (containing | 
| 93 | // a roman numeral) into an integer (if possible). If not | |
| 94 | // this is not possible, the functions should return None. | |
| 95 | ||
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 96 | def String2Int(s: String): Option[Int] = | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 97 | String2RomanNumeral(s).map(RomanNumeral2Int(_)) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 98 | |
| 109 | 99 | // some test cases | 
| 100 | String2Int("IIII")      // 4 (though invalid roman numeral)  
 | |
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 101 | String2Int("IV")        // 4
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 102 | String2Int("VI")        // 6
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 103 | String2Int("IX")        // 9
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 104 | String2Int("MCMLXXIX")  // 1979
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 105 | String2Int("MCMXLIV")   // 1944
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 106 | String2Int("")          // 0
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 107 | String2Int("MDCLXI")    // 1661
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 108 | String2Int("MMMCMXCIX") // 3999
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 109 | String2Int("XLVIII")    // 48
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 110 | String2Int("MMVIII")    // 2008
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 111 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 112 | String2Int("MMXI")      // 2011 
 | 
| 111 | 113 | String2Int("MIM")       // 2001
 | 
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 114 | String2Int("MCMLVI")    // 1956 
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 115 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 116 | String2Int("III") 	// 3
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 117 | String2Int("XXX") 	// 30
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 118 | String2Int("CCC") 	// 300
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 119 | String2Int("MMM") 	// 3000
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 120 | String2Int("VII") 	// 7
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 121 | String2Int("LXVI") 	// 66
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 122 | String2Int("CL") 	// 150
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 123 | String2Int("MCC") 	// 1200
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 124 | String2Int("IV") 	// 4
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 125 | String2Int("IX") 	// 9
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 126 | String2Int("XC") 	// 90
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 127 | String2Int("MDCLXVI")	// 1666
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 128 | |
| 109 | 129 | String2Int("VIV")       // 9 (but should be written as IX) 
 | 
| 130 | String2Int("IVX")       // 14 (also invalid)
 | |
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 131 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 132 | // error cases | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 133 | String2Int("MC?I")
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 134 | String2Int("abc")
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 135 | |
| 109 | 136 | |
| 108 | 137 | // (5) The file roman.txt contains a list of roman numerals. | 
| 138 | // Read in these numerals, convert them into integers and then | |
| 139 | // add them all up. | |
| 140 | ||
| 141 | import io.Source | |
| 142 | import scala.util._ | |
| 143 | ||
| 144 | // function for reading files: | |
| 145 | // Source.fromFile("file_name")("ISO-8859-9")
 | |
| 146 | ||
| 147 | def addromanfile(filename: String) = {
 | |
| 148 |   val lines = Source.fromFile(filename)("ISO-8859-9").getLines.toList.map(_.trim)
 | |
| 149 | lines.map(String2Int(_)).flatten.sum | |
| 150 | } | |
| 151 | ||
| 152 | ||
| 153 | addromanfile("roman.txt")
 | |
| 154 | ||
| 111 | 155 | val ls = """IIII | 
| 156 | IV | |
| 157 | VI | |
| 158 | IX | |
| 159 | MCMLXXIX | |
| 160 | MCMXLIV | |
| 161 | ||
| 162 | MDCLXI | |
| 163 | MMMCMXCIX | |
| 164 | XLVIII | |
| 165 | MMVIII | |
| 166 | ||
| 167 | MMXI | |
| 168 | MIM | |
| 169 | MCMLVI | |
| 170 | ||
| 171 | III | |
| 172 | XXX | |
| 173 | CCC | |
| 174 | MMM | |
| 175 | VII | |
| 176 | LXVI | |
| 177 | CL | |
| 178 | MCC | |
| 179 | IV | |
| 180 | IX | |
| 181 | XC | |
| 182 | MDCLXVI""".split("\n").map(_.trim).map(String2Int(_)).flatten
 | |
| 183 | ||
| 184 | String2Int("MIM")
 | |
| 108 | 185 | |
| 109 | 186 | // Part 2 about Validation of Roman Numerals | 
| 187 | //=========================================== | |
| 108 | 188 | |
| 109 | 189 | def Digit2Int(r: RomanDigit) = r match {
 | 
| 190 | case I => 1 | |
| 191 | case V => 5 | |
| 192 | case X => 10 | |
| 193 | case L => 50 | |
| 194 | case C => 100 | |
| 195 | case D => 500 | |
| 196 | case M => 1000 | |
| 197 | } | |
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 198 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 199 | def runsAllowed(r: RomanDigit) = r match {
 | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 200 | case I | X | C | M => true | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 201 | case V | L | D => false | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 202 | } | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 203 | |
| 109 | 204 | def subtractable(r1: RomanDigit, r2: RomanDigit) = (r1, r2)  match {
 | 
| 205 | case (I, V) | (I, X) => true | |
| 206 | case (X, L) | (X, C) => true | |
| 207 | case (C, D) | (C, M) => true | |
| 208 | case _ => false | |
| 209 | } | |
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 210 | |
| 109 | 211 | def isValidNumeral(digitList: RomanNumeral): Boolean = digitList match {
 | 
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 212 | |
| 109 | 213 | // empty list is valid | 
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 214 | case Nil => true | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 215 | |
| 109 | 216 | // no more than three runnables in succession | 
| 217 | case d1::d2::d3::d4::_ if (d1 == d2 && d1 == d3 && d1 == d4 && runsAllowed(d1)) => false | |
| 218 | ||
| 219 | // no more than one non-runnables in succession | |
| 220 | case d1::d2::_ if (d1 == d2 && !runsAllowed(d1)) => false | |
| 221 | ||
| 222 | // subtractable | |
| 223 | case d1::d2::_ if (Digit2Int(d1) < Digit2Int(d2) && !subtractable(d1, d2)) => false | |
| 224 | ||
| 225 | // followable1 | |
| 226 | case d1::d2::d3::_ if (Digit2Int(d2) < Digit2Int(d3) && subtractable(d2,d3) && | |
| 227 | Digit2Int(d1) < Digit2Int(d2) * 10) => false | |
| 228 | ||
| 229 | // followable2 | |
| 230 | case d1::d2::d3::_ if (Digit2Int(d1) < Digit2Int(d2) && subtractable(d1,d2) && | |
| 231 | Digit2Int(d1) <= Digit2Int(d3)) => false | |
| 105 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 232 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 233 | // A single digit is always allowed | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 234 | case _::ds => isValidNumeral(ds) | 
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 235 | |
| 
0f9f774c7697
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
104diff
changeset | 236 | } | 
| 109 | 237 | |
| 238 | ||
| 239 | val invalids = List("IXC", "XCX", "IIII", "IIIII", "DD", "VL", "MIM", "XXCIII", "LXXIIX", "IIIIX",
 | |
| 240 | "IIXX", "ICM", "CIM", "VIV", "IVX", "MCMC", "XIIX", "IIXX") | |
| 241 | invalids.map(String2RomanNumeral(_)).flatten.map(isValidNumeral(_)) | |
| 242 | invalids.map(String2RomanNumeral(_)).flatten.map((r) => (r, isValidNumeral(r))) | |
| 243 | ||
| 244 | ||
| 245 | val valids = List("IV", "VI", "IX", "MCMLXXIX", "MCMXLIV", "", "MDCLXI",
 | |
| 246 | "MMMCMXCIX", "XLVIII", "MMVIII", "MMXI", "MCMLVI", "III", | |
| 247 | "XXX", "CCC", "MMM", "VII", "LXVI", "CL", "MCC", "XC", | |
| 248 | "MDCLXVI") | |
| 249 | valids.map(String2RomanNumeral(_)).flatten.map(isValidNumeral(_)) | |
| 250 | ||
| 251 | ||
| 252 | ||
| 253 | ||
| 254 | ||
| 255 | def Int2Roman(n: Int): RomanNumeral = n match {
 | |
| 256 | case 0 => Nil | |
| 257 | case n if (1000 <= n) => M :: Int2Roman(n - 1000) | |
| 258 | case n if (900 <= n) => C :: M :: Int2Roman(n - 900) | |
| 259 | case n if (500 <= n) => D :: Int2Roman(n - 500) | |
| 260 | case n if (400 <= n) => C :: D :: Int2Roman(n - 400) | |
| 261 | case n if (100 <= n) => C :: Int2Roman(n - 100) | |
| 262 | case n if (90 <= n) => X :: C :: Int2Roman(n - 90) | |
| 263 | case n if (50 <= n) => L :: Int2Roman(n - 50) | |
| 264 | case n if (40 <= n) => X :: L :: Int2Roman(n - 40) | |
| 265 | case n if (10 <= n) => X :: Int2Roman(n - 10) | |
| 266 | case n if (9 <= n) => I :: X :: Int2Roman(n - 9) | |
| 267 | case n if (5 <= n) => V :: Int2Roman(n - 5) | |
| 268 | case n if (4 <= n) => I :: V :: Int2Roman(n - 4) | |
| 269 | case n if (1 <= n) => I :: Int2Roman(n - 1) | |
| 270 | } | |
| 271 | ||
| 272 | ||
| 273 | Int2Roman(4) | |
| 274 | Int2Roman(6) | |
| 275 | Int2Roman(9) | |
| 276 | Int2Roman(1979) | |
| 277 | Int2Roman(1944) | |
| 278 | ||
| 279 | RomanNumeral2Int(List(I,V)) | |
| 280 | RomanNumeral2Int(List(V,I)) | |
| 281 | RomanNumeral2Int(List(I,X)) | |
| 282 | RomanNumeral2Int(List(M,C,M,L,X,X,I,X)) | |
| 283 | RomanNumeral2Int(List(M,C,M,X,L,I,V)) | |
| 284 | ||
| 285 | ||
| 286 | def addvalidromanfile(filename: String) = {
 | |
| 287 |   val lines = Source.fromFile(filename)("ISO-8859-9").getLines.toList.map(_.trim)
 | |
| 288 | val ints = lines.map(String2RomanNumeral(_)).flatten.filter(isValidNumeral(_)).map(RomanNumeral2Int(_)) | |
| 289 | ints.sum | |
| 290 | } | |
| 291 | ||
| 292 | ||
| 293 | addvalidromanfile("roman2.txt")
 |