Знайдіть крапковий добуток Rationals


31

Я був у будинку друга на вечерю, і вони запропонували ідею "простору вектора основного фактору". У цьому просторі додатні цілі числа виражаються у вигляді вектора такого, що n- й елемент у векторі - це кількість разів, де n- го простих ділить число. (Зверніть увагу, що це означає, що наші вектори мають нескінченну кількість термінів.) Наприклад 20 є

2 0 1 0 0 0 ...

Тому що його основна факторизація становить 2 * 2 * 5 .

Оскільки проста множина є унікальною, кожне число відповідає одному вектору.

Ми можемо додати вектори, попарно додавши їх записи. Це те саме, що множення чисел, з якими вони пов'язані. Ми також можемо зробити скалярне множення, яке схоже на підняття асоційованого числа до потужності.

Проблема полягає в тому, що цей простір насправді не є векторним простором, оскільки немає зворотів. Якщо ми продовжимо додавання обертів і закриємо векторний простір, тепер у нас є спосіб виразити кожне позитивне раціональне число як вектор. Якщо ми збережемо той факт, що векторне додавання являє собою множення. Тоді зворотне натуральне число є його зворотним.

Наприклад, число 20 мало вектор

2 0 1 0 0 0 ...

Значить, частка 1/20 - це її обернена

-2 0 -1 0 0 0 ...

Якби ми хотіли знайти вектор, асоційований із дробом на зразок 14/15, ми знайшли б 14

1 0 0 1 0 0 ...

та 1/15

0 -1 -1 0 0 0 ...

і помножте їх, виконуючи векторне додавання

1 -1 -1 1 0 0 ...

Тепер, коли у нас є векторний простір, ми можемо модифікувати його, щоб утворювати внутрішній простір продукту, надаючи йому внутрішній продукт. Для цього ми вкрадаємо внутрішній продукт, у якому векторні простори задані класично. Внутрішній добуток двох векторів визначається як сума попарного множення їх доданків. Наприклад, 20 · 14/15 буде обчислено наступним чином

20    =  2  0  1  0  0  0 ...
14/15 =  1 -1 -1  1  0  0 ...
         2  0 -1  0  0  0 ...  -> 1

В якості іншого прикладу добуток 2/19 · 4/19

2/19 = 1 0 0 0 0 0 0 -1 0 0 0 ...
4/19 = 2 0 0 0 0 0 0 -1 0 0 0 ...
       2 0 0 0 0 0 0  1 0 0 0 ... -> 3

Ваше завдання - реалізувати програму, яка виконує цей точковий продукт. Він повинен приймати два позитивних раціональних числа або через пару натуральних чисел (чисельник і знаменник), або раціональний тип (поплавці заборонені, оскільки вони створюють проблеми з точністю і роздільністю) і повинні вивести ціле число, що представляє крапковий добуток двох входи.

Це тому відповіді будуть набрані в байтах, а менша кількість байтів буде кращою.

Випробування

4 · 4 = 4
8 · 8 = 9
10 · 10 = 2
12 · 12 = 5
4 · 1/4 = -4
20 · 14/15 = 1
2/19 · 4/19 = 3

Вектор не має розмірності, має векторний простір.
Джонатан Фрех

5
@JonathanFrech Я думаю, що це трохи педантично, але я змінив зміни.
Пшеничний майстер

Як правило, "натуральні числа" містять 0, який не представлений у вашій системі. І це не вектори. Векторний простір знаходиться над полем, і це над кільцем, яке зробило б це модулем. І це не окремий простір від цілих чисел, це той самий простір з іншим поданням.
Нагромадження

6
@ Накопичення "Натуральні числа" не є чітко визначеним терміном, залежно від того, кого ви запитуєте, він може містити або не містити нуля. Ви вірні, що "скалярне множення" у моєму запитанні утворює набір G з моноїдом, а не групою, але це було спрощено для того, щоб зробити питання приємним. Я не впевнений, що робити з вашим останнім коментарем, впевнений, що він має таку ж кардинальність, як цілі числа, але дія дійсно те, що визначає пробіл, а не його розмір. Можливо, ви маєте на увазі щось більш конкретне, чого я сумую. Якщо так, я би радий продовжити цю дискусію (у чаті, можливо, найкраще).
Пшеничний майстер

2
Інша термінологія вибору ниток: векторні простори зазвичай мають скалярне множення з поля, тому просто використання цілих чисел недостатньо. Це тому, що ми хочемо, щоб паралельні вектори були кратними один одному, а не просто малими кількома спільними. Наприклад, $ 4 і 8 $ є паралельними "векторами" в цьому просторі (вони обидва вигляду (a, 0, 0, ...)), але не є скалярним кратним (тобто цілою силою) інший. Існує не так багато інших термінів, які ви могли б використовувати, хоча це було б відомо людям загалом. "Вільний модуль над цілими числами" - це найкраще, що я можу зробити.
Артур

Відповіді:


4

MATL , 12 байт

YF2:&Y)dwd*s

Вхід - це масив [num1 den1 num2 den2].

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення

Розглянемо приклад введення [20 1 14 15].

YF      % Implicit input: array of 4 numbers. Exponents of prime factorization.
        % Gives a matrix, where each row corresponds to one of the numbers in
        % the input array. Each row may contain zeros for non-present factors
        % STACK: [2 0 1 0
                  0 0 0 0
                  1 0 0 1
                  0 1 1 0]
2:&Y)   % Push a submatrix with the first two rows, then a submatrix with the
        % other two rows
        % STACK: [2 0 1 0
                  0 0 0 0],
                 [1 0 0 1
                  0 1 1 0]
d       % Consecutive difference(s) along each column
        % STACK: [2 0 1 0
                  0 0 0 0],
                 [-1 1 -1 1]
wd      % Swap, and do the same for the other submatrix
        % STACK: [-1 1 -1 1]
                 [-2 0 -1 0]
*       % Element-wise product
        % STACK: [2 0 -1 0]
s       % Sum. Implicit display
        % STACK: 1

4

C (gcc) , 99 + 32 = 131 байт

  • Використовуючи прапор компілятора , що вимагає 32 байта, -D=F(v,V,e)for(;v%p<1;V+=e)v/=p;.
T,p,A,C;f(a,b,c,d){T=0;for(p=2;a+b+c+d>4;p++){A=C=0;F(a,A,1)F(b,A,~0)F(c,C,1)F(d,C,~0)T+=A*C;}a=T;}

Спробуйте в Інтернеті!


Я думаю, що краще чітко вказати, що використовується додатковий прапор -D=F(v,V,e)for(;v%p<1;V+=e)v/=p;(32 байти) (так 99 + 32 = 131); інакше сам код мало сенсу.
Бубон


3

Python 2 , 110 байт

l=input()
p=t=2
while~-max(l):r=i=0;exec"while l[i]%p<1:l[i]/=p;r+=1j**i\ni+=1\n"*4;t+=r*r;p+=1
print t.imag/2

Спробуйте в Інтернеті!

Приймає вхід як [num1, num2, den1, den2]. Використовує складне число, rщоб зберігати записи для простих pдвох раціоналів та (r*r).imag/2витягувати їх продукт r.real*r.imagу загальній сумі t. Додавання 1j**iдля i=0,1,2,3робить кожну комбінацію збільшуючи або зменшуючи реальну або уявну частину для чотирьох вхідних чисел.

Bubbler зберег 2 байти, поєднуючи початкові значення p=t=2.


1
p=t=2замість того , p=2;t=0так як t.realігнорується в будь-якому випадку ( TIO ).
Бубон

@Bubbler Приємний, додаючи!
xnor


1

JavaScript (Node.js) , 104 ... 100 94 байт

F=(A,i=2)=>A.some(x=>x>1)&&([a,b,c,d]=A.map(G=(x,j)=>x%i?0:1+G(A[j]/=i,j)),a-b)*(c-d)+F(A,i+1)

Спробуйте в Інтернеті!

Передайте числа у вигляді масиву [Num1, Den1, Num2, Den2].

Дякуємо Арноульду, що він виправив відсутніх F=зайвих байтів і ще на 2 байти менше.

Пояснення і невольф

function F(A, i = 2) {                 // Main function, recursing from i = 2
 if (A.some(function(x) {              // If not all numbers became 1:
  return x > 1;
 })) {
  var B = A.map(G = function(x, j) {   // A recursion to calculate the multiplicity
   if (x % i)
    return 0;
   else
    return 1 + G(A[j] /= i, j);        // ...and strip off all powers of i
  });
  return (B[0] - B[1]) * (B[2] - B[3]) // Product at i
   + F(A, i + 1);                      // Proceed to next factor. All composite factors 
 }                                     // will be skipped effectively
 else 
  return 0;                            // Implied in the short-circuit &&
}

1

J , 19 байт

1#.*/@,:&([:-/_&q:)

Спробуйте в Інтернеті!

Пояснення:

Діадичне дієслово, аргументи є і на лівій, і на правій стороні

         &(        ) - for both arguments (which are lists of 2 integers)
               _&q:  - decompose each number to a list of prime exponents
           [:-/      - and find the difference of these lists
       ,:            - laminate the resulting lists for both args (to have the same length)
   */@               - multiply them
1#.                  - add up 

1

Стакс , 11 байт

ä÷ß½♂←√:=Ü]

Запустіть і налагоджуйте його

Відповідне представлення такої ж програми ascii.

{|nmMFE-~-,*+

В основному, він отримує основні показники факторизації для кожної частини. Він займає різницю кожної пари, потім продукт і, нарешті, підбиває всі результати.


1

Python 2 , 133 127 байт

a=input();s=0;p=2;P=lambda n,i=0:n%p and(n,i)or P(n/p,i+1)
while~-max(a):a,(w,x,y,z)=zip(*map(P,a));s+=(w-x)*(y-z);p+=1
print s

Спробуйте в Інтернеті!

Вкрасти стан циклу з подання xnor .

Дякую за пораду від @mathmandan щодо зміни функції в програму (Так, вона дійсно зберегла деякі байти).

Застаріле, неправильне рішення (124 байти):

lambda w,x,y,z:sum((P(w,p)-P(x,p))*(P(y,p)-P(z,p))for p in[2]+range(3,w+x+y+z,2))
P=lambda n,p,i=1:n%p and i or P(n/p,p,i+1)

Не pзбираєтеся перевіряти непрості значення, як 9?
xnor

На жаль, я скоро це виправлю.
Бубон

3
Ви можете замінити returnна print, а також можете зберегти пробіли, якщо ви пишете як програму замість функції.
mathmandan

@mathmandan Дякую за інформацію. Здається корисним для інших моїх подань на Py2, хоча для Py3 не впевнений (це займе, eval()якщо введення функції не є рядком).
Бубон

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.