Reputation: 149
I need a function which interprets vectors of integers as numbers with a certain base like this:
vectonum([1,2,3,4], 10) #=> 1234
vectonum([0,0,0,1], 2) #=> 1
vectonum([1,1,1,1], 2) #=> 15
The following function does the job, but looks a little bit awkward to me:
function vectonum(vector, base)
result = 0
vector = reverse(vector)
for (idx, val) in enumerate(vector)
val_ = val * base ^ (idx - 1)
result += val * base ^ (idx - 1)
end
return result
end
Is there a better, more julia-style way to do this, perhaps even a built-in function or module for this?
Thanks in advance!
Upvotes: 3
Views: 808
Reputation: 12644
What you wrote is definitely good Julia-style. You just chose a slightly inefficient algorithm. It's better to avoid exponentiation, since that is an expensive operation that does a lot of redundant work here (calculating b^n
in one iteration and then b^(n+1)
in the next is clearly inefficient.)
Here's an implementation that is basically the same as @BogumilKaminski's first solution, just written out as a loop (loops are Julia-style), and apparently also slightly faster than using foldl
:
function vectonum(d, base=10)
s = zero(eltype(d))
for val in d
s = s * base + val
end
return s
end
Upvotes: 2
Reputation: 69819
You can write:
f(v, b) = foldl((x,y) -> b*x+y, v)
which is probably shortest and fast. Change it to foldl((x,y) -> b*x+y, v, init=0)
in the call if you want this to work also for empty vector returning 0
.
There are some alternatives that also came to my mind, so I post them below.
First the relatively short (not fast) way to do it is:
f(v, b) = parse(Int, join(v), base=b)
Something along your implementation would be:
f(v, b) = sum(x -> b^(x[1]-1)*x[2], enumerate(Iterators.reverse(v)))
Upvotes: 6