Encontre o produto escalar do Rationals


31

Eu estava na casa de um amigo para jantar e eles sugeriram a idéia de um "espaço vetorial de fator primordial". Neste espaço das números inteiros positivos são expressos como um vector de modo a que o n ésimo elemento no vector é o número de vezes que o n th divide primos do número. (Observe que isso significa que nossos vetores têm um número infinito de termos.) Por exemplo, 20 é

2 0 1 0 0 0 ...

Porque sua fatoração principal é 2 * 2 * 5 .

Como a fatoração primária é única, cada número corresponde a um vetor.

Podemos adicionar vetores adicionando suas entradas em pares. É o mesmo que multiplicar os números aos quais estão associados. Também podemos fazer a multiplicação escalar, o que é semelhante a elevar o número associado a uma potência.

O problema é que esse espaço não é de fato um espaço vetorial, porque não há inversos. Se prosseguirmos, adicionarmos os inversos e fecharmos o espaço vetorial, agora temos uma maneira de expressar todo número racional positivo como um vetor. Se mantivermos o fato de que a adição de vetores representa multiplicação. Então o inverso de um número natural é recíproco.

Por exemplo, o número 20 tinha o vetor

2 0 1 0 0 0 ...

Então a fração 1/20 é inversa

-2 0 -1 0 0 0 ...

Se quiséssemos encontrar o vetor associado a uma fração como 14/15 , encontraríamos 14

1 0 0 1 0 0 ...

e 1/15

0 -1 -1 0 0 0 ...

e multiplique-os executando a adição de vetores

1 -1 -1 1 0 0 ...

Agora que temos um espaço vetorial, podemos modificá-lo para formar um espaço interno do produto, fornecendo-lhe um produto interno. Para fazer isso, roubamos o produto interno que os espaços vetoriais recebem classicamente. O produto interno de dois vetores é definido como a soma da multiplicação por pares de seus termos. Por exemplo 20 · 14/15 seria calculado da seguinte forma

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

Como outro exemplo, o produto 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

Sua tarefa é implementar um programa que executa esse produto de ponto. Ele deve receber dois números racionais positivos por meio de um número inteiro positivo (numerador e denominador) ou um tipo racional (flutuadores não são permitidos, porque causam problemas de precisão e divisibilidade) e deve gerar um número inteiro representando o produto escalar dos dois entradas.

Isso é então as respostas serão pontuadas em bytes, com menos bytes sendo melhores.

Casos de teste

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

Um vetor não tem uma dimensão, um espaço vetorial.
Jonathan Frech 22/02

5
@ JonathanFrech Eu acho que é um pouco pedante, mas eu fiz a mudança.
Assistente de trigo

Geralmente, entende-se por "números naturais" como 0, que não é representado no seu sistema. E esses não são vetores. Um espaço vetorial está sobre um campo e sobre um anel, o que tornaria este um módulo. E não é um espaço separado dos números inteiros, é o mesmo espaço com uma representação diferente.
Acumulação

6
@ Acumulação "Números naturais" não é um termo bem definido, dependendo de quem você pergunta pode ou não conter zero. Você está certo de que a "multiplicação escalar" na minha pergunta forma um conjunto G com um monóide, e não um grupo, mas isso foi simplificado com o objetivo de tornar a pergunta palatável. Não tenho certeza do que fazer com seu último comentário, com certeza tem a mesma cardinalidade que os números inteiros, mas a ação é realmente o que define um espaço, não o tamanho. Talvez você queira dizer algo mais específico que estou perdendo. Nesse caso, eu ficaria feliz em continuar esta discussão (no chat pode ser melhor).
Assistente de trigo

2
Outra terminologia nit-pick: geralmente é necessário que os espaços vetoriais tenham multiplicação escalar de um campo; portanto, apenas o uso de números inteiros não é suficiente. Isso ocorre porque queremos que os vetores paralelos sejam múltiplos um do outro, e não apenas tenham múltiplos em comum. Por exemplo, $ 4 $ e $ 8 $ são "vetores" paralelos nesse espaço (ambos têm a forma (a, 0, 0, ...)), mas também não é um múltiplo escalar (isto é, uma potência inteira) do de outros. No entanto, não existem muitos outros termos que você possa usar que seriam conhecidos pelas pessoas em geral. "Módulo livre sobre números inteiros" é o melhor que posso fazer.
Arthur

Respostas:


4

MATL , 12 bytes

YF2:&Y)dwd*s

Entrada é uma matriz [num1 den1 num2 den2].

Experimente online! Ou verifique todos os casos de teste .

Explicação

Considere exemplo de entrada [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 bytes

  • Usando um sinalizador de compilador que requer 32 bytes -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;}

Experimente online!


Eu acho que é melhor especificar explicitamente que o sinalizador adicional -D=F(v,V,e)for(;v%p<1;V+=e)v/=p;(32 bytes) é usado (então 99 + 32 = 131); caso contrário, o código por si só faz pouco sentido.
Bubbler


3

Python 2 , 110 bytes

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

Experimente online!

Toma entrada como [num1, num2, den1, den2]. Usa um número complexo rpara armazenar as entradas de prime ppara os dois racionais e (r*r).imag/2extrair seu produto r.real*r.imagna soma geral t. Adicionar 1j**ipara i=0,1,2,3cada combinação de incremento ou decremento da parte real ou imaginária dos quatro números de entrada.

O Bubbler salvou 2 bytes combinando os valores iniciais p=t=2.


1
p=t=2em vez de p=2;t=0uma vez t.realé ignorada qualquer maneira ( TIO ).
Bubbler

@Bubbler Nice, adicionando!
xnor 24/02


1

JavaScript (Node.js) , 104 ... 100 94 bytes

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)

Experimente online!

Passe os números como uma matriz de [Num1, Den1, Num2, Den2].

Obrigado por Arnauld por corrigir os desaparecidos F=sem bytes extras e mais 2 bytes a menos.

Explicação e não destruídos

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 bytes

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

Experimente online!

Explicação:

Um verbo diádico, os argumentos estão do lado esquerdo e do lado direito

         &(        ) - 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

Stax , 11 bytes

ä÷ß½♂←√:=Ü]

Execute e depure

A representação ascii correspondente do mesmo programa é essa.

{|nmMFE-~-,*+

Basicamente, obtém os expoentes da fatoração principal para cada parte. É preciso a diferença de cada par, depois do produto e, finalmente, soma todos os resultados.


1

Python 2 , 133 127 bytes

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

Experimente online!

Roubou a condição de loop da submissão do xnor .

Obrigado pelo conselho de @mathmandan para alterar a função em um programa (Sim, ele realmente salvou alguns bytes).

Solução obsoleta e incorreta (124 bytes):

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)

Não pvai testar valores não primos como 9?
Xnor

Opa, eu vou consertar isso em breve.
Bubbler

3
Você pode substituir returnpor printe também pode salvar os espaços de indentação se escrever como um programa em vez de uma função.
mathmandan

@ mathmandan Obrigado pela informação. Parece útil para meus outros envios de Py2, mas não tenho certeza para o Py3 (é preciso extra eval(), a menos que a entrada da função em si seja uma string).
Bubbler

1

Haskell , 153 bytes

(2%)
n%m|all(<2)m=0|(k,[a,b,c,d])<-unzip[(,)=<<div x.max 1.(n*)$until((>0).mod x.(n^))(+1)1-1|x<-m]=(a-b)*(c-d)+[i|i<-[n..],all((>0).rem i)[2..i-1]]!!1%k

Experimente online! Exemplo de utilização para 20 · 14/15: (2%) [20,1,14,15].

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.