progs/roman.scala
changeset 265 59779ce322a6
parent 109 293ea84d82ca
equal deleted inserted replaced
264:ecd989eee8bd 265:59779ce322a6
     1 // Part 1 about Roman Numerals
     1 // Replacement Exam: Scala Part
     2 //=============================
     2 //=======================================
     3 
     3 
       
     4 // Roman Digits and Numerals
     4 
     5 
     5 abstract class RomanDigit 
     6 abstract class RomanDigit 
     6 case object I extends RomanDigit 
     7 case object I extends RomanDigit 
     7 case object V extends RomanDigit 
     8 case object V extends RomanDigit 
     8 case object X extends RomanDigit 
     9 case object X extends RomanDigit 
    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")