Base Conversion With Strings
Python 2, 115 114 106 105 94 bytes
Golfing suggestions welcome. Try it online!
Edit: -9 bytes thanks to mbomb007. -2 bytes thanks to FlipTack.
def a(n,f,t,d,z=0,s=''):
for i in n:z=z*f+d.find(i)
while z:s=d[z%t]+s;z/=t
print s or d[0]
Ungolfed:
def arbitrary_base_conversion(num, b_from, b_to, digs, z=0, s=''):
for i in num:
z = z * b_from + digs.index(i)
while z:
s = digs[z % b_to] + s
z = z / t
if s:
return s
else:
return d[0]
Seriously, 50 bytes
0╗,╝,2┐,3┐,4┐╛`4└í╜2└*+╗`MX╜ε╗W;3└@%4└E╜@+╗3└@\WX╜
Hex Dump:
30bb2cbc2c32bf2c33bf2c34bfbe6034c0a1bd32c02a2bbb60
4d58bdeebb573b33c0402534c045bd402bbb33c0405c5758bd
I'm proud of this one despite its length. Why? Because it worked perfectly on the second try. I wrote it and debugged it in literally 10 minutes. Usually debugging a Seriously program is an hour's labor.
Explanation:
0╗ Put a zero in reg0 (build number here)
,╝,2┐,3┐,4┐ Put evaluated inputs in next four regs
╛ Load string from reg1
` `M Map over its chars
4└ Load string of digits
í Get index of char in it.
╜ Load number-so-far from reg0
2└* Multiply by from-base
+ Add current digit.
╗ Save back in reg0
X Discard emptied string/list.
╜ Load completed num from reg0
ε╗ Put empty string in reg0
W W While number is positive
; Duplicate
3└@% Mod by to-base.
4└E Look up corresponding char in digits
╜@+ Prepend to string-so-far.
(Forgetting this @ was my one bug.)
╗ Put it back in reg0
3└@\ integer divide by to-base.
X Discard leftover 0
╜ Load completed string from reg0
Implicit output.
CJam, 34 bytes
0ll:Af#lif{@*+}~li:X;{XmdA=\}h;]W%
Input format is input_N alphabet input_B output_B
each on a separate line.
Run all test cases.
Explanation
0 e# Push a zero which we'll use as a running total to build up the input number.
l e# Read the input number.
l:A e# Read the alphabet and store it in A.
f# e# For each character in the input number turn it into its position in the alphabet,
e# replacing characters with the corresponding numerical digit value.
li e# Read input and convert to integer.
f{ e# For each digit (leaving the base on the stack)...
@* e# Pull up the running total and multiply it by the base.
+ e# Add the current digit.
}
~ e# The result will be wrapped in an array. Unwrap it.
li:X; e# Read the output base, store it in X and discard it.
{ e# While the running total is not zero yet...
Xmd e# Take the running total divmod X. The modulo gives the next digit, and
e# the division result represents the remaining digits.
A= e# Pick the corresponding character from the alphabet.
\ e# Swap the digit with the remaining value.
}h
; e# We'll end up with a final zero on the stack which we don't want. Discard it.
]W% e# Wrap everything in an array and reverse it, because we've generated the
e# digits from least to most significant.
This works for the same byte count:
L0ll:Af#lif{@*+}~li:X;{XmdA=@+\}h;
The only difference is that we're building up a string instead of collecting everything on the stack and reversing it.