20
\$\begingroup\$

Given a number as input, print out its collective sum

What is a collective sum?

Consider the number 13214, the input

Looping through each of the digits starting from the left, we will be able to obtain its collective sum.

1 means look at the first digit, and add it to the sum, sum = 1

3 means look at the "first 3 digits" and add it to the sum, sum = 1 + 132

2 means look at the "first 2 digits" and add it to the sum, sum = 1 + 132 + 13

1 means look at the first digit, and add it to the sum, sum = 1 + 132 + 13 + 1

4 means look at the "first 4 digits" and add it to the sum, sum = 1 + 132 + 13 + 1 + 1321

Total sum = 1468 and this is your output


Special cases:

If we encounter a 0, then clearly we keep the sum the same

The number 1301 would have a sum = 1 + 130 + 1 = 132

If we encounter a number that is larger then the length of the input, we add it all

The number 251 would have a sum = 25 + 251 + 2 = 278

Test cases:

collectiveSum(0) = 0

collectiveSum(2) = 2

collectiveSum(2315) = 23 + 231 + 2 + 2315 = 2571

Shortest amount of bytes wins. Happy golfing!

\$\endgroup\$
  • 6
    \$\begingroup\$ As is often a question with these kinds of tasks: May we accept a list of the digits as our input? \$\endgroup\$ – Jonathan Allan Feb 24 '18 at 0:10
  • 7
    \$\begingroup\$ The 2315 test case is missing the + 2 from the 1 and should result in 2571. \$\endgroup\$ – Jonathan Allan Feb 24 '18 at 0:15
  • \$\begingroup\$ Do we expect to have to deal with inputs starting with 0 aside from 0? How should the program deal with these inputs \$\endgroup\$ – fəˈnɛtɪk Feb 24 '18 at 1:08
  • \$\begingroup\$ It looks like the last test case is wrong; should be 2571. \$\endgroup\$ – Shaggy Feb 24 '18 at 3:43
  • \$\begingroup\$ I don't see why the input should be a number rather than a list of integers. It seems like an unnecessarily cumbersome form of input. \$\endgroup\$ – Sriotchilism O'Zaic Feb 24 '18 at 5:27

26 Answers 26

7
\$\begingroup\$

05AB1E,  4  3 bytes

-1 thanks to Kevin Cruijssen (use of avoiding a })

€£O

Try it online!

How?

€£O - implicit input   e.g. 2315
€   - map with:
 £  -   head to             23, 231, 2, 2315
  O - sum                   2571
\$\endgroup\$
  • \$\begingroup\$ Beat me by 13 seconds xD \$\endgroup\$ – Magic Octopus Urn Feb 24 '18 at 0:27
  • \$\begingroup\$ Glad I waited to add the link to bytes then :p \$\endgroup\$ – Jonathan Allan Feb 24 '18 at 0:27
  • \$\begingroup\$ ε£} can be €£ to save a byte. \$\endgroup\$ – Kevin Cruijssen Jun 24 at 13:06
  • \$\begingroup\$ @KevinCruijssen was that also an option when I created this? \$\endgroup\$ – Jonathan Allan Jun 24 at 13:09
  • \$\begingroup\$ @JonathanAllan Not entirely sure, but I think it indeed already was. Adnan started writing the Elixir rewrite in the Summer of 2018 (which was released in August), and was already there for quite a while in the legacy version of 05AB1E before that. It was already there when I posted my very first 05AB1E answer in April 2018. So it might be possible it was added shortly after you posted this answer, but I'm not sure. \$\endgroup\$ – Kevin Cruijssen Jun 24 at 13:24
5
\$\begingroup\$

Python 2, 43 bytes

lambda n:sum(int('0'+n[:int(x)])for x in n)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Unfortunately this appears to raise a ValueError for input of 1301, or any input that has a zero as one of its digits. \$\endgroup\$ – mathmandan Feb 24 '18 at 19:08
  • \$\begingroup\$ @mathmandan Should be fixed now? \$\endgroup\$ – ASCII-only Feb 25 '18 at 1:37
  • \$\begingroup\$ The int function can accept an integer, replacing the '0' string literal with just 0 should shave off one byte. \$\endgroup\$ – MooseOnTheRocks Feb 25 '18 at 7:26
  • \$\begingroup\$ @MooseOnTheRocks Did in a way that seems less hacky-looking (?) to me, unless I'm stupid and messed something up (usually) \$\endgroup\$ – ASCII-only Feb 25 '18 at 8:14
4
\$\begingroup\$

Python 2, 72 bytes

First submission! Thanks to @DestructibleLemon for the help!

import sys;d=sys.argv[1];s=0;for e in d:s+=int(d[:int(e)]);print str(s)
\$\endgroup\$
  • \$\begingroup\$ Just so you know, the downvote seems to have been given automatically by the community user when I edited the header of your post. Sorry. It's an annoying, nonsensical feature. Though I don't know why it did that this time, because as far as I can tell, this was not flagged as low-quality. \$\endgroup\$ – Steadybox Feb 26 '18 at 3:56
  • \$\begingroup\$ Welcome to PPCG! Nice first submission! And yeah, as Steadybox said, the downvote was automatically placed for no good reason in particular. Your post has gotten a few upvotes so hopefully at the next cron job the automatic downvote should be removed :) \$\endgroup\$ – HyperNeutrino Feb 26 '18 at 4:18
3
\$\begingroup\$

Haskell, 43 37 bytes

f l=sum[read$'0':take(read[d])l|d<-l]

Try it online!

The input number is taken as a string.

   [        |d<-l]      -- for every digit d in the input string
        read[d]         -- convert to a number
      take     l        -- and take that many digits from l
     0:                 -- prepend a 0 (to handle 0s)
   read                 -- convert to a number
sum                     -- sum all numbers
\$\endgroup\$
3
\$\begingroup\$

Ruby, 36 bytes

->n{n.sum{|x|n[0,x.to_i].join.to_i}}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ #sum isn't defined on fixnums, so I assume you want n to be a string. However, String#sum computes a not a particularly good checksum and ignores the block you give it. If you meant n.chars.sum{, Enumerable#sum isn't in the ruby stdlib, it's an extension provided by rails. Please test your solutions before posting them. \$\endgroup\$ – Shelvacu Feb 24 '18 at 19:04
  • \$\begingroup\$ @Shelvacu Yeah, I'm taking input as an array though... see the footer provided. Plus Enumerable#sum is in Ruby 2.4, and TIO uses 2.4 \$\endgroup\$ – ASCII-only Feb 25 '18 at 1:45
  • \$\begingroup\$ 31 bytes if you take an array of digits as input \$\endgroup\$ – Asone Tuhid Feb 26 '18 at 10:55
  • \$\begingroup\$ @AsoneTuhid I don't think that's a valid form of input, if you find evidence otherwise please explain \$\endgroup\$ – ASCII-only Feb 26 '18 at 11:04
  • \$\begingroup\$ This page doesn't seem to address the issue but i don't see a list of integers as being too different from a list of characters (which is what your answer takes as input) \$\endgroup\$ – Asone Tuhid Feb 26 '18 at 11:40
3
\$\begingroup\$

JavaScript, 42 40 bytes

Thanks @Shaggy for golfing off 2 bytes

f=
x=>[...x].map(y=>a+=+x.slice(0,y),a=0)|a

console.log(f("2315"))
console.log(f("0100"))
console.log(f("2"))
console.log(f("01025"))

Receives input as a string and returns an integer. As currently written, this code leaves leading zeroes on any integers.

\$\endgroup\$
  • \$\begingroup\$ 40 bytes: x=>[...x].map(y=>a+=+x.slice(0,y),a=0)|a \$\endgroup\$ – Shaggy Feb 24 '18 at 8:53
3
\$\begingroup\$

R, 57 bytes

saved one more thanks to @Vlo

sum(strtoi(substring(i<-scan(,""),1,el(strsplit(i,"")))))

was: Saved 4 bytes thanks to @Robert Hacken's suggestion.

i=scan(,"");sum(strtoi(substring(i,1,el(strsplit(i,"")))))

A simple string approach.

\$\endgroup\$
  • 1
    \$\begingroup\$ You can save 4 bytes replacing unlist by el. \$\endgroup\$ – Robert Hacken Feb 25 '18 at 20:32
  • 1
    \$\begingroup\$ Save 1 with inline assignment sum(strtoi(substring(i<-scan(,""),1,el(strsplit(i,""))))) \$\endgroup\$ – Vlo Feb 27 '18 at 18:32
2
\$\begingroup\$

C (gcc), 106 bytes

j,k,c,t;f(char*S){for(t=j=0;S[j];j++)c=S[k=S[j]-48<(c=strlen(S))?S[j]-48:c],S[k]=0,t+=atoi(S),S[k]=c;S=t;}

Try it online!

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

Charcoal, 10 bytes

IΣIEθ✂θ⁰Iι

Try it online! Link is to verbose version of code. Explanation:

   Eθ       Map over input string
        Iι  Cast current character to integer
     ✂θ⁰    Slice input string to that length
 ΣI         Cast slices to integer and take the sum
I           Cast result to string and implicitly print
\$\endgroup\$
  • \$\begingroup\$ Haha, I had the exact same thing \$\endgroup\$ – ASCII-only Feb 24 '18 at 0:29
2
\$\begingroup\$

Octave, 56 bytes

@(n)sum(str2num(['' 32+char(n.*(find(n)<=(n'-48))-32)]))

Anonymous function that takes a string as input argument and returns a number as output.

Try it online!

The shorter version

@(n)sum(str2num(['' char(n.*(find(n)<=(n'-48)))]))

works in Matlab, because char(0) is treated as a space.

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

Jelly,  7  5 bytes

-2 thanks to Dennis (head vectorises >.<)

4 if we may take lists of digits*

Dḣ`ḌS

Try it online!

* ḣ`ḌS

How?

Dḣ`ḌS - Link: integer, n   e.g. 2315
D     - to decimal list         [2,3,1,5]
  `   - repeat left as right    [2,3,1,5]
 ḣ    - head                    [2,3], [2,3,1], [2], [2,3,1,5]
   Ḍ  - from decimal lists      23, 231, 2, 2315
    S - sum                     2571
\$\endgroup\$
2
\$\begingroup\$

Perl 6, 27 bytes

{sum $_ X[&substr]^«.comb}

Test it

Expanded:

{  # bare block lambda with implicit param 「$_」

  sum

    $_           # the input

      X[&substr] # crossed using &substr sub as if it was an infix operator

    ^«\          # upto 「^」 for each of the following 「«」 (creates Range objects)
    .comb        # the input split into digits (implicit method call on 「$_」
}
\$\endgroup\$
2
\$\begingroup\$

C (gcc), 77 75 bytes

Has to be compiled with the -lm switch or GCC doesn't recognize the math functions.

r,q,i;f(n){for(r=0,i=n;i;i/=10)q=log10(n)+1-i%10,r+=n/pow(10,q>0?q:0);n=r;}

Try it online!

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

dc, 55 bytes

[0*]sq?dsfZ1-se[lfddZrIle^/I%-d0>qIr^/+led1-se0<a]dsaxp

No strings nor arrays! Indeed, the required digits are acquired solely through mathematical manipulation.

Try it online!

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

Husk, 6 bytes

ṁd´M↑d

Try it online!

Explanation

ṁd´M↑d  -- example input: 1301
     d  -- decimal digits: [1,3,0,1]
  ´M    -- map over it using it as argument (example with 3):
    ↑   -- | take: [1,3,0]
        -- : [[1],[1,3,0],[],[1]]
ṁ       -- map and then sum the result (example on [1,3,0]):
 d      -- | as decimal: 130
        -- : 1 + 130 + 0 + 1 = 132
\$\endgroup\$
1
\$\begingroup\$

J, 18 bytes

[:+/"."0".@{."0 1]

Explanation

Takes a string as input

           {."0 1  - take
    "."0           - current char as int items
                 ] - from the argument
         ".        - and convert them to an integer  
[:+/               - add them up

Try it online!

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

Japt, 5 bytes

Takes input as a string.

¬x@¯X

Try it


Explanation

          :Implicit input of integer string U
¬         :Split to an array of characters/digits
  @       :Pass each X through a function
   ¯X     :Slice U from the first to the Xth character
 x        :Reduce by addition
\$\endgroup\$
  • \$\begingroup\$ O_o Either Japt is really golfy or I'm doing Actually wrong \$\endgroup\$ – ASCII-only Feb 24 '18 at 2:30
  • 2
    \$\begingroup\$ @ASCII-only: Japt is a lot more "golfy" than most people realise; we win our fair share of challenges, even beating Charcoal and SOGL in a recent ascii-art challenge. \$\endgroup\$ – Shaggy Feb 24 '18 at 2:58
  • \$\begingroup\$ @Shaggy Sure, but I didn't realize it was Jelly/Actually/05AB1E level golfy \$\endgroup\$ – ASCII-only Feb 24 '18 at 8:05
  • \$\begingroup\$ @ASCII-only: Oh, yeah, it's definitely up there with them, holding it's own nicely :) If you're interested, have a look at our language of the month nom. or drop into the Japt chatroom sometime and we'll give you a tour. \$\endgroup\$ – Shaggy Feb 24 '18 at 21:42
1
\$\begingroup\$

Stax, 6 bytes

ç╫&º±å

Run and debug it online

The corresponding ascii representation of the same program is this.

EZFy(e+

E        get array of digits
 Z       push 0 under array of digits
  F      for each digit, run the rest of the program
   y     input as a string
    (    get start of string for specified number of characters
     e   evaluate substring as integer
      +  add
\$\endgroup\$
0
\$\begingroup\$

Actually, 10 bytes

╝ß⌠≈╛H≈⌡MΣ

Try it online!

Explanation

╝          Push input to register 1
 ß         Push n-th input (0 by default)
        M  Map
  ⌠    ⌡   Function
   ≈       Cast current character of input to int
    ╛      Get value of register 1 (input)
     H     Push input[:current character]
      ≈    Cast to int
         Σ Sum
\$\endgroup\$
0
\$\begingroup\$

JavaScript, 43 bytes

It's well after 3 in the morning, why am I still golfing?!

Takes input as a string.

s=>(g=x=>s[x]?+s.slice(0,s[x])+g(++x):0)(0)

Try it online

\$\endgroup\$
0
\$\begingroup\$

Perl 5, 26 bytes

Includes +1 for p

perl -pE 's%.%/.{0,$&}/;$\+=$&%eg}{' <<< 2315; echo
\$\endgroup\$
0
\$\begingroup\$

K4, 22 bytes

Solution:

+/10/:'(x&#x)#\:x:10\:

Examples:

q)k)+/10/:'(x&#x)#\:x:10\:13214
1468
q)k)+/10/:'(x&#x)#\:x:10\:1301
132
q)k)+/10/:'(x&#x)#\:x:10\:251
278
q)k)+/10/:'(x&#x)#\:x:10\:2315
2571

Explanation:

Break into base-10, take min of each number and the length of list from this. Convert back and sum up.

+/10/:'(x&#x)#\:x:10\: / the solution
                  10\: / to base 10, 123 => 1 2 3
                x:     / save as x
             #\:       / take (#) each left
       (    )          / the left
          #x           / count (#) length of x
        x&             / min of x and the length
  10/:'                / from base 10 each
+/                     / sum up the results
\$\endgroup\$
0
\$\begingroup\$

Java 8, 92 bytes

n->n.chars().map(c->(c-=48)>0?new Integer(n.substring(0,c<n.length()?c:n.length())):0).sum()

Explanation:

Try it online.

n->                                  // Method with String parameter and int return-type
  n.chars()                          //  Loop over the characters
   .map(c->(c-=48)                   //   Convert character to digit
        >0?                          //    And if it's larger than 0
         new Integer(n.substring(0,  //     Take the first `x` digits, where `x` is:
          c<n.length()?              //      If the digit higher than the total a.o. digits
           c                         //       Take the first `c` digits
          :                          //      Else:
           n.length()))              //       Take all digits
         :                           //    Else:
          0)                         //     Take 0
   .sum()                            //   And sum everything
\$\endgroup\$
0
\$\begingroup\$

REXX 118 bytes

pull n                           
l=length(n)                      
a=0                              
j=1                              
do while (j<=l)                  
if substr(n,j,1)==0 then m=0;    
else m=substr(n,1,substr(n,j,1));
a=a+m                            
j=j+1                            
end                              
say a                                 

Try it here
Provide Input value in the STDIN tab.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 66 bytes

lambda n:sum([int(str(n)[:int(i)])if i!='0'else 0for i in str(n)])

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Jelly, 6 bytes

DµḣµVS

Try it online!

Get the Digits of the input, then get the first [each digit] elements of the input (ead), then eVal each sum to make it a number again and Sum.

\$\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.