Gerçek dize eklemeyi uygulama


29

Birçok dilde dizelerin "eklenmesi" sağlanır +. Ancak bu gerçekten birleştirmedir, gerçek bir ekleme grup aksiyomlarını izler:

  • Kapalıdır (iki dizenin eklenmesi her zaman bir dizedir)

  • Bu birleştiricidir ( (a + b) + c = a + (b + c) )

  • Bir kimlik var ( :e: a + e = a )

  • Her elemanın bir tersi vardır ( ∀a: ∃b: a + b = e )

(birleştirme 4. grup aksiyomunu ihlal ediyor)

Bu yüzden benim görevim, gerçek bir dize eklemesi uygulamaktır; bu, dizeleri temsil eden iki bayt dizisi alan ve işlevinizin bayt dizileri üzerindeki tüm grup aksiyomlarını karşıladığı şekilde üçüncü olanı döndüren bir işlevdir.

Boş bayt olanları da içeren dizeleri temsil eden tüm bayt dizileri üzerinde çalışmalıdır.

Bu olduğundan, cevaplar daha az byte'ın daha iyi olmasıyla byte olarak puanlanacak.

Yanıtlar:


5

Python 3 , 177 170 163 130 bayt

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

Çevrimiçi deneyin!

-Jaganat sayesinde 14 byte

Leaky Rahibe sayesinde -33 bayt (ve endianness değiştirildi)

Python'da herhangi bir şeyi golf yapmaya çalışan bir işim yok ama Lua'yı kullanmak istemedim çünkü bu yöntem makul uzunluktaki sokmalar üzerinde çalışmak için büyük tam sayılara ihtiyaç duyuyordu. (Not: dize uzunluğunu yükseltirken algoritma hala Gerçekten Yavaş.) Bu çoğunlukla sadece bir cevap vermek içindir;)

Her dize kendi kendine ters ve boş dize kimliktir. Bu basitçe xor'u stringler ile negatif olmayan tamsayılar arasındaki basit bir önyargı altında gerçekleştirir. sbijeksiyonu hesaplayan bir yardımcı fonksiyon (sadece bir yön) ve dtersidir.

Yavaş olmayan versiyon (148 byte, Leaky Nun'un izniyle):

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

Çevrimiçi deneyin!

Bunu grup teorisi için de kullanacağım.

Herhangi sağ tersidir bir sol ters: (+ inv (inv (a)), inv (a)) = inv (a) + e = (inv (a) + a) + e = (inv (a) + a) + inv (a) + (a + inv (a)) + inv (inv (a)) = (inv (a) + e) ​​+ inv (inv (a)) = inv (a) + inv (inv (a) ) = e

Bu aynı zamanda, yani bir arasında bir ters olan inv (a) .

Herhangi bir doğru kimlik sol kimliktir: e + a = (a + inv (a)) + a = a + (inv (a) + a) = a

Kimlik benzersizdir, diğer kimlik verildiğinde f : e = e + f = f

Eğer a + x = a daha sonra x = e : X = e + x = (inv (a) + a) + X = inv (a) + (a + x) = inv (a) + e = e

Ters çevirmeler benzersizdir, eğer a + x = e ise : x = e + x = (inv (a) + a) + x = inv (a) + (a + x) = inv (a) + e = inv (a )

Kanıtları takip ederek, bu önerileri karşılamayan önerilen çözümler için karşı örnekler oluşturmayı oldukça kolaylaştırmalıdır.

İşte hayata (ama golf yoktu) 'de daha doğal bir algoritma var Lua . Belki birisine bir fikir verecektir.

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

Buradaki fikir temel olarak ipin uzunluğunun iki bileşeninin gücüne göre ayrılması ve daha sonra bunları sıfırı temsil eden bir eksik bileşen ile alan olarak ele alması ve 1 ila 256 ^ n arasında sayıları temsil eden her eksik olmayan bileşenin alan olarak ele alınması, toplamda 256 ^ n + 1 değer. Sonra bu gösterimler, bileşen bazında modulo 256 ^ n + 1 eklenebilir.

Not: Bu Lua uygulaması, 7'den büyük boyuttaki dizgiler için sayısal taşma sorunlarına sahip olacaktır.

Çevrimiçi deneyin!


Eğlenceli gerçek: Her element kendi tersi olduğundan, bu grup da abelistir.
Buğday Sihirbazı

4

Jöle , 8 bayt

‘ḅ⁹^/ḃ⁹’

Bu kullanım, bir örten eşleme φ olmayan negatif tamsayı bayt dizileri, XORs uygulanması sonucu gelen cp iki giriş şeritlerine, daha sonra geçerli cp -1 sonuca.

Boş dizi nötr elemandır ve her byte dizisi kendi tersidir.

Çevrimiçi deneyin!

Nasıl çalışır

‘ḅ⁹^/ḃ⁹’  Main link. Argument: [A, B] (pair of byte arrays)

‘         Increment all integers in A and B.
 ḅ⁹       Convert from base 256 to integer.
   ^/     XOR the resulting integers.
     ḃ⁹   Convert from integer to bijective base 256.
       ’  Subtract 1.

Hangi esolangs'ın temel üssü dönüşüm yerleşiklerinin olduğunu merak ediyordum ...
Neil

Taban 257 değil mi?
Titus

@Titus Hayır, basamak örten 1 ile 256 (dahil) baz 256 aralığında.
Dennis,

Öyleyse ḅ⁹, bijektif taban 256'dan tamsayıya mı? Ne A+Averir? chr(-1)?
Titus,

@Titus Base-to-integer dönüşüm işlemi, mükerrer ve "normal" bazlar için aynıdır. [65] + [65]üretecek [].
Dennis,

3

Python 2 , 114 bayt

lambda a,b:s(d(a)^d(b))
d=lambda s:s and d(s[1:])*256+ord(s[0])+1or 0
s=lambda d:d and chr(~-d%256)+s(~-d/256)or''

Çevrimiçi deneyin!Dizeleri XORing ile çalışır, küçük endian bijective base 256 olarak yorumlanır.


d=lambda s:s>''and-~ord(s[0])+d(s[1:])*256üç bayt kaydeder; s=lambda d:d*'?'and chr(~-d%256)+s(~-d/256)bir tane daha kaydeder.
Lynn,

@Lynn İkincisi büyük d için çalışacak mı?
Neil

Dizeler aynı uzunlukta değilse bu nasıl çalışır?
Buğday Sihirbazı

@WheatWizard Dizelerin uzunluğu önemli değil. Dizi kümesinden tam sayı kümesine kadar bir çift eşleme var. Tam sayı değerleri daha sonra XORed ve eşleme tersine çevrilir.
Neil

@Neil Tamam teşekkürler şimdi görüyorum.
Buğday Sihirbazı

1

Python 2 , 197 bayt

def n(s):
 n=s and ord(s[0])+1 or 0
 for c in s[1:]:n=n*256+ord(c)
 return(-1)**n*n/2
def f(l,r,s=""):
 i=n(l)+n(r)
 i=abs(i*2+(i<=0))
 while i>257:s=chr(i%256)+s;i/=256
 return["",chr(i-1)+s][i>0]

Çevrimiçi deneyin!

Dize bir sayıya döner (charcode ile küçültme), tek ise negatif olur, sonra yarıya düşer. Diğerleri kadar golfçü değil, daha hızlı: P



1
nEnjektif değil, bu sorunlara neden olur. Örneğin, n("\x00\x00")==n("\xff")bu başarısız olur:print(f("\x00\x00","") == "\x00\x00")
tehtmi

: | oh hayır bu düzeltmek için çok pahalı olacak
ASCII sadece

1 or=>1or
Zacharý
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.