Минимальный скалярный продукт


16

Минимальный скалярный продукт

Источником вдохновения для решения этой проблемы является гольф- конкурс Google . Причиной проблемы является, учитывая вход двух векторов различной длины, найти минимально возможный скаляр. Скаляр можно найти по следующей формуле:

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

Проблема, однако, заключается в том, что можно найти несколько значений для скаляра в зависимости от порядка чисел во входном регистре (см. Ниже). Ваша цель состоит в том, чтобы определить минимально возможное скалярное целочисленное решение, вставив входные числа наблюдений в уравнение и найдя для него решение. Вы можете использовать каждое число на входе только один раз, и должны использовать все числа.

Позвольте мне привести пример со следующими векторами.

вход

3
1 3 -5
-2 4 1

Выход

-25

Первое целое число в строке представляет количество чисел n в каждом векторе. В этом случае у нас есть три числа в каждом векторе.

Число n может варьироваться в зависимости от каждого теста, но всегда будет два вектора.

В приведенном примере минимальное скалярное произведение будет равно -25.

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

правила

  • Вы можете использовать каждое целое число в обоих векторах только один раз.
  • Вы должны использовать все целые числа в векторах.
  • Ваш вывод должен включать только конечный продукт
  • Я выберу решение с наименьшим количеством кода, которое соответствует всем перечисленным выше спецификациям, на любом языке!

Подсказка: вам не нужно грубо форсировать эту проблему, если она не делает ваш код короче. Существует определенный метод поиска минимального охватывающего скаляра :).


Я действительно не хочу никого портить, поэтому не открывайте это, если вы уже не знаете ответ. это так хорошо известно, это смешно. en.m.wikipedia.org/wiki/Rearrangement_inequality
гордый haskeller

Ответы:


8

Желе, 6 байт

ṢṚ×Ṣ}S

Попробуйте онлайн!

Использование грубой силы одинаково коротко:

Œ!×S€Ṃ

Как это устроено

ṢṚ×Ṣ}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.


5

APL, 15 байт

{+/⍺[⍒⍺]×⍵[⍋⍵]}

Это двоичная функция, которая принимает массивы слева и справа и возвращает целое число. Он использует тот же подход, что и мой ответ Джулии : скалярное произведение отсортированных массивов, одного по убыванию и одного по возрастанию.

Попробуй здесь



4

Mathematica, 30 17 байт

-13 байтов от Murphy

Sort@#.-Sort@-#2&

Функция, input это vector1 (список), vector2 (список) Несколько ревизий:

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*)

умное решение!
baseman101

2
Sort@#.Reverse@Sort@#2&
алефальфа

Sort@#.Sort[#2,#>#2&]&
Мерфи

1
Sort@#.-Sort@-#2&
Мерфи

Или для вашего решения 1,Sort@#.SortBy[#2,-#&]
CalculatorFeline


2

Юлия, 32 25 байт

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

Это анонимная функция, которая принимает два массива и возвращает целое число. Чтобы вызвать его, назначьте его переменной и выполните f(x)(y).

Для входов x и y мы просто вычисляем скалярное произведение x, отсортированное в обратном порядке по y . Мы получаем x в обратном порядке, отрицая все значения, сортируя и снова отрицая.

Сэкономили 7 байт благодаря Денису!


2

Javascript ES6, 69 байт

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

Вау, это слишком долго.


Я думаю, что попытка повторно использовать функцию сортировки стоит вам 3 байта.
Нил

Я сделал больше игры в гольф. Лучше?
Mama Fun Roll

Вы, вероятно, можете сохранить байт |iвместо&&i
ETHproductions

Thx @ETHproductions
Mama Fun Roll

Да, это то, о чем я думал.
Нил



1

Python, 139 байт

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

1
Вы можете сохранить несколько байтов, удалив пробелы рядом с равными, например, b = sorted(b)превращается в b=sorted(b)(сохранено 2 байта). Вы можете дополнительно поместить несколько операторов в одну строку, например, разделив их точкой с запятойa=list(reversed(sorted(a)));b=sorted(b);res=0
charredgrass

@charredgrass Я новичок здесь. Зачем нужно сохранять каждый возможный байт? Я пытался сделать это читабельным.
бунтарь

Тогда добро пожаловать в PPCG! Этот вопрос представляет собой соревнование по коду-гольфу, целью которого является написание кода для выполнения задачи с наименьшим возможным количеством байтов, что обычно означает менее читаемый код.
Charredgrass

@charredgrass понял!
бунтарь

2
Гораздо короче lambda a,b,s=sorted:sum(x*y for x,y in zip(s(a)[::-1],s(b))). Нам не нужно, чтобы имена функций были названы (так что лямбда без имени действительна), а nпараметр не нужен (во многих других представлениях он полностью отсутствует).
Мего

1

C ++, 124 байта

#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;
}

Сначала я использовал std::greater<int>()для сортировки, bно проще поменять порядок в суммировании.



0

ВОЗВРАТ , 29 байт

[{␆␃}\{␆}␄␅[¤¥][×␌]#}␁[¤][+]#]

Try it here.

Заменить любой ␆␃␄␇ их непечатными копиями.

Анонимная лямбда, которая оставляет результат на stack2. Использование:

""{1 3 0 5-}""{0 2- 4 1}[{␆␃}\{␆}␄␅[¤¥][×␌]#}␁[¤][+]#]!

объяснение

[                                 ]  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

0

J, 14 байт

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

Использует тот же принцип, что и другие.

объяснение

+/@(*|.)&(/:~)  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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.