Mở rộng chuỗi được mã hóa


18

Có mã hóa và giải mã chiều dài chạy cổ điển.

input   output
a3b2c5  aaabbccccc

Và đó là khá thẳng về phía trước và thực hiện trước đó.

Thách thức là cũng chiếm một hành vi phi tiêu chuẩn khi nhiều nhân vật đứng trước chiều dài chạy (một đơn chữ số từ 0-9). Mỗi nhân vật trước chữ số chạy dài (chữ số cuối cùng trước khi một tổ chức phi chữ số hoặc kết thúc của chuỗi) có giá trị áp dụng cho nó độc lập và in ra theo thứ tự.

Một số thử nghiệm đầu vào và đầu ra bao gồm một số trường hợp cạnh:

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • Một chuỗi ký tự ( [a-zA-Z0-9]+) phải được theo sau bởi độ dài chạy ( [0-9])
  • Chỉ đầu vào hợp lệ cần được xem xét ( ([a-zA-Z0-9]+[0-9])*)
    • có, chuỗi rỗng là đầu vào hợp lệ.
  • Đầu vào là thông qua đầu vào tiêu chuẩn, đầu ra thông qua đầu ra tiêu chuẩn

Đây là mã golf, số byte xác định người chiến thắng.


@AlexA. Chính xác. Có một số esolang mà tôi thích nhìn thấy theo thời gian mà bị phạt bởi số byte. (Tôi chắc chắn sẵn sàng nhận đề xuất về lý do tại sao điều này có thể là một sai lầm khi tính theo cách đó)

4
@MichaelT Ghi điểm theo các ký tự khuyến khích mạnh mẽ việc nén mã nguồn vào UTF32, cho phép mã hóa tối đa 4 byte mỗi ký tự, nhưng hoàn toàn không thể đọc được.
isaacg

@isaacg công bằng 'nuff. Tôi sẽ chỉnh sửa để thay đổi thành byte. Tôi sẽ suy nghĩ về cách thể hiện phong cách của sclipting để được chấp nhận cho những thách thức trong tương lai.

Việc gửi của chúng tôi có được hoàn thành mà không có lỗi nếu đầu vào là chuỗi rỗng không? Sự đồng thuận về meta là đầu ra cho STDERR có thể bị bỏ qua, nhưng vì bạn đã đề cập rõ ràng đến nó, tôi phải hỏi.
Dennis

@Dennis một chuỗi trống làm đầu vào nên dừng lại. Nó không nên đi vào một vòng lặp vô hạn hoặc in văn bản khác đến đầu ra tiêu chuẩn.

Câu trả lời:


3

Pip, 22 + 1 = 23 byte

Sử dụng -rcờ. Lưu ý rằng điều này yêu cầu bạn phải nhập 1) sau khi nhập EOF sau khi nhập (Ctrl-D trên Linux, Ctrl-Z trên Windows) hoặc 2) dẫn đầu vào từ một nơi khác.

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

Giải trình:

                        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)

Kết quả của hoạt động bản đồ thực sự là một danh sách các danh sách, nhưng theo mặc định các danh sách chỉ được nối với nhau khi được in, do đó không cần chuyển đổi thủ công thành chuỗi.

Ví dụ, với đầu vào a13b1:

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

Pip có hỗ trợ regex cơ bản tính đến ... 2 ngày trước . Thời gian tuyệt vời!


Cái đó hoạt động (và chủ cũng vậy) với -rcờ. (Câu hỏi chỉ định rằng đầu vào phải đến từ STDIN.)
Dennis

@Dennis Oops, đã bỏ lỡ điều đó. Đã thêm cờ vào số byte. Tôi đã có thể sử dụng biến đặc biệt qthay vì akhông có cờ bổ sung, nhưng dường như có một lỗi và nó yêu cầu đầu vào hai lần.
DLosc

Cuối cùng là một ngôn ngữ chơi golf với sự hỗ trợ của regex!
Dennis

@Dennis Tôi thấy bạn chuyển sang pip ngay bây giờ!
Tối ưu hóa

8

Perl / Bash 54 40 + 1 = 41 byte

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

Về cơ bản, nó là một regex trong một regex. Và một chút ma thuật.

Giải trình

Regex bên ngoài /(\D*\d*)(\d)/gtrích xuất từng nhóm được mã hóa theo chiều dài chạy. Chúng tôi nắm bắt những thứ để lặp lại $1và số lần lặp lại trong $2. Bây giờ chúng tôi thay thế từng nhóm như vậy bằng việc mở rộng nhóm đó. Đối với điều đó, chúng tôi đánh giá mã "\$1=~s/./\$&x$2/egr" hai lần (như bằng /eecờ trên thay thế bên ngoài).

Đánh giá đầu tiên sẽ chỉ nội suy số lần lặp lại thành chuỗi - các biến khác được bảo vệ bằng dấu gạch chéo ngược. Vì vậy, giả sử đầu vàoa14 , bây giờ chúng ta sẽ có mã $1=~s/./$&x4/egr, sẽ được đánh giá lại.

Điều này sẽ áp dụng thay thế cho nội dung của $1(những thứ cần lặp lại a1). Sự thay thế phù hợp với từng nhân vật .. Các $&biến giữ toàn bộ trận đấu, mà chúng tôi lặp lại x4lần. Chúng tôi thực hiện điều này một cách /gtối thiểu cho mỗi trận đấu và khắc /rchuỗi thay thế thay vì sửa đổi $1biến (chỉ đọc). Vì vậy, kết quả của sự thay thế bên trong là aaaa1111.

Các -pcờ được áp dụng thay thế cho mỗi dòng đầu vào và in ra kết quả.


3
Theo thông lệ, điểm số này là một giải pháp Perl, trong đó bạn chỉ cần thêm 1 byte cho công cụ -psửa đổi. Tôi đếm 45 byte. Ngoài ra, bạn sẽ có thể sử dụng \Dthay thế [a-z], điều này cũng loại bỏ sự cần thiết i.
Dennis

7

CJam, 33 31 27 byte

Ughh, thiếu biểu cảm thông thường làm cho điều này khá dài ...

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

Làm thế nào nó hoạt động

Chúng tôi lặp qua tất cả các ký tự của chuỗi đầu vào và trong mỗi lần lặp, theo dõi ký tự gặp phải cuối cùng (bắt đầu bằng một ký tự trống lần đầu tiên). Sau đó, chúng tôi kiểm tra xem ký tự hiện tại có phải là số không ký tự cuối cùng là số. Nếu vậy, chúng tôi lặp lại từng ký tự trước đó (chưa được lặp lại), số lần.

(Mở rộng mã lỗi thời một chút)

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

Dùng thử trực tuyến tại đây


Tôi đánh giá cao sự trình diễn của vấn đề mà vòng loại byte gây ra. Cảm ơn bạn. Tôi đang suy nghĩ một chút về cách phát âm trình độ sao cho các ngôn ngữ trong đó một lệnh là một ký tự nhiều byte không bị phạt vì kiểu ngôn ngữ đó mà không cho phép mã hóa UTF mà bạn hiển thị để thông qua lỗ hổng. PS Tôi thực sự thích nhìn thấy sự cố thuật toán mà bạn cung cấp.

6

rs , 43 71 ký tự

Chà, điều này biến thành lâu dài nhanh chóng. Những con số ngu ngốc ...

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

Hãy thử nó ở đây!

Phiên bản gốc (không hoạt động với đầu vào như 123):

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

Giải trình

Dòng đầu tiên đặt khoảng trắng giữa các lần chạy chứa số, ví dụ: biến a313thành a3 13.

Dòng thứ hai liên tục mở rộng mã hóa nén như aa5để a5a5.

Dòng thứ ba chuyển đổi tất cả các thể hiện của a5thành aaaaabằng cách sử dụng toán tử lặp lại .

Dòng cuối cùng loại bỏ khoảng trắng.


Làm thế nào để nó xử lý a123b1?
Tối ưu hóa

@Optimizer Không tốt. Tôi cần phải điều chỉnh nó một chút ...
kirbyfan64sos

@Optimizer Đã sửa.
kirbyfan64sos

5

Javascript ( ES6 ), 86 83 byte

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

Đã bình luận:

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

Sẽ không alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))làm như vậy? Nó chỉ dài 71 byte.
Ismael Miguel

@IsmaelMiguel sẽ chỉ hoạt động nếu có một ký tự duy nhất trước chữ số. Việc hiểu mảng xử lý lặp lại từng ký tự riêng lẻ.
nderscore

Hãy thử Array(6).join('12')và nó sẽ trở lại '1212121212'.
Ismael Miguel

Cái này hoạt động: alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))(cùng 71 byte, được thử nghiệm trên es6fiddle.net/ia7gocwg )
Ismael Miguel

1
Tôi đã tìm thấy một cách khác (rõ ràng) để nói 3 byte mặc dù: D
nderscore

4

CJam, 27 25 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

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 byte

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

Dùng thử trực tuyến: Trình diễn hoặc thử nghiệm khai thác

Giải trình

Tôi sẽ giải thích mã bằng cách sử dụng đầu vào ví dụ aa1a23b2. Hy vọng rằng điều này là một chút dễ dàng để làm theo hơn là không có.

                               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 byte

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

Điều này chỉ thực hiện một tìm kiếm regex đơn giản cho các chữ số không được theo sau bởi một chữ số, và sau đó thực hiện số học chuỗi trên mỗi nhóm và nối tất cả chúng lại với nhau.


Bạn có thể lưu 2 byte bằng cách chuyển từ Python 2 sang 3. raw_inputtrở thành inputnhưng printcần dấu ngoặc đơn.
Alex A.

Đúng, nhưng tôi thích chơi gôn ở python 2.7.
đệ quy

1

Julia, 105 99 95 87 byte

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

Điều này tạo ra một hàm không tên, lấy một chuỗi làm đầu vào trả về một chuỗi. Để gọi nó, đặt tên cho nó, vd f=s->....

Hai mảng hiểu được sử dụng ở đây, một mảng lồng vào nhau. Sự hiểu biết bên ngoài hoạt động trên mỗi trận đấu của chuỗi đầu vào so với biểu thức chính quy \D*\d*\d. Sự hiểu biết bên trong lặp lại từng nhân vật của trận đấu theo chữ số. Các phần tử của mảng bên trong được nối thành một chuỗi, vì vậy mảng bên ngoài là một chuỗi các chuỗi. Chúng được tham gia và trả lại.

Trong Julia, chuỗi có thể được coi như mảng ký tự. Tuy nhiên, lưu ý rằng CharStringcác loại trong Julia không có cùng phương thức được xác định; đặc biệt, không có phương pháp lặp lại sử dụng ^cho các ký tự. Điều này sử dụng một cách giải quyết phức tạp:

  • Lặp lại chuỗi bỏ qua ký tự cuối cùng, được loại bỏ bằng cách sử dụng chop().
  • Chuyển đổi ký tự hiện tại thành một chuỗi bằng cách sử dụng string() .
  • Chuyển đổi chữ số đuôi, cũng là một ký tự, thành một số nguyên. Tuy nhiên, lưu ý rằng, ví dụ,int('4') không trả về 4. Thay vào đó, nó trả về mật mã, trong trường hợp này là 52. Vì vậy, chúng ta có thể trừ 48 để lấy lại số nguyên thực tế.
  • Lặp lại string(b)theo int(p[end]) - 48.

Ví dụ:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

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

1

Python 3, 148 144 136 135 byte

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)

Cảm ơn Pietu1998 và mbomb007 vì những gợi ý.

Python 2, 161 151 147 139 138 byte

Có lẽ hôm nay chỉ là một ngày dài làm việc, nhưng tôi không thể tìm ra cách chơi golf này ..

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
Thay đổi thành Python 3 lưu một vài byte ( raw_ngoài, dấu ngoặc đơn thành print). len(d)>0có thể được thay thế bởi dvì một danh sách trống là giả và một danh sách không trống rỗng. list(...)Có thể đi thẳng đến for. Dấu ngoặc vuông w([...])là không cần thiết vì đó là đối số duy nhất. Bạn có thể loại bỏ không gian trong ) for. Đó là tất cả những điều nhỏ nhặt mà tôi nghĩ ra cho đến nay.
PurkkaKoodari

@ Pietu1998 Cảm ơn sự giúp đỡ!
Kade

Không thay đổi cách tiếp cận của bạn quá nhiều, bạn có thể thoát khỏi list()vì các chuỗi có thể lặp lại. Bạn có thể sử dụng w=r=''. Nếu bạn sẵn sàng thay đổi nó nhiều, hãy xem giải pháp của tôi. :)
đệ quy

if c.isdigit()có thể trở thành if'/'<c<':', nếu tôi không nhầm.
DLosc

@DLosc cảm ơn, điều đó dường như làm việc.
Kade

0

Java 7, 175 byte

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;}

Thử thách khó hơn vẻ ngoài của nó, imo ..

Mã thử nghiệm & mã hóa:

Hãy thử nó ở đây.

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"));
  }
}

Đầu ra:

aaabbbccccc
bbb
111b
aaa111b
aaa111222b
aaaaab
111222
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.