Python 3 , 177 170 163 130 byte
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
Provalo online!
-14 byte grazie a notjagan
-33 byte grazie a Leaky Nun (e commutazione endianness)
Non ho intenzione di provare a giocare a golf su Python, ma non volevo usare Lua poiché questo metodo ha bisogno di numeri interi esatti di grandi dimensioni per funzionare con punture di lunghezza ragionevole. (Nota: l'algoritmo è ancora molto lento quando aumenta la lunghezza della stringa.) Questo è principalmente solo per fornire una risposta;)
Ogni stringa è auto-inversa e la stringa vuota è l'identità. Questo semplicemente esegue xor sotto una semplice biiezione tra stringhe e numeri interi non negativi. s
è una funzione di supporto che calcola la biiezione (solo andata) ed d
è l'inverso.
Versione non lenta (148 byte, per gentile concessione di 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
Provalo online!
Dirigerò questo anche per un primer di teoria dei gruppi.
Qualsiasi inverso destro è un inverso sinistro: 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 (inv (a) ) = e
Questo significa anche che a è un inverso di inv (a) .
Qualsiasi identità corretta è un'identità sinistra: e + a = (a + inv (a)) + a = a + (inv (a) + a) = a
L'identità è unica, data altra identità f : e = e + f = f
Se a + x = a allora x = e : x = e + x = (inv (a) + a) + x = inv (a) + (a + x) = inv (a) + a = e
Le inversioni sono univoche, se a + x = e quindi: x = e + x = (inv (a) + a) + x = inv (a) + (a + x) = inv (a) + e = inv (a )
Seguire le prove dovrebbe rendere abbastanza facile costruire controesempi per soluzioni proposte che non soddisfano queste proposizioni.
Ecco un algoritmo più naturale che ho implementato (ma non ho golf) in Lua . Forse darà un'idea a qualcuno.
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
L'idea è fondamentalmente di dividere la stringa in base alla potenza di due componenti della sua lunghezza e quindi di trattarli come campi con un componente mancante che rappresenta zero e ogni componente non mancante che rappresenta i numeri da 1 a 256 ^ n, quindi 256 ^ n + 1 valori totali. Quindi queste rappresentazioni possono essere aggiunte in base al componente modulo 256 ^ n + 1.
Nota: questa implementazione di Lua avrà problemi di overflow numerici per stringhe di dimensioni maggiori di 7. Ma l'insieme di stringhe di lunghezza 7 o inferiore è chiuso in questa aggiunta.
Provalo online!