Get the best of two Arrays
Python 2, 45 bytes
A mix of my initial solution and @ovs'.
lambda*a:map(lambda x,y:max(x,y)*-~(x==y),*a)
Try it online!
Python 2, 49 bytes
lambda x,y:[max(a,b)*-~(a==b)for a,b in zip(x,y)]
Try it online!
Python 2, 46 bytes
@ovs suggested this method to save 3 bytes.
lambda*x:[max(a,b)*-~(a==b)for a,b in zip(*x)]
Try it online!
How?
First off, we pair the corresponding elements, by using either *
or zip()
. That allows us to do our further golfing by working either with a map or a list comprehension.
The cool trick in this answer is this part: max(x,y)*-~(x==y)
. How does that work? - Well, as most of you already know, Python auto-converts bool values to integers when they are used in arithmetic operations. Hence, (x==y)
gets evaluated as 1
, if the condition is met. However, if the two values are not equal, it returns 0
instead. Then, the bitwise operation -~
increments the value returned from the bool by 1
, giving us either 2
or 1
. max(a,b)
gives the maximum value of the pair and *
multiplies it by the value returned above (so it gets multiplied by 2
only if they are equal, in which case max()
returns the value of both).
This is based on the fact that the sum of two equal numbers is in fact either of them doubled, and kind of "abuses" Python's bool class being a subclass of int.
Kotlin, 78 75 71 66 65 59 bytes
It's my first attempt, be cool :D
a.zip(b).map{(a,b)->when{b>a->b;a>b->a;else->a*2}}.toList()
TIO doesn't work with this solution (and i don't know why), source code for testing below
fun main(args: Array<String>) {
bestOfTwo(floatArrayOf(), floatArrayOf()).print()
bestOfTwo(floatArrayOf(0F), floatArrayOf(0F)).print()
bestOfTwo(floatArrayOf(1F,2F,3F), floatArrayOf(1F,3F,2F)).print()
bestOfTwo(floatArrayOf(1F,3F,3.2F,2.3F), floatArrayOf(3F,1F,3.2F,2.6F)).print()
bestOfTwo(floatArrayOf(1F,2F,3F,4F,5F,5F,7F,8F,9F,10F), floatArrayOf(10F,9F,8F,7F,6F,5F,4F,3F,2F,1F)).print()
bestOfTwo(floatArrayOf(-3.2F,-3.2F,-2.4F,7F,-10.1F), floatArrayOf(100F,-3.2F,2.4F,-7F,-10.1F)).print()
}
fun bestOfTwo(a :FloatArray, b :FloatArray): List<Float> =
a.zip(b).map{(a,b)->when{b>a->b;a>b->a;else->a*2}}.toList()
fun List<Float>.print() {
this.forEach { print("$it, ") }; println("")
}
EDIT:
-3 by replace "a+b[i]" by "a*2"
-4 by replace "mapIndexed" method by "zip" (Thanks to @AnonymousReality Swift solution)
-5 by replace "Math.max" method by when condition
-1 by change when condition order
-6 by change toFloatArray() by toList()
JavaScript (ES6), 53 49 45 43 bytes
a=>b=>a.map((x,y)=>(y=b[y])>x?y:y<x?x:x+y)
- 4 bytes saved by borrowing a trick from Mr. Xcoder.
- 2 bytes saved thanks to Arnauld.
Try it
o.innerText=(f=
a=>b=>a.map((x,y)=>(y=b[y])>x?y:y<x?x:x+y)
)(i.value=[1,3,3.2,2.3])(j.value=[3,1,3.2,2.6]);oninput=_=>o.innerText=f(i.value.split`,`.map(eval))(j.value.split`,`.map(eval))
<input id=i><input id=j><pre id=o>
Explanation
a=>b=>
Anonymous function taking the 2 arrays as arguments via parameters a
and b
, in currying syntax (i.e., call with f(a)(b)
a.map((x,y)=> )
Map over the first array, passing each element through a function where x
is the current element and y
is the current index.
(y=b[y])
Get the element at index y
in the second array and assign that as the new value of y
.
>x?y
Check if y
is greater than x
and, if so, return y
.
:y<x?x
Else, check if y
is less than x
and, if so, return x
:x+y
Else, return the sum of x
and y
. (Multiplying x
or y
by 2 would also work here, for the same number of bytes.)