PAT Advanced 1100 Mars Numbers

Overview

PAT advanced 1100 Mars Number is actually just about converting between base 13 and 10 and translate between mars and earth digits by mapping.

PAT Advenced 1100 Mars Number Problem

People on Mars count their numbers with base 13:

  • Zero on Earth is called “tret” on Mars.
  • The numbers 1 to 12 on Earch is called “jan, feb, mar, apr, may, jun, jly, aug, sep, oct, nov, dec” on Mars, respectively.
  • For the next higher digit, Mars people name the 12 numbers as “tam, hel, maa, huh, tou, kes, hei, elo, syy, lok, mer, jou”, respectively.

For examples, the number 29 on Earth is called “hel mar” on Mars; and “elo nov” on Mars corresponds to 115 on Earth. In order to help communication between people from these two planets, you are supposed to write a program for mutual translation between Earth and Mars number systems.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (< 100). Then N lines follow, each contains a number in [0, 169), given either in the form of an Earth number, or that of Mars.

Output Specification:

For each number, print in a line the corresponding number in the other language.

Sample Input:

4    
29    
5   
elo nov    
tam    

Sample Output:

hel mar    
may    
115    
13    

PAT Advenced 1100 Mars Number Algorithm

This problem just tests whether we can convert between base 13 and 10, and then use the described mapping to convert digits to mars digits. The following c++ source code could pass PAT OJ for this PAT advanced 1100 Mars Numbers problem:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <string>
#include <cstdlib>
#include <map>
#include <stdexcept>

class MarsDigits {
public:
	const static int MARS_BASE = 13;
	const static std::string MARS_UNITS[];
	const static std::string MARS_TENS[];
	const static std::map<std::string, int> EARTH_VALUES;

	static std::map<std::string, int> init() {
		std::map<std::string, int> values;
		for (int i = 0; i < MARS_BASE; ++i) {
			values.insert(std::make_pair(MARS_UNITS[i], i));
		}
		for (int i = 1; i < MARS_BASE; ++i) {
			values.insert(std::make_pair(MARS_TENS[i - 1], i * MARS_BASE));
		}
		return values;
	}

private:
	int toValue(const std::string &token) {
		if (EARTH_VALUES.find(token) != EARTH_VALUES.end()) {
			return EARTH_VALUES.find(token)->second;
		}
	}

public:
	int toEarthNumber(const std::string &val) {
		size_t pos = val.find(" ");
		int result = 0;
		if (pos == std::string::npos) {
			result += toValue(val);
		} else {
			std::string tens = val.substr(0, pos);
			std::string units = val.substr(pos + 1);
			result += toValue(tens);
			result += toValue(units);
		}
		return result;
	}

	std::string toMarsNumber(int val) {
		std::string result("");
		if (val / MARS_BASE > 0) {
			result += MARS_TENS[val / MARS_BASE - 1];
			val %= MARS_BASE;
			if (val != 0) {
				result += " ";
				result += MARS_UNITS[val];
			}
		} else {
			result += MARS_UNITS[val];
		}
		return result;
	}
};

const std::string MarsDigits::MARS_UNITS[] = {
		"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"
};

const std::string MarsDigits::MARS_TENS[] = {
		"tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"
};

const std::map<std::string, int> MarsDigits::EARTH_VALUES = MarsDigits::init();

int main() {
	MarsDigits mars;
	int n = 0;
	std::cin >> n;
	getchar();
	std::string val;
	while (n --> 0) {
		std::getline(std::cin, val);
		if (std::isdigit(val.at(0))) {
			std::cout << mars.toMarsNumber(std::atoi(val.c_str())) << std::endl;
		} else {
			std::cout << mars.toEarthNumber(val) << std::endl;
		}
	}

	return 0;
}

PAT Advenced 1100 Mars Number Test Cases

Be careful about special cases: 13 should output just “tam”, rather than “tam tret”, there are two test cases in the OJ about it, both of which worth 2 points.

Summary

PAT advanced 1100 Mars Number could be simply solved by converting between base 13 and 10 and translate between mars and earth digits by mapping.

Written on January 31, 2016