16 // (1) First write a polymorphic function that recursively |
17 // (1) First write a polymorphic function that recursively |
17 // transforms a list of options into an option of a list. |
18 // 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 // As soon as a None is inside the list, the result is None. |
19 // Otherwise produce a list of all Some's appended. |
20 // Otherwise produce a list of all Some's appended. |
20 |
21 |
21 def optionlist[A](xs: List[Option[A]]): Option[List[A]] = |
22 //def optionlist[A](xs: List[Option[A]]): Option[List[A]] = |
|
23 |
|
24 |
|
25 // some testcases |
|
26 //optionlist(List(Some(1), Some(2), Some(3))) // -> Some(List(1, 2, 3)) |
|
27 //optionlist(List(Some(1), None, Some(3))) // -> None |
|
28 //optionlist(List()) // -> Some(List()) |
|
29 |
|
30 |
|
31 |
22 |
32 |
23 // (2) Write a function first a function that converts a character |
33 // (2) Write a function first a function that converts a character |
24 // into a roman digit (if possible). Then convert a string into |
34 // into a roman digit (if possible). Then convert a string into |
25 // a roman numeral (if possible). If this is not possible, the functions |
35 // a roman numeral (if possible). In both cases, if the conversion |
26 // should return None. |
36 // is not possible, the functions should return None. |
27 |
37 |
28 def Char2RomanDigit(c: Char): Option[RomanDigit] = |
38 //def Char2RomanDigit(c: Char): Option[RomanDigit] = |
29 |
39 |
30 def String2RomanNumeral(s: String) : Option[RomanNumeral] = |
40 //def String2RomanNumeral(s: String) : Option[RomanNumeral] = |
31 |
41 |
32 |
42 |
33 // some test cases |
43 // some test cases |
34 //String2RomanNumeral("IIII") |
44 //String2RomanNumeral("IIII") |
35 //String2RomanNumeral("IV") |
45 //String2RomanNumeral("IV") |
40 //String2RomanNumeral("M C M X L I V") // None |
50 //String2RomanNumeral("M C M X L I V") // None |
41 |
51 |
42 // (3) Write a recursive function RomanNumral2Int that converts a |
52 // (3) Write a recursive function RomanNumral2Int that converts a |
43 // RomanNumeral into an integer. |
53 // RomanNumeral into an integer. |
44 |
54 |
45 def RomanNumeral2Int(rs: RomanNumeral): Int = |
55 //def RomanNumeral2Int(rs: RomanNumeral): Int = |
46 |
56 |
47 |
57 |
48 // some test cases |
58 // some test cases |
49 RomanNumeral2Int(List(I,I,I,I)) // 4 |
59 //RomanNumeral2Int(List(I,I,I,I)) // 4 |
50 RomanNumeral2Int(List(I,V)) // 4 |
60 //RomanNumeral2Int(List(I,V)) // 4 |
51 RomanNumeral2Int(List(V,I)) // 6 |
61 //RomanNumeral2Int(List(V,I)) // 6 |
52 RomanNumeral2Int(List(I,X)) // 9 |
62 //RomanNumeral2Int(List(I,X)) // 9 |
53 RomanNumeral2Int(List(M,C,M,L,X,X,I,X)) // 1979 |
63 //RomanNumeral2Int(List(M,C,M,L,X,X,I,X)) // 1979 |
54 RomanNumeral2Int(List(M,C,M,X,L,I,V)) // 1944 |
64 //RomanNumeral2Int(List(M,C,M,X,L,I,V)) // 1944 |
|
65 |
|
66 |
55 |
67 |
56 // (4) Write a function that converts a string (containing |
68 // (4) Write a function that converts a string (containing |
57 // a roman numeral) into an integer (if possible). If not |
69 // a roman numeral) into an integer (if possible). If |
58 // this is not possible, the functions should return None. |
70 // this is not possible, the functions should return None. |
59 |
71 |
60 def String2Int(s: String): Option[Int] = |
72 //def String2Int(s: String): Option[Int] = |
61 |
|
62 // some test cases |
|
63 String2Int("IIII") // 4 (though invalid roman numeral) |
|
64 String2Int("IV") // 4 |
|
65 String2Int("VI") // 6 |
|
66 String2Int("IX") // 9 |
|
67 String2Int("MCMLXXIX") // 1979 |
|
68 String2Int("MCMXLIV") // 1944 |
|
69 String2Int("") // 0 |
|
70 String2Int("MDCLXI") // 1661 |
|
71 String2Int("MMMCMXCIX") // 3999 |
|
72 String2Int("XLVIII") // 48 |
|
73 String2Int("MMVIII") // 2008 |
|
74 |
|
75 String2Int("MMXI") // 2011 |
|
76 String2Int("MIM") // 1999 |
|
77 String2Int("MCMLVI") // 1956 |
|
78 |
|
79 String2Int("III") // 3 |
|
80 String2Int("XXX") // 30 |
|
81 String2Int("CCC") // 300 |
|
82 String2Int("MMM") // 3000 |
|
83 String2Int("VII") // 7 |
|
84 String2Int("LXVI") // 66 |
|
85 String2Int("CL") // 150 |
|
86 String2Int("MCC") // 1200 |
|
87 String2Int("IV") // 4 |
|
88 String2Int("IX") // 9 |
|
89 String2Int("XC") // 90 |
|
90 String2Int("MDCLXVI") // 1666 |
|
91 |
|
92 String2Int("VIV") // 9 (but should be written as IX) |
|
93 String2Int("IVX") // 14 (also invalid) |
|
94 |
|
95 // error cases |
|
96 String2Int("MC?I") |
|
97 String2Int("abc") |
|
98 |
|
99 |
|
100 // (5) The file roman.txt contains a list of roman numerals. |
|
101 // Read in these numerals from the file, convert them into |
|
102 // integers and then add them all up. |
|
103 |
|
104 import io.Source |
|
105 import scala.util._ |
|
106 |
|
107 // function for reading files: |
|
108 // Source.fromFile("file_name")("ISO-8859-9") |
|
109 |
|
110 def addromanfile(filename: String) = |
|
111 |
|
112 //test case |
|
113 addromanfile("roman.txt") |
|
114 |
|
115 |
|
116 // Part 2 about Validation of Roman Numerals |
|
117 //=========================================== |
|
118 |
|
119 // (6) Write a function that validates roman numerals according |
|
120 // to the rules given in the CW. |
|
121 |
|
122 def isValidNumeral(digitList: RomanNumeral): Boolean = |
|
123 |
73 |
124 |
74 |
125 |
75 |
126 // some test cases |
76 // some test cases |
127 val invalids = List("IXC", "XCX", "IIII", "IIIII", "DD", "VL", |
77 //String2Int("IIII") // 4 (though invalid roman numeral) |
128 "MIM", "XXCIII", "LXXIIX", "IIIIX", "IIXX", |
78 //String2Int("IV") // 4 |
129 "ICM", "CIM", "VIV", "IVX", "MCMC", "XIIX", "IIXX") |
79 //String2Int("VI") // 6 |
|
80 //String2Int("IX") // 9 |
|
81 //String2Int("MCMLXXIX") // 1979 |
|
82 //String2Int("MCMXLIV") // 1944 |
|
83 //String2Int("") // 0 |
|
84 //String2Int("MDCLXI") // 1661 |
|
85 //String2Int("MMMCMXCIX") // 3999 |
|
86 //String2Int("XLVIII") // 48 |
|
87 //String2Int("MMVIII") // 2008 |
130 |
88 |
131 val valids = List("IV", "VI", "IX", "MCMLXXIX", "MCMXLIV", "", "MDCLXI", |
89 //String2Int("MMXI") // 2011 |
132 "MMMCMXCIX", "XLVIII", "MMVIII", "MMXI", "MCMLVI", "III", |
90 //String2Int("MIM") // 1999 |
133 "XXX", "CCC", "MMM", "VII", "LXVI", "CL", "MCC", "XC", |
91 //String2Int("MCMLVI") // 1956 |
134 "MDCLXVI") |
|
135 |
92 |
136 // (7) Write a recursive function that converts an Integer into a |
93 //String2Int("III") // 3 |
137 // a roman numeral. The input will be between 0 and 3999. |
94 //String2Int("XXX") // 30 |
|
95 //String2Int("CCC") // 300 |
|
96 //String2Int("MMM") // 3000 |
|
97 //String2Int("VII") // 7 |
|
98 //String2Int("LXVI") // 66 |
|
99 //String2Int("CL") // 150 |
|
100 //String2Int("MCC") // 1200 |
|
101 //String2Int("IV") // 4 |
|
102 //String2Int("IX") // 9 |
|
103 //String2Int("XC") // 90 |
|
104 //String2Int("MDCLXVI") // 1666 |
138 |
105 |
139 def Int2Roman(n: Int): RomanNumeral = |
106 //String2Int("VIV") // 9 (but should be written as IX) |
|
107 //String2Int("IVX") // 14 (also invalid) |
140 |
108 |
141 // (8) Write a function that reads a text file containing valid and |
109 // error cases |
142 // invalid roman numerals. Convert all valid roman numerals into integers, |
110 //String2Int("I I I I") |
143 // add them up and produce the result as a roman numeral (using the |
111 //String2Int("MC?I") |
144 // function in (7) |
112 //String2Int("abc") |
145 |
113 |
146 def addvalidromanfile(filename: String) = |
|
147 |
114 |
148 // a test case |
|
149 //addvalidromanfile("roman2.txt") |
|