Sum of integers in string, separated by non-numericals such as 'a' and 'Y'

Create a program which sums all integers found in a string which is set as a variable in the program (thus, the program doesn't have to handle any input). The integer numbers are separated by non-numericals (anything but 0, 1, 2, 3, ..., 9).

Examples:

• e7rde f ,fe 43 jfj 54f4sD = 7+43+54+4=108
• 5 = 5
• 64 545,5445-32JIFk0ddk = 64+545+5445+32+0=6086
• 0ab0 = 0+0 = 0

Extra notes:

• Unicode support is not necessary, but allowed
• -n (where n is an integer) is not counted as a negative n, but as a hyphen followed by n.

The answer may be printed on the screen (but not required).

• Should we print the result too? (You mention no I/O). Feb 8 '11 at 19:43
• @Dogbert - I didn't think about that. Sorry, yes. I will update the post.
– Anto
Feb 8 '11 at 19:45
• Changed it as some people already had answers and didn't want to "hurt" them. I guess I should sleep now, so I will think a bit clearer ;)
– Anto
Feb 8 '11 at 19:49
• Anto: A task where a solution has no observable side-effects isn't very nice, though.
– Joey
Feb 8 '11 at 21:00
• An interesting test case I just ran into would be 5a-3 (my code would skip - if it follows a number immediately, but not if there was a non-number before it). Sep 1 '15 at 11:48

Perl, 15

Input in $_, sum in$c:

s/\d+/$c+=$&/ge

Ruby 1.9, 21 characters

eval a.scan(/\d+/)*?+

To print the solution to stdout, 2 additional characters are required:

p eval a.scan(/\d+/)*?+

And to read from stdin instead of using a predefined variable, another 3 characters have to be used:

p eval gets.scan(/\d+/)*?+

For Ruby 1.8, replace ?+ with "+" to get a working solution in 22 characters.

• The input is supposed to be taken from a variable, not stdin. Also scan is shorter than split. So your solution becomes eval s.scan(/\d+/)*?+ - 21 characters. Feb 8 '11 at 21:37
• @sepp2k: Yeah, didn't read the description correctly. I'm just used to the other golf-tasks, where you usually have to read from stdin and print to stdout. Good point with scan, thanks! Feb 8 '11 at 21:48
• +1, great use of eval and * '+' Feb 8 '11 at 21:55

Ruby - 36 34 chars

s.scan(/\d+/).map(&:to_i).reduce:+

36 chars if you want the result printed.

p s.scan(/\d+/).map(&:to_i).reduce:+

Assumes the input is present as a string in s.

Python (60)

import re;print sum(map(int,filter(len,re.split(r'\D',s))))

JavaScript (ES6), 30

c=0,s.replace(/\d+/g,d=>c+=+d)

Annotated version:

// Store the sum.
c=0,
// Process every number found in the s.
s.replace(/\d+/g,
// Convert the number into an integer.
// Add it to the sum.
d => c += +d
)

With output.

Try it online!

05AB1E (legacy), 5 bytes

.œþOà

Try it online or verify a few more test cases. (Times out for the larger test cases due to the builtin.)

Explanation:

.œ     # Get all partitions of the (implicit) input-string,
# which are all possible ways of dividing the input-strings into substrings
þ    # Only leave the items consisting of digits for each partition
# (in the new version of 05AB1E, an explicit € is required)
O   # Sum each inner list
à  # Pop and push its maximum
# (after which the result is output implicitly)

dc<<<tr -c 0-9 +<<<$sp Try it online! Input in the variable s, output on stdout. Pip, 7 bytes$+a@+XD

Try it online!

Regexes all numbers to a list and sums them.

+1 byte fix from DLosc.

• This fails the third test case because XN includes leading minus signs in the number. You can use +XD instead, for +1 byte. Aug 15 at 21:45
• Are you sure? If the third testcase counted minuses it'd be 6022, not 6086 Aug 16 at 2:43
• XN gives 6022; +XD correctly gives 6086. Aug 16 at 3:23
• ... although, the XN approach would work on this very similar challenge. Aug 16 at 3:26
• ah yes trivial modification time! Aug 16 at 4:13

PHP - 37

Without printing;

<?array_sum(@split("[^0-9]+",cat));

With printing (38):

<?=array_sum(@split("[^0-9]+",cat`));

Perl, 16 chars

s/\d+/$r+=$&/ge;

Takes input in $_, output goes on$r. Last semicolon is superfluous, but it will probably be needed when the program does more things. Add say$r for output. • Oops, didn't see your exact same answer when I posted. Though I counted one character more even without the semicolon. – J B Feb 8 '11 at 21:30 • @J B: I can't count! :P. Actually, I made the mistake of echo'ing a double quoted string to wc -c. Feb 8 '11 at 21:33 R, 30 sum(scan(t=gsub("\\D"," ",x))) Here, x is the name of the variable. Example: > x <- "e7rde f ,fe 43 jfj 54f4sD" > sum(scan(t=gsub("\\D"," ",x))) Read 4 items [1] 108 J - 23 char Not a winner, but we get to see a fairly rare primitive in action. +/".(,_=_"."0 y)}y,:' ' Explained: • _"."0 y - For each character in the input string y, try to read it in as a number. If you can't, use the default value _ (infinity) instead. • ,_= - Check each result for equality to _, and then run the final array of 0s and 1s into a vector. ("."0 always adds one too many dimensions to the result, so we correct for that here.) • y,:' ' - Add a row of spaces beneath the input string. • } - Used as it is here, } is called Item Amend, and it uses the list of 0s and 1s on the left as indices to select the row to draw from in the right argument. So what happens is, for each column in the right side, we take the original character if it could be read in as a number, and otherwise we take the space beneath it. Hence, we cover up any non-numeric characters with spaces. • +/". - Now convert this entire string into an list of numbers, and sum them. Brachylog, 9 bytes {~cịˢ+}ᶠ⌉ Try it online! It's... inefficient... so I've neglected to test the longer cases. It appears to work, though. Takes input through the input variable, which just so happens to be the usual form of input anyhow. ⌉ The output is the largest { }ᶠ possible + sum of ịˢ integers the string representations of which are some elements of ~c a partition of the input. ensures that numbers are maximally matched as well as never negative, since splitting a number up, invalidating a number, or turning it negative will never result in a larger sum. C 96 Thanks to @ceilingcat for some very nice pieces of golfing - now even shorter t;main(i,v)int**v;{for(char*q,*s=v[1];*s;q>s?t+=abs(i),s=q:s++)i=strtol(s,&q,0);printf("%d",t);} Try it online! An earlier 85 byte version that is cheating a bit by hardcoding the string inside the program: t=0;main(i){for(char*q,*s;i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);} To actually use the 85 byte program you need to assign the variable like so: t=0;main(i){for(char*q,*s="text";i=strtol(s,&q,0),*s;q>s?t+=abs(i),s=q:s++);printf("%d",t);} K4, 21 bytes Solution: +/"J"$" "\:.Q.n .Q.n?

Explanation:

Not particularly pleased with this, but it works...

+/"J"$" "\:.Q.n .Q.n? / the solution .Q.n? / lookup right in the string "0123456789" .Q.n / index back into "0123456789" " "\: / split string on whitespace "J"$                / cast to numeric
+/                    / sum up

Extra:

• +/0{.[{(0,. y)+1 10*x};(x;y);(+/x),0]}/ for 39 bytes which is 'nicer' but almost twice the count...

Stax, 8 bytes

µÖ▀o)♫⌐ƒ

Run and debug it

Finds all substrings matching \d+, then eval and sum.

Funky, 38 bytes

s=>{n=0forv ins::gmatch"\\d+"n-=-v[0]}

Explained

s=>{                                 } $# A function taking argument "s" n=0$# Preset n to 0
s::gmatch"\\d+"          $# An iterator function which finds all groups of digits in a string forv in$# Iterate through, setting v to the match
n-=       $# Subtract n by -v[0]$# The negative of the whole match, which implicitely numberfies it.

It assumes that the input is in the variable $a (formally, in a) and stores the answer in the interpreter result. I/O is left as an exercise. APL, 16 bytes {+/⍎b\⍵/⍨b←⍵∊⎕d} ⎕d is a built-in containing the digits (0-9). b is assigned to a vector of 0/1 where 1 is given to the characters that are digits. b is used to compress the given character array and then reused to expand it, which inserts blanks. is APL's eval which converts a string into a vector a integers, in this case. +/ computes the sum. • Equal length, but interesting: +/2⊃⍞⎕VFI⍨⎕AV~⎕D – Adám Jul 20 '16 at 14:46 Swift 3, 78 s.characters.split{!("0"..."9"~=$0)}.flatMap{Int(String($0))}.reduce(0){$0+\$1}

where s is the string