16
\$\begingroup\$

Minimum Scalar Product

The inspiration for this code golf problem is from Google's code jam competition. The premise behind the problem is, given the input of two vectors of varying lengths, find the minimum possible scalar. A scalar can be found using the following formula:

x1 * y1 + x2 * y2 + ... + xn * yn

The problem, however, is that multiple values for the scalar can be found depending on the order of the numerals in the input case (seen below). Your goal is to determine the minimum possible scalar integer solution by plugging in the input case numbers into the equation and solving for it. You may use every number in the input only once, and must use all of the numbers.

Allow me to provide an example with the following vectors.

Input

3
1 3 -5
-2 4 1

Output

-25

The first integer on the line represents the number of numbers, n, in each vector. In this case, we have three numbers in each vector.

The number n may vary with each test case, but there will always be two vectors.

In the example input, the minimum scalar product would be -25.

(-5 * 4) + (1 * 1) + (3 * -2) = 25

Rules

  • You may only use each integer in both vectors once.
  • You must use all integers in the vectors.
  • Your output must only include the final product
  • I'll select the solution with the least amount of code, which follows all of the specifications listed above, in any language!

Hint: You don't need to brute force this problem, unless it makes your code shorter. There is a specific method involved in finding the minimum spanning scalar :).

asked Mar 12, 2016 at 3:18
\$\endgroup\$
1

20 Answers 20

8
\$\begingroup\$

Jelly, 6 bytes

×ばつṢ}S

Try it online!

Using brute force is equally short:

×ばつS€Ṃ

How it works

×ばつṢ}S Main link. Arguments: u (vector), v (vector)
Ṣ Sort the components of u.
 Ṛ Reverse.
 Ṣ} Sort the components of v.
 ×ばつ Multiply the results, element by element.
 S Compute the sum of the products.
answered Mar 12, 2016 at 5:04
\$\endgroup\$
6
\$\begingroup\$

Seriously, 6 bytes

,SR,S*

Try it online!

Explanation:

,SR,S*
,SR input first vector, sort, reverse
 ,S input second vector, sort
 * dot product
answered Mar 12, 2016 at 6:38
\$\endgroup\$
0
5
\$\begingroup\$

APL, 15 bytes

×ばつ⍵[⍋⍵]}

This is a dyadic function that accepts arrays on the left and right and returns an integer. It uses the same approach as my Julia answer: dot product of the sorted arrays, one descending and one ascending.

Try it here

answered Mar 12, 2016 at 6:55
\$\endgroup\$
5
\$\begingroup\$

MATL, 6 bytes

Code:

SiSP*s

My first MATL answer :)

Explanation:

S # Sort the first array
 iS # Take the second array and sort it
 P # Flip the array
 * # Multiply both arrays with each other
 s # Sum of the result

Try it online!

answered Mar 12, 2016 at 9:28
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I'm glad to see this! :-) \$\endgroup\$ Commented Mar 12, 2016 at 10:05
4
\$\begingroup\$

Mathematica, (削除) 30 (削除ここまで) 17 bytes

-13 bytes by murphy

Sort@#.-Sort@-#2&

Function, input is vector1(list),vector2(list) Several revisions:

Plus@@(Sort@#*Reverse@Sort@#2)&(*me*)
Total[Sort@#*Reverse@Sort@#2]& 
Sort@#.Reverse@Sort@#2& (*alephalpha*)
Sort@#.Sort[#2,#>#2&]& (*murphy*)
Sort@#.SortBy[#2,-#&] (*me*)
Sort@#.-Sort@-#2& (*murphy*)
answered Mar 12, 2016 at 3:39
\$\endgroup\$
5
  • \$\begingroup\$ clever solution! \$\endgroup\$ Commented Mar 12, 2016 at 4:49
  • 2
    \$\begingroup\$ Sort@#.Reverse@Sort@#2& \$\endgroup\$ Commented Mar 12, 2016 at 6:36
  • \$\begingroup\$ Sort@#.Sort[#2,#>#2&]& \$\endgroup\$ Commented Mar 12, 2016 at 21:21
  • 1
    \$\begingroup\$ Sort@#.-Sort@-#2& \$\endgroup\$ Commented Mar 12, 2016 at 21:33
  • \$\begingroup\$ Or for your solution 1, Sort@#.SortBy[#2,-#&] \$\endgroup\$ Commented Mar 12, 2016 at 21:45
3
\$\begingroup\$

Julia, (削除) 32 (削除ここまで) 25 bytes

x->y->-sort(-x)⋅sort(y)

This is an anonymous function that accepts two arrays and returns an integer. To call it, assign it to a variable and do f(x)(y).

For inputs x and y, we simply compute the dot product of x sorted in reverse order with y sorted. We get x in reverse sorted order by negating all values, sorting, then negating again.

Saved 7 bytes thanks to Dennis!

answered Mar 12, 2016 at 6:47
\$\endgroup\$
0
2
\$\begingroup\$

Pyth - (削除) 14 (削除ここまで) 8 bytes

I think I figured out the trick.

s*VSQ_SE

Try it online here.

answered Mar 12, 2016 at 3:58
\$\endgroup\$
0
2
\$\begingroup\$

Javascript ES6, 69 bytes

a=>b=>a.sort((x,y)=>x-y).map((x,y)=>i+=b.sort((x,y)=>y-x)[y]*x,i=0)|i

Wow, this is way too long.

answered Mar 12, 2016 at 20:30
\$\endgroup\$
5
  • \$\begingroup\$ I think trying to reuse the sort function is costing you 3 bytes. \$\endgroup\$ Commented Mar 12, 2016 at 20:35
  • \$\begingroup\$ I did more golfing. Better? \$\endgroup\$ Commented Mar 12, 2016 at 20:43
  • \$\begingroup\$ You can probably save a byte with |i instead of &&i \$\endgroup\$ Commented Mar 13, 2016 at 1:36
  • \$\begingroup\$ Thx @ETHproductions \$\endgroup\$ Commented Mar 13, 2016 at 1:38
  • \$\begingroup\$ Yes, that's what I was thinking of. \$\endgroup\$ Commented Mar 13, 2016 at 10:58
2
\$\begingroup\$

Perl 6, (削除) 33 (削除ここまで) 30 bytes

{sum @^a.sort Z*@^b.sort.reverse}
answered Mar 12, 2016 at 6:32
\$\endgroup\$
1
  • \$\begingroup\$ Why not {sum @^a.sort Z*[R,] @^b.sort}((1,3,-5),(-2,4,1)).say \$\endgroup\$ Commented May 8, 2016 at 15:16
1
\$\begingroup\$

CJam, 11 Bytes

q~$\$W%.*:+

Try it online!

answered Mar 12, 2016 at 15:12
\$\endgroup\$
1
\$\begingroup\$

C++, 124 bytes

#include<algorithm>
int m(int*a,int*b,int n){std::sort(a,a+n);std::sort(b,b+n);int r=0;while(--n>=0)r+=a[n]**b++;return r;}

ungolfed:

#include<algorithm>
int m(int*a,int*b,int n){
 std::sort(a,a+n);
 std::sort(b,b+n);
 int r=0;
 while(--n>=0)
 r+=a[n]*(*b++);
return r;
}

At first i used std::greater<int>() for the sort in b but just reversing the order in the summation is easier.

answered Jul 13, 2016 at 8:58
\$\endgroup\$
1
\$\begingroup\$

Haskell, 59 bytes

import Data.List
v?u=sum$zipWith(*)(sort v)$reverse$sort u
answered Jul 14, 2016 at 13:28
\$\endgroup\$
1
\$\begingroup\$

Python 3, 136 bytes

def mdp(n, a, b):
 a = list(reversed(sorted(a)))
 b = sorted(b)
 res = sum([a[i] * b[i] for i in range(len(a))])
 return res

Try it online!

Lucenaposition
2,5181 gold badge5 silver badges28 bronze badges
answered Jul 13, 2016 at 3:04
\$\endgroup\$
5
  • 2
    \$\begingroup\$ You can save a few bytes by removing spaces next to equals, for instance b = sorted(b) turns into b=sorted(b) (2 bytes saved). You can additionally put multiple statements on the same line by separating them with a semicolon, for instance a=list(reversed(sorted(a)));b=sorted(b);res=0 \$\endgroup\$ Commented Jul 13, 2016 at 4:01
  • \$\begingroup\$ @charredgrass I'm new here. What's the need to save every possible byte? I was trying to make it readable. \$\endgroup\$ Commented Jul 13, 2016 at 4:02
  • 1
    \$\begingroup\$ Welcome to PPCG then! This question is a code-golf competition where the goal is to write code to complete the challenge in the fewest bytes possible, which usually means less readable code. \$\endgroup\$ Commented Jul 13, 2016 at 4:21
  • \$\begingroup\$ @charredgrass got it! \$\endgroup\$ Commented Jul 13, 2016 at 4:30
  • 2
    \$\begingroup\$ Much shorter: lambda a,b,s=sorted:sum(x*y for x,y in zip(s(a)[::-1],s(b))). We don't require function submissions to be named (so an unnamed lambda is valid), and the n parameter is unnecessary (many other submissions omit it entirely). \$\endgroup\$ Commented Jul 13, 2016 at 5:40
0
\$\begingroup\$

RETURN, 29 bytes

×ばつ␌]#}␁[¤][+]#]

Try it here.

Replace any ␆␃␄␇ with their unprintable counterparts.

Anonymous lambda that leaves result on stack2. Usage:

""{1 3 0 5-}""{0 2- 4 ×ばつ␌]#}␁[¤][+]#]!

Explanation

[ ] lambda
 {␆␃} sort and reverse first stack
 \{␆} sort second stack
 ␄␅ transpose and flatten
 [ ][ ]# while loop
 ¤\ check if 2 items exist in stack
 ×ばつ if so, multiply top 2 items
 ␌ and push to stack2
 }␁ switch to stack2
 [¤][+]# sum stack2
answered Mar 13, 2016 at 2:59
\$\endgroup\$
0
\$\begingroup\$

J, 14 bytes

+/@(*|.)&(/:~)

Uses the same principle as the others.

Explanation

+/@(*|.)&(/:~) Input: x on LHS and y on RHS
 &(/:~) Sort both x and y
 |. Reverse the sorted y
 * Multiply the sorted x and reversed sorted y elementwise
+/@ Reduce the products using addition and return
answered Jul 14, 2016 at 16:28
\$\endgroup\$
0
\$\begingroup\$

Ruby, 44 bytes

->a,b{a.sort.reverse.zip(b.sort).sum{_1*_2}}

Attempt This Online!

answered Aug 27, 2024 at 15:25
\$\endgroup\$
0
\$\begingroup\$

Japt -x, 6 bytes

Íí*VÍÔ

Try it

answered Aug 27, 2024 at 18:15
\$\endgroup\$
0
\$\begingroup\$

Uiua, 9 bytes

×ばつ⇌∩⊏∩⊸⍏

Try it!

×ばつ⇌∩⊏∩⊸⍏
 ⊏ ⊸⍏ # sort
 ∩ ∩ # both
 ⇌ # reverse one
 ×ばつ # multiply
/+ # sum
answered Aug 27, 2024 at 20:01
\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 62 bytes

a=>a.map(x=>x.sort((x,y)=>x-y))[i=0].map(x=>i+=a[1].pop()*x)|i

Try it online!

Based on Mama Fun Roll's

-4B by Shaggy by switching Input format

answered Aug 28, 2024 at 2:26
\$\endgroup\$
1
  • \$\begingroup\$ 62 bytes with a 2D-array. \$\endgroup\$ Commented Aug 28, 2024 at 17:00
0
\$\begingroup\$

Scala 3, 76 bytes

(x,y)=>x.sorted(Ordering[Int].reverse).zip(y.sorted).map{case(a,b)=>a*b}.sum

Attempt This Online!

answered Aug 30, 2024 at 8:25
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.