A={f={private["_i","_r"];_r=1;_i=0;while{_i<count _this}do{o=_this select _i;if(o in [o])then{if(o==0)then{_r=0}}else{_r=o call f};_i=_i+1};_r};if(count _this==0)then{0}else{_this call f}}
Call with:
[3,6,4,[4,6],[3,6,[],[2,4,[0],3]]] call A
or with:
hint format["%1", [3,6,4,[4,6],[3,6,[],[2,4,[0],3]]] call A]
Explanation:
In the game's scripting language, any string containing code can be called. The curly braces {}
denote the beginning and the end of a string. (Quotation marks work too, but that gets messy when they are nested.) So, A={...}
assigns a string to variable A
, and the variable can then be called like a function with: <argument> call A
. Basically any string can be treated as a block of code.
Then, inside the "function" A
, we define another function f
. private
declares the two variables _i
and _r
local to function f
. A local variable's name has to start with an underscore.
while {} do {}
is a loop, where the first string (denoted by {}
) contains the code for the loop condition and the second one for the loop body.
_this
is the argument that was passed with the call
function. _this
can be of any type, but here we assume it is an array.
In the loop, o=_this select _i
accesses the _i:th element of the array and assigns it to variable o
. if (o in [o])
is a trick to determine if the o
is another array or not.
If o
is a number (or anything other than an array), o in [o]
will evaluate to true
, because the in
function finds a value matching o
from the array [o]
. If o
is an array, the expression yields false
, because the in
refuses to compare arrays.
If o
is not an array, we check if it equals zero, and if it does, we'll set the variable _r
, which we'll use as the return value, to zero.
Otherwise, if o
is an array, we assign to _r
the return value of the recursive call to f
with the new array o
as the argument.
After the loop, at the end of function f
, we evaluate the expression _r
, which yields the value of _r
, and as this is the last expression to be evaluated, this is what the call to function f
returns.
Now that we have defined f
(f
need not be inside A
, but this way we could have declared it a local variable/function (no difference really) of A
if we didn't want to save some bytes), let's get back A
. if (count _this == 0)
checks if A
's input array is empty, and if it is, A
returns 0. Otherwise the function f
is called and its return value will be A
's return value.
One might notice that it seems that a semicolon would be missing from a few of places, but this is not the case, because a semicolon is only needed after a statement if another statement follows it inside the same block of code (i.e. string).