Denary number to roman numerals (golang)

Updated vegaseat 2 Tallied Votes 577 Views Share

Use Google's modern Go language (aka. golang) to convert a denary number (base 10) to a roman numeral. Just a good exercise to explore Go's map, slice, sort and for loop features.

Note that in Go the := is shorthand for assigning a type (by inference) and a value to a variable. A slice is like an array that can grow, and a map is a key indexed list. Go has only the for loop, but the syntax is very flexible and can accomplish all the usual loop duties.

// roman_numerals.go
//
// convert a denary number (base 10) to a roman numeral
// tested with Go version 1.4.2   by vegaseat  25apr2015

package main

import (
	"fmt"
	"sort"
	"strconv"
)

// accept an integer number and return the roman numeral as a string
func getRoman(number int) string {
	// create a denary_number:roman_symbol map
	romanMap := map[int]string{
		1: "I", 4: "IV", 5: "V", 9: "IX", 10: "X", 40: "XL", 50: "L",
		90: "XC", 100: "C", 400: "CD", 500: "D", 900: "CM", 1000: "M",
	}
	// create a slice of slices
	rows := len(romanMap)
	matrix := make([][]string, rows)
	// create a slice of the map keys
	var key_slice []int
	// range of a map returns key, value pair
	// value is not needed so use blank identifier _
	for k, _ := range romanMap {
		key_slice = append(key_slice, k)
	}
	// sort the slice in place, highest number first (decending)
	sort.Sort(sort.Reverse(sort.IntSlice(key_slice)))
	// create a slice of romanMap content slices 
	row := 0
	// range of a slice returns index, value pair
	// index not needed so use blank identifier _
	for _, key := range key_slice {
		// convert int key to string key
		skey := strconv.Itoa(key)
		matrix[row] = []string{skey, romanMap[key]}
		row++

	}
	result := ""
	for _, item := range matrix {
		// convert string to int
		den, err := strconv.Atoi(item[0])
		if err != nil {
			panic(err)
		}
		sym := item[1]
		for number >= den {
			result += sym
			number -= den
		}
	}
	return result
}

func main() {
	fmt.Println("Convert a denary number (base 10) to a roman numeral:")

	// for readability keep the number below 5000
	number := 123
	roman := getRoman(number)
	fmt.Printf("denary %4v same as roman %v\n", number, roman)

	// a few more conversions ...
	numbers := []int{4, 12, 516, 2123}
	for _, number := range numbers {
		roman := getRoman(number)
		fmt.Printf("denary %4v same as roman %v\n", number, roman)
	}
}

/*
denary  123 same as roman CXXIII
denary    4 same as roman IV
denary   12 same as roman XII
denary  516 same as roman DXVI
denary 2123 same as roman MMCXXIII
*/