Reduce over the range [1..n]
Task
I often need to find the factorial of a number or the sum of all numbers up to a number when cheating on math tests. To help me with this, your task is to write $F$, a generalized version of those functions:
$$F(n) = 1 * 2 * \space ... \space * (n-1) * n$$
Please note that the operator $ * $ does not necessarily represent multiplication here, but stands for a commutative, associative operator that will be an input to your program/function. This means that $a * b$ is the same as $b * a$, and $a * (b * c)$ is the same as $(a * b) * c$. Its inputs are positive integers, and its outputs are integers.
Rules
- $n$ will be a positive integer.
- $*$ is a binary function/operator that can be taken in any convenient format, including but not limited to:
- A function object
- A function pointer
- An object with a method with a specific name (e.g. Java's
BiFunction
) - A string that can be evaluated to get a function
$*$ is a blackbox function. That means that you will not be able to examine it to see how it works; all you can do is feed it two positive integers and get an integer back.- The output of your function will be an integer (not necessarily positive).
- This is code golf, so shortest code in bytes wins!
Testcases
f | n | F(f, n)
Add | 1 | 1
Add | 5 | 15
Multiply | 1 | 1
Multiply | 5 | 120
XOR | 1 | 1
XOR | 2 | 3
XOR | 5 | 1
XOR | 10 | 11
Ruby, 17 bytes ``` ->{2.re …
3y ago
[Haskell], 18 bytes …
3y ago
Vyxal `R`, 1 byte ``` R ` …
3y ago
[Python 2], 33 bytes …
3y ago
JavaScript, 25 bytes The fu …
3y ago
Japt, 4 bytes Takes the ope …
3y ago
[APL (Dyalog Unicode)], 4 byte …
3y ago
[Jelly], 3 bytes Rç/ …
3y ago
Factor, 95 bytes ``` USING …
2y ago
J, 11 9 bytes ``` /@(>:@i. …
2y ago
Ruby, 22 bytes ```ruby ->{ …
3y ago
[C (gcc)], 50 bytes …
3y ago
BQN, 8 bytes ``` {𝔽´1+↕𝕩} ` …
3y ago
[C (clang)], 59 bytes …
3y ago
14 answers
Japt, 4 bytes
Takes the operator as a string but would also work without modification using a function by assigning it to variable V
. That can be done in the header by leaving a blank line and then entering a function in the form XY{X[op]Y}
, where [op]
is the operator or method.
õ rV
õ rV :Implicit input of integer U and operator V, as string
õ :Range [1,U]
rV :Reduce by V
0 comment threads
Ruby, 17 bytes
->{_2.reduce(_1)}
Takes function (Proc) followed by Array.
32 bytes without inject
or reduce
->f,(a,*r){r.map{|n|a=f[a,n]};a}
JavaScript, 25 bytes
The function is called with f(g)(n)
, where g
is a function.
g=>h=n=>n-1?g(h(n-1),n):1
0 comment threads
APL (Dyalog Unicode), 4 bytes
⎕/⍳⎕
⎕
input /
reduction over ⍳
the integers until ⎕
input.
0 comment threads
Vyxal R
, 1 byte
R
Function must be inserted in the header.
The R
flag casts integers to ranges when an integer can't be used. R
is the builtin for 'Reduce list by function', and it can't use an integer, so ranges before reducing.
0 comment threads
Jelly, 3 bytes
Rç/
Takes f
as the helper link. Very basic, R
casts to range, then ç/
reduces by the helper link
0 comment threads
Ruby, 22 bytes
->{(1.._2).reduce &_1}
Without using reduce
(28 bytes):
f=->g,n{n<2?n:g[n,f[g,n-1]]}
0 comment threads
Factor, 95 bytes
USING: kernel ranges sequences ;
IN: r
: r ( n q -- n ) [ [1..b] [ ] ] dip map-reduce ; inline
0 comment threads
C (clang), 59 bytes
c;f(int a,(*b)(int,int)){for(c=a;a>1;)c=b(--a,c);return c;}
This program written by @Hakerh400 in the comments is basically how the other answers before this post existed actually did it, by a reduction sort of method. I'd like to thank them for making such program and the amount of bytes it literally shaved compared to the program below.
C (clang), 142 103 bytes
i,j;f(a,b){if(b==42){j=1;}for(i=1;i<=a;i++){if(b==43){j+=i;}if(b==42){j*=i;}if(b==94){j^=i;}}return j;}
I wanted to try to make something similar to this, but with whatever Python has that C doesn't, I couldn't do so.
Instead, I chose to make a function. It works differently from the others, but it's all I could do.
Ungolfed form of the function with comments:
int f(int num, char operator){ // Assign a function with 2 parameters: a number and character for operations
int x, result = 0; // Assign 2 integers: the succeeding number and the base
if(operator == '*' || operator == '/'){result = 1;} // Check if the character resembles multiplication or division; if so, set base as 1
for(x = 1; x <= num; x++){ // Start a loop to prompt the calculation that satisfies the challenge
if(operator == 43){result += x;} // Addition
if(operator == 42){result *= x;} // Multiplication
if(operator == 94){result ^= x;} // XOR
}
return result; // Return the result
}
BQN, 8 bytes
{𝔽´1+↕𝕩}
basic fold builtin version. Use as a dyadic 1-modifier.
Longer than APL since evaluated output is shorter than using first class functions.
A more fun recursive implementation without fold:
{1𝔽{(𝕨𝔽⊑𝕩)(1<≠𝕩)◶⊣‿𝕊1↓𝕩}1+1↓↕𝕩}
A previous(wrong) version of this exposed a bug which prevented the program from erroring here.
EDIT: the bug is fixed!
1 comment thread