Alien Numbers
September 24, 2010
Today’s exercise comes to us from the Google Code Jam via Christian Harms’ blog:
Problem
The decimal numeral system is composed of ten digits, which we represent as “0123456789” (the digits in a system are written from lowest to highest). Imagine you have discovered an alien numeral system composed of some number of digits, which may or may not be the same as those used in decimal. For example, if the alien numeral system were represented as “oF8”, then the numbers one through ten would be (F, 8, Fo, FF, F8, 8o, 8F, 88, Foo, FoF). We would like to be able to work with numbers in arbitrary alien systems. More generally, we want to be able to convert an arbitrary number that’s written in one alien system into a second alien system.
Input
The first line of input gives the number of cases, N. N test cases follow. Each case is a line formatted as
alien_number source_language target_language
Each language will be represented by a list of its digits, ordered from lowest to highest value. No digit will be repeated in any representation, all digits in the alien number will be present in the source language, and the first digit of the alien number will not be the lowest valued digit of the source language (in other words, the alien numbers have no leading zeroes). Each digit will either be a number 0-9, an uppercase or lowercase letter, or one of the following symbols !”#$%&'()*+,-./:;?@[\]^_`{|}~
Output
For each test case, output one line containing “Case #x: ” followed by the alien number translated from the source language to the target language.
Your task is to write a program to solve the Google Code Jam. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Simple solution in haskell:
C# Solution
public static string sourceToDestination(string alianNumber, string sourceLanguage, string destinationLanguage)
{
int decimalValue = 0;
int product = 1;
int sourceRadix = sourceLanguage.Length;
int destinationRadix = destinationLanguage.Length;
string newNumber = “”;
for (int i = alianNumber.Length – 1; i >= 0; i–, product = product * sourceRadix)
{
char numb = alianNumber[i];
int alianValue = -1;
for (int j = 0; j 0; decimalValue = decimalValue / destinationRadix)
{
newNumber = destinationLanguage[decimalValue % destinationRadix] + newNumber;
}
return newNumber;
}
C# again copy paste does not like me
public static string sourceToDestination(string alianNumber, string sourceLanguage, string destinationLanguage)
{
int decimalValue = 0;
int product = 1;
int sourceRadix = sourceLanguage.Length;
int destinationRadix = destinationLanguage.Length;
string newNumber = "";
for (int i = alianNumber.Length - 1; i >= 0; i--, product = product * sourceRadix)
{
char numb = alianNumber[i];
int alianValue = -1;
for (int j = 0; j 0; decimalValue = decimalValue / destinationRadix)
{
newNumber = destinationLanguage[decimalValue % destinationRadix] + newNumber;
}
return newNumber;
}
Actually wordpress doesn’t like me.
Hope it works this time and that someone can delete the failed attempts.
public static string sourceToDestination(string alianNumber, string sourceLanguage, string destinationLanguage)
{
int decimalValue = 0;
int product = 1;
int sourceRadix = sourceLanguage.Length;
int destinationRadix = destinationLanguage.Length;
string newNumber = "";
for (int i = alianNumber.Length – 1; i >= 0; i–, product = product * sourceRadix)
{
char numb = alianNumber[i];
int alianValue = -1;
for (int j = 0; j <= sourceLanguage.Length – 1; j++)
{
if (sourceLanguage[j] == numb)
{
alianValue = j;
break;
}
}
decimalValue += (alianValue * product);
}
for (; decimalValue > 0; decimalValue = decimalValue / destinationRadix)
{
newNumber = destinationLanguage[decimalValue % destinationRadix] + newNumber;
}
return newNumber;
}
[…] response of my article a scheme solution (and haskel as […]
Mine in F#
Here is mine in Clojure:
The full solution with tests is here.
My clojure generating data structures to meet the adequated functions:
oops
(ns alien-nums
(:require (clojure.contrib [combinatorics :as comb :only cartesian-product]
[seq-utils :as seq-utils :only indexed])))
(defn generate-nums [lang]
(when-let [lst (seq lang)]
(let [leading-zero? #(= (first %) (first lang))
fcp #(remove leading-zero?
(map flatten
(comb/cartesian-product lst %1)))]
(apply concat (iterate fcp lst)))))
(defn get-index [nums num]
(first (some #(when (= (second %) (seq num)) %)
(seq-utils/indexed nums))))
(defn valid-num [lang num]
(every? (set lang) num))
(defn convert-num [alien-num from-lang to-lang]
(let [[from-nums to-nums]
(map generate-nums [from-lang to-lang])
idx (when (valid-num from-lang alien-num)
(get-index from-nums alien-num))]
(when idx (apply str (nth to-nums idx)))))
[…] response of my article a scheme solution (and haskel as […]