Python 3 , 177 170 163 130 bytes
lambda a,b:s(d(a)^d(b))
def s(n,x=0,s=''):
while n:n-=1;s+=chr(n%256);n>>=8
return s
def d(n,c=0):
while s(c)!=n:c+=1
return c
Experimente online!
-14 bytes graças a notjagan
-33 bytes graças a Leaky Nun (e endianness comutado)
Não tenho negócios tentando jogar golfe em Python, mas não queria usar Lua, pois esse método precisa de números inteiros exatos grandes para funcionar com picadas de comprimento razoável. (Nota: o algoritmo ainda é muito lento ao aumentar o comprimento da string.) Isso é apenas para fornecer uma resposta;)
Cada sequência é auto-inversa e a sequência vazia é a identidade. Isso simplesmente executa xor sob uma simples bijeção entre cadeias e números inteiros não negativos. s
é uma função auxiliar que calcula a bijeção (apenas de sentido único) e d
é a inversa.
Versão não lenta (148 bytes, cortesia de Leaky Nun):
lambda a,b:s(d(a)^d(b))
def s(n,x=0,s=''):
while n:n-=1;s=chr(n%256)+s;n>>=8
return s
def d(n,c=0):
while n:c=c*256+ord(n[0])+1;n=n[1:]
return c
Experimente online!
Vou sequestrar isso também para uma cartilha de teoria de grupos.
Qualquer inversa à direita é uma inversa à esquerda: inv (a) + a = (inv (a) + a) + e = (inv (a) + a) + (inv (a) + inv (inv (a))) = Inv (a) + (a + inv (a)) + inv (inv (a)) = (inv (a) + e) + inv (inv (a)) = inv (a) + inv (a (inv)) ) = e
Isso também significa que a é um inverso de inv (a) .
Qualquer identidade certa é uma identidade esquerda: e + a = (a + inv (a)) + a = a + (inv (a) + a) = a
A identidade é única, dada outra identidade f : e = e + f = f
Se a + x = a então x = e : x = e + x = (inv (a) + a) + x = inv (a) + (a + x) = inv (a) + a = e
Inversos são únicos, se a + x = e então: x = e + x = (inv (a) + a) + x = inv (a) + (a + x) = inv (a) + e = inv (a )
Seguir as provas deve facilitar bastante a construção de contra-exemplos para soluções propostas que não satisfazem essas proposições.
Aqui está um algoritmo mais natural que eu implementei (mas não joguei golfe) em Lua . Talvez isso dê uma ideia a alguém.
function string_to_list(s)
local list_val = {}
local pow2 = 2 ^ (math.log(#s, 2) // 1) -- // 1 to round down
local offset = 0
list_val.p = pow2
while pow2 > 0 do
list_val[pow2] = 0
if pow2 & #s ~= 0 then
for k = 1, pow2 do
list_val[pow2] = 256 * list_val[pow2] + s:byte(offset + k)
end
list_val[pow2] = list_val[pow2] + 1
offset = offset + pow2
end
pow2 = pow2 // 2
end
return list_val
end
function list_to_string(list_val)
local s = ""
local pow2 = list_val.p
while pow2 > 0 do
if list_val[pow2] then
local x = list_val[pow2] % (256 ^ pow2 + 1)
if x ~= 0 then
x = x - 1
local part = ""
for k = 1, pow2 do
part = string.char(x % 256) .. part
x = x // 256
end
s = s .. part
end
end
pow2 = pow2 // 2
end
return s
end
function list_add(list_val1, list_val2)
local result = {}
local pow2 = math.max(list_val1.p, list_val2.p)
result.p = pow2
while pow2 > 0 do
result[pow2] = (list_val1[pow2] or 0) + (list_val2[pow2] or 0)
pow2 = pow2 // 2
end
return result
end
function string_add(s1, s2)
return list_to_string(list_add(string_to_list(s1), string_to_list(s2)))
end
A idéia é basicamente dividir a string com base na potência de dois componentes de seu comprimento e tratá-los como campos com um componente ausente representando zero e cada componente não ausente representando números de 1 a 256 ^ n, então 256 ^ n + 1 total de valores. Em seguida, essas representações podem ser adicionadas módulo módulo 256 ^ n + 1.
Nota: Esta implementação de Lua terá problemas de estouro numérico para cadeias de tamanhos maiores que 7. Mas o conjunto de cadeias de comprimento 7 ou menos é fechado nesta adição.
Experimente online!
Gelatina , 8 bytes
Isto utiliza um mapeamento bijective & Phi de matrizes de bytes para os inteiros não negativos, XORs o resultado da aplicação φ para duas cadeias de entrada, em seguida, aplica-se φ -1 para o resultado.
A matriz vazia é o elemento neutro e todas as matrizes de bytes são inversas.
Experimente online!
Como funciona
fonte
ḅ⁹
é da base bijetiva 256 para o número inteiro? O queA+A
dá?chr(-1)
?[65] + [65]
vai render[]
.Python 2 , 114 bytes
Experimente online! Trabalhos de XOR nas seqüências interpretadas como base bijetiva little-endiana 256.
fonte
d=lambda s:s>''and-~ord(s[0])+d(s[1:])*256
salva três bytes;s=lambda d:d*'?'and chr(~-d%256)+s(~-d/256)
salva mais um.Python 2 , 197 bytes
Experimente online!
Transforma a string em um número (reduzindo por código), nega se ímpar e depois reduz pela metade. Não é tão divertido quanto o outro, mas mais rápido: P
fonte
n
não é injetivo, o que causa problemas. Por exemplo,n("\x00\x00")==n("\xff")
para que isso falhe:print(f("\x00\x00","") == "\x00\x00")
1 or
=>1or