IntToRoman converts an integer value to a roman numeral string. An error is returned if the integer is not between 1 and 3999.
(n int)
| 21 | // IntToRoman converts an integer value to a roman numeral string. An error is |
| 22 | // returned if the integer is not between 1 and 3999. |
| 23 | func IntToRoman(n int) (string, error) { |
| 24 | if n < 1 || n > 3999 { |
| 25 | return "", errors.New("integer must be between 1 and 3999") |
| 26 | } |
| 27 | // Concatenate strings for each of 4 lookup array categories. |
| 28 | // |
| 29 | // Key behavior to note here is how math with integers is handled. Values are floored to the |
| 30 | // nearest int, not rounded up. For example, 26/10 = 2 even though the actual result is 2.6. |
| 31 | // |
| 32 | // For example, lets use an input value of 126: |
| 33 | // `r3[n%1e4/1e3]` --> 126 % 10_000 = 126 --> 126 / 1_000 = 0.126 (0 as int) --> r3[0] = "" |
| 34 | // `r2[n%1e3/1e2]` --> 126 % 1_000 = 126 --> 126 / 100 = 1.26 (1 as int) --> r2[1] = "C" |
| 35 | // `r1[n%100/10]` --> 126 % 100 = 26 --> 26 / 10 = 2.6 (2 as int) --> r1[2] = "XX" |
| 36 | // `r0[n%10]` --> 126 % 10 = 6 --> r0[6] = "VI" |
| 37 | // FINAL --> "" + "C" + "XX" + "VI" = "CXXVI" |
| 38 | // |
| 39 | // This is efficient in Go. The 4 operands are evaluated, |
| 40 | // then a single allocation is made of the exact size needed for the result. |
| 41 | return r3[n%1e4/1e3] + r2[n%1e3/1e2] + r1[n%100/10] + r0[n%10], nil |
| 42 | } |
no outgoing calls