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).

Shortest answer (in characters) win.

  • Should we print the result too? (You mention no I/O). – Dogbert 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
  • 2
    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). – Martin Ender Sep 1 '15 at 11:48

23 Answers 23

up vote 10 down vote accepted

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. – sepp2k 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! – Ventero Feb 8 '11 at 21:48
  • +1, great use of eval and * '+' – Dogbert Feb 8 '11 at 21:55

Python (60)

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

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.

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
)

Windows PowerShell, 23 25 29 31

With output.

$x-replace'\D','+0'|iex

In fact, without output is exactly the same, you'd just pipe it somewhere else where it's needed.

J - 40 38 characters

Lazy version. Requires the string library.

+/".(,' ',.~a.-.'0123456789')charsub y
  • Supports Unicode. Supports encoding, come to think of it! – MPelletier Feb 8 '11 at 22:03

Java

out of the contest ;)

public static long sum(String s) {
    long sum = 0;
    String p = "";
    char[] ch = s.toCharArray();
    for (int i = 0; i < ch.length; i++) {
        boolean c = false;
        if (Character.isDigit(ch[i])) {
            if (i + 1 < ch.length) {
                if (Character.isDigit(ch[i + 1])) {
                    p += ch[i];
                    c = true;
                }
            }
            if (!c) {
                p += ch[i];
                sum += Integer.valueOf(p);
                p = "";
                c = false;
            }
        }
    }
    return sum;
}

JavaScript [30 bytes]

eval(s.match(/\d+/g).join('+'))

Labyrinth, 29 21 bytes

(Disclaimer: Labyrinth is newer than this challenge.)

Also, Labyrinth doesn't have variables, so I went with a normal input/output program.

)_"+`
( "?"
";;,;;(!@

This was fairly simple because of the way Labyrinth's input commands work. ? tries to read a signed integer from STDIN and stops at the first non-digit. If it can't read an integer (because the next character is a - not followed by a digit, or any other non-digit, or we've reached EOF), it will return 0 instead. , on the other hand reads any subsequent byte and pushes the byte value. If this one is called at EOF it will return -1 instead.

So here's some pseudocode for the solution:

running total = 0
while(true)
  while(true)
    try reading a non-zero integer N with ?
    if(N < 0)
      running total -= N
    else if(N > 0)
      running total += N
    else
      break
  // We've either read a zero or hit a something that isn't a number
  try reading a character with ,
  if(that returned -1)
    break
print running total

Dealing with negative numbers correctly complicates this solution quite a lot. If it weren't for those, I'd have this 8-byte solution:

?+
;,;!@

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. – ninjalj Feb 8 '11 at 21:33

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.

gs2, 4 bytes

W#Θd

Encoded in CP437; the third byte is E9.

W reads all numbers /-?\d+/ from a string, maps absolute value, d sums.

(gs2, too, is newer than this challenge, but its read-nums command is a total coincidence.)

Smalltalk (Smalltalk/X) (51 chars)

using the regex pakage:

(s regex:'\d+' matchesCollect:[:n|n asNumber])sum

w.o. regex:

((s asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:c|c isDigit not]) map:#asNumber)sum

input in s

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

Javascript - 43 chars

I know it's long, but there was no JS solution so :)

c=0
a=a.split(/[^\d]/g)
for(i in a)c+=+a[i]

ais the string. c contains answer.

Tcl, 30

expr [regsub -all \\D+ $a.0 +]

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.

C99 (with warnings) 85

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 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);}

If you are using gcc you need to compile it as C99 like so:

gcc -std=c99 x.c

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

Perl - 24 chars

warn eval join'+',/\d+/g

Input is in $_

Actually, 14 bytes (non-competing)

9u▀8╙r♂┌-@s♂≈Σ

Try it online!

This submission is non-competing because Actually is a fair bit newer than this challenge.

This program supports the CP437 code page for input.

Explanation:

9u▀8╙r♂┌-@s♂≈Σ
9u▀             base 10 digits (0-9)
   8╙r♂┌        all characters in CP437 (map(ord_cp437, range(2**8)))
        -       set difference
         @s     split input on any value in the resulting list
           ♂≈Σ  convert to ints and sum

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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