ขยายสตริงที่เข้ารหัส


18

มีการเข้ารหัสและถอดรหัสความยาวแบบคลาสสิค

input   output
a3b2c5  aaabbccccc

และนั่นก็ตรงไปตรงมาและทำมาก่อน

ความท้าทายคือการบัญชีสำหรับพฤติกรรมที่ไม่ได้มาตรฐานเมื่อตัวละครหลายตัวนำหน้าความยาว ( หลักเดียวจาก 0-9) อักขระแต่ละตัวก่อนหน้าหลักความยาวการรัน (หลักสุดท้ายก่อนหน้าไม่ใช่ตัวเลขหรือจุดสิ้นสุดของสตริง) มีค่าที่ใช้กับมันทีละตัวและพิมพ์ออกมาตามลำดับ

อินพุตและเอาต์พุตทดสอบบางรายการรวมถึงกรณีขอบบางอย่าง:

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • ลำดับอักขระ ( [a-zA-Z0-9]+) ต้องตามด้วยความยาวความยาว ( [0-9])
  • ต้องพิจารณาอินพุตที่ถูกต้องเท่านั้น ( ([a-zA-Z0-9]+[0-9])*)
    • ใช่สตริงว่างคืออินพุตที่ถูกต้อง
  • อินพุตคือผ่านอินพุตมาตรฐานเอาต์พุตผ่านเอาต์พุตมาตรฐาน

นี่คือรหัสกอล์ฟจำนวนไบต์เป็นตัวกำหนดผู้ชนะ


@AlexA แก้ไข. มีesolangsบางอย่างที่ฉันสนุกกับการดูเป็นครั้งคราวที่ถูกลงโทษอย่างอื่นโดยการนับไบต์ (ฉันเปิดให้คำแนะนำอย่างแน่นอนว่าทำไมนี่อาจเป็นความผิดพลาดในการนับด้วยวิธีนี้)

4
@MichaelT การให้คะแนนโดยตัวละครขอแนะนำให้บีบอัดซอร์สโค้ดเป็น UTF32 ซึ่งอนุญาตให้เข้ารหัสได้ถึง 4 ไบต์ต่ออักขระ แต่ไม่สามารถอ่านได้อย่างสมบูรณ์
isaacg

@isaacg fair 'nuff ฉันจะแก้ไขเพื่อเปลี่ยนเป็นไบต์ ฉันจะไตร่ตรองถึงวิธีการแสดงออกถึงสไตล์ของการเลื่อนเพื่อยอมรับในความท้าทายในอนาคต

การส่งของเราควรเสร็จสมบูรณ์โดยไม่มีข้อผิดพลาดหรือไม่ถ้าอินพุตเป็นสตริงว่างเปล่า? ฉันทามติเกี่ยวกับเมตาคือผลลัพธ์ที่ STDERR สามารถปฏิเสธ แต่เนื่องจากคุณกล่าวถึงอย่างชัดเจนผมต้องถาม
เดนนิส

@ เดนนิสสตริงว่างควรป้อนควรหยุด ไม่ควรเข้าสู่วงวนไม่สิ้นสุดหรือพิมพ์ข้อความอื่น ๆ ไปยังเอาต์พุตมาตรฐาน

คำตอบ:


3

Pip, 22 + 1 = 23 ไบต์

ใช้-rธง โปรดทราบว่าสิ่งนี้กำหนดให้คุณต้อง 1) ป้อน EOF หลังจากอินพุต (Ctrl-D บน Linux, Ctrl-Z บน Windows) หรือ 2) ไพพ์อินพุตจากที่อื่น

(^_@<v)X_@vMa@`\D*\d+`

คำอธิบาย:

                        a is first line of stdin (from -r flag) and v is -1 (implicit)
              `\D*\d+`  Pattern (regex) object that matches zero or more non-digits
                        followed by at least one digit
            a@          Find all non-overlapping matches in a, returning a list of strings
           M            To that list, map a lambda function:
  _@<v                    Argument sans last character (equivalent to Python a[:-1])
(^    )                   Split into a list of characters
        _@v               Last character of argument
       X                  Repeat each character of the list that many times
                          (String multiplication X, like most operators, works item-wise
                          on lists)
                        Auto-print (implicit)

ผลลัพธ์ของการดำเนินการแมปเป็นรายการของรายการจริง ๆ แต่ตามรายการเริ่มต้นจะถูกรวมเข้าด้วยกันอย่างง่ายดายเมื่อพิมพ์ดังนั้นจึงไม่จำเป็นต้องแปลงด้วยตนเองเป็นสตริง

ตัวอย่างด้วยอินพุตa13b1:

Var a gets        "a13b1"
After regex match  ["a13" "b1"]
After map          [["aaa" "111"] ["b"]]
Final output       aaa111b

Pip มีการสนับสนุน regex พื้นฐานเป็นของ ... 2 วันที่ผ่านมา ช่วงเวลาที่ยอดเยี่ยม!


อันนั้นใช้ได้กับ-rธง (เช่นกัน) (คำถามระบุว่าข้อมูลจะต้องมาจาก STDIN)
Dennis

@Dennis โอ๊ะพลาดว่า เพิ่มการตั้งค่าสถานะเป็นจำนวนไบต์ ฉันควรจะสามารถใช้ตัวแปรพิเศษqแทนการaไม่มีค่าสถานะพิเศษ แต่ดูเหมือนว่าจะมีข้อผิดพลาดและมันขอให้ป้อนข้อมูลสองครั้ง
DLosc

ในที่สุดภาษากอล์ฟด้วยการสนับสนุน regex!
Dennis

@Dennis ฉันเห็นว่าคุณเปลี่ยนไป pip แล้ว!
เครื่องมือเพิ่มประสิทธิภาพ

8

Perl / ทุบตี 54 40 + 1 = 41 ไบต์

perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'

มันเป็นพื้น regex ภายใน regex และความมหัศจรรย์เล็กน้อย

คำอธิบาย

regex ด้านนอก/(\D*\d*)(\d)/gแยกแต่ละกลุ่มที่เข้ารหัสความยาวรัน เราจับภาพสิ่งที่จะทำซ้ำในและจำนวนของการเกิดซ้ำใน$1 $2ตอนนี้เราแทนที่แต่ละกลุ่มดังกล่าวด้วยการขยายตัวของกลุ่มนั้น สำหรับการที่เราประเมินรหัส"\$1=~s/./\$&x$2/egr" สองครั้ง (ตาม/eeธงในการทดแทนด้านนอก)

การประเมินครั้งแรกจะสอดแทรกจำนวนการทำซ้ำลงในสตริงเท่านั้น - ตัวแปรอื่น ๆ ได้รับการป้องกันโดยแบ็กสแลช ดังนั้นสมมติว่าอินพุตa14ตอนนี้เราจะมีรหัส$1=~s/./$&x4/egrซึ่งจะถูกประเมินอีกครั้ง

วิธีนี้จะใช้การทดแทนกับเนื้อหาของ$1(เนื้อหาที่จะทำซ้ำa1) .การเปลี่ยนตัวผู้เล่นตรงกับตัวละครแต่ละตัว $&ตัวแปรถือการแข่งขันทั้งที่เราทำซ้ำx4ครั้ง เราทำสิ่งนี้แบบ/globally สำหรับการแข่งขันแต่ละครั้งและ/rหาสตริงที่ถูกแทนที่แทนที่การแก้ไข$1ตัวแปร (ซึ่งเป็นแบบอ่านอย่างเดียว) aaaa1111ดังนั้นผลของการทดแทนภายในคือ

-pธงนำไปใช้ทดแทนกับสายการป้อนข้อมูลแต่ละคนและพิมพ์ออกผล


3
มันเป็นธรรมเนียมที่จะให้คะแนนสิ่งนี้เป็นวิธีการแก้ปัญหา Perl ซึ่งคุณเพียงแค่เพิ่ม 1 ไบต์สำหรับ-pตัวปรับเปลี่ยน ฉันนับ 45 ไบต์ นอกจากนี้คุณควรจะสามารถใช้\Dแทนซึ่งยังกำจัดความจำเป็นในการ[a-z] i
Dennis

7

CJam, 33 31 27 bytes

อ๊ะการขาดการแสดงออกปกติทำให้เรื่องนี้ค่อนข้างยาว ...

qN+{:XA,s&L\:L>{])~e*[}&X}%

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

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

(การขยายโค้ดที่ล้าสมัยเล็กน้อย)

q{                       }%        e# Read the input (q) and loop through each character
  L                                e# Put variable L (initially empty character) on stack
   A,                              e# Put variable A (equals 10) and create an array 0..9
     s                             e# Convert the array to string "0123456789"
      &                            e# Do a set intersect b/w previous char and 0-9 string
                                   e# If numeric, it gives 1 char string, otherwise 0
       \:LA,s&                     e# Swap to bring current character on top. Store it in L
                                   e# and do the same set intersect with it
              >                    e# Means we are checking that current char is non-numeric
                                   e# and previous numeric
               {      }&           e# Run this block if above is true
                ])~                e# Wrap everything not already repeated in an array and
                                   e# take out the last character and convert it to integer.
                                   e# This is the run length of the preceding string
                   e*              e# Repeat each character in the string, run length times
                     [             e# Start a new array to help when next run length is found
                        L          e# Restore the current character back on stack to be used
                                   e# in next iteration
                           )~e*    e# The last string-run-length pair is not decoded..
                                   e# So we do that now

ลองออนไลน์ได้ที่นี่


ฉันขอขอบคุณการสาธิตปัญหาที่ตัวระบุไบต์เป็นสาเหตุ ขอขอบคุณ. ฉันกำลังคิดว่าจะใช้วลีเพื่อรับรองว่าภาษาที่คำสั่งเดียวคืออักขระหลายไบต์ไม่ได้รับโทษสำหรับรูปแบบของภาษานั้นโดยไม่อนุญาตให้เข้ารหัส UTF ที่คุณแสดงผ่านช่องโหว่ ป.ล. ฉันชอบเห็นการแจกแจงอัลกอริทึมที่คุณให้

6

อาร์เอส , 43 71 ตัวอักษร

ทีนี้มันกลับมาเร็วมาก ตัวเลขโง่ ...

(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
 /

ลองที่นี่!

รุ่นดั้งเดิม (ไม่ทำงานกับอินพุตเหมือน123):

+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)

คำอธิบาย

ครั้งแรกที่ช่องว่างตำแหน่งเส้นแบ่งระหว่างการทำงานที่มีตัวเลขเช่นการเปลี่ยนเข้าสู่a313a3 13

บรรทัดที่สองอย่างต่อเนื่องขยายการเข้ารหัสบีบอัดเช่นการaa5a5a5

บรรทัดที่สามแปลงตัวอย่างของทุกa5เข้าไปaaaaaใช้ประกอบการทำซ้ำ

บรรทัดสุดท้ายจะลบช่องว่าง


มันจัดการa123b1อย่างไร
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer ไม่ดี ฉันต้องบิดมันหน่อย ...
kirbyfan64sos

@Optimizer คงที่
kirbyfan64sos

5

Javascript ( ES6 ), 86 83 ไบต์

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))

แสดงความคิดเห็น:

alert( // output final result
    prompt(). // take input
    replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters 
                                // followed by a digit (captured)
                                // and not followed by a digit (negative lookahead)
        (a, b, c)=> // replace with a function
            b.replace(/./g, // replace all characters in b
                y=>y.repeat(c) // with that character repeated c times
            )
    )
)

จะไม่alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))ทำเช่นเดียวกัน? ยาวเพียง 71 ไบต์
Ismael Miguel

@IsmaelMiguel ที่จะทำงานได้ก็ต่อเมื่อมีตัวละครตัวหนึ่งอยู่หน้าตัวเลข ความเข้าใจของอาเรย์จะจัดการกับตัวละครแต่ละตัวซ้ำ
nderscore

ลองและมันจะกลับมาArray(6).join('12') '1212121212'
Ismael Miguel

อันนี้ใช้งานได้: alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))(ยาว 71 ไบต์เหมือนกันทดสอบบนes6fiddle.net/ia7gocwg )
Ismael Miguel

1
ฉันพบวิธีที่แตกต่างกัน (ชัดเจน) ในการพูด 3 ไบต์แม้ว่า:
nderscore

4

CJam, 27 25 ไบต์

r_'A+1>.{64&1$>{])~f*o}&}

ลองใช้ออนไลน์ในล่าม CJam

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

r_                        e# Read a token from STDIN and push a copy.
  'A+                     e# Append the character A to the copy.
     1>                   e# Discard the first character of the copy.
       .{               } e# For each character C of the input string and the
                          e# corresponding character D of the copy:
         64&              e#   Take the bitwise and of D and 64. This pushes @
                          e#   if D is a letter and NUL if it is a digit.
            1$>           e#   Compare the result to a copy of C. This pushes 1
                          e#   if and only if D is a letter and C is a digit.
               {      }&  e#   If the result was 1, do the following:
                ]         e#     Wrap the stack in an array.
                 )~       e#     Pop and evaluate the last character.
                   f*     e#     Repeat each char in the array that many times.
                     o    e#     Print all characters.

3

Pyth, 33 32 28 ไบต์

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

ลองใช้งานออนไลน์: การสาธิตหรือชุดทดสอบ

คำอธิบาย

aa1a23b2ฉันจะอธิบายรหัสโดยใช้การป้อนข้อมูลตัวอย่าง หวังว่านี่จะเป็นเรื่องง่ายกว่าที่จะติดตาม

                               implicit: z = input string = 'aa1a23b2'
                         Uz    the indices of z: [0, 1, 2, 4, 5, 6, 7]
                  f            filter for indices T, which satisfy:
                   <@zT\=        z[T] < "="
                               this gives us the list of indices [2, 4, 5, 7], 
                               which correspond to digits in z. 
                 J             assignment, J = [2, 4, 5, 7]
               hMJ             increment all element in J: [3, 5, 6, 8]
              -            J   and remove the elements of J:
                                 [3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
            cz                 split z at these indices: ['aa1', 'a23', 'b2', '']
           P                   remove last element: ['aa1', 'a23', 'b2']
  m                            map each string d to:
   m     Pd                      map each string k of d-without-last-char to:
     ved                           int(last element of d)
    *   k                          * k
                               this creates [['a', 'a'], ['aaa', '222'], ['bb']]
 s                             sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s                              sum the strings: 'aaaaa222bb'



2

Python 2.7, 98 ไบต์

import re
print"".join(c*int(m[-1])for m in 
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])

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


คุณสามารถประหยัด 2 ไบต์โดยการเปลี่ยนจากงูหลาม 2 ถึง 3 raw_inputกลายเป็นinputแต่printความต้องการวงเล็บ
Alex A.

จริง แต่ฉันชอบเล่นกอล์ฟใน python 2.7
เรียกซ้ำ

1

Julia, 105 99 95 87 ไบต์

s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีชื่อที่ใช้สตริงเป็นอินพุตและส่งคืนสตริง หากต้องการเรียกใช้ให้ตั้งชื่อเช่นf=s->...เรียกว่าให้มันชื่อเช่น

มีการใช้ความเข้าใจอาร์เรย์สองชุดที่นี่หนึ่งซ้อนภายในอีกชุดหนึ่ง ความเข้าใจภายนอกทำหน้าที่ในแต่ละการจับคู่ของสตริงอินพุตกับนิพจน์ทั่วไป\D*\d*\dความเข้าใจด้านนอกทำหน้าที่ในการแข่งขันแต่ละครั้งของสายเข้ากับการแสดงออกปกติความเข้าใจภายในจะทำซ้ำตัวละครแต่ละตัวของการแข่งขันตามหลักท้าย องค์ประกอบของอาร์เรย์ภายในเข้าร่วมในสตริงดังนั้นอาร์เรย์ด้านนอกจึงเป็นอาร์เรย์ของสตริง เหล่านี้เข้าร่วมและกลับมา

ใน Julia สามารถใช้สตริงได้เหมือนกับอาร์เรย์อักขระ อย่างไรก็ตามโปรดทราบว่าประเภทCharและStringประเภทใน Julia ไม่มีวิธีการเดียวกันที่กำหนดไว้ โดยเฉพาะอย่างยิ่งไม่มีวิธีการทำซ้ำโดยใช้^สำหรับอักขระ วิธีนี้ใช้วิธีแก้ปัญหาที่ซับซ้อน:

  • วนรอบสตริงที่ไม่ใช้อักขระตัวสุดท้ายซึ่งจะถูกลบออกโดยใช้ chop()ห่วงมากกว่าสตริงถนัดตัวอักษรตัวสุดท้ายซึ่งจะถูกลบออกโดยใช้
  • แปลงอักขระปัจจุบันเป็นสตริงโดยใช้ string()แปลงตัวอักษรในปัจจุบันเพื่อใช้สตริง
  • แปลงตัวเลขต่อท้ายซึ่งเป็นอักขระด้วยจำนวนเต็ม อย่างไรก็ตามโปรดทราบว่าตัวอย่างเช่นint('4')ไม่ส่งคืน 4 แต่จะส่งคืน codepoint ซึ่งในกรณีนี้คือ 52 ดังนั้นเราสามารถลบ 48 เพื่อให้ได้จำนวนเต็มจริงกลับมา
  • ทำซ้ำตามstring(b)int(p[end]) - 48

ตัวอย่าง:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

julia> f("13b1")
"111b"

1

Python 3, 148 144 136 135 ไบต์

w,o,r,d=''.join,'',[],[]
for c in input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print(o)

ขอบคุณ Pietu1998 และ mbomb007 สำหรับคำแนะนำ

Python 2, 161 151 147 139 138 Bytes

บางทีวันนี้อาจจะเป็นวันที่ยาวนานของการทำงาน แต่ฉันไม่สามารถหาวิธีการตีกอล์ฟได้

w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print o

3
การเปลี่ยนเป็น Python 3 จะบันทึกสองสามไบต์ ( raw_ออก, วงเล็บเป็นprint) len(d)>0สามารถถูกแทนที่ด้วยdเนื่องจากรายการที่ว่างเปล่าเป็นเท็จและความจริงที่ไม่ว่างเปล่ารายการ สามารถตรงไปที่list(...) forวงเล็บเหลี่ยมw([...])ไม่จำเป็นเนื่องจากเป็นอาร์กิวเมนต์เท่านั้น ) forคุณสามารถลบพื้นที่ใน นั่นคือสิ่งเล็ก ๆ น้อย ๆ ทั้งหมดที่ฉันเกิดขึ้น
PurkkaKoodari

@ Pietu1998 ขอบคุณสำหรับความช่วยเหลือ!
Kade

โดยไม่ต้องเปลี่ยนวิธีการของคุณมากเกินไปคุณสามารถกำจัดได้list()เนื่องจากสตริงมีการวนซ้ำ w=r=''คุณสามารถใช้ หากคุณยินดีที่จะเปลี่ยนแปลงมันมากดูโซลูชันของฉัน :)
เรียกซ้ำ

if c.isdigit()สามารถกลายเป็นif'/'<c<':'ถ้าฉันไม่ผิด
DLosc

@DLosc ขอบคุณที่ดูเหมือนว่าจะทำงาน
Kade

0

Java 7, 175 bytes

String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}

ความท้าทายนั้นยากกว่าที่คิด

Ungolfed & รหัสการทดสอบ:

ลองที่นี่

class M{
  static String c(String s){
    String r = "",
           a[];
    for(String x : s.split("(?<=(\\d)(?!\\d))")){
      a = x.split("");
      for(int i = 0, j, l = a.length-1; i < l; i++){
        for(j = 0; j++ < new Short(a[l]); r += a[i]);
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("ab3c5"));
    System.out.println(c("a0b3"));
    System.out.println(c("13b1"));
    System.out.println(c("a13b1"));
    System.out.println(c("a123b1"));
    System.out.println(c("aa2a1b1"));
    System.out.println(c("123"));
  }
}

เอาท์พุท:

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