7
\$\begingroup\$

Smallest code to return sum of all characters of an array of C-strings, including null-byte-terminattor of each string in the array.

example in C:

    const char *a[] = { "abc", "bdef", "cee", "deee" };
    size_t n = sumOfAllBytes(a);
    printf("n = %d\n", n); // n = 18

e.g.,

   strlen(a[0]) + 1 + ... + strlen(a[n])

where n is array-size-1, ie, the last elemet in the array, in this case, deee word. Note that n = 4 (starting from 0 as C does)

Each character is an ASCII character in C it's 1 byte-size.

\$\endgroup\$
  • 2
    \$\begingroup\$ How do you define the value of each character? \$\endgroup\$ – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Mar 28 '14 at 18:11
  • 2
    \$\begingroup\$ Do you have to create a complete program, or is it OK to write only a function with an array as parameter? \$\endgroup\$ – ProgramFOX Mar 28 '14 at 18:41
  • 1
    \$\begingroup\$ How do you know how many strings are in the array? Your example doesn't have any sort of length argument or sentinel value to indicate it. \$\endgroup\$ – user2357112 supports Monica Mar 29 '14 at 13:33
  • 1
    \$\begingroup\$ How is this sum of all characters or sumOfAllBytes. Isn't it just a count, rather than a sum? At best sumoflengthsof, but not sum of characters or bytes. \$\endgroup\$ – Bill Woodger Mar 31 '14 at 8:39
  • 1
    \$\begingroup\$ You say sum of bytes, sum of characters. You are asking for neither of those things. It is a count of characters, or bytes, including delimiters, or a sum of the lengths, including delimiters. It is not the sum of bytes/characters. This is computers. \$\endgroup\$ – Bill Woodger Mar 31 '14 at 22:25

26 Answers 26

3
\$\begingroup\$

GolfScript [4 bytes]

n*,)

There are no functions in GolfScript, so you should use a standard input instead:

["abc" "bdef" "cee" "deee"]
n*,)

>>> 18

DEMO: http://golfscript.apphb.com/?c=WyJhYmMiICJiZGVmIiAiY2VlIiAiZGVlZSJdCgpuKiwp

\$\endgroup\$
  • \$\begingroup\$ I need to learn GolfScript. :) \$\endgroup\$ – Jack Jun 21 '14 at 19:12
4
\$\begingroup\$

Haskell, 21 19 bytes

succ.length.unwords

Edit: Removed two bytes thanks to ais523!

\$\endgroup\$
  • 2
    \$\begingroup\$ Hi, and welcome to PPCG! We allow submitting anonymous functions here; you don't need to name them. As such, you could remove the s= to save two bytes, as the submission evaluates to an expression of function type as it is. (I'm also curious as to whether there's a way to golf down the succ into something shorter, but all the possibilities I've thought of, such as (+1), are the same number of bytes or longer.) Incidentally, you can use # or ## at the start of a line for heading-bold (# is larger); that's the formatting most people use for their answers. \$\endgroup\$ – user62131 Jun 12 '17 at 22:18
  • 1
    \$\begingroup\$ It also took me some time to figure out that this answer was correct. Often it's a good idea to include a link to an online interpreter that shows the program working. Here's one for your program; you could edit it into your answer. \$\endgroup\$ – user62131 Jun 12 '17 at 22:24
  • 1
    \$\begingroup\$ By the way, don't worry about the downvote: it was caused by a bug in the Stack Exchange software, not made by an actual user. \$\endgroup\$ – user62131 Jun 12 '17 at 23:28
  • \$\begingroup\$ You can use unlines instead of unwords and drop the succ, because unlines adds a final newline: Try it online! \$\endgroup\$ – Laikoni Jun 13 '17 at 6:59
2
\$\begingroup\$

bash+coreutils - function body 10 bytes

sumOfAllBytes()(wc -c<<<$@)

Call as follows:

$ a=("abc" "bdef" "cee" "deee")
$ sumOfAllBytes ${a[@]}
18
$ 
\$\endgroup\$
2
\$\begingroup\$

Mathematica 31 29 bytes

-2 bytes thanks to numbermaniac

StringLength[""<>#]+Length@#&

Example

StringLength[""<>#]+Length@#&@{ "abc", "bdef", "cee", "deee" }

18

\$\endgroup\$
  • \$\begingroup\$ I don't think you need to assign the function name to a variable to be a valid answer, so you could save 2 bytes there. \$\endgroup\$ – numbermaniac Jun 13 '17 at 7:40
  • \$\begingroup\$ @numermaniac, you are right. Thanks. \$\endgroup\$ – DavidC Jun 13 '17 at 12:02
1
\$\begingroup\$

Rebol (body: 18 chars, function: 30 chars)

1 + length? form x

Usage example in Rebol console:

>> f: func[x][1 + length? form x]

>> f ["abc" "bdef" "cee" "deee"]
== 18
\$\endgroup\$
1
\$\begingroup\$

Perl, function body: 15 bytes

sub sumOfAllBytes{!!@_+length"@_"}

Function sumOfAllBytes returns the sum of the string lengths including a "virtual" terminator byte. Perl does not have the concept of terminating a string with a null byte.

A variant without a "terminating byte":

sub sumOfAllBytes{$"=$;@_+length"@_"}

Byte count: The body of the functions are 15 or 17 bytes (with or without terminator). 7 bytes must be added, if the whole function with one-byte name should be counted.

Test with degolfed version:

sub sumOfAllBytes {
    # the argument(s) are put into array @_ by Perl
    !!@_ +       # short for: @_ ? 1 : 0
                 # (if the array is empty nothing should be added)
    length "@_"  # The array elements are interpolated into the double-
                 # quoted string; the elements are separated by a space ($").
    # without explicit return statement, the value of the last
    # statement is returned.
}

@a = qw[abc bdef cee deee];
print sumOfAllBytes(@a), "\n"; # prints 18
\$\endgroup\$
1
\$\begingroup\$

C, 78 minus declaration of a[]

Assumes 64 bit target and a[] containing at least one string.

char *a[]={"abc","bdef","cee","deee"};
f(int i){return strlen(a[i])+1+(i?f(i-1):0);}
main(){return f(sizeof(a)/8-1);}

To see the result, invoke thusly:

$ ./whatever || echo $?
\$\endgroup\$
1
\$\begingroup\$

c preprocessor macros, 94 chars

The example in the question is not doable in c as a regular function as the function would have no idea the size of the array if just a pointer to the array is passed in. But we can do this as a couple of preprocessor macros:

#define c(s) sizeof(s)/sizeof(s[0])-1
#define sumOfAllBytes(s) s[c(s)]-s[0]+strlen(s[c(s)])+1

We assume that the array is declared, defined and initialised as in the question. That way the strings should be laid out sequentially in memory. We can then subtract the address of the first element from the last element and add the strlen() of the last element. No need to loop over all elements and strlen().

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

Haskell 24

s=sum.(map$(+1).length)

Usage, in ghci:

ghci> s ["abc", "bdef", "cee", "deee"]
18
\$\endgroup\$
1
\$\begingroup\$

Java: 56 characters (body) 74 characters (full method)

Hey, this is as good as it gets in Java!

This is the method:

int z(String[]a){int s=0;for(String b:a)s+=b.length();return s+a.length;}

The main code is just 56 characters (witout spaces and comments):

int s=0;            // The sum variable.
for(String b:a)     // The 'for each' loop is handy
    s+=b.length();  // Adding the length of each String
return s+a.length;  // Adding the length of the array

Calling this function:

int answer = z(new String[]{ "abc", "bdef", "cee", "deee" }); // Stores 18
\$\endgroup\$
  • 1
    \$\begingroup\$ I know it's been over three years, but you can golf two bytes by changing int s=0; to int s=a.length; and removing the +a.length in the return. \$\endgroup\$ – Kevin Cruijssen Jun 13 '17 at 8:25
1
\$\begingroup\$

05AB1E, 5 bytes (non-competing)

JgIg+

Try it online!

-1 thanks to @Datboi

\$\endgroup\$
  • \$\begingroup\$ JgIg+ should work as well \$\endgroup\$ – Datboi Jun 13 '17 at 14:19
  • \$\begingroup\$ I have no idea how that works. I is supposed to read the current input as a String, and if the first input was consumed by J, how is it still reading the input, as an array no less? Unless they changed what I does... Weird... \$\endgroup\$ – Magic Octopus Urn Jun 13 '17 at 15:54
  • \$\begingroup\$ As far as I know it will read the input as an array if it is in the form of [item1, item2, ...]. To answer your second question: If there are no items on the stack nor in the input I will use a copy of the bottom input to pop. Jg¹g+ should also work though \$\endgroup\$ – Datboi Jun 13 '17 at 16:35
  • \$\begingroup\$ @Datboi yeah, I think they changed it since a year ago. A year ago I don't think that would've worked. Then again this is a 3 year old question, so this answer is non-competing anyway; just noticed that too lol. \$\endgroup\$ – Magic Octopus Urn Jun 13 '17 at 16:37
0
\$\begingroup\$

C [body: 48 chars, function: 107 chars]

int f(const char** r, const char* c, const char** e) { 
  return r-e?1+(*c?f(r,c+1,e):f(r+1,*(r+1),e)):0; 
}

Ugly piece of code. Just trying to do it without loops by using recursion.

Call it this way:

    const char *a[] = { "abc", "bdef", "cee", "deee" };
    size_t n = f(a,*a,a+4);
    printf("n = %zu\n", n);

No warnings and result is OK:

$ gcc koe.c -Wall -Wextra -o koe
$ ./koe
n = 18
\$\endgroup\$
0
\$\begingroup\$

C - Loop:64, Recursion:56 (-18 for function body overhead)

Loop

s(char*a[],int n){int r=0;for(;n;)r+=strlen(a[--n])+1;return r;}

Recursion

r(char*a[],int n){return n?strlen(a[0])+1+r(a+1,n-1):0;}
\$\endgroup\$
0
\$\begingroup\$

PHP 5.3 - 60

array_sum(array_map(function($v){return strlen($v)+1;},$a));

Where $a is the array.

\$\endgroup\$
  • \$\begingroup\$ <?=strlen(join(_,$_GET))+1; should do the same \$\endgroup\$ – Jörg Hülsermann Jun 12 '17 at 21:40
0
\$\begingroup\$

Fortran 90+ - 75 total, 23 for function alone

Unfortunately, Fortran doesn't allow for implicit typing of character strings, but we can abuse F77+F90 for golfing purposes. The whole program would be:

character*4::c(4)=["abc","bdef","cee","deee"];print*,sum(len_trim(c)+1);end

The function alone, written using a statement function would be

k(s)=sum(len_trim(s)+1)

which would be called using print*,k(c).

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

in C# 34 Excluding "string [] a=new [] { "abc", "bdef", "cee", "deee" };"

   string [] a=new [] { "abc", "bdef", "cee", "deee" };
                var i=string.Join(" ",a).Length+1;
sol:2  
var j =  string.Concat(a).Length + a.Length;
\$\endgroup\$
0
\$\begingroup\$

Python - 55 42 38

def s(v):print sum(1+len(x)for x in v)
\$\endgroup\$
0
\$\begingroup\$

JavaScript - 42 characters without declaration

function s(x){return x.join(" ").length+1}

Usage:

a=["abc","bdef","cee","deee"];console.log(s(a));
\$\endgroup\$
0
\$\begingroup\$

D - 58 54 bytes

int x(T)(T t){return reduce!"a+b.length"(t.length,t);}

This requires std.algorithm, so add the characters necessary for making that import if you want to.

Example of usage:

import std.stdio,std.algorithm;

int x(T)(T t){return reduce!"a+b.length"(t.length,t);}

void main(){
    writeln(x!(string[])(["abc","bdef","cee","deee"]));
}
\$\endgroup\$
0
\$\begingroup\$

C#, 52 including variable declaration

int c=0;for(int i=0;i<a.Length;i++)c+=1+a[i].Length;

Uncompressed version for ease of reading:

int count = 0;
for (int i = 0; i < a.Length; i++)
    count += 1 + a[i].Length;
\$\endgroup\$
0
\$\begingroup\$

APL 6

+/1+⍴¨a

where

a←"abc" "bdef" "cee" "deee"

yields

      +/1+⍴¨a
 18

Read as "Sum over 1 plus size of each element in a"

\$\endgroup\$
  • \$\begingroup\$ Isn't that 6? +/1+⍴¨ Anyway, you can make it 4: ⍴⊢,∊ \$\endgroup\$ – Adám Jun 12 '17 at 20:16
0
\$\begingroup\$

q/kdb+, 14 bytes

Solution:

sum 1+(#:)each

Example:

q)sum 1+(#:)each("abc";"bdef";"cee";"deee")
18

Explanation:

Evaluated right-to-left, thus:

// count (#:) length of each item in the list
q)(#:)each("abc";"bdef";"cee";"deee")
3 4 3 4
// add one to each item
q)1+ 3 4 3 4
4 5 4 5
// sum up the items
q)sum 4 5 4 5
18
\$\endgroup\$
0
\$\begingroup\$

JavaScript - 20 17 Characters

s.join().length+1

Assumes that the array of strings is in variable 's' and outputs the answer to the console.

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

Clojure, 32 bytes

#(apply +(map(comp inc count)%))

Composition FTW. Aww it is the same length as #(apply +(count %)(map count %)).

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

F#, 56 bytes

Still practicing with F#...

let f a=(a|>Seq.map String.length|>Seq.sum)+Seq.length a

Invoke with:

[<EntryPoint>]
let main argv = 
    let sum = [| "abc"; "bdef"; "cee"; "deee" |] |> f
    printfn "%A" sum
    0
\$\endgroup\$
  • \$\begingroup\$ Seq.sumBy(fun s->s.Length+1) \$\endgroup\$ – Asik Apr 25 '18 at 19:55
0
\$\begingroup\$

Jelly (nc), 3 bytes

KL‘

Try it online!

I believe Jelly is (a lot) newer than the challenge, so I've marked this as non-competing.

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