Pythonの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
オンラインでお試しください!
notjaganのおかげで-14バイト
Leaky Nunのおかげで33バイト(およびエンディアンの切り替え)
Pythonでゴルフをしようとするビジネスはありませんが、Luaを使用したくありませんでした。この方法は、適切な長さの刺し傷で動作するために大きな正確な整数を必要とするからです。(注:文字列の長さを増加させるとき、アルゴリズムはまだ本当に遅いです。)これはほとんど答えを提供するためだけです;)
各文字列は自己反転型であり、空の文字列はIDです。これは、文字列と非負整数間の単純な全単射で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()+ A =(INV()+)+ E =(INV()+)+(INV()+ INV(INV()))= inv(a)+(a + inv(a))+ inv(inv(a))=(inv(a)+ e)+ inv(inv(a))= inv(a)+ inv(inv(a) )= e
これは、aがinv(a)の逆であることも意味します。
右のアイデンティティは左のアイデンティティです:e + a =(a + inv(a))+ a = a +(inv(a)+ a)= a
他のアイデンティティfが与えられると、アイデンティティは一意です:e = e + f = f
もし+ X =次いで、X = E:X = E + X =(INV()+)+ X = INV()+(+ X)= INV()+ A = E
a + x = eの場合、逆は一意です:x = e + x =(inv(a)+ a)+ x = inv(a)+(a + x)= inv(a)+ e = inv(a )
証明に従うことで、これらの命題を満たさない提案されたソリューションの反例を簡単に構築できるはずです。
Luaで実装した(ただし、ゴルフはしなかった)より自然なアルゴリズムを次に示します。たぶんそれは誰かにアイデアを与えるでしょう。
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
基本的には、長さの2のべき乗成分に基づいて文字列を分割し、ゼロを表す欠損成分と、1から256 ^ nまでの数字を表す各欠損成分のないフィールドとしてこれらを処理します。合計256 ^ n + 1個の値。次に、これらの表現は、コンポーネントごとに256 ^ n + 1を法として追加できます。
注:このLua実装では、サイズが7を超える文字列に対して数値オーバーフローの問題が発生しますが、この追加では長さ7以下の文字列のセットは閉じられます。
オンラインでお試しください!