40
\$\begingroup\$

Using your language of choice, write a function that takes a variable number of arguments and returns the number of arguments it was called with.

Specifics:

  • Your language needs to support variadic argument functions: something callable that takes an arbitrary number of arguments and returns a value.
  • Parameters must be able to be passed individually. This means that passing an array would only count for one parameter. You can use an "all passed arguments" array if your language supports it; the restriction is on how the function is called.
  • Code that calls this function must not be required to pass the number of arguments in its source. If a compiler inserts the number of arguments as part of a calling convention, that is allowed.
  • The arguments can be of any type you want. You can support only a single type (e.g. only supporting int is still valid), arbitrary types (any type of argument is allowed), or any combination of argument types (e.g. first arg is int, rest are strings).
  • Your function may have a maximum number of arguments (especially since resources are finite), but must support at least 2 arguments.

Samples:

  • f() returns 0
  • f(1) or f("a") returns 1
  • f([1, 2, 3]) returns 1 as it is passed an array, not 3 arguments
  • f(1, 10) or f(1, "a") returns 2

As this is code-golf, the winning solution is the one that uses the fewest number of bytes.

\$\endgroup\$
21
  • 6
    \$\begingroup\$ It's not entirely clear (objectively) what is a "function", "return value" or "variadic arguments". For example, would Dodos function be considered as monadic or variadic? \$\endgroup\$
    – DELETE_ME
    Apr 10, 2018 at 5:06
  • 27
    \$\begingroup\$ @user202729 If your language doesn't support functions, use another language. It's not a requirement that all languages can compete, part of code golfing is finding the right tool for the job. \$\endgroup\$
    – Sanchises
    Apr 10, 2018 at 7:46
  • 5
    \$\begingroup\$ @user202729 I have no problems with the occasional challenge aimed at traditional/high-level languages, just as we have the occasional challenge that is only possible in unusual languages. \$\endgroup\$
    – Sanchises
    Apr 10, 2018 at 13:58
  • 7
    \$\begingroup\$ didn't know we had to solve the halting problem for language characteristics to have a clear challenge.... \$\endgroup\$ Apr 11, 2018 at 2:06
  • 6
    \$\begingroup\$ If your language doesn't have the concept of arguments / calling convention then it doesn't fit the criteria of supporting arbitrary numbers of arguments. \$\endgroup\$ Apr 11, 2018 at 8:23

81 Answers 81

1
\$\begingroup\$

JavaScript, 35 bytes

f=
function(){return arguments.length}

console.log(f(2,5,4))

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

Cauliflower, 16 bytes

(\((@a))(len@a))

Try it online!

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

Actually, 2 bytes

` 

Try it online!

Note: this is a grave and a space

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

Japt, 2 bytes

Nl

I suspect the answer will be similar in many golfing languages, take all of the inputs as an array and return its length.

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Beat me to it. If I haven't done so already: Welcome to Japt! :) \$\endgroup\$
    – Shaggy
    Apr 10, 2018 at 8:10
1
\$\begingroup\$

Kotlin, 26 bytes

Defines function a with a vararg parameter x: Any. Thus, the arguments passed can be anything but null.

fun a(vararg x:Any)=x.size

Try It Online!

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

Clojure, 11 bytes

#(count %&)

Try it online!

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

Lua, 11 bytes

print(#arg)

Try it online: 1 input | 3 inputs

\$\endgroup\$
1
  • \$\begingroup\$ Note that as of Lua 5.1, arg only refers to the parameters passed when evaluating the script and does not work when defining a function. \$\endgroup\$ Apr 12, 2018 at 6:26
1
\$\begingroup\$

Julia 0.6, 16 bytes

f(x...)=endof(x)

Try it online!

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

Stax, 4 bytes

{L%}

Run and debug it at staxlang.xyz!

Simple. Listifies the entire stack and all input, and returns the resulting length. No thought went into this answer.

Works without the closing brace, but I think that that makes it an incomplete "function" (block).

\$\endgroup\$
3
  • \$\begingroup\$ I don't think I realized that it would be a legal program without the closing brace. Interesting! \$\endgroup\$
    – recursive
    Apr 10, 2018 at 17:37
  • \$\begingroup\$ @recursive I was as surprised as you. Though interesting, this sadly seems useless at this point (as far as I can tell). \$\endgroup\$ Apr 10, 2018 at 19:03
  • \$\begingroup\$ Yes, it doesn't seem useful for general golfing, which is probably why I didn't make it do anything in particular. An unterminated block is necessarily at the end of the program, so there's nothing to do but execute it. You could achieve the same result by "inlining" the contents of the block. Maybe some day I could make it do something else. Hm... \$\endgroup\$
    – recursive
    Apr 10, 2018 at 19:05
1
\$\begingroup\$

Vim, 10 bytes

:ec argc()

Where "an argument" is a filename for Vim to edit. Hopefully this counts.

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

Avail, 32 characters.

Method"f(«_‡,»)"is[t:tuple||t|];

Avail's a little different. Any particular function has fixed arity, so the nearest approximation is a multi-method taking a polyadic argument (shown with spaces)...

Method "f(«_‡,»)" is [t : tuple | |t|];
Assert f(10,20,30) = 3;

The guillemets say expect multiple arguments (the underscore), separated by commas (the comma after the double-dagger). The "f", "(", and ")" (and ",") are actual keywords of this method. The guillemet mechanism is supported by the compiler, which assembles instructions at call sites (like the Assert statement on the second line) to assemble arguments into a tuple, mostly similar to Java. However, Avail also supports multiple repeated arguments, nested repetitions, strong heterogeneously typed arguments, and a ton more.

In the general spirit of code golf,

Method "g(«x‡,»#)" is [w : whole number | w];
Assert g(x,x,x) = 3;

The # after the close-guillemet arranges to pass the number of repetitions of the preceding group, rather than the actual tuple. However, it's pointless to throw away actual arguments, so they're forbidden in such a group. Only constant tokens are allowed, namely "x" in this case, as reflected in the example assertion.

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to PPCG! Since this is code golf, could you include the byte count of the code that is necessary to define f (ideally with unnecessary whitespace removed, if any of it is unnecessary). A link to an implementation and/or specification of Avail would be great too. :) \$\endgroup\$ Apr 10, 2018 at 19:29
  • \$\begingroup\$ Updated. Thanks for the tip! \$\endgroup\$ Apr 10, 2018 at 20:26
  • \$\begingroup\$ There's a summary of the message pattern language (including the «p1‡,p2» format) in the quick start, and the |_| size method is documented in the stacks here. \$\endgroup\$
    – tdhsmith
    Apr 10, 2018 at 21:03
1
\$\begingroup\$

Pyth, 10 bytes

D[$*b$)Rlb

Try it online!

Pyth doesn't really support defining variadic functions, but it does allow embedding Python code directly into the source, and Python allows variadic functions. We can get away with just using two bytes of Python code: *b, which makes b a variadic argument, containing the list of arguments passed in. We redefine the function [, which the Pyth parser understands to be a variadic function, and then we simply return the length of b.

Note that this can be run on TIO but not the standard Pyth executor at http://pyth.herokuapp.com/, due to sandboxing limitations.

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

AutoHotkey, 33 bytes

f(p*){
n+=p.MaxIndex()
return n
}

The asterisk * defines the parameter p as a variadic parameter.
MaxIndex() returns the highest numeric index which, in this case, is the parameter count.
By starting with nothing and adding the MaxIndex, you get a 0 for empty calls.

Here's an example of it in a full program:

MsgBox % f()
MsgBox % f(1)
MsgBox % f([1, 2, 3])
MsgBox % f(1, 10)
MsgBox % f(1, "a")

Exit

f(p*){
n+=p.MaxIndex()
return n
}

The returns as shown in the message box are (in order) 0,1,1,2,2.


AutoHotkey, 8 bytes

If it is allowable to write an entire program that returns the number of parameters passed to it, the result is much shorter:

Send %0%
\$\endgroup\$
4
  • \$\begingroup\$ I don't know this language, but won't something like return p.MaxIndex() work? \$\endgroup\$ Apr 12, 2018 at 18:06
  • \$\begingroup\$ @ØrjanJohansen Unfortunately, that would return an empty value when no parameters are passed instead of the desired value 0. \$\endgroup\$ Apr 12, 2018 at 18:09
  • \$\begingroup\$ Hm. What about return 0+p.MaxIndex()? \$\endgroup\$ Apr 12, 2018 at 18:13
  • \$\begingroup\$ @ØrjanJohansen Also an empty value. AHK is pretty finnicky about doing math (or any other functions) inside of another function. It's not a very good golfing language. \$\endgroup\$ Apr 12, 2018 at 18:16
1
\$\begingroup\$

Röda, 15 bytes

main a...{[#a]}

Try it online!

a... indicates that the program takes in a variable number of arguments

[ ] prints the following

  • #a the length of variable a
\$\endgroup\$
1
\$\begingroup\$

x86-64 machine code, 5 bytes (program for Linux, exit status = ret value)

ia32 (i386) machine code, 4 bytes

This program does sys_exit(argc).

It works for the x86-64 System V ABI, where the stack on process entry has argc followed by argv[0], argv[1], ... NULL, envp[0], ..., NULL. (Or the i386 SysV ABI, where the stack layout is the same, but in 4-byte elements).

nasm -felf64 -l /dev/stdout arg-count.asm listing output:

 1                                  global _start
 2                                  _start:
 3 00000000 5F                          pop rdi
 4 00000001 B03C                        mov al, 60     ; __NR_exit
 5 00000003 0F05                        syscall

Most registers (including rax) are zeroed by the kernel on entry to user-space. To we can set rax=60 with just a mov al in a static executable where no dynamic linker code ran first.

Assemble + link into a static executable with
yasm -felf64 arg-count.asm && ld -o arg-count arg-count.o


   32-bit version: nasm -felf32 -l /dev/stdout arg-count.asm 
 1                                  global _start
 2                                  _start:
 3 00000000 5B                          pop ebx
 4 00000001 40                          inc eax       ; __NR_exit = 1
 5 00000002 CD80                        int 0x80

yasm -felf32 arg-count32.asm &&
ld -melf_i386 -o arg-count32 arg-count32.o

32-bit __NR_exit is 1, so the constant only takes a 1-byte inc (the kernel still zeros registers).


Note that argc includes the first arg passed by the shell which by convention is the name of the executable, but doesn't have to be. execve doesn't care if you exec a process with argv[0] being something other than the executable filename. It's a real arg, and some programs actually use it to figure out how they were invoked (useful for multiple hardlinks to one executable with different behaviours, like busybox can be ls or mv depending on argv[0])

$ ./arg-count ; echo $?     # by convention, program name is passed as a first arg
1
$ ./arg-count a b c d; echo $?
5
$ ./arg-count {a..z} ; echo $?
27
$ ./arg-count $(seq 100); echo $?
101
$ ./empty-args ./arg-count ; echo $?     # runs with argc=0 / argv[0]=NULL
0

(empty-args is a wrapper program that calls execve(argv[1], {NULL}, {NULL}). It is possible to "call" the program with an empty argument list, just not from bash directly.)

Note that the echo $? is just how you can see the exit status printed to the screen. It's always returned to the shell by this program, whether you print it or not. The submission is the program's machine code, not the way I run it from the shell.

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

05AB1E, 2 bytes

|g

Try it online.

Explanation:

|     # Take all new-line separated inputs as a single list
 g    # Take the length of this list
\$\endgroup\$
1
\$\begingroup\$

Pyth, 9 bytes

D[$*N$)lN

Try it online!

Variadic functions cannot be defined in pure Pyth, but using the raw Python override $$, it's easy. This translates to the Python program:

def list(*N):
    print(len(N))

Where [ is the function defined.

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

Spice, 23 bytes

;a;return@LEN a return;

Un-golfed explanantion

Spice has no concept of functions - the closest would be a module which are called with the format:

LOD .\module.spice (^)input result

Where the result is set to the final value of the variable return in the module. The optional ^ character passes the input as the given value rather than flattening the array across all variables in the module. So in this case we can require ^ and:

;a;return@     - declare vars
LEN a return;  - Get length of our input, a, and store in result
\$\endgroup\$
1
\$\begingroup\$

Flurry, 2 bytes

[]

Run example

$ ./flurry -nin -c "[]" 4 7 2 5 3
5

The arguments are pushed to the stack before running the code, and [] nilad returns the stack height. Flurry can output via return value (ignoring the stack), so we don't need to do anything about the stack.

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

Vyxal, 7 bytes

@f:*|!;

Try it Online!

Note the last number before the input called is the no. of arguments.

shoutout to @lyxal for helping me!

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

Julia 1.0, 17 bytes

f(x...)=length(x)

Try it online!

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

Ruby, 12 bytes

Nothing exciting here. The splat operator (*) gathers all of the arguments into an array.

->*a{a.size}

Attempt This Online!

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

Go, 31 bytes

func(a...any)int{return len(a)}

Attempt This Online!

Same length as this Go answer and 2 bytes longer than this Go answer.

Returns a value instead of printing.

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

tinylisp, 27 bytes

(load library
(q(A(length A

Try it online!

Explanation

(q (A (expr))) creates a variadic anonymous function that binds its arglist to A and evaluates (expr). Then we just use the length function from the library to return the length of A.


Non-library solution, 33 bytes:

(d F(q(A(i A(a(v(c(q F)(t A)))1)0

Try it online!

(d F                                )  ; Define F as
    (q(A                          ))   ; a variadic function:
        (i A                     )     ; If the arglist is not empty:
                       (t A)           ;  Tail of arglist
                (c(q F)     )          ;  Cons the symbol F to the front
              (v             )         ;  Evaluate (calling the function again)
            (a                1)       ;  Add 1 to the result
                                0      ; Otherwise, return 0

This approach evaluates some of the arguments multiple times and may generate lots of warning messages; however, I believe it always ultimately returns the correct answer.

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

Attache, 5 bytes

{#__}

Try it online!

This is an anonymous lambda. __ simply represents the arguments passed to it, and # calculates the length.

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

CJam, 4 bytes

{],}

This defines a code block (CJam's analogous construct to a function) that takes all the stack contents as inputs.

Try it online!

Explanation

{  }    e# Define block
 ]      e# Concatenate all stack into a list
  ,     e# Length
\$\endgroup\$
0
\$\begingroup\$

Go, 31 bytes

func a(b ...int){print(len(b))}

Only works with integers to save space.

Try it here

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

Tcl, 27 bytes

proc F args {llength $args}

Try it online!

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

Jstx, 3 bytes

s£O

Try it online!

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

Swift, 37 bytes

func r(s:Any...)->Int{return s.count}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ As of Swift 5.1, you can remove the word return for -7. \$\endgroup\$
    – Bbrk24
    Apr 22, 2023 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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