33
\$\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\$
  • 4
    \$\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\$ – user202729 Apr 10 '18 at 5:06
  • 24
    \$\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 '18 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 '18 at 13:58
  • 6
    \$\begingroup\$ didn't know we had to solve the halting problem for language characteristics to have a clear challenge.... \$\endgroup\$ – Conor O'Brien Apr 11 '18 at 2:06
  • 5
    \$\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\$ – Glenn Smith Apr 11 '18 at 8:23

66 Answers 66

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
    \$\begingroup\$ Beat me to it. If I haven't done so already: Welcome to Japt! :) \$\endgroup\$ – Shaggy Apr 10 '18 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\$
  • \$\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\$ – Lucien Greathouse Apr 12 '18 at 6:26
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\$
  • \$\begingroup\$ I don't think I realized that it would be a legal program without the closing brace. Interesting! \$\endgroup\$ – recursive Apr 10 '18 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\$ – Khuldraeseth na'Barya Apr 10 '18 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 '18 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\$
  • \$\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\$ – Martin Ender Apr 10 '18 at 19:29
  • \$\begingroup\$ Updated. Thanks for the tip! \$\endgroup\$ – Mark van Gulik Apr 10 '18 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 '18 at 21:03
1
\$\begingroup\$

PowerShell 3, 25 bytes

function a(){$args.Count}

Usage:

a 1 2 ...

Console output for "a 1 2 3"

PS: C:\> a 1 2 3
3

Pretty self explanatory. Powershell stores all unspecified args in the $args list, so we just grab a count of it. Since the language implicitly writes values to the console, the act of finding the count will print to the console without needing a Write-Host or Write-Output.

Edit: Mistyped; should have been 25 bytes (typed 35).

\$\endgroup\$
  • 1
    \$\begingroup\$ You can use filter instead of function. Or just raw scriptblock: .{$args.Count} 1 2 3 4 5 \$\endgroup\$ – beatcracker Apr 10 '18 at 18:56
  • \$\begingroup\$ Good idea. I chose "function" to fulfill the challenge text: Using your language of choice, write a function that takes a variable number of arguments... I guess it depends on how loose the definition of "function" is in this case. \$\endgroup\$ – Arkitekt Apr 10 '18 at 20:26
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\$
  • \$\begingroup\$ I don't know this language, but won't something like return p.MaxIndex() work? \$\endgroup\$ – Ørjan Johansen Apr 12 '18 at 18:06
  • \$\begingroup\$ @ØrjanJohansen Unfortunately, that would return an empty value when no parameters are passed instead of the desired value 0. \$\endgroup\$ – Engineer Toast Apr 12 '18 at 18:09
  • \$\begingroup\$ Hm. What about return 0+p.MaxIndex()? \$\endgroup\$ – Ørjan Johansen Apr 12 '18 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\$ – Engineer Toast Apr 12 '18 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\$

Go, 44 30 28 bytes

-2 bytes thanks to BMO

My first code golf attempt.

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

Try it online (outputs to Debug-window instead of STDOUT).

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to the site! I've edited your post to match the general answer format we use here. Is it possible for you to edit in a link to somewhere where others can test your code, such as Try It Online! \$\endgroup\$ – caird coinheringaahing Apr 10 '18 at 12:15
  • \$\begingroup\$ added a link to a modified workign example, sadly go only runs main packages \$\endgroup\$ – Pizza lord Apr 10 '18 at 12:26
  • \$\begingroup\$ Welcome to PPCG! I noticed you had your TIO-link in your header. So I've put it below it, and fixed the header-link. Enjoy your stay! \$\endgroup\$ – Kevin Cruijssen Apr 10 '18 at 13:49
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\$

Julia 0.6, 16 bytes

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

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\$
0
\$\begingroup\$

SimpleTemplate, 23 bytes

In this language, all functions have some special variables.

Luckly, one of them is argc, which contains the number of arguments passed to the program or function.

{@fna}{@returnargc}{@/}

This could be written as {@fna}{@returnargc} if it was the last thing in the file.

Alternativelly, running {@returnargc} by itself gives you back the number of arguments passed to the program itself.


Ungolfed:

{@fn a}
    {@return argc}
{@/}

All whitespace present here is optional.


Example: count the arguments passed to the function

{@fna}{@returnargc}{@/}

{@call a into b 1, 2, 3, 4, 5, 6}

{@echo b}

How to run:

  1. Get the code from https://github.com/ismael-miguel/SimpleTemplate
  2. Run the following code:

    <?php
        include 'SimpleTemplate.php';
    
        $template = new SimpleTemplate('<code>');
    
        $template->render();
    
  3. Done!

(Shamelessly lifted from Print a word clock and adapted for this challenge)

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

REXX, 12 bytes

return arg()

arg without arguments returns the number of arguments.

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

Swift, 25 characters

func f(a:Any...){a.count}

return is implicit in a trivial function body like this.

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

Wolfram Language (Mathematica), 9 bytes

Length@*f

Try it online!

Composition of the Length function, which returns the number of arguments of an expression, and the undefined function f.

\$\endgroup\$
0
\$\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\$
0
\$\begingroup\$

Scheme, 16 bytes

(λ a(length a))

Or defining a named function (25 bytes):

(define(f . a)(length a))
\$\endgroup\$
0
\$\begingroup\$

Yabasic, 17 bytes

An anonymous function that takes input as discrete arguments and outputs to the console.

?peek("argument")

Try it online!

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

Brainfuck, 27

>>,[>,]<[[-]<[<]<+>>[>]<].

Try it online!

"arguments" are single characters. output is in ASCII (eg 32 args outputs a space). In order to see output normally, add this thing that I stole from esolang wiki (204 bytes)

>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->++++++++<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]<

Explanation

>> padding
,[>,] input all
<[ for each
  [-] delete
  <[<]< go back to beginning
  + add one
  >>[>] go to the end
<] go back
<. print
\$\endgroup\$
0
\$\begingroup\$

Lua, 30 bytes

function f(...)return#{...}end

Try it online!

Explanation: ... is used to pass variadic arguments, {...} creates a new table and expands the argument list into that table, and # is the length operator (for arrays, returns number of elements).

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

Funky, 10 bytes

(...a)=>#a

Funky does this pretty well. I first tried @#arguments, however, arguments is never actually used by @ functions, and even if, that turned out larger...

Try it online!

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