Пітон 3 , 177 170 163 130 байт
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
Спробуйте в Інтернеті!
-14 байт завдяки нежагану
-33 байти завдяки Leaky Nun (та переключеній витримці)
У мене немає жодного бізнесу, який намагався бити що-небудь у Python, але я не хотів використовувати Lua, оскільки цей метод потребує великих точних чисел для роботи над розумними довжинами. (Примітка: алгоритм все ще дуже повільний при нарощуванні довжини рядка.) Це здебільшого просто для надання відповіді;)
Кожна струна є самооберненою, а порожня рядок - тотожністю. Це просто виконує xor під простим біекцією між рядками та негативними цілими числами. s
- це допоміжна функція, яка обчислює біекцію (лише в один бік), і d
є зворотною.
Не повільна версія (148 байт, люб’язно надавши 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
Спробуйте в Інтернеті!
Я збираюся викрасти це також для групової теорії.
Будь-яке право зворотної ліва зворотний: INV (а) + а = (INV (а) + а) + е = (INV (а) + а) + (INV (а) + INV (INV (а))) = inv (a) + (a + inv (a)) + inv (inv (a)) = (inv (a) + e) + inv (inv (a)) = inv (a) + inv (inv (a) ) = е
Це також означає, що a є зворотним інв (a) .
Будь-яка права ідентичність - це ліва ідентичність: e + a = (a + inv (a)) + a = a + (inv (a) + a) = a
Ідентичність унікальна, враховуючи іншу тотожність f : e = e + f = f
Якщо a + x = a, то x = e : x = e + x = (inv (a) + a) + x = inv (a) + (a + x) = inv (a) + a = e
Звороти унікальні, якщо a + x = e, тоді: x = e + x = (inv (a) + a) + x = inv (a) + (a + x) = inv (a) + e = inv (a )
Після доказів слід досить легко побудувати контрприклади для запропонованих рішень, які не задовольняють цих пропозицій.
Ось більш природний алгоритм, який я реалізував (але не гольф) у Луа . Можливо, це дасть комусь ідею.
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
В основному ідея полягає в тому, щоб розділити рядок на основі потужності двох компонентів його довжини, а потім трактувати їх як поля з пропущеним компонентом, що представляє нуль, і кожен несутній компонент, що представляє числа від 1 до 256 ^ n, тому 256 ^ n + 1 значення всього. Тоді до цих уявлень може бути доданий компонентний модуль 256 ^ n + 1.
Примітка. Ця реалізація Lua матиме чисельні проблеми переповнення рядків розмірами більше 7. Але набір рядків довжиною 7 або менше закритий під цим доповненням.
Спробуйте в Інтернеті!