23
\$\begingroup\$

Input:
A list/array of integers for which each item is in the range of 2-36.

Output:
The sum of the integers (as base 10), where each next integer is in the base of the previous value (starting with a regular base 10).

Example:
Let's say we have an input like this: [4, 12, 34, 20, 14, 6, 25, 13, 33]
Then we have a sum like this:

4    (4  in base-10) +
6    (12 in base-4 ) +
40   (34 in base-12) +
68   (20 in base-34) +
24   (14 in base-20) +
6    (6  in base-14) +
17   (25 in base-6 ) +
28   (13 in base-26) +
42   (33 in base-13)
= 235

Mathematical base explained:
I considered assuming everyone knows how base works, but I'll give a brief example of how it works anyway, just in case. Let's take the 34 in base-12 for example, how did we get 40?

1-34 in regular base-10:
 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
 So, from 1 to 34 is 34 steps in base-10

1-34 in base-12:
 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 1A, 1B, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 2A, 2B, 30, 31, 32, 33, 34
 So, from 1 to 34 is 40 steps in base-12

Here is perhaps a useful calculator.

Challenge rules:

  • Array size will be in reasonable range (like 1-100 / see test cases).
  • The test cases will never contain integers of which the current value is invalid for it's previous base (i.e. You will never have something like 19 in base-6 or 6 in base-6, because base-6 only contains the digits 0-5).
  • You can take the input any way you'd like. Can be as an int-array, as a comma/space-separated string, etc. Your call. (You are also allowed to take the int-array reversed, which could be useful for stack-based programming languages.)

General Rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-golfing languages. Try to come up with as short an answer as possible for any programming language.
  • Standard rules apply for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code.
  • Also, please add an explanation if necessary.

Test cases:

[4, 12, 34, 20, 14, 6, 25, 13, 33]                            ->   235
 4+ 6+  40+ 68+ 24+ 6+ 17+ 28+ 42

[5, 14, 2, 11, 30, 18]                                        ->   90
 5+ 9+  2+ 3+  33+ 38

[12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 12, 2, 11, 3, 10, 2, 10]    ->   98
 12+ 13+ 11+ 9+ 8+ 7+ 6+ 5+ 4+ 3+ 5+  2+ 3+  3+ 3+  2+ 2

[36, 36]                                                      ->   150
 36+ 114
\$\endgroup\$
  • 1
    \$\begingroup\$ For stack based languages which have a LIFO container, can the input be given in reversed order? In dc I would require ~30 bytes just to flip the stack to have the first number in the input be the first one to be processed, which non-stack based languages have by default. \$\endgroup\$ – seshoumara Sep 23 '16 at 8:13
  • \$\begingroup\$ @seshoumara Why not. I'll clarify this in the challenge. It's mainly about the challenge and output, and not really about the input-format. \$\endgroup\$ – Kevin Cruijssen Sep 23 '16 at 8:17

23 Answers 23

4
\$\begingroup\$

05AB1E, 7 6 5 bytes

Uses the 05AB1E encoding.

Saved 1 byte using the new built-in š as suggested by Kevin Cruijssen

TšüöO

Explanation

Input list is taken reversed, as allowed by challenge specification.

Tš     # prepend a 10 to the list
  üö   # reduce by conversion to base-10
    O  # sum

Try it online!

Modified testsuite

\$\endgroup\$
  • 2
    \$\begingroup\$ Can be 5 bytes now with the builtin š instead of ¸ì. Also, your explanation states "append" instead of "prepend". :) \$\endgroup\$ – Kevin Cruijssen Mar 21 at 8:50
  • \$\begingroup\$ @KevinCruijssen: Thank you :) \$\endgroup\$ – Emigna Mar 21 at 9:39
9
\$\begingroup\$

Python 3, 40 bytes

lambda a:sum(map(int,map(str,a),[10]+a))

Tests are at ideone

map(str, a) creates a generator, G, that calls str on each value in a, converting to strings
map(int, G, [10]+a) creates a generator that calls int(g, v) for pairs across G and [10]+a
int(g, v) converts the string g from the integer base v (if v is in [2,36] and g is valid)
sum does what it says on the tin

\$\endgroup\$
7
\$\begingroup\$

Python 2, 48 bytes

lambda a:sum(int(`x`,y)for x,y in zip(a,[10]+a))

Tests are at ideone

zip(a,[10]+a) traverses pairs of the values in a, and the previous value or 10 for the first
the backticks in the int call convert x to a string, s
int(s, y) converts the string s from the integer base y (if y is in [2,36] and s is valid)
sum does what it says on the tin

\$\endgroup\$
6
\$\begingroup\$

Perl, 35 34 33 bytes

Includes +2 for -ap

Run with the list of numbers on STDIN:

basemix.pl <<< "4 12 34 20 14 6 25 13 33";echo

basemix.pl:

#!/usr/bin/perl -ap
$\+=$&+"$`$& 10"*/.$/*$`for@F}{

I've been waiting for ages for a chance to use this abuse...

Explanation

The input numbers can have at most 2 digits. A number xy in base b is simply b*x+y. I'm going to use the regex /.$/ so the first digit ends up in $` and the last digit in $&, so the contribution to the sum is $&+$b*$`.

I abuse the fact that for does not properly localize the regex variables (like for example map and while do) so the results of a match in the previous loop is still available in the current loop. So if I'm careful about the order in which I do the operations the base is available as "$`$&", except for the very first loop where I need the base to be 10. So I use "$`$& 10" instead

The way the first $& works is an abuse too since it is actually changed by the /.$/ while it is already on the stack waiting to be added.

The final abuse is the }{ at the end which changes the loop implied by -p from

LINE: while (defined($_ = <ARGV>)) {
    ...code..
}
continue {
    die "-p destination: $!\n" unless print $_;
}

to

LINE: while (defined($_ = <ARGV>)) {
    ...code..
}
{
}
continue {
    die "-p destination: $!\n" unless print $_;
}

Which means $_ will be undefined in the print, but it still adds $\ in which I accumulated the sum. It is also a standard golf trick to get post-loop processing

\$\endgroup\$
  • \$\begingroup\$ I'd be really interested in an explanation for those of us with weaker perl-fu! \$\endgroup\$ – m-chrzan Sep 23 '16 at 15:16
  • 2
    \$\begingroup\$ @m-chrzan Solution fixed and explanation added \$\endgroup\$ – Ton Hospel Sep 23 '16 at 17:18
4
\$\begingroup\$

PHP, 53 51 bytes

for(;$x=$argv[++$i];$b=$x)$s+=intval($x,$b);echo$s;

Iterates over the input, converting each input to string variant. Then takes the integer value using the previous number as base. For the first number, the base will not be set, PHP will then start off with 10 (inferred from the number format).

Run like this (-d added for aesthetics only):

php -d error_reporting=30709 -r 'for(;$x=$argv[++$i];$b=$x)$s+=intval($x,$b);echo$s;' -- 12 11 10 9 8 7 6 5 4 3 12 2 11 3 10 2 10;echo

Tweaks

  • Actually, no need to convert to string, as CLI arguments are already string. Saved 2 bytes.
\$\endgroup\$
3
\$\begingroup\$

Jelly, 7 bytes

ṙ1DḅṖḌS

Try it online!

\$\endgroup\$
  • 3
    \$\begingroup\$ You could replace ṖḌ with F \$\endgroup\$ – Jonathan Allan Sep 23 '16 at 7:58
  • 4
    \$\begingroup\$ Unfortunately, that won't work in the first number has two digits. \$\endgroup\$ – Dennis Sep 23 '16 at 15:31
3
\$\begingroup\$

Java, 86 bytes

s->{int[]b={10};return s.reduce(0,(r,n)->{r+=n.valueOf(""+n,b[0]);b[0]=n;return r;});}

Testing and ungolfed

import java.util.function.ToIntFunction;
import java.util.stream.Stream;

public class Main {

  public static void main(String[] args) {
    ToIntFunction<Stream<Integer>> f = s -> {
      int[] b = {10};                 // Base, initialized with 10
      return s.reduce(0, (r, n) -> {  // Typical use of reduction, sum starts with 0.
        r += n.valueOf("" + n, b[0]); // Add the value in the previous base.
        b[0] = n;                     // Assign the new base;
        return r;
      });
    };

    System.out.println(f.applyAsInt(Stream.of(new Integer[]{4, 12, 34, 20, 14, 6, 25, 13, 33})));
  }
}
\$\endgroup\$
3
\$\begingroup\$

JavaScript ES6, 45 42 41 Bytes

const g =
     a=>a.map(v=>s+=parseInt(v,p,p=v),s=p=0)|s
;

console.log(g.toString().length);                                            // 42
console.log(g([4, 12, 34, 20, 14, 6, 25, 13, 33]));                          // 235
console.log(g([5, 14, 2, 11, 30, 18]  ));                                    // 90
console.log(g([12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 12, 2, 11, 3, 10, 2, 10] )); // 98

Conventiently parseInt(x,0) === parseInt(x,10).

edit: Saved 1 byte thanks to @ETHproductions

\$\endgroup\$
  • \$\begingroup\$ Nice! I think you can save a byte by replacing &&s with |s. \$\endgroup\$ – ETHproductions Sep 23 '16 at 15:26
  • \$\begingroup\$ You can also replace const g with just g \$\endgroup\$ – Clyde Lobo Sep 24 '16 at 8:51
3
\$\begingroup\$

Pure bash, 38

b=10
for i;{((t+=$b#$i,b=i));}
echo $t

The input list is given at the command-line. for i; automatically iterates over the input parameters (equivalent to for i in $@;).

Ideone.

\$\endgroup\$
3
\$\begingroup\$

Java 7, 109 89 86 bytes

int c(int[]a){for(Byte i=1;i<a.length;a[0]+=i.valueOf(a[i]+"",a[++i-2]));return a[0];}

Golfed 20 bytes thanks to @cliffroot (of which 12 because of a stupid mistake I made myself).

Ungolfed & test code:

Try it here.

class M{
  static int c(int[] a){
     for(Byte i = 1; i < a.length; a[0] += i.valueOf(a[i]+"", a[++i-2]));
     return a[0];
  }

  public static void main(String[] a){
    System.out.println(c(new int[]{ 4, 12, 34, 20, 14, 6, 25, 13, 33 }));
    System.out.println(c(new int[]{ 5, 14, 2, 11, 30, 18 }));
    System.out.println(c(new int[]{ 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 12, 2, 11, 3, 10, 2, 10 }));
    System.out.println(c(new int[]{ 36, 36 }));
  }
}

Output:

235
90
98
150
\$\endgroup\$
  • \$\begingroup\$ Do you really need p? The sum can be computed like this, can't it: r+=r.valueOf(""+a[i],a[i-1])? \$\endgroup\$ – Olivier Grégoire Sep 23 '16 at 8:32
  • 1
    \$\begingroup\$ used conversion +"" instead of valueOf and removed unnecessary variables – int c(int[]a){for(Integer i=1;i<a.length;a[0]+=i.valueOf(a[i]+"",a[++i-2]));return a[0];} \$\endgroup\$ – cliffroot Sep 23 '16 at 8:35
  • \$\begingroup\$ @cliffroot Ah, I'm an idiot.. When I was testing I made a mistake and had the 10 and p reversed. I realized the mistake and fixed it, but since the String part is now regular base-10 I can indeed remove the toString and just use +"".. Thanks, and also thanks for golfing the other things, -20 bytes. I really gotta make an answer you can't golf more (not that I don't appreciate it! the shorter the better of course - in code-golfing that is ;P) \$\endgroup\$ – Kevin Cruijssen Sep 23 '16 at 8:38
  • \$\begingroup\$ Just to compare with my answer, yours in current Java's syntax is 79 bytes long (mine is presently 86 bytes long). But that's not fun taking others' code ;) \$\endgroup\$ – Olivier Grégoire Sep 23 '16 at 9:06
  • 1
    \$\begingroup\$ @KevinCruijssen , I'm more than fine with it :) I just feel that realistically Java does not compete with all that 5-6 bytes solution, so I don't add my own answers often, but I still find it fun to golf down others' solution. \$\endgroup\$ – cliffroot Sep 23 '16 at 9:14
2
\$\begingroup\$

Actually, 12 bytes

;p(dX(♂$♀¿Σ+

Try it online!

Explanation:

;p(dX(♂$♀¿Σ+
;             dupe input
 p            pop first element from list
  (dX         pop and discard last element from other copy
     (♂$      stringify all elements in first copy
        ♀¿    for each pair of elements in the two lists, interpret the first element as a base-(second element) integer
          Σ   sum
           +  add first element of original list
\$\endgroup\$
2
\$\begingroup\$

CJam, 15 bytes

l~{A\:A10bb}%:+

Try it online!

Explanation

l~     e# Read and evaluate input.
{      e# Map this block over the input...
  A    e#   Push A. Initially this is 10, afterwards it will be the value of the
       e#   last iteration.
  \:A  e#   Swap with current value and store that in A for the next iteration.
  10b  e#   Convert to base 10 to get its decimal digits.
  b    e#   Interpret those in the base of the previous A.
}%
:+     e# Sum all of those values.
\$\endgroup\$
2
\$\begingroup\$

Haskell, 65 59 bytes

b%x|x<1=x|y<-div x 10=b*b%y+x-10*y
sum.((10:)>>=zipWith(%))

Test it on Ideone.

\$\endgroup\$
2
\$\begingroup\$

Matlab, 68 bytes

Not a very creative solution, but here it is:

function[s]=r(x);j=10;s=0;for(i=x)s=s+base2dec(num2str(i),j);j=i;end

Tests:

>> r([4,12,34,20,14,6,25,13,33])
ans =
   235
>> r([12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 12, 2, 11, 3, 10, 2, 10])
ans =
   98
>> r([5, 14, 2, 11, 30, 18])
ans =
   90
>> r([36,36])
ans =
   150
\$\endgroup\$
  • \$\begingroup\$ You can save one byte with function s=r(x);... \$\endgroup\$ – Luis Mendo Sep 24 '16 at 15:18
2
\$\begingroup\$

JavaScript (ES6), 54 48 40 bytes

I used a recursive approach.

f=([b,...a],c)=>b?parseInt(b,c)+f(a,b):0

Saved 6 bytes, thanks to Lmis!
Saved 8 more bytes, thanks to Neil!

\$\endgroup\$
  • 1
    \$\begingroup\$ I think you can save 3 bytes by using parseInt(a,b) instead of parseInt(a[0],b) since parseInt converts the first argument to string and ignores everything starting at the first invalid character (i.e. ','). \$\endgroup\$ – Lmis Sep 23 '16 at 8:21
  • 1
    \$\begingroup\$ I also think you can save some bytes by using a[0]?stuff():0 instead of a.length&&stuff() \$\endgroup\$ – Lmis Sep 23 '16 at 8:31
  • \$\begingroup\$ @Lmis Thanks, I've updated it :) \$\endgroup\$ – Huntro Sep 23 '16 at 8:44
  • 1
    \$\begingroup\$ I think you can shorten this to 40 bytes: f=([b,...a],c)=>b?parseInt(b,c)+f(a,b):0 \$\endgroup\$ – Neil Sep 24 '16 at 18:07
  • \$\begingroup\$ @Neil nice way of not using the slice function \$\endgroup\$ – Huntro Sep 25 '16 at 9:59
2
\$\begingroup\$

Perl 6,  52  50 bytes

{sum (10,|@_).rotor(2=>-1).map:{+":{.[0]}<{.[1]}>"}}
{sum (10,|@_).rotor(2=>-1).map:{":{.[0]}<$_[1]>"}}

Explanation:

# bare block lambda with implicit parameter 「@_」
{
  sum

    ( 10, |@_ )        # the input with a preceding 10
    .rotor( 2 => -1 )  # grab 2 values, back up one, repeat
    .map:
    {
      # create a string of the form ":10<4>"
      ":{
        .[0]            # first element from $_
      }<{
        .[1]            # second element from $_
      }>"
    }
}
\$\endgroup\$
1
\$\begingroup\$

Python 2, 52 bytes

f=lambda x:x[1:]and int(`x.pop()`,x[-1])+f(x)or x[0]

Test it on Ideone.

\$\endgroup\$
1
\$\begingroup\$

Julia, 63 Bytes

f(l)=sum([parse(Int,string(l[i]),l[i-1])for i=2:length(l)])+l[]

Parses each number (except the first) taking the previous element as base and sums. Adds the first element at the end

\$\endgroup\$
1
\$\begingroup\$

Ruby, 52 bytes

->a{eval a.zip([10]+a).map{|e|'"%s".to_i(%s)'%e}*?+}

ungolfed

->a{
  eval(
    a.zip([10]+a).map { |e|
      '"%s".to_i(%s)' % e
    }.join("+")
  )
}

usage

f=->a{eval a.zip([10]+a).map{|e|'"%s".to_i(%s)'%e}*?+}
p f[[4, 12, 34, 20, 14, 6, 25, 13, 33]] # => 235
\$\endgroup\$
1
\$\begingroup\$

Scala, 67 bytes

def f(a:Int*)=a zip(10+:a)map{t=>Integer.parseInt(""+t._1,t._2)}sum

Explanation:

def f(a: Int*) =     //declare a method f with varargs of type Int as parameter
a zip (10 +: a)      //zip a with 10 prepended to a, resulting in...
                     //...Array((4,10), (12,4), (34,12), (20,34), (14,20), (6,14), (25,6), (13,25), (33,13))
map { t =>           //map each tuple t to...
  Integer.parseInt(  //...an integer by parsing...
    ""+t._1, t._2    //...a string of the first item in base-second-item.
  )
}
sum                  //and sum
\$\endgroup\$
1
\$\begingroup\$

Mathematica, 59 bytes

I wish Mathematica's function names were shorter. But otherwise I'm happy.

Tr[FromDigits@@@Transpose@{IntegerDigits/@{##,0},{10,##}}]&

For example,

Tr[FromDigits@@@Transpose@{IntegerDigits/@{##,0},{10,##}}]&[4,12,34,20,14,6,25,13,33]

yields 235.

{##,0} is a list of the input arguments with 0 appended (representing the numerals); {10,##} is a list of the input arguments with 10 prepended (representing the bases). That pair of lists is Transposed to associate each with numeral with its base, and FromDigits (yay!) converts each numeral-base pair to a base-10 integer, the results of which are summed by Tr.

\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 83

(lambda(s)(loop for b ="10"then x for x in s sum(#1=parse-integer x :radix(#1#b))))

Details

(defun base-mix (list)
  (loop
     for base = "10" then string
     for string in list
     sum (parse-integer string :radix (parse-integer base))))

The loop construct accepts "v then w" iteration constructs, where v is an expression to be evaluated the first time the iteration variable is computed, and w is the expression to be evaluated for the successive iterations. Declarations are evaluated one after the other, so base is first "10", then the previous element stringof the list list being iterated. The sum keyword computes a sum: the integer read from string with base b, where b is the integer parsed from the base string, in base 10. #1= and #1# are notations to define and use reader variables: the first affects an s-expression to a variable, the other one replaces the reference by the same object. This saves some characters for long names.

Example

(base-mix '("4" "12" "34" "20" "14" "6" "25" "13" "33"))
=> 235
\$\endgroup\$
1
\$\begingroup\$

Japt -x, 7 bytes

äÏsnX}A

Try it

äÏsnX}A     :Implicit input of array
ä           :Take each consecutive pair of elements
 Ï          :Pass them through the following function as X & Y
  s         :  Convert Y to a base-10 string
   nX       :  Convert to an integer from base-X
     }      :End function
      A     :Before doing any of that, though, prepend 10 to the array
            :Implicit output of the sum of the resulting array
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.