fork download
  1. package main
  2.  
  3. import (
  4. "bufio"
  5. "errors"
  6. "fmt"
  7. "os"
  8. "strconv"
  9. "strings"
  10. )
  11.  
  12. func getInput() string {
  13.  
  14. scanner := bufio.NewScanner(os.Stdin)
  15. scanner.Scan()
  16. inputExpression := scanner.Text()
  17. return inputExpression
  18.  
  19. }
  20.  
  21. // validateAndParseInput проверяет формат строки и возвращает операнды и оператор
  22. func validateAndParseInput(input string) (string, string, string, error) {
  23. parts := strings.Fields(input)
  24.  
  25. // Проверяем, что строка состоит из трех частей: операнд, оператор, операнд
  26. if len(parts) != 3 {
  27. return "", "", "", errors.New("Строка состоит не из трех частей: операнд, оператор, операнд")
  28. }
  29.  
  30. // Проверяем оператор
  31. if parts[1] == "+" || parts[1] == "-" || parts[1] == "*" || parts[1] == "/" {
  32. return parts[0], parts[1], parts[2], nil
  33. } else {
  34. return "", "", "", errors.New("Оператор не соотвествует ни одному значению из : '+', '-', '*', '/'")
  35. }
  36.  
  37. }
  38.  
  39. // validateOperands проверяет операнды и возвращает их числовые значения и тип
  40. func validateOperands(a, b string) (int, int, bool, error) {
  41. // Пробуем преобразовать оба операнда в арабские числа
  42. leftOperandArabic, leftErr := strconv.Atoi(a)
  43. rightOperandArabic, rightErr := strconv.Atoi(b)
  44.  
  45. // Если оба операнда успешно преобразованы, они арабские
  46. if leftErr == nil && rightErr == nil {
  47. return leftOperandArabic, rightOperandArabic, false, nil
  48. }
  49.  
  50. // Проверяем что оба операнда одной системы счисления
  51. checkingRoman := 0
  52. romeNumber := []string{"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"}
  53. for i := 0; i < len(romeNumber); i++ {
  54. if romeNumber[i] == a {
  55. checkingRoman += 1
  56. break
  57. }
  58. }
  59. for i := 0; i < len(romeNumber); i++ {
  60. if romeNumber[i] == b {
  61. checkingRoman += 1
  62. break
  63. }
  64. }
  65. if checkingRoman != 2 {
  66. return 0, 0, false, errors.New("Операнды в разных системах счисления")
  67. }
  68.  
  69. // Преобразуем римские числа в арабские, возвращаем флаг римских чисел
  70. romanMap := map[string]int{
  71. "I": 1,
  72. "II": 2,
  73. "III": 3,
  74. "IV": 4,
  75. "V": 5,
  76. "VI": 6,
  77. "VII": 7,
  78. "VIII": 8,
  79. "IX": 9,
  80. "X": 10,
  81. }
  82. for key, result := range romanMap {
  83. if a == key {
  84. leftOperandArabic = result
  85. }
  86. if b == key {
  87. rightOperandArabic = result
  88. }
  89. }
  90. return leftOperandArabic, rightOperandArabic, true, nil
  91. }
  92.  
  93. func ArabicToRoman(a int) (string, error) {
  94. // реализация преобразования арабских чисел в римские
  95. arabicSlice := []int{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
  96. romanSlice := []string{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}
  97.  
  98. var romanResult string
  99. if a <= 0 {
  100. return "", errors.New("Результат меньше или равен 0")
  101. }
  102. for index, number := range arabicSlice {
  103. for number <= a {
  104. romanResult = romanResult + romanSlice[index]
  105. a -= number
  106. }
  107. }
  108. return romanResult, nil
  109. }
  110.  
  111. func calculate(a int, operator string, b int) (int, error) {
  112. if operator == "+" {
  113. return a + b, nil
  114. } else if operator == "-" {
  115. return a - b, nil
  116. } else if operator == "*" {
  117. return a * b, nil
  118. } else if operator == "/" {
  119. if b == 0 {
  120. return 0, errors.New("На 0 делить нельзя")
  121. }
  122. return a / b, nil
  123. }
  124. return 0, nil
  125. }
  126.  
  127. func main() {
  128. // Ввод данных от пользователя из os.Stdin
  129. input := getInput()
  130.  
  131. // Валидация и парсинг входных данных
  132. left, operator, right, err := validateAndParseInput(input)
  133. if err != nil {
  134. panic(err)
  135. }
  136.  
  137. // // Валидация и парсинг операндов
  138. a, b, isRoman, err := validateOperands(left, right)
  139. if err != nil {
  140. panic(err)
  141. }
  142.  
  143. // Выполнение операции
  144. result, err := calculate(a, operator, b)
  145. if err != nil {
  146. panic(err)
  147. }
  148.  
  149. // Вывод результата согласно введенным данным
  150. if isRoman == true {
  151. resultRoman, err := ArabicToRoman(result)
  152. if err != nil {
  153. panic(err)
  154. }
  155. fmt.Println(resultRoman)
  156. } else {
  157. fmt.Println(result)
  158. }
  159. }
  160.  
Success #stdin #stdout 0s 5288KB
stdin
V + I
stdout
VI