Over is a higher-order function in multiple languages such as APL (⍥). It takes 2 functions and 2 values as arguments, applies the first function to both values, then applies the second to their result. For example, using ⍥ to represent Over:
1 2⍥+ 2
We would first calculate 2 of each argument: 12 = 1 and 22 = 4. We then apply + to these, yielding 5.
You are to take as input:
- A black box function, \$f\$, which takes an integer as input and returns an integer
- A black box function, \$g\$, which takes 2 integers as input and returns a single integer
- 2 integers, \$a\$ and \$b\$.
You should then return the result of \$g(f(a), f(b))\$.
If you have a builtin specifically for this (e.g. APL's ⍥, Husk's ¤ etc.), consider including a non-builtin answer as well. It might even get you an upvote :)
You may input and output in the most convenient format for your language, and in any convenient method, including taking \$a\$ and \$b\$ as a pair/list/tuple [a, b]
For the sake of simplicity, you can assume that the black-box function will always input and output integers within your language's integer domain, and that \$a\$, \$b\$ and the output will be with your language's integer domain.
This is code-golf, so the shortest code in bytes wins
Test cases
f
g
a, b -> out
f(x) = x2
g(x,y) = x - y
-2, 2 -> 0
f(x) = φ(x) (Euler totient function)
g(x,y) = 2x + y
5, 9 -> 14
f(x) = x3-x2-x-1
g(x,y) = y4-x3-y2-x
-1, -1 -> 22
f(x) = x
g(x,y) = x / y (Integer division)
-25, 5 -> -5
52 Answers 52
Japt, (削除) 6 (削除ここまで) 5 bytes
As far as I know, Japt does not support taking functions as inputs, or at least I couldn't find a way that actually works. To sidestep this problem, I've moved the blackbox functions into the code header while excluding them from the byte count. Their definition or form is not important for the implementation itself. Hope this is valid, otherwise I don't think Japt can compete.
The functions are to be stored in V and W respectively.
mV rW
mV // Map the array of input numbers through V
rW // then reduce the result with W.
Shaved off a byte thanks to Shaggy by taking the input as an array instead.
-
1\$\begingroup\$ If they were all built-in Japt methods, they could be taken as input strings. Consensus does allow, though, for black box functions to be assigned to pre-defined variables so we're OK there. Although, you could take advantage of mult-line code to allow for both options, like so. You can also save a byte by taking the integer inputs as a single array and ditching the
N. \$\endgroup\$Shaggy– Shaggy2021年04月20日 17:12:52 +00:00Commented Apr 20, 2021 at 17:12 -
\$\begingroup\$ @Shaggy Thanks for the tip on the empty leading line in the header, didn't know I could avoid overriding
Uthat way, that's the reason I went withN. \$\endgroup\$Etheryte– Etheryte2021年04月20日 17:25:35 +00:00Commented Apr 20, 2021 at 17:25
CJam, 4 bytes
q~%*
Inputs are: function g; array of numbers; function f. Functions are defined as code blocks.
Try it online! Or verify all test cases: 1, 2, 3, 4.
Explanation
q e# Read all input as an unevaluated string
~ e# Evaluate. Pushes a code block, an array, and a code block to the stack
% e# Map (second function over the array)
* e# Reduce (the array using the first function)
e# Print (implicitly)
Raku, 17 bytes
{&^g(|@^x».&^f)}
&^f and &^g are the function arguments to the over function, and @^x is the list of arguments to f. @^x».&^f maps the arguments to f over f, and | flattens that list into the arguments to g.
MMIX, 32 bytes (8 instrs)
Takes arguments f,g,x,y.
(jxd)
00000000: fe040004 c1070200 bf060000 c1080300 "\¡\Ḋ¬£¡Ḃ©¡¡Ḋ®¤¡
00000010: bf070000 bf050100 f6040004 f8060000 Ḃ¬¡¡Ḃ¦¢¡ẇ\¡\ẏ©¡¡
Disassembly:
on GET 4,ドルrJ
SET 7,ドル2ドル
PUSHGO 6,ドル0ドル // 6ドル = f(x)
SET 8,ドル3ドル
PUSHGO 7,ドル0ドル // 7ドル = f(y)
PUSHGO 5,ドル1ドル // 5ドル = g(6,ドル7ドル)
PUT rJ,4ドル
POP 6,0 // return 5,ドルf,g,x,y,4ドル
PPL v1.0.11, 31 bytes
fnv(f,g,x,y){
returng(f(x,y))
}
This must be run on PPL version 1.0.11 (or later) because the ability to pass functions as parameters was only added in v1.0.11. Fairly simple, if you can get past the unreadability of the "mashing tokens together".
Python, 27 bytes
lambda f,g,a,b:g(f(a),f(b))
Fig, \2ドル\log_{256}(96)\approx\$ 1.646 bytes
RM
See the README to see how to run this
The perfect job for a functional language. Here is an example program with \$a = 1\$, \$b = 2\$, \$f(x) = -x\$, \$g(x, y) = x - y\$, producing the correct result of
1:
RMw1 2'Nx'-
Explanation:
RM # Takes input as [a, b], f, g
M # Map the input with the first function
R # Reduce the result by the second function
Zsh -P, 16 bytes
eval g '`f '$@\`
Expects the functions to be predefined as f and g.
The -P option makes the $@ array expand to wrap the word around every element, e.g. x$@y with A B makes xAy xBy instead of xA By. This allows it to generalise implicitly for more than 2 inputs.
For 1 byte less, you can have an uninteresting answer that only works with 2 inputs:
Zsh, 15 bytes
g `f 1ドル` `f 2ドル`
Knight, 22 bytes
O E++P" "+=f+P" "+P+fP
Since knight doesn't have the concept of functions, this program instead takes in the "functions" as strings from standard in and outputs to standard out. Specifically, in f, g, x and y on separate lines in input, and outputs g(f(x),f(y)). It does this by combining the inputs into a single string, then evaluating (adding appropriate white space).
-
\$\begingroup\$ It does have a concept of functions.
BLOCK(B). I guess it doesn't work though, because they don't take arguments. \$\endgroup\$naffetS– naffetS2022年08月10日 21:14:18 +00:00Commented Aug 10, 2022 at 21:14
-
1\$\begingroup\$ you don't need the outer ring of parentheses,
& &2.(&1.(&3),&1.(&4))saves a byte. \$\endgroup\$naffetS– naffetS2022年10月05日 17:45:13 +00:00Commented Oct 5, 2022 at 17:45
Go, 70 bytes
type i=int
func o(f func(i)i,g func(i,i)i,l,r i)i{return g(f(l),f(r))}
int shows up enough here to be aliased into a single character and save 3 bytes.
Go, generic, 66 bytes
func o[T any](f func(T)T,g func(T,T)T,l,r T)T{return g(f(l),f(r))}
Usually, generic solutions in Go are longer than the non-generic version. In this case, it's 4 bytes shorter.
dc, 16 bytes
4Rdsfxsrlfxlr3Rx
Takes input as the four preceding items on the stack, and pushes the result onto the stack.
J-uby, 3 bytes
J-uby has this as a built-in. :** takes a pair of lambdas and returns a lambda that takes two arguments. It can be invoked like :**[f,g][x,y], where f and g are lambdas and x and y are arguments to the returned lambda.
:**
Explore related questions
See similar questions with these tags.
a&bas an array[a,b]? \$\endgroup\$