24
\$\begingroup\$

zipwith is a functional construct that takes three arguments: one binary function and two lists of the same length, and returns a single list where each element is constructed by applying the binary function to each pair of elements from the two lists:

zipwith (a+b) [1,2,3] [4,5,6] = [5,7,9]

You are to take a black-box function which takes exactly two arguments and two non-empty arrays of the same length consisting of positive integers, and output the result of applying zipwith to this function and arrays.

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.

If your answer consists solely of a builtin which does this (for example Haskell's zipWith), please edit into this Community Wiki answer. You may input and output in any convenient method.

This is so the shortest code in bytes wins

Test Cases

function, array, array -> output
a = b, [1, 2, 3], [3, 2, 1] -> [0, 1, 0]
a - b, [8, 3], [3, 8] -> [5, -5]
a² + b/2, [6, 8, 1, 3], [5, 3, 6, 2] -> [38, 65, 4, 10]
a × φ(b), [4, 2, 5, 8, 3], [7, 6, 10, 2, 1] -> [24, 4, 20, 8, 3]

The third test case uses integer (floor) division. The fourth uses the Euler Totient function

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Sandbox \$\endgroup\$ Jan 26, 2021 at 11:04
  • 6
    \$\begingroup\$ +1 for the underhanded way to get people to implement the totient function. \$\endgroup\$
    – Adám
    Jan 26, 2021 at 11:48
  • 2
    \$\begingroup\$ @Adám Sneaky coding is the best coding :) \$\endgroup\$ Jan 26, 2021 at 11:49
  • \$\begingroup\$ Are integers in the list limited by my language's integer domain as well? \$\endgroup\$
    – user99151
    Jan 27, 2021 at 5:53
  • 1
    \$\begingroup\$ @2x-1 Yes. That restriction is just to allow as many languages to compete as possible \$\endgroup\$ Jan 27, 2021 at 7:04

41 Answers 41

1
2
1
\$\begingroup\$

Lua, 63 bytes

load'o,f,a,b={},...for i=1,#a do o[i]=f(a[i],b[i])end return o'

Try it online!

Functions are 1st-class values in Lua, so this is pretty simple (if a bit long because of it's need to iterate).

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

Batch, 99 bytes

@set/pf=
@set/ps=
@call:c %s%
@exit/b
:c
@set/ps=
@for %%i in (%s%)do @call %f% %%1 %%i&shift

Takes three lines of input, the command or batch function to execute, followed by two space or comma separated lists. Works fine with numbers but anything needing quoting is likely to crash and burn. Explanation:

@set/pf=

Input the command or function to execute.

@set/ps=

Input the first list.

@call:c %s%

Call the subroutine, expanding the list into separate parameters.

@exit/b

Exit the program.

:c

Declare the subroutine.

@set/ps=

Input the second list.

@for %%i in (%s%)do 

Expand the list, looping over each element.

@call %f% %%1 %%i&shift

Call the command or function, passing in the current element from both the first and current list, then shift the element from the first list. The use of call here both allows the function to be a batch script but also allows the expansion of %1 to be delayed using an extra % so that it uses the most recently shifted value.

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

Io, 37 bytes

method(f,a,b,a map(i,x,f(x,b at(i))))

Try it online!

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

Ruby, 34 bytes

def z(f,b)zip(b).map{|p|f.(*p)}end

Try it online!

\$\endgroup\$
7
  • \$\begingroup\$ I don't think that's a valid method of input, as it looks like you are assuming that the inputs are stored in b? \$\endgroup\$ Jan 31, 2021 at 14:28
  • \$\begingroup\$ b is defined in the surrounding method that links the function to the Array class. You can see in the example calls in the footer that no b is needed when using the method, I am not quite sure if it is allowed to put these parts in the header and footer. \$\endgroup\$
    – Donat
    Jan 31, 2021 at 14:35
  • \$\begingroup\$ I think you’d need to include the def zipWith(f,b) (but golfed), as it’s defining the function \$\endgroup\$ Jan 31, 2021 at 14:36
  • \$\begingroup\$ @caird coinheringaahing: Ok \$\endgroup\$
    – Donat
    Jan 31, 2021 at 14:40
  • 2
    \$\begingroup\$ Assuming the function is predefined is a valid method of input for black box functions: codegolf.meta.stackexchange.com/a/13707/52210. However, assuming that the array b is predefined is not. I'm not too familiar with Ruby though \$\endgroup\$ Jan 31, 2021 at 14:49
1
\$\begingroup\$

Perl 5, 46 bytes, 37 bytes

-9 bytes thanks to Kjetil S.

sub{map$_[0](@_[$_,$_+@_/2]),1..@_/2}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Save 9 bytes with sub{map$_[0](@_[$_,$_+@_/2]),1..@_/2} Try it online! \$\endgroup\$
    – Kjetil S
    Feb 1, 2021 at 11:45
  • \$\begingroup\$ thanks, shifting indexes by 1 instead of using shift \$\endgroup\$ Feb 1, 2021 at 12:45
1
\$\begingroup\$

05AB1E, 6 bytes

øε`I.V

Try it online or verify all test cases.

05AB1E lacks functions, but strings can be used with an eval builtin to mimic the behavior of functions (which I've also used pretty often for recursive [ragged-list] challenges).

Explanation:

ø       # Zip the first two (implicit) input-lists
 ε      # Map over each pair:
  `     #  Pop and push the contents of the pair separated to the stack
   I    #  Push the third input function-string
    .V  #  Evaluate and execute it as 05AB1E code
        # (after which the resulting list is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Go, 90 89 bytes

func z[T any](f func(T,T)T,l,r[]T)(o[]T){for i:=range l{o=append(o,f(l[i],r[i]))}
return}

Attempt This Online!

In a strange reversal, this answer is 1 byte shorter if made generic. Usually the generic version is more verbose.

Old answer, ints only, 90 bytes

func(f func(int,int)int,l,r[]int)(o[]int){for i:=range l{o=append(o,f(l[i],r[i]))}
return}

Attempt This Online!

The fun thing about Go is that you have to implement things like the functional programming functions "from scratch" every single time.

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

Ruby, 26 bytes

Like Donat’s answer, just tighter syntax and doesn’t have to monkey-patch Array.

->(f,a,b){a.zip(b).map &f}

Attempt This Online!

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

QBasic, 59 bytes

SUB z(a(),b(),n)
FOR i=1TO n
a(i)=f(a(i),b(i))
NEXT
END SUB

Defines a subprogram z that takes two arrays and their length, calls a predefined function f on pairs of elements, and stores the results back into the first array. It can be invoked either as CALL z(a(), b(), n) or as z a(), b(), n.

Explanation

The tricky part was figuring out a way to do this at all in QBasic, since it doesn't have first-class functions, function pointers, or the ability to return arrays from functions. Once I found a combination of technically allowed approaches that would work, the code itself was pretty straightforward: loop over each index i and set a(i) to f(a(i), b(i)).

Testing instructions

You can run QBasic code at Archive.org. Here's a full program that runs the third test case:

CLS
CONST LENGTH = 4
DIM a(LENGTH), b(LENGTH)

DATA 6, 8, 1, 3
DATA 5, 3, 6, 2

FOR i = 1 TO LENGTH
  READ a(i)
NEXT i
FOR i = 1 TO LENGTH
  READ b(i)
NEXT i

CALL z(a(), b(), LENGTH)

FOR i = 1 TO LENGTH
  PRINT a(i);
NEXT i
PRINT

FUNCTION f(x, y)
f = x ^ 2 + y \ 2
END FUNCTION

SUB z(a(),b(),n)
FOR i=1TO n
a(i)=f(a(i),b(i))
NEXT
END SUB

Note: as soon as you type the FUNCTION or SUB line, the editor will automatically add the corresponding END FUNCTION or END SUB and put the new function/subprogram in its own window. To add the sub after entering the function, position your cursor below the END FUNCTION line and start typing from SUB z(.... Once you've entered both the function and the sub, you can run the program using Run > Start (or press F5). You can also switch between the sub, function, and main program using View > SUBs (or press F2).

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

Arturo, 37 bytes

$[f a b][map combine a b'x->f x\0x\1]

Try it

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

Japt, 3 bytes

The same byte count as using the interleave built-in.

Takes the arrays as input as a single, 2D array. Black box function is pre-assigned to variable V.

yrV

Try it

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