19
\$\begingroup\$

Think of cleave as the conceptual inverse of map. If map applies a function to each number in a list...

map([1, 2, 3], x -> x * 5) -> [5, 10, 15]

then cleave applies each function in a list to a number.

cleave(5, [x -> x * 2, x -> x - 1, x -> x * x]) -> [10, 4, 25]

More formally, given:

  • \$n\$, an integer, and
  • \$L\$, a list of black box functions with type signature integer -> integer or equivalent

Apply each function in \$L\$ to \$n\$, collecting the results in a list the same length as \$L\$. (It can be the same list if you want.)

Challenge

Implement the cleave function in your language of choice.

Format

You must accept an integer and a list of black box functions and output a list of integers in any reasonable format. Argument order doesn't matter. The list of functions is flexible. You may accept:

  • A list of black box functions (including a list of function pointers, etc.).
  • A variable number of black box functions as parameters (varargs).
  • A number indicating how many functions to accept.
  • Etc.

Rules

  • Builtins are allowed, but please consider adding a less trivial answer so we can see how cleave might be implemented in your language.
  • Explaining your answer(s) is encouraged!
  • Standard loopholes are forbidden.
  • This is , so the code with the fewest bytes (in each language) wins.

Test cases

Note: for simplicity, instead of showing functions like x -> 10 * x, I will show them like 10x. Imagine there is an \$f(x) =\$ in front of each of these.

  3, [] -> []
 42, [x] -> [42]
  0, [10x, x/2, abs(x), -x] -> [0, 0, 0, 0]
  8, [10x, x/2, abs(x), -x] -> [80, 4, 8, -8]
 -5, [abs(x), -x, x+10] -> [5, 5, 5]
  5, [abs(x), -x, x+10] -> [5, -5, 15]
 10, [x*x, x/10, x*x + 2x + 1, 13, x%3 - 3] -> [100, 1, 121, 13, -2]
950, [x*x, x/10, x*x + 2x + 1, 13, x%3 - 3] -> [902500, 95, 904401, 13, -1]
\$\endgroup\$
3
  • \$\begingroup\$ Husk 1 byter: m \$\endgroup\$
    – Razetime
    Jun 21 at 7:10
  • \$\begingroup\$ I would love to see a Java solution to this question, which is fully object-oriented and wasn't totally meant for this.... \$\endgroup\$
    – wasif
    Jun 21 at 7:12
  • 1
    \$\begingroup\$ @Wasif done \$\endgroup\$
    – hyper-neutrino
    Jun 21 at 7:23

38 Answers 38

9
\$\begingroup\$

Haskell, 11 bytes

map.flip($)

(If using Stack, this can be dropped to 7 bytes: map.(&).)

\$\endgroup\$
4
  • \$\begingroup\$ Really is a shame & isn't there by default \$\endgroup\$ Jun 21 at 6:49
  • 1
    \$\begingroup\$ x#y=x<*>[y] also works for same bytecount I think? \$\endgroup\$
    – Bubbler
    Jun 21 at 7:11
  • \$\begingroup\$ @Bubbler As does f x=map($x) \$\endgroup\$ Jun 21 at 7:15
  • \$\begingroup\$ And \x->map($x). \$\endgroup\$ Jun 21 at 14:30
7
\$\begingroup\$

JavaScript, 20 bytes

a=>n=>a.map(f=>f(n))

Try it online! or run all test cases (courtesy of Arnauld)

\$\endgroup\$
4
  • 1
    \$\begingroup\$ All test cases \$\endgroup\$
    – Arnauld
    Jun 21 at 6:50
  • \$\begingroup\$ @Arnauld, i think you accidentally switched the array and the number in the test cases \$\endgroup\$
    – user100752
    Jun 21 at 6:57
  • \$\begingroup\$ @EliteDaMyth Ah, yes. I was taking the parameters the other way around in my version and just pasted Shaggy's code without noticing. \$\endgroup\$
    – Arnauld
    Jun 21 at 6:59
  • 1
    \$\begingroup\$ Thanks, @Arnauld :) No way was I fiddling about on my phone to reformat all those! \$\endgroup\$
    – Shaggy
    Jun 21 at 10:59
6
\$\begingroup\$

Python 3, 27 bytes

lambda L,n:[g(n)for g in L]

Try it online!

Anonymous function that takes the list of functions and a number as arguments.

\$\endgroup\$
6
\$\begingroup\$

Java (OpenJDK 8), 22 bytes

L->x->L.map(a->a.f(x))

Try it online!

-4 bytes thanks to Olivier Grégoire

L is a stream of Function<Integer, Integer> and x is an int. Function here is not java.util.function.Function but rather is a custom interface Function<T, U> with a single method U f(T t). This is just to save bytes over the normal Function<T, U> which requires the method name apply, which is apparently allowed.

\$\endgroup\$
6
  • \$\begingroup\$ very nice. It was out of my expectation that java supports functions \$\endgroup\$
    – wasif
    Jun 21 at 7:35
  • \$\begingroup\$ Mmm reminds me of my own java \$\endgroup\$
    – lyxal
    Jun 21 at 11:19
  • 2
    \$\begingroup\$ You can define your own interface interface F { int f(int x); } instead of Function<Integer, Integer>. Works the same, and you spare 5 bytes like this: L->x->L.map(a->a.f(x)) \$\endgroup\$ Jun 21 at 15:03
  • \$\begingroup\$ @OlivierGrégoire oh, that's allowed? well, that's very clever - thanks \$\endgroup\$
    – hyper-neutrino
    Jun 21 at 15:05
  • 2
    \$\begingroup\$ @hyper-neutrino That's one of the tools that we (Java golfers) use all the time. so yes, it's definitely allowed. Technically, in regards of golfing, what's the difference between an imported Function<F,T> interface and a customly defined F interface? Absolutely zero difference. \$\endgroup\$ Jun 21 at 15:09
5
\$\begingroup\$

C# (Visual C# Interactive Compiler), 23 bytes

a=>b=>b.Select(x=>x(a))

C# was born for this

Try it online!

\$\endgroup\$
5
\$\begingroup\$

R, 38 bytes

function(i,m)sapply(m,do.call,list(i))

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Julia 1.0, 9 bytes

a^b=a.|>b

Try it online!

Julia 1.6+, 3 bytes

As pointed out by @MarcMush, Julia 1.6 has since allowed defining .|> as a function, giving this 3-byter:

.|>

TIO does not offer Julia 1.6, but here's an interactive example:

julia> f=.|>
Base.Broadcast.BroadcastFunction(|>)
julia> println(f(5, [x->x*2, x->x-1, x->x*x]))
[10, 4, 25]
\$\endgroup\$
2
  • \$\begingroup\$ in Julia 1.6 f=.|> works, getting the answer down to 3 bytes \$\endgroup\$
    – MarcMush
    Jun 21 at 7:50
  • \$\begingroup\$ @MarcMush Thanks, I did not know about this feature! \$\endgroup\$ Jun 23 at 4:08
4
\$\begingroup\$

Ruby 2.7, 19 bytes

->a,b{b.map{_1[a]}}

Try it online!

Doesnt work on TIO cause of Numbered arguments.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ wow, ninja'd by 11 seconds \$\endgroup\$
    – Razetime
    Jun 21 at 7:11
  • \$\begingroup\$ @Razetime phew. \$\endgroup\$
    – user100752
    Jun 21 at 7:13
4
\$\begingroup\$

APL (Dyalog Unicode), 0 bytes

APL doesn't normally use lists of functions, but there are ways to use such. Even if the syntax for their creation is awkward, their use is simple: Try it online!

For the specific case of a list of integer↦integer functions, it is convenient to represent \$L\$ as a train, though it, despite appearances, isn't a list of functions. The calling syntax is identical to the above: Try it online!

If we absolutely wanted something that took \$L\$ and \$n\$ and applied \$L\$ to \$n\$ using the above juxtaposition syntax, we write a full program which prompts first for \$\$ and then for \$L\$, applying \$L\$ to \$n\$ by juxtaposition of the input values:

APL (Dyalog Unicode), 2 bytes

⎕⎕

Each stylised console prompts for a value from the console (STDIN).

Try it online!

Alternatively, we could define an "apply" operator that takes \$L\$ on the left and \$n\$ on the right:

APL (Dyalog Unicode), 5 bytes

{⍺⍺⍵}

⍺⍺ is the left operand and is the right argument.

Try it online!

\$\endgroup\$
11
  • 3
    \$\begingroup\$ I downvoted this answer because firstly I don't think it's fair to say there is a 0 byte solution here, as there isn't. It doesn't define a full program or function which performs the task. Also, I don't think using a train here is really in keeping with the actual question. The fact it happens to 'look' like a list in other languages is merely coincidence, might fool non APLers, but doesn't fool me! \$\endgroup\$
    – rak1507
    Jun 21 at 7:04
  • 1
    \$\begingroup\$ @rak1507 I think the L←N.f part is valid, though the L0-5 variables aren't \$\endgroup\$
    – Jo King
    Jun 21 at 7:15
  • 3
    \$\begingroup\$ @rak1507 I discussed it with OP in the sandbox, and they wanted see this 0-byte approach, so I included it here, but also made sure to have actual program/function solutions included. Correct, trains are not lists of functions, which is why I included a link to their explanation. I wasn't trying to fool anyone. Anyway, I've now made it explicit that they are not lists of functions, and the "real" solution is the via-namespaces one, which is actually a real list of functions. I included trains because it was interesting and they had identical usage to the proper list approach. \$\endgroup\$
    – Adám
    Jun 21 at 7:39
  • 1
    \$\begingroup\$ I'm still not convinced that it is valid, ⎕NC 'L' is 3, so it's a function not a list of functions. \$\endgroup\$
    – rak1507
    Jun 21 at 7:45
  • 1
    \$\begingroup\$ @rak1507 It really is a list of function (I have inside info about how the interpreter works), but since functions cannot take functions as arguments, and don't work on them. \$\endgroup\$
    – Adám
    Jun 21 at 8:03
4
\$\begingroup\$

Raku, 13 bytes

{@^f».($^n)}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ This language is insanity. It's like a code golfer wrote the sequel to Perl but wanted to include all of the other languages as well, and the result is beautiful. \$\endgroup\$ Aug 12 at 14:38
4
\$\begingroup\$

BQN, 7 bytes

{𝕎𝕩}¨⟜<

Try it!

-2 bytes from dzaima.

Takes a list of monadic BQN functions, returns a list of the same length.

\$\endgroup\$
3
  • \$\begingroup\$ Take \$L\$ as a train for 0 bytes :-) \$\endgroup\$
    – Adám
    Jun 21 at 7:02
  • \$\begingroup\$ Your function isn't an integer↦integer function. \$\endgroup\$
    – Adám
    Jun 21 at 7:03
  • \$\begingroup\$ i don't think there's a way to have a 0-byte function. \$\endgroup\$
    – Razetime
    Jun 21 at 7:07
3
\$\begingroup\$

Jelly, 2 bytes

v€

Try it online!

Accepts a list of functions on the left in Jelly source code and the value on the right.

v€  Main Link; (x: functions, y: value)
 €  For each function in x
v   Evaluate it at y

Less trivial answer:

Jelly, 6 bytes

³Ç$СḊ

Try it online!

Full program that accepts the blackbox-functions as a tied function in the header (standard for inputting blackbox-functions for Jelly), the initial value in the third argument (first value), and the number of functions in the fourth argument (second value).

³Ç$СḊ    Main Link; (x: value, y: number of functions)
   С     Collecting intermediate values, repeat y times:
  $       - last two:
³           - x
 Ç          - call the helper link (the blackbox)
     Ḋ    All but the first element

Basically, calls the black-box N times, where each time the function cycles its behavior (that's how tie works), and collects all N+1 results, then removes the initial value.

\$\endgroup\$
3
\$\begingroup\$

R >= 4.1, 21 bytes

\(l,i)Map(\(x)x(i),l)

Try it online!

An anonymous function taking a list of functions and an integer and returning a list of integers.

TIO version uses function instead of \ since TIO hasn’t been upgraded to R 4.1 yet.

\$\endgroup\$
3
\$\begingroup\$

Wolfram Language (Mathematica), 7 bytes

Through

Try it online!

Built-in. Input [L[n]].


Wolfram Language (Mathematica), 12 bytes

n#@n&/@#&

Try it online!

Input [n][L].

\$\endgroup\$
3
\$\begingroup\$

J-uby, 3 Bytes

:-@

J-uby actually has a built-in for this, despite me never having actually used it. You are intended to use it with -[f, g, h] to create a function that will "cleave" a provided argument over the functions in the array. :-@ is the symbol for unary minus in Ruby, which is callable in J-uby. It would take input in the form :-@.call(L).call(n).

But built-ins are boring. How would it be implemented otherwise?

13 Bytes

~:*%(:& &~:^)

There are basically three components to this function. First is ~:* which just creates a flipped-argument map function: ->(a, f){ a.map(&f) }.

Next, there is :& &~:^. This defines the "n-applicator" function: given the input n, this defines a function that will apply n to whatever function you pass it. Essentially, it’s equivalent to ->(n){ ->(f){ f[n] } }. How does this work? ^ is the function application operator, so ~:^ is function application with flipped arguments: ->(x, f){ f[x] }. Since & is the partial application operator, :& & ~:^ means you partially apply the flipped function application operator to the partial application operator. Anyone else getting semantic satiation?

Finally, we've got % in the middle. The % operator has different functionalities depending on its arguments, but in this case it denotes a "hook": given a binary function F and a unary function G, it returns a function that applies G to one of its two arguments before passing them on to F: F % G == ->(L,n){ F[L, G[n]] }. In this case, that means calling a flipped map (~:*) on the input array L and the n-applicator function (:& & ~:^).

The result is mapping the n-applicator function over the supplied array of functions, applying n to each element of the array. In plain Ruby, it's equivalent to ->(L,n){ L.map { |f| f[n] } }

\$\endgroup\$
2
  • \$\begingroup\$ I've been looking at a lot of j-uby answers lately. Is there any sort of tutorial other than the docs in the README? \$\endgroup\$
    – Razetime
    Jul 23 at 8:27
  • \$\begingroup\$ @Razetime The Readme is it. I might make a better tutorial some time if people are interested \$\endgroup\$
    – Cyoce
    Jul 23 at 17:54
2
\$\begingroup\$

Red, 32 bytes

func[g n][forall g[g/1: g/1 n]g]

Modifies the list in place. Doesn't work in TIO, but works fine in the Red GUI console:

enter image description here

Here's a TIO-compatible version:

Red, 41 bytes

func[L n][collect[foreach g L[keep g n]]]

Try it online!

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

C (gcc), 62 52 bytes

f(n,L)int(**L)();{while(*L)printf("%d ",(*L++)(n));}

Try it online!

Takes L as a NULL-terminated array of pointers to functions taking an int and returning an int. Outputs results space-separated on stdout (with a trailing space).

-10 bytes from @EasyasPi

(also C++ (gcc), 79 bytes with #include<cstdio> and ANSI function syntax. Try it online! (C++))


If writing to a caller-allocated array that is passed to the function is a valid form of output, then:

C (gcc), 59 51 bytes

f(int n,int(**L)(),int*r){while(*L)*r++=(*L++)(n);}

Try it online!

Same input as above, but outputs results through r, which must point to at least as many ints as L does int(*)(int)s (not including L's NULL terminator).

-8 bytes from @EasyasPi

(also C++ (gcc), 59 bytes [Try it online! (C++)][TIO-kq6vpd7q])

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can save a lot of you drop C++ support, as C lets you do implicit int, K&R definitions, and empty parameter lists \$\endgroup\$
    – EasyasPi
    Jun 22 at 0:09
2
\$\begingroup\$

JavaScript, 43 bytes

I know there's already a nice JS entry, but I wanted to give it a go by giving both parameters to a single function. Different approach, same output.

Here's mine:

(n,a)=>a.reduce((A,F)=>A.concat([F(n)]),[])

Try it online! Also test cases (modified from Arnauld's imlementation).

This is NOT memory friendly because I had to create a new array each time I used Array.prototype.concat. It would have been much nicer and slightly shorter if JavaScript's Array.prototype.push would just return the modified array...

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

tinylisp, 37 bytes

(d C(q((F N)(i F(c((h F)N)(C(t F)N))(

Try it online!

Ungolfed/explanation

(def cleave        Define cleave to be
 (lambda (F N)     a function taking a list of functions F and a number N
  (if F            If F is nonempty:
   (cons             Construct a list
    ((head F) N)      whose head is the first function in F applied to N
    (cleave           and whose tail is the result of a recursive call
     (tail F)         with the remaining functions in F
     N))              and the same number N
   nil))))         Else, return empty list
\$\endgroup\$
2
\$\begingroup\$

Mlatu, 20 bytes

->n;{n swap call}map

Explanation: ->n; pops off the stack and binds it to n. The list is left as the implicit parameter of map and is never bound. {n swap call} is a closure in Mlatu, which pushes n (the number) onto the stack, swaps the placement of the number and the function, and then calls the function with n as its argument. map takes the list and the closure and maps the list with the given closure.

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf! Nice first answer. \$\endgroup\$ Jun 24 at 3:33
1
\$\begingroup\$

Vyxal, 4 bytes

Mƛ÷†

Try it Online!

A full program that takes number then functions.

Explained

Mƛ÷†
M    # [[number, fn] for fn in functions]
 ƛ   # to each pair:
  ֠ #     apply the function to the stack

Takes input in the header because that's how to input functions

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

Lua, 55 bytes

function g(L,n)for k,v in pairs(L)do print(v(n))end end

Try it online!

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

Factor + combinators, 6 bytes

cleave

Try it online!

Built-in.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Hm. I asked for a list and you gave me a stack full of numbers. \$\endgroup\$
    – chunes
    Jun 21 at 7:13
1
\$\begingroup\$

Proton, 19 bytes

L=>x=>[g(x)for g:L]

Try it online!

You might be wondering why I'm doing fs.append on each element. That's because making a list of functions errors when you try to print it or iterate through it - that's because it never becomes a list.

Observe this and notice that making a tuple of functions in Proton actually automatically cleaves.

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

Perl 5, 27 bytes

sub{$x=shift;map&$_($x),@_}

Try it online!

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

Jelly, 3 bytes

ṛĿⱮ

Try it online!

Takes \$n\$ on the left and a list of link indices on the right.

  Ɱ    For each element of the right argument,
ṛĿ     call the link at that index monadically on the left argument.
\$\endgroup\$
1
\$\begingroup\$

Japt, 4 bytes

Takes the integer as input as a single digit array with the array of functions pre-assigned to variable V, outputs and array of single integer arrays.

V£mX

Try it

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

Scala, 14 bytes

x=>_.map(_(x))

Try it online!

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

Standard ML, 20 bytes

fn n=>map(fn f=>f n)

Try it online!

Not too exciting, I’m afraid.

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

J, 11 bytes

4 :'x`:0 y'

Try it online!

Called like:

+:`<:`*: f 5 

In J, you cannot pass around a list "functions" (aka "verbs") directly, but you can pass around a list of "gerunds", which, like English gerunds, are noun-ified verbs.

Then you can use the "Evoke Gerund" conjunction, specifically the `:0 form of it, to call those gerunds as verbs again.

Doing this requires (afaik) an explicit verb, because conjunctions can only apply to a literal or a named variable. Here, the default LHS variable x represents the list of gerunds we are "evoking", and the integer we are applying them to is y.

worth noting

This would be a very un-J thing to do, and if you wanted to solve this specific problem the natural solution would be to create a train like this:

+:,<:,*:

which creates a single new verb, rather than a list of verbs, but will produce the same output as the submission above when applied to 5.

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