ใช้การเพิ่มสตริงที่แท้จริง


29

หลายภาษาช่วยให้สายที่จะ "เพิ่ม" +กับ อย่างไรก็ตามนี่คือการต่อกันที่แท้จริงการเพิ่มที่แท้จริงจะทำตามสัจพจน์ของกลุ่ม:

  • มันถูกปิด (การเพิ่มสองสตริงใด ๆ เป็นสตริงเสมอ)

  • มันคือการเชื่อมโยง ( (a + b) + c = a + (b + c) )

  • มีตัวตน ( ∃e: a + e = a )

  • ทุกองค์ประกอบมีค่าผกผัน ( ∀a: ∃b: a + b = e )

(เรียงต่อกันละเมิดความจริงของกลุ่มที่ 4)

ดังนั้นหน้าที่ของฉันคือการใช้การเพิ่มสตริงที่แท้จริงนั่นคือฟังก์ชั่นที่ใช้สองลำดับของไบต์ที่แทนสตริงและส่งกลับค่าที่สามที่ฟังก์ชันของคุณตรงกับความจริงของกลุ่มทั้งหมดในลำดับของไบต์

ต้องทำงานกับลำดับไบต์ทั้งหมดที่แสดงถึงสตริงรวมถึงสตริงไบต์ที่ว่าง

นี่คือดังนั้นคำตอบจะได้คะแนนเป็นไบต์โดยไบต์น้อยจะดีขึ้น

คำตอบ:


5

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

ลองออนไลน์!

-14 ไบต์ขอบคุณ notjagan

-33 ไบต์ขอบคุณ Leaky Nun (และเปลี่ยน endianness)

ฉันไม่มีธุรกิจที่พยายามจะเล่นกอล์ฟอะไรใน Python แต่ฉันไม่ต้องการใช้ Lua เนื่องจากวิธีนี้ต้องการจำนวนเต็มจำนวนมากเพื่อทำงานกับ stings ความยาวที่เหมาะสม (หมายเหตุ: อัลกอริทึมยังคงช้าจริง ๆ เมื่อเพิ่มความยาวของสตริง) นี่เป็นเพียงเพื่อให้คำตอบ;)

แต่ละสตริงเป็นแบบย้อนกลับด้วยตนเองและสตริงว่างคือตัวตน สิ่งนี้จะทำการ xor ภายใต้ bijection อย่างง่ายระหว่างสตริงและจำนวนเต็มที่ไม่เป็นลบ sเป็นฟังก์ชั่นตัวช่วยที่คำนวณ bijection (ทางเดียวเท่านั้น) และ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) + a = (inv (a) + a) + e = (inv (a) + a) + (inv (a) + inv (a)) () inv (a) + (a + inv (a)) + inv (a ()) = (inv (a) + e) ​​+ inv (inv (a)) = inv (a) + inv (a) ) = e

นี่ก็หมายความว่าเป็นผกผันของInv (ก)

ตัวตนที่ถูกต้องใด ๆ คือตัวตนด้านซ้าย: 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 )

การทำตามบทพิสูจน์ควรทำให้ค่อนข้างง่ายในการสร้างตัวอย่างสำหรับวิธีแก้ปัญหาที่เสนอซึ่งไม่เป็นไปตามข้อเสนอเหล่านี้

นี่คือขั้นตอนวิธีการที่ผมนำมาใช้เป็นธรรมชาติมากขึ้น ( แต่ไม่ได้กอล์ฟ) ใน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

โดยพื้นฐานแล้วแนวคิดนี้จะแบ่งสตริงตามส่วนประกอบ power-of-two ของความยาวของมันจากนั้นปฏิบัติต่อสิ่งเหล่านี้เป็นฟิลด์ที่มีองค์ประกอบที่ขาดหายไปซึ่งเป็นศูนย์และแต่ละองค์ประกอบที่ไม่ขาดหายไปแทนตัวเลขตั้งแต่ 1 ถึง 256 ^ n ดังนั้นทั้งหมด 256 ^ n + 1 ค่าทั้งหมด จากนั้นตัวแทนเหล่านี้สามารถเพิ่มโมดูโลส่วนประกอบที่ชาญฉลาด 256 ^ n + 1

หมายเหตุ: การนำ Lua นี้ไปใช้จะมีปัญหาการล้นของตัวเลขสำหรับสตริงที่มีขนาดใหญ่กว่า 7 แต่ชุดของสตริงที่มีความยาว 7 หรือน้อยกว่านั้นจะถูกปิดภายใต้การเพิ่มนี้

ลองออนไลน์!


สนุกจริง: เพราะทุกองค์ประกอบเป็นสิ่งที่ตรงกันข้ามของตัวเองกลุ่มนี้จึงเป็น Abelian
ตัวช่วยสร้างข้าวสาลี

4

เยลลี่ขนาด 8 ไบต์

‘ḅ⁹^/ḃ⁹’

สิ่งนี้ใช้การทำแผนที่ไบเจ็กทีฟφจากอาร์เรย์ไปยังจำนวนเต็มที่ไม่เป็นลบ XORs ผลลัพธ์ของการใช้φถึงสองสตริงอินพุตจากนั้นใช้φ -1เพื่อผล

อาร์เรย์ที่ว่างเปล่าเป็นองค์ประกอบที่เป็นกลางและทุกอาร์เรย์ของไบต์เป็นค่าผกผันของมันเอง

ลองออนไลน์!

มันทำงานอย่างไร

‘ḅ⁹^/ḃ⁹’  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.

ผมสงสัยว่าที่ esolangs มี bijective builtins ฐานแปลง ...
นีล

ไม่ควรเป็นฐาน 257 ใช่ไหม
ติตัส

@Titus ไม่ตัวเลขของฐานbijective 256 ช่วงจาก 1 ถึง 256 (รวม)
Dennis

ดังนั้นḅ⁹จากฐานbijective 256 ถึงจำนวนเต็ม? อะไรA+Aให้ chr(-1)?
ติตัส

@Titus กระบวนการแปลงพื้นฐานเป็นจำนวนเต็มเหมือนกันสำหรับ bijective และฐาน "ปกติ" จะให้ผลผลิต[65] + [65] []
Dennis

3

Python 2 , 114 ไบต์

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''

ลองออนไลน์! ทำงานโดย XORing สตริงที่ตีความว่าเป็นฐานข้อมูล bijective แบบ end-endian 256


d=lambda s:s>''and-~ord(s[0])+d(s[1:])*256บันทึกสามไบต์ s=lambda d:d*'?'and chr(~-d%256)+s(~-d/256)ประหยัดอีกหนึ่ง
ลินน์

@Lynn คนที่สองจะไปทำงานกับ d ใหญ่ไหม?
Neil

มันจะทำงานอย่างไรถ้าสายไม่ยาวเท่ากัน?
ข้าวสาลีตัวช่วยสร้าง

@WheatWizard ความยาวของสตริงไม่เกี่ยวข้อง มีการทำแผนที่ bijective จากชุดของสตริงไปยังชุดของจำนวนเต็ม ค่าจำนวนเต็มจะถูก XORed และการแมปกลับด้าน
Neil

@ Neil Ok ขอบคุณฉันเห็นตอนนี้
ตัวช่วยสร้างข้าวสาลี

1

Python 2 , 197 ไบต์

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]

ลองออนไลน์!

เปลี่ยนสตริงให้เป็นตัวเลข (ลดด้วย charcode) ทำให้มองไม่เห็นถ้าเป็นคี่แล้วแบ่งครึ่ง ไม่เร็วเหมือนกอล์ฟ แต่เร็วกว่า: P



1
nไม่ฉีดซึ่งทำให้เกิดปัญหา เช่นn("\x00\x00")==n("\xff")นี้ล้มเหลว:print(f("\x00\x00","") == "\x00\x00")
tehtmi

: | โอ้ไม่เลยว่ามันจะมีค่าใช้จ่ายสูงในการแก้ไข
ASCII- เท่านั้น

1 or=>1or
Zacharý
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.