| Bytes | Lang | Time | Link |
|---|---|---|---|
| 066 | Tcl | 250515T211331Z | sergiol |
| 018 | Juby | 250515T191115Z | Jordan |
| nan | 210126T105737Z | caird co | |
| 003 | Japt | 230110T081059Z | Shaggy |
| 037 | Arturo | 230110T051727Z | chunes |
| nan | 221005T134303Z | bigyihsu | |
| 059 | QBasic | 221016T041031Z | DLosc |
| 032 | R | 210126T113116Z | Dominic |
| 026 | Ruby | 221014T181035Z | Jordan |
| 006 | 05AB1E | 221005T085538Z | Kevin Cr |
| 005 | Pip xp | 221005T050152Z | DLosc |
| 011 | Wolfram Language Mathematica | 210126T181522Z | att |
| 005 | Vyxal | 210531T183058Z | user |
| nan | Perl 5 | 210126T145812Z | Nahuel F |
| 019 | Python 3 | 210201T061706Z | Danis |
| 093 | PowerShell | 210201T053832Z | wasif |
| 034 | Ruby | 210131T142651Z | Donat |
| 035 | Python 3 | 210128T233128Z | mhawke |
| 037 | Io | 210131T125003Z | Donat |
| 036 | Groovy | 210131T120533Z | Donat |
| 014 | x8616 machine code | 210127T100730Z | user9915 |
| 9048 | GNUCPreprocessor | 210127T213135Z | ChrisoLo |
| nan | GNU sed | 210127T194545Z | seshouma |
| 077 | Idris | 210127T162227Z | nicoty |
| 099 | Batch | 210127T120208Z | Neil |
| 049 | C gcc | 210126T121233Z | EasyasPi |
| 063 | Lua | 210127T045254Z | Benrob03 |
| 022 | Haskell | 210127T000040Z | orthocre |
| 024 | Factor | 210126T233226Z | Bubbler |
| 002 | Husk | 210126T225523Z | Leo |
| 006 | Stax | 210126T195605Z | Joshua |
| 031 | Pure Zsh | 210126T190842Z | GammaFun |
| 087 | Scala 3 compile time | 210126T174700Z | user |
| 041 | Racket | 210126T151030Z | Galen Iv |
| 034 | Rust | 210126T150900Z | Aiden4 |
| 070 | Nim | 210126T142642Z | Adam |
| 069 | Red | 210126T122538Z | Galen Iv |
| 008 | CJam | 210126T125100Z | Luis Men |
| 052 | Icon | 210126T124714Z | Galen Iv |
| 052 | Java 8 | 210126T123522Z | Kevin Cr |
| 005 | Husk | 210126T120816Z | Razetime |
| 024 | Zsh | 210126T120612Z | pxeger |
| 032 | JavaScript ES6 | 210126T110413Z | Arnauld |
Tcl, 66 bytes
proc Z {f L M} {lmap x $L y $M {expr [string map {a $x b $y} $f]}}
Tcl parser substitution is delicious!
J-uby, 18 bytes
Takes curried arguments like F[g][a,b] where g is a function and a and b are the arrays.
:+@|:& &:*|:|&:zip
This exposes a bug in J-uby with the + operator (:+@ above). +F is a shortcut for :<< & F, i.e. binding F to the << operator. The << operator is used like F << a, where it "splats" the array a as individual arguments to F, i.e. F.(*a). However, this doesn't work for all functions. In the ATO above you can see it works fine for the function :+, which adds its two arguments. However, it doesn't work for ->x,y{ x+y }, which also takes two arguments. I'd love to know why.
Trivial builtin answers
Edit your answer into this post if it consists of a builtin which does the entire task by itself
HBL, 0.5 bytes
2
(Not implemented in the online version at the time of this writing.)
Fig, \$1\log_{256}(96)\approx\$ 0.823 bytes
z
Same as Husk.
APL (Dyalog Unicode), 1 byte
¨
BQN, 1 byte
¨
Same as APL. Try it at BQN online!
Husk, 1 byte
z
Jelly, 1 byte
"
J, 2 bytes
"0
Not technically a builtin, but close enough.
C#, 3 bytes
Zip
Google Sheets/Excel, 3 bytes
MAP
Julia, 3 bytes
map
Python 2, 3 bytes
map
R, 3 bytes
Map
The canonical R built-in function is mapply (6 bytes).
However, the R documentation for Map reads "Map is a simple wrapper to mapply which does not attempt to simplify the result" (meaning that Map leaves its output as a list, rather than a vector, of results), so this seems to be a perfectly-acceptable 3-byte alternative here.
Factor, 4 bytes
2map
Raku, 4 bytes
&zip
Haskell, 7 bytes
zipWith
Prolog (SWI), 7 bytes
maplist
MATLAB / Octave, 8 bytes
arrayfun
Elm, 9 bytes
List.map2
PHP, 9 bytes
array_map
Try it online! (PHP's array_map can take any number of array arguments)
Wolfram Language (Mathematica), 9 bytes
MapThread
tinylisp, 18 bytes
Not exactly a builtin, but a library function:
map*
4 bytes for the function, 14 bytes for (load library). Try it online!
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
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}
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}
The fun thing about Go is that you have to implement things like the functional programming functions "from scratch" every single time.
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).
R, 32 bytes
function(f,x,y)Vectorize(f)(x,y)
If R didn't already have a built-in (mapply/Map) for zipwith, here's how one could implement it in 32 bytes...
(...and if R didn't have Vectorize, we'd need to implement it the 'hard' way for 54 bytes: function(f,x,y){for(i in seq(a=x))T[i]=f(x[i],y[i]);T})
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}
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)
Pip -xp, 5 bytes
aMZbc
Explanation
This is essentially a built-in, the ternary MZ (map-zip) operator. However, I'm pretty sure a bare operator isn't a valid solution, so I've made it a full program. The -x flag allows functions and lists to be evaluated as such when passed as command-line arguments, and the -p flag means lists will be output in list format rather than concatenated together.
Wolfram Language (Mathematica), 11 bytes
Inner[##,]&
Returns a Null of results.
Inner almost does zipwith - except, by default, it returns the sum of the results.
Also 11 bytes
#@@@In@@#2&
In (among others) is as short as a built-in Listable function gets, and remains unevaluated with >1 argument.
Vyxal, 5 bytes
£Zƛ¥R
I don't know how to input functions properly in Vyxal, so the Vyxal interpreter link just has the function stuffed with the code.
£Zƛ¥R
£ Set the register to the blackbox function
Z Zip the two lists
ƛ For each element of that
R Reduce using
¥ The function in the register
PowerShell, 93 bytes
function Z($F,$S,$R={,$args}){[Linq.Enumerable]::Zip($F,$S,[Func[Object,Object,Object[]]]$R)}
Example
Z (1,2,3) (4,5,6) {param($a, $b) ($a+$b)}
'-'
Z (8,3) (3,8) {param($a, $b) ($a-$b)}
'-'
Z (6,8,1,3) (5,3,6,2) {param($a, $b) ([math]::pow($a,2)+$b/2)}
'-'
Z (1,2,3) (3,2,1) {param($a, $b) ([int]($a-eq$b))}
It is a zip function which can take map expression as its third parameter to know how to pass it then see the demo in the Try it online "Footer" section how to use it.
x86-16 machine code, 15 14 bytes
Saved 1 byte thanks to @Joshua!
AD 50 87 F3 AD 50 87 F3-FF D2 AB E2 F3 C3
Callable function.
Inputs:
CX= lengths of both lists[SI]= address of first list[BX]= address of second list[DX]= address of function
Outputs towards [DI] = address of output list (buffer needs to be large enough).
Disassembly:
LoopTop:
AD LODSW ; AX = [SI], SI+=2
50 PUSH AX ; push AX onto stack
87 F3 XCHG SI, BX ; swap SI and BX
AD LODSW ; AX = [SI], SI+=2
50 PUSH AX ; push AX onto stack
87 F3 XCHG SI, BX ; swap SI and BX
FF D2 CALL DX ; call function at [DX]
; the function should take two items on the stack
; and AX = the return value (stock calling convention)
AB STOSW ; [DI] = AX, DI+=2
E2 F3 LOOP LoopTop ; --CX; jump to top of loop while CX >= 0
C3 RET ; return to caller
Example run
Tested with DOS debug:
-r
AX=0000 BX=0040 CX=0003 DX=0060 SP=FFFE BP=0000 SI=0030 DI=0050
DS=1000 ES=1000 SS=0B17 CS=1000 IP=0000 NV UP EI PL NZ NA PO NC
1000:0000 AD LODSW
-u1000:0060
1000:0060 58 POP AX
1000:0061 A37600 MOV [0076],AX
1000:0064 58 POP AX
1000:0065 A37800 MOV [0078],AX
1000:0068 58 POP AX
1000:0069 01067800 ADD [0078],AX
1000:006D A17600 MOV AX,[0076]
1000:0070 50 PUSH AX
1000:0071 A17800 MOV AX,[0078]
1000:0074 C3 RET
-t
AX=0004 BX=0030 CX=0003 DX=0060 SP=FFFF BP=0000 SI=0042 DI=0050
DS=1000 ES=1000 SS=0B17 CS=1000 IP=0001 NV UP EI PL NZ NA PO NC
1000:0001 50 PUSH AX
-t
AX=0004 BX=0030 CX=0003 DX=0060 SP=FFFD BP=0000 SI=0042 DI=0050
DS=1000 ES=1000 SS=0B17 CS=1000 IP=0002 NV UP EI PL NZ NA PO NC
1000:0002 87F3 XCHG SI,BX
...
-t
AX=0009 BX=0036 CX=0000 DX=0060 SP=FFFF BP=0000 SI=0046 DI=0056
DS=1000 ES=1000 SS=0B17 CS=1000 IP=000D NV UP EI PL NZ NA PE NC
1000:000D C3 RET
-d1000:0000
1000:0000 AD 50 87 F3 AD 50 87 F3-FF D2 AB E2 F3 C3 00 19 .P...P..........
1000:0010 00 00 00 00 00 00 00 20-20 20 20 20 20 20 20 20 .......
1000:0020 20 20 20 20 20 20 20 20-20 20 00 00 00 00 00 00 ......
1000:0030 01 00 02 00 03 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0040 04 00 05 00 06 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0050 05 00 07 00 09 00 00 00-00 00 00 00 00 00 00 00 ................
1000:0060 58 A3 76 00 58 A3 78 00-58 01 06 78 00 A1 76 00 X.v.X.x.X..x..v.
1000:0070 50 A1 78 00 C3 00 0A 00-09 00 00 00 00 00 00 00 P.x.............
GNU-C-Preprocessor, 90 + O(48*n) Bytes
There should be code golf challenges for C preprocessor only, my idea:
#define T(x,...) x
#define D(x,y...) y
#define A(f,x,y) f(x,y)
#define Z5(f,x,y) A(f,T x,T y),Z4(f,(D x),(D y))
#define Z4(f,x,y) A(f,T x,T y),Z3(f,(D x),(D y))
#define Z3(f,x,y) A(f,T x,T y),Z2(f,(D x),(D y))
#define Z2(f,x,y) A(f,T x,T y),Z1(f,(D x),(D y))
#define Z1(f,x,y) A(f,T x,T y)
This example works for input lists of length <= 5. You can call the function like this:
#define C(x,y) x##y
(Z5(C,(h,e,l,l,o),(w,o,r,l,d)))
which results in
(hw,eo,lr,ll,od)
The "n" is the maximum list length to process and output. Of course you could use single characters instead of "Z" as name but using a digit allows for more flexibility and easier maintenance. For example you could add a parameter for "Z" to specify the bounds which is concatenated as Z##n and used as nested macro call.
The C Preprocessor opens a new realm of languages for code golf and is a rather minimal pure-functional primitive-recursive programming language which only features macro substitutions (which look like function calls, '(', ')', ',' and '#' are the only characters with special meaning), stringification, character concatenation (must be result in valid C tokens) and no direct recursion (each call must be defined with different macro name). Primitive-recursive means, it uses inputs of strictly bounded or fixed lengths and the program always terminates for all inputs. If you want a program for unbounded length, you would need an infinite program but program inputs are always bounded in practice. Literally any strictly limited output for strictly limited input values can be programmed by a primitive-recursive program and thus the C preprocessor. The program only must be big enough to compute it. It can become quite memory-inefficient though.
GNU-C Preprocessor, 238 + O(32*log3(n)) Bytes
A more optimal program size with O(log(n)) program growth is possible but requires hacky additional macro definitions and will only pay off starting with slightly larger input lists. This example purposefully does not add commas between elements in the output to allow for higher flexibility in output.
#define L4(p) L3(p) L3(p) L3(p)
#define L3(p) L2(p) L2(p) L2(p)
#define L2(p) L1(p) L1(p) L1(p)
#define L1(p) p() p() p()
#define T(x,...) x
#define D(x,y...) y
#define I(x...) x
#define W(r,f,a,b,x,y) (I r f(a,b)),f,x,y
#define X(r,f,x,y) W(r,f,T x,T y,(D x),(D y))
#define Y(x...) X(x)
#define C() )
#define O() (
#define U(x...) T(x)
#define Z(f,x,y) U(U(L4(Y O)(),f,x,y L4(C)))
Explanation:
L<x>is the loop and<x>is the exponent of how often to loop.T,U= take first element from comma-separated listD= drop first element from comma-separated listI= identity function (evaluates arguments and can remove parens)A= applies a function but without lazy argument-evaluationX,Y,Z= the actual zipWith functionC= closing parenthesis, needed for code generationO= opening parenthesis, needed for code generation (prevents unclosed macro call errors)
The main idea is to code-generate a long nested expression in a loop so that Z(args) evaluates to literally Y ( Y ( Y ( ... args' ...) ) ) and Y reduces the arguments by one step when evaluated in U(U(...)) (it does not work with only one U).
This example can process up to 3^4 = 243 elements of two lists. If you want to multiply the processing limit by 3, add a new loop line on the top of the code. You need about 20 loop lines to handle unsigned 32-bit of elements. But keep in mind that each element is evaluated, even if does not exist! This is an example which zip-concatenates elements of two lists and places a comma between elements iff the concatenation is not empty:
#define V2(x...) ,##x
#define V(x...) V2(x)
#define CONC(x,y...) y##x
#define CONC1(x,y) V(CONC(y,x))
#define D2(x) (D x)
D2(Z(CONC1,(h,e,l,l,o),(w,o,r,l,d)))
The result is (hw ,eo ,lr ,ll ,od) . It works with any lists with any number of elements but will output at most 243 elements. Tested on godbolt.org.
If you find improvements which aren't only shorter macro names, please feel free to update this answer and leave a comment.
GNU sed, 55 + 1(r flag) = 56 bytes
GNU sed doesn't even have integers, not to mention functions, lists / arrays, etc. In order to participate, I used the following assumptions for the I/O methods, which hopefully respect the consensus regarding sed:
- each input list / array is given on a separate input line, with the integers separated by space.
- the black-box function is predefined under the label
f. - the black-box function arguments are two space separated integers read from the first pattern space line (generated there at runtime during each iteration).
- the return value of the black-box function is placed on the first pattern space line
- the output list / array is given as one integer per line.
1N # read the 2nd input list
s:([^ ]+) ?(.*\n)([^ ]+) ?(.*):\1 \3\n\2\4: # put list1[i] and list2[i] on first line
tf;: # call the black-box function `f`
P # print the function return value
D # delete return value, start new iteration
The implemented black-box function in the link above is a == b. The other test functions are significantly harder to implement in sed, but possible since the language is Turing complete.
Idris - 77 bytes
z:(a->b->c)->List a->List b->List c
z f(x::v)(y::w)=f x y::z f v w
z _ _ _=[]
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.
C (gcc), 49 bytes
z(f,a,b,n)int*a,*b,(*f)();{for(;n--;f(a++,b++));}
Loops for 0-n, applying f on &a[i], &b[i]. Fairly simple.
Ungolfed signature:
void zipwith(void (*blackbox)(int *, int *), int *a, int *b, int length);
This version expects a function like this:
void func(int *a, int *b)
{
*a = *a OP *b;
}
It overwrites the contents in a.
Since this is a pretty loose interpretation of the rules, I have also provided a more strict version which acts like a normal zipwith.
C (gcc) strict, 61 54 bytes
z(f,a,b,n)int*a,*b,(*f)();{for(;n--;*a++=f(*a,*b++));}
Loops for 0-n, storing the result of f on a[i], b[i] to a[i]. Fairly simple.
Degolfed signature:
void zipwith(int (*blackbox)(int, int), int *a, int *b, int length);
Thanks to @att for reminding me I don't need a separate output array, saving 7 bytes.
Lua, 63 bytes
load'o,f,a,b={},...for i=1,#a do o[i]=f(a[i],b[i])end return o'
Functions are 1st-class values in Lua, so this is pretty simple (if a bit long because of it's need to iterate).
Haskell, 22 bytes
(.zip).(.).map.uncurry
Not particularly interesting, just a reimplementation of zipWith converted to pointfree form:
\f x y -> map (uncurry f) (zip x y)
\f x -> map (uncurry f) . zip x
\f x -> (map (uncurry f) .) zip x
\f -> (map (uncurry f) .) . zip
\f -> (. zip) (map (uncurry f) .)
\f -> (. zip) ((.) (map (uncurry f)))
\f -> (. zip) ((.) ((map . uncurry) f))
\f -> (. zip) ((.) . (map . uncurry) $ f)
\f -> (. zip) . ((.) . (map . uncurry)) $ f
(. zip) . ((.) . (map . uncurry))
Factor, 24 bytes
[ zip swap f assoc>map ]
Avoids the obvious built-in 2map and its trivial generalizations nmap and 2map-as, and uses zip and assoc>map instead (so it works like e.g. the Rust answer). Takes the input from the stack in the order of func arr1 arr2.
Small golfing tip: when using a function that takes an "exemplar" (which specifies the type of the output container), supplying f has the same effect as supplying { } (a plain array).
Factor, using nmap, 10 bytes
[ 2 nmap ]
nmap is a generalized version of map-family of functions that works with n input arrays and n-ary functions. Obviously, 2 nmap works on two input arrays and binary functions.
Factor, using 2map-as, 13 bytes
[ f 2map-as ]
2map-as is a simple variation of 2map that takes an exemplar.
2map itself is already listed in the trivial built-in catalogue.
Husk, 2 bytes
δm
Try it online! (Implement the function in the footer, the header passes it to the main code)
Sure, Husk has a trivial builtin solution for this (z), but here's the shortest interesting solution :)
δ is a higher order function that turns something using an unary function on elements of one list into one using a binary function on elements from two lists.
Here, we turn the map function m that applies the (unary) input function to each element of the input list into one that applies the (binary) input function to each pair of elements from the two input lists: exactly what zipWith should do!
Stax, 6 bytes invocable, or 3 bytes toplevel
Does not make sense to compress functions in stax so I didn't.
The two arrays are passed on the stack, and the black-box function is passed in the x register.
|\{x!m
Explained:
|\ Zip input arrays
{
x push contents of x register
! invoke top of stack
m map
Program head version: two arrays are passed to it on the stack; body of blackbox program follows
|\m
Explained:
|\ Zip input arrays
m map array with rest of program
Pure Zsh, 31 bytes
b=($=3)
for 2 3 (${${=2}:^b})$@
Takes parameters function name, space-delimited list, space-delimited list
With -o shwordsplit, one byte is saved with b=($3) instead.
b=($=3) # =split $3 and save as array $b
# ${${=2}:^b} # Zip $=2 and $b together
for 2 3 (${${=2}:^b}) # Loop over 2 at a time as $2 and $3 (argv[2], argv[3])
$@ # $1 $2 $3
Scala 3 (compile time), 87 bytes
type Z[F[_,_],A<:Tuple,B]<:Tuple=(A,B)match{case(a*:b,c*:d)=>F[a,c]*:Z[F,b,d]case _=>A}
Takes tuples instead of lists.
This isn't particulary interesting or complicated, but here's an explanation:
type Z[ //Declare a type Z taking these arguments
F[_,_], //A type F that itself takes two arguments
A <: Tuple, //The first list, a tuple
B //The second list (actually also a tuple)
] <: Tuple = //The returned type is also a tuple
(A, B) match { //Make a tuple (A, B) and match it:
//`h*:t` represents a tuple with head `h` and tail `t` (like :: or :)
case (a *: b, c *: d) => //If A is of the form a*:b and B is of the form c*:d
F[a, c] //Call F on the heads
*: //And prepend that to
Z[F, b, d] //The result of zipping the rest of the tuples
case _ => A //Otherwise, both tuples are empty, so we return an empty tuple
}
Racket, 41 bytes
(λ(x y f)(for/list([i x][j y])(f i j))))
for/list is almost the necessary builtin, just needs some additional syntax.
Rust, 34 bytes
|f,a,b|a.into_iter().zip(b).map(f)
Rust doesn't have a zipwith function but it does have a zip and a map function. Returns an iterator over the values.
Nim, 71 70 bytes
iterator z[I](f:proc(x,y:I):I;a,b:seq):I=
for i,x in a:yield x.f b[i]
Red, 69 bytes
func[a b f][collect[repeat i length? a[keep compose[(f a/:i b/:i)]]]]
Printing the result instead of returning it:
61 bytes
func[a b f][repeat i length? a[print compose[(f a/:i b/:i)]]]
CJam, 8 bytes
l'.l++~p
Try it online! Or verify the first three cases: 1, 2, 3.
Input is a line with (the string representation of) two arrays, and then a line with (the string representation of) the function, defined as a CJam block.
How it works
l e# Read line containing the two arrays
'. e# Push character "." (which will do the actual job)
l e# Read line containing a code block
++ e# Concatenate twice
~ e# Evaluate as CJam code
p e# Print
Java 8, 52 bytes
A->B->{for(int l=A.length;l-->0;)A[l]=f(A[l],B[l]);}
Puts the result in the first argument instead of returning a new integer-array (to save 25 bytes).
Explanation:
A->B->{ // Method with two integer-array parameters & no return-type
for(int l=A.length;l-->0;)// Loop `l` in the range (length,0]:
A[l]= // Change the `l`'th item in the first array to:
f( // Call the black-box function `f`
A[l],B[l]);} // with the `l`'th items of both arrays as parameters
Black box input format:
Assumes a named function Object f(Object a,Object b) is present, which is allowed according to this meta answer.
I have an abstract class Test containing the default function f(a,b), as well as the lambda above:
abstract class Test{
Object f(Object a,Object b){
return(int)a+(int)b;
}
public java.util.function.Function<Object[], java.util.function.Consumer<Object[]>>c=
A->B->{for(int l=A.length;l-->0;)A[l]=f(A[l],B[l]);}
;
}
For the test cases, I overwrite this function f. For example, the third test case (which is responsible for the black-box having Object as parameters/return-type instead of int) is called like this:
Object[] a = new Object[]{1,2,3};
new Test(){
@Override
Object f(Object a,Object b){
return a==b;
}
}.c.apply(a).accept(new Object[]{3,2,1});
System.out.println(java.util.Arrays.toString(a));
Husk, 5 bytes
mF₁Te
Takes the two arrays as arguments, and the function in the footer. You can use any binary function which operates on two TNums from Husk's Commands page.
Explanation
mF₁Te Main program: accepts two arrays
e two element list from the arrays
T transpose
m map each pair to
F itself folded by
₁ the black box function
Zsh, 24 bytes
for 1 2 (`paste $@`)f $@
Uses a black-box function named f, with input from two files specified in command line arguments.
However, paste alone is really just a zip, and this brings up some interesting debate depending on your interpretation of what counts as a "function" under the Unix philosophy of "everything should be a text stream":
#!/bin/zsh
# using a predefined function F
z1() { paste $1 $2 | F }
# using a function named in the arguments
z2() { paste $1 $2 | $3 }
F() { while read line; do rev <<< line; done }
z1 input1 input
z2 input1 input2 F
paste input1 input2 | F
paste input1 input2 | rev
# so maybe paste is just a point-free function?
paste
So maybe this is a trivial built-in solution:
Unix shell (?), 5 bytes (?)
paste