Skip to content

Instantly share code, notes, and snippets.

@mukulrawat1986
Created September 15, 2014 20:12
Show Gist options
  • Save mukulrawat1986/2687383452af07777045 to your computer and use it in GitHub Desktop.
Save mukulrawat1986/2687383452af07777045 to your computer and use it in GitHub Desktop.
Palantir Technologies hiring puzzle
Variable-Base Expression Evaluation:
You've woken up one day to find that everyone suddenly expresses numbers in different number bases. You're seeing prices in octal and phone numbers in hexadecimal. It's a numerical Tower of Babel! For your own sanity, you decide to program a simple mathematical expression evaluator that can handle numbers in different number bases. It should support addition, subtraction, and multiplication, should respect order of operations, and should handle number bases between 2 and 16.
While your language of choice may directly support expression evaluation, please create your own.
The input on stdin is a mathematical expression on a single line. Number constants are expressed like "123_4", which is "123" in base 4, which is 27 in base 10. Some digits in the higher bases will be represented with uppercase letters. Numbers within the expression will always be non-negative integers. The operators will be +, -, and *. Whitespace should be ignored.
Your program should emit to stdout a single base-10 number with no underscores.
While correctness and performance are the most important parts of this problem, a human will be reading your solution, so please make an effort to submit clean, readable code. In particular, do not write code as if you were solving a problem for a competition.
Here's an example input and output:
Input : 1430_5 - 110_2 * 2A_12 + 10_10
Output : 46
import re
#Function to calculate the decimal value for numbers of any base
def calculate(exp):
#split the expression into the number and base
div = exp.split('_')
#if base is equal to 10 return the number part, else we will calculate the value of the number in base 10
if div[1] == '10':
return div[0]
#store the number and base separately
no = div[0]
base = div[1]
l = len(no)
l-=1
#Use res to store the final value of the number in base 10
res = 0
for i in no:
#convert it to suitable no. if its a digit, otherwise use it as it is
if i == 'A' or i == 'B' or i == 'C' or i =='D' or i == 'E':
val = ord(i) - 65 + 10
else:
val = int(i)
res += (val * (int(base)**l))
l-=1
return res
#Input the string
s = raw_input()
# we will use regular expression to separate the number constants
number = re.findall(r'\w+_\w+',s)
#find operators in the order of their appearance
operator = []
#store the operators in a list in the order of their appearance
for i in s:
if i=='+' or i == '-' or i == '*':
operator += i
#used to save the numbers in base-10 form in a list
base_10 = []
for exp in number:
inter = str(calculate(exp))
base_10.append(inter)
#print base_10
#print operator
#Now we have list containing the number in base-10 form and the operators in their order of appearance. To calculate
#the final value we first need to perform all the multiplication and then perform either addition or subtraction
#in the order of appearance from left to right.
#Perform all multiplication
pos = 0
for i in operator:
if i!='*':
pos += 1
else:
l1 = pos
l2 = pos + 1
val = int(base_10[l1])*int(base_10[l2])
base_10[l1] = str(val)
del base_10[l2]
#print base_10
#print operator
#Perform addition/subtraction from left to right in the order of appearance.
pos = 0
for i in operator:
if i == '+':
val = int(base_10[0]) + int(base_10[1])
pos += 1
base_10[0] = str(val)
del base_10[1]
elif i == '-':
val = int(base_10[0]) - int(base_10[1])
pos += 1
base_10[0] = str(val)
del base_10[1]
print int(base_10[0])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment