Um linear equação Diofantina em duas variáveis é uma equação da forma ax + by = C , em que um , b e c são números inteiros constantes e x e y são inteiros variáveis.
Para muitas equações diofantinas de ocorrência natural, x e y representam quantidades que não podem ser negativas.
Tarefa
Escrever um programa ou função que aceita os coeficientes de um , b e c como entrada e devolve um par arbitrário de números naturais (0, 1, 2, ...) x e y que verificar a equação ax + by = c , se um tal par existe.
Regras adicionais
Você pode escolher qualquer formato de entrada e saída que envolva apenas os números inteiros desejados e, opcionalmente, notação de matriz / lista / matriz / tupla / vetor do seu idioma, desde que não incorpore nenhum código à entrada.
Você pode assumir que os coeficientes de um e b são ambos não-zero.
Seu código deve funcionar para qualquer trio de números inteiros entre -2 60 e 2 60 ; ele deve terminar em menos de um minuto na minha máquina (Intel i7-3770, 16 GiB RAM).
Você não pode usar nenhum built-in que resolva equações diofantinas e, portanto, banalize esta tarefa, como as do Mathematica
FindInstance
ouFrobeniusSolve
.Seu código pode se comportar como quiser, se nenhuma solução puder ser encontrada, desde que cumpra o prazo e sua saída não possa ser confundida com uma solução válida.
Aplicam-se regras padrão de código de golfe .
Exemplos
Os exemplos abaixo ilustram E / S válidas para a equação 2x + 3y = 11 , que possui exatamente duas soluções válidas ( (x, y) = (4,1) e (x, y) = (1,3) ).
Input: 2 3 11 Output: [4 1] Input: (11 (2,3)) Output: [3],(1)
A única solução válida de 2x + 3y = 2 é o par (x, y) = (1,0) .
Os exemplos abaixo ilustram E / S válidas para a equação 2x + 3y = 1 , que não possui soluções válidas .
Input: (2 3 1) Output: [] Input: 1 2 3 Output: -1 Input: [[2], [3], [1]] Output: (2, -1)
Para (a, b, c) = (1152921504606846883, -576460752303423433, 1) , todas as soluções corretas (x, y) satisfazem que (x, y) = (135637824071393749 - bn, 271275648142787502 + an) para algum número inteiro não negativo n .
fonte
Respostas:
Pitão, 92 bytes
É um monstro e tanto.
Experimente online: Demonstração . O formato de entrada é
c\n[a,b]
e o formato de saída é[x,y]
.Caso não exista uma solução inteira, não imprimirei nada e, caso não exista uma solução natural natural, simplesmente imprimirei uma solução inteira aleatória.
Explicação (Visão Geral Bruta)
Inicialmente, encontrarei uma solução inteira para a equação
ax + by = gcd(a,b)
usando o algoritmo Euclidiano Estendido.Então eu modificarei a solução (minha multiplicação
a
eb
comc/gcd(a,b)
) para obter uma solução inteira deax + by = c
. Isso funciona, sec/gcd(a,b)
é um número inteiro. Caso contrário, não existe uma solução.Todas as outras soluções inteiras têm o formato
a(x+n*b/d) + b(y-n*a/d) = c
comd = gcd(a,b)
for inteiron
. Usando as duas desigualdadesx+n*b/d >= 0
ey-n*a/d >= 0
eu posso determinar 6 valores possíveis paran
. Vou tentar todos os 6 deles e imprimir a solução com o maior coeficiente mais baixo.Explicação (detalhada)
O primeiro passo é encontrar uma solução inteira para a equação
ax' + by' = gcd(a,b)
. Isso pode ser feito usando o algoritmo euclidiano estendido. Você pode ter uma idéia de como isso funciona na Wikipedia . A única diferença é que, em vez de usar 3 colunas (r_i s_i t_i
), usarei 6 colunas (r_i-1 r_i s_i-1 s_i t_i-1 t_i
). Dessa forma, não preciso manter as duas últimas linhas na memória, apenas a última.Agora eu quero encontrar uma solução para
ax + by = c
. Isso é possível apenas quandoc mod gcd(a,b) == 0
. Se esta equação for satisfeita, eu simplesmente multiplicox',y'
comc/gcd(a,b)
.Temos uma solução inteira para
ax + by = c
. Aviso, quex
,y
ou ambos, podem ser negativo. Portanto, nosso objetivo é transformá-los em não negativos.O bom das equações diofantinas é que podemos descrever todas as soluções usando apenas uma solução inicial. Se
(x,y)
é uma solução, todas as outras soluções têm a forma(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
den
número inteiro.Portanto, queremos encontrar a
n
, ondex-n*b/gcd(a,b) >= 0
ey+n*a/gcd(a,b >= 0
. Após alguma transformação, terminamos com as duas desigualdadesn >= -x*gcd(a,b)/b
en >= y*gcd(a,b)/a
. Observe que o símbolo de desigualdade pode olhar na outra direção devido à divisão com um potencial negativoa
oub
. Não me importo muito com isso, simplesmente digo que um número de-x*gcd(a,b)/b - 1, -x*gcd(a,b)/b, -x*gcd(a,b)/b + 1
satisfaz definitivamente a desigualdade 1 e um número dey*gcd(a,b)/a - 1, y*gcd(a,b)/a, y*gcd(a,b)/a + 1
satisfaz a desigualdade 2. Existe umn
que satisfaz ambas as desigualdades, um dos 6 números também satisfaz.Então eu calculo as novas soluções
(x-n*b/gcd(a,b),y+n*a/gcd(a,b))
para todos os 6 valores possíveis den
. E imprimo a solução com o menor valor mais alto.A classificação por ordem de classificação funciona da seguinte maneira. Estou usando o exemplo
2x + 3y = 11
Classifico cada uma das 6 soluções (chamadas de chaves) e classifico as soluções originais por suas chaves:
Isso classifica uma solução completa não negativa até o fim (se houver).
fonte
Matlab (660)
Explicação:
o código usa três invariantes a, b, c como entrada, esses últimos são subdivididos em duas condições antes de proceder ao cálculo:
1- se (a + b> c) e (a, b, c> 0) não há solução!
2- se (a + b <c), (a, b, c <0) não há solução!
3- se (a, b) têm sinais opostos comuns de c: sem solução!
4- se o GCD (a, b) não dividir c, não haverá solução novamente! caso contrário, divida todas as variantes por GCD.
depois disso, temos que verificar outra condição, deve facilitar e facilitar o caminho para a solução desejada.
5- se c divide a ou b, solução s = (x ou y) = (c- [ax, yb]) / [b, a] = C / [b, a] + [ax, yb] / [b , a] = S + [ax, yb] / [b, a] onde S é natural, então ax / b ou by / a teriam doravante soluções diretas não-negativas que são respectivamente x = b ou y = a. (observe que as soluções podem ser apenas valores nulos, caso soluções arbitrárias anteriores sejam reveladas negativas)
quando o programa chega a esse estágio, uma gama mais estreita de soluções para x = (c-yb) / a é varrida, graças à congruência de varrer faixas maiores de números, que são repetidas repetidamente por ciclos regulares. o maior campo de pesquisa é [xa, x + a] onde a é o divisor.
TENTE
fonte
Axioma, 460 bytes
ungolf e algum teste
Nas outras 'soluções' possíveis, houve um erro porque tentou salvar as infinitas soluções em uma lista; agora é imposto o limite de 80 soluções no máximo
fonte