ย้อนกลับสตริงไบนารีครึ่งหนึ่ง


12

นี่คือคำถามที่ติดตามของฉันคำถาม Puzzling.SE : ผมถามว่ามีฟังก์ชั่นทำแผนที่สตริงบูลีนสตริงบูลีนเพื่อให้f (f (ข)) = ย้อนกลับ (ข)สำหรับการป้อนข้อมูลทุกสายข (โดยย้อนกลับฉันหมายถึงฟังก์ชั่นที่กลับคำสั่งของบิต)

ลิงก์ด้านบนมีคำตอบที่เป็นบวกโดยมีข้อพิสูจน์โดยf ''ที่ยอดเยี่ยมแต่คุณอาจต้องการไตร่ตรองคำถามด้วยตัวคุณเองก่อนที่จะมอง

ใช้ฟังก์ชันfในจำนวนน้อยที่สุดเท่าที่เป็นไปได้

  • คุณสามารถอ่านอินพุตจาก STDIN หรือรับฟังก์ชั่นอาร์กิวเมนต์ และเขียนสตริงผลลัพธ์ไปที่ STDOUT หรือส่งคืน

  • ทั้งสองวิธีคุณอาจทำงานร่วมกับสายที่เกิดขึ้นจริงของทั้งสองไบต์ที่แตกต่างกันหรือตัวอักษรที่คุณเลือก (พูด0และ1หรือ\x00และ\x01) หรือกับอาร์เรย์ / รายการtruthy และ falsy ค่า เลือกค่าสองค่าแล้วใช้ค่าเหล่านั้น

  • ผลลัพธ์ของแอปพลิเคชั่นเดียวของf ต้องเป็นสตริงไบนารีตัวเอง: ไม่มีคำตอบที่โง่เช่นb -> if b starts with 'x' then reverse(b[1:]) else 'x' + b...

  • ฟังก์ชั่นของคุณควรจะรวม ; โดยเฉพาะอย่างยิ่งการป้อนข้อมูลอาจเป็นสตริงที่ว่างเปล่าหรือหนึ่งบิตยาว ฯลฯ ไม่มีขอบเขตบนสำหรับความยาวของสตริง

  • มันควรจะบริสุทธิ์ : อย่ารักษาสถานะโกลบอลระหว่างการเรียกฟังก์ชัน สตริงอินพุตต้องพิจารณาสตริงเอาต์พุตอย่างสมบูรณ์


เอาต์พุตมีความยาวแตกต่างจากอินพุตได้หรือไม่?
Luis Mendo

แน่นอน! (อันที่จริงแล้วความท้าทายเป็นไปไม่ได้ที่จะพิสูจน์ได้)
Lynn

มันจะต้องใช้สำหรับสตริงที่มีความยาวหนึ่งหรือศูนย์หรือไม่?
CalculatorFeline

ใช่; ฟังก์ชั่นจะต้องมีทั้งหมด ฉันได้ชี้แจงเรื่องนี้ในคำถาม!
Lynn

คำตอบ:



7

Python 2, 64 69ไบต์

def f(s):p=(s+s).find(s,1);return[s[~p::-1],s+s[:p]][len(s)/p%2]

Ungolfed:

def f(s):
    p = (s+s).find(s,1)
    n = len(s)/p
    return s[:p][::1|n%-2] * -~(n-1^1)

นี่เป็นการหาช่วงเวลาของสตริงนั่นคือค่าน้อยที่สุดpนั่นsคือสตริงของความยาวpซ้ำหลายnครั้ง (ฉันพบวิธี golfyบน SO) จากนั้นถ้าnเป็นเลขคี่จะเพิ่มการเกิดซ้ำอีกหนึ่งช่วงเวลา ถ้าnเป็นเช่นนั้นมันจะลบหนึ่งรอบระยะเวลาและกลับรายการ

ขอบคุณ @ Sp3000 ที่ช่วยในการปรับใช้ฟังก์ชั่นการแมประหว่าง 1 <-> 2, 3 <-> 4 ฯลฯ


... รหัส ungolfed จะได้รับการอัพเดตเมื่อใด
CalculatorFeline

@CatsAreFluffy ฉันไม่มีแผนที่จะแก้ไขโค้ดที่ไม่ได้ถูกดัดแปลงเนื่องจากใช้แนวคิดเดียวกันกับความแตกต่างเล็กน้อย ในทางกลับกันภาษาอังกฤษเป็นปัจจุบัน
feersum

2

Perl, 49 47 ไบต์

รวมถึง +2 สำหรับ -lp

ขึ้นอยู่กับอัลกอริทึมที่ดีมากของ @ feersum

เรียกใช้ด้วยอินพุตบน STDIN เช่น

perl -lp halfreverse.pl <<< "101001"

halfreverse.pl:

/^(.+?)((\1\1?)*)$/;$_=$3eq$1?reverse$2:$_.$1

คำอธิบาย

/^               $/         Match the complete input string
  (.+?)                     Non-greedy match. Try only one digit at the start,
                            if that doesn't work try 2, then 3 etc. The string
                            being tried is remembered in backreference \1
       ((\1\1?)*)           Try to repeat \1 as many times as possible but
                            prefer in groups of 2. Fall back to only 1 at the
                            end of the string if the trailing part has an odd
                            number of \1 (so the total count is even)

   $3eq$1                   So the last match $3 equals the first match $1
         ?                  if and only if the total count is even
          reverse$2         If total count is even drop the first instance of
                   :        \1 and reverse
                    $_.$1   If total count is odd extend $_ by one instance
$_=                         Assign result

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