37
\$\begingroup\$

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

We would first calculate ² of each argument: 1² = 1 and 2² = 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 , so the shortest code in bytes wins

Test cases

f
g
a, b -> out

f(x) = x²
g(x,y) = x - y
-2, 2 -> 0

f(x) = φ(x)     (Euler totient function)
g(x,y) = 2x + y
5, 9 -> 14

f(x) = x³-x²-x-1
g(x,y) = y⁴-x³-y²-x
-1, -1 -> 22

f(x) = x
g(x,y) = x / y   (Integer division)
-25, 5 -> -5
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can we take a & b as an array [a,b]? \$\endgroup\$
    – Shaggy
    Commented Apr 20, 2021 at 7:12
  • \$\begingroup\$ @Shaggy Yes you can \$\endgroup\$ Commented Apr 20, 2021 at 11:31

52 Answers 52

1
2
2
\$\begingroup\$

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.

Try it online!

\$\endgroup\$
2
  • 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
    Commented 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 U that way, that's the reason I went with N. \$\endgroup\$
    – Etheryte
    Commented Apr 20, 2021 at 17:25
2
\$\begingroup\$

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

Raku, 17 bytes

{&^g(|@^x».&^f)}

Try it online!

&^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.

\$\endgroup\$
2
\$\begingroup\$

Racket, 30 bytes

(λ(f g x)(apply g (map f x)))

Try it online! Takes a and b as a list i.e. '(a b).

\$\endgroup\$
2
\$\begingroup\$

Lua, 41 bytes

function k(f,g,x,y)return g(f(x),f(y))end

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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

Clojure, 17 16 bytes

#(%(%2%3)(%2%4))

Try it online!

Takes inputs in the order of \$g, f, a, b\$.

\$\endgroup\$
2
\$\begingroup\$

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".

\$\endgroup\$
2
\$\begingroup\$

Java (JDK), 30 bytes

(f,g,x,y)->g.a(f.a(x),f.a(y));

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Python, 27 bytes

lambda f,g,a,b:g(f(a),f(b))
\$\endgroup\$
2
\$\begingroup\$

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

Arturo, 21 bytes

$[f g x y][g f x f y]

Try it

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

Python 2, 37 bytes

lambda f,g,a,b:reduce(g,map(f,[a,b]))

Try it online!

Some approach different than dingledooper

Python 2, 27 bytes

lambda f,g,a,b:g(f(a),f(b))

Try it online!

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

Zsh -P, 16 bytes

eval g '`f '$@\`

Try it online!

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`

Try it online!

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

Knight, 22 bytes

O E++P" "+=f+P" "+P+fP

Try it online!

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).

\$\endgroup\$
1
  • \$\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
    Commented Aug 10, 2022 at 21:14
1
\$\begingroup\$

Elixir, 22 bytes

-1 byte thanks to @Steffan.

& &2.(&1.(&3),&1.(&4))

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ you don't need the outer ring of parentheses, & &2.(&1.(&3),&1.(&4)) saves a byte. \$\endgroup\$
    – naffetS
    Commented Oct 5, 2022 at 17:45
1
\$\begingroup\$

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))}

Attempt This Online!

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))}

Attempt This Online!

Usually, generic solutions in Go are longer than the non-generic version. In this case, it's 4 bytes shorter.

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

Kamilalisp, 15 bytes

(λ(f g)g&[f f])

Attempt This Online!

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

Uiua, 5 bytes

^2∩^1

Try it!

^2∩^1
  ∩^1  # call the unary function on both inputs
^2     # call the binary function
\$\endgroup\$
0
\$\begingroup\$

dc, 16 bytes

4Rdsfxsrlfxlr3Rx

Try it online!

Takes input as the four preceding items on the stack, and pushes the result onto the stack.

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

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.

:**

Attempt This Online!

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

K (ngn/k), 7 bytes

{x y z}

Try it online!

Simple. Apply function y to all numbers in z, then apply function x to the result.

\$\endgroup\$
1
  • \$\begingroup\$ This doesn't answer the question \$\endgroup\$
    – att
    Commented Oct 1, 2023 at 19:00
1
2

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.