Rút ngắn văn bản với Mã hóa chiều dài chạy


8

Rút ngắn (hoặc không) văn bản bằng cách sử dụng mã hóa thời lượng chạy

Đầu vào:

heeeello
thế giới

Đầu ra:

1h4e2l1o
1w4o1r1l1d
  • Đọc các dòng từ stdin.
  • In ra thiết bị xuất chuẩn.
  • Stderr tất nhiên là bị loại bỏ.
  • Giả sử có các testcase ẩn (không nhúng đầu ra)
  • Đầu vào / đầu ra dưới dạng ASCII
  • Mọi ngôn ngữ đều được chấp nhận

3
Bạn có thể (thường) tiết kiệm được một chút nếu bạn bỏ qua tất cả những thứ đó, ví dụ w4orldthay vì 1w4o1r1l1d(bạn cần thoát số, ví dụ `f111 -> f3 \ 1). Nhưng sau đó, nó sẽ là một bản sao gần như của điều này: codegolf.stackexchange.com/questions/6774
primo

1
Vì nó đủ gần để Mã hóa Độ dài Run mà tôi bỏ phiếu để đóng dưới dạng dupe. Nó sẽ không cung cấp bất kỳ thách thức hoặc điểm quan tâm mới.
Peter Taylor

Điểm thưởng cho bất cứ ai quản lý để tìm một điểm cố định.
FUZxxl

4
@FUZxxl, 22là một điểm cố định tầm thường.
Peter Taylor

2
@PeterTaylor Và người duy nhất không trống. Chúng tôi biết nó phải bắt đầu bằng một chữ số. 11là không thể 22phải kết thúc ở đó hoặc được theo sau bởi một điểm cố định khác không bắt đầu bằng 2. 333nnnlà một mô hình không thể, vì bạn sẽ không bao giờ tìm thấy cùng một ký tự ở các chỉ số lẻ liên tiếp. 4444và thất bại vì lý do tương tự.
Khuldraeseth na'Barya

Câu trả lời:


2

Perl: 46 → 36 hoặc 27 ký tự

perl -pe's|((.)\2*)|@x=split//,$1;@x.$x[0]|eg'

Tất cả mưa đá @ardnew đã nảy ra ý tưởng sử dụng tr///ctoán tử để đếm số lượng ký tự trong chuỗi khớp thay vì chia tách:

perl -pe's|((.)\2*)|$1=~y///c.$2|eg'

Bị thoái hóa:

while(defined($_ = <>)) {
  $_ =~ s{((.)\2*)}           # match 1 or more consecutive identical non-newlines
         {
           ($1 =~ y///c )     # count the number of characters in $1
           .                  # and concatenate it
           $2                 # with the first matched character
         }eg;                 # execute substitution, match "global"
  print $_;                   # print the modified line
}

Sử dụng:

$ perl -pe's|((.)\2*)|$1=~y///c.$2|eg' infile

hoặc thông qua STDIN

$ perl -pe's|((.)\2*)|$1=~y///c.$2|eg'
heeeello

in

1h4e2l1o

Bạn đang tự thay đổi số lượng nhân vật của mình - Tôi đếm 37 ký tự trong đó có 1 ký tự cho ptùy chọn.
Gareth

Bạn có thể lưu 10 ký tự bằng cách sử dụng s|((.)\2*)|$1=~y///c.$2|eg, tổng cộng thành 27 ký tự (sử dụng cùng quy tắc đếm ký tự như @Gareth)
ardew

1
Có thể rút ngắn hơn nữa xuống còn 25 byte (bao gồm -p) bằng cách loại bỏ các dấu ngoặc ngoài: Hãy thử trực tuyến!
Xcali

2

Stax , 7 byte

ûèB☼å°╤

Chạy và gỡ lỗi nó st staxlang.xyz!

Giải nén (8 byte) và giải thích:

m|RFNppz
m           For each line of input:
 |R           Run-length encode: "heeeello" -> [[104,1],[101,4],[108,2],[111,1]]
   F          For each pair:
    N           Uncons-left: [104,1] -> push [104]; push 1
     ppz        Pop and print. Pop and print. Push "".
              Implicit print (always an empty string) with a newline

5 byte, chỉ hoạt động trên một dòng duy nhất:

∩l↨me
|RmEp]    Unpacked
|R        Run-length encode: "heeeello" -> [[104,1],[101,4],[108,2],[111,1]]
  m       Map block over input:
   E        Explode array: [104,1] -> push 104, push 1
    p       Pop and print with no newline
     ]      Make a one-element list: 104 -> [104] (which is "h")
            Implicit print with newline

Chạy và gỡ lỗi nó tại staxlang.xyz!

Có lẽ không hợp pháp. Chương trình này in mỗi cặp trên một dòng của riêng mình. Một chút sơ sài.

Nếu định dạng đầu ra đó là bất hợp pháp, tôi cung cấp cho bạn 6 byte :

╡δôZ→╬
|RFEp]p    Unpacked
  F        For each item in array, execute block:
      p      Pop and print with no newline
             No implicit print in for-each block, so no extra newlines

Chạy và gỡ lỗi nó tại staxlang.xyz!

Trình tạo đệ quy của ngôn ngữ chỉ ra rằng uncons-right ( N) có thể rút ngắn điều này xuống còn sáu byte được giải nén, vì nó tự xử lý Evà chính ]nó. Tuy nhiên, các chương trình này thường không ngắn hơn khi được đóng gói và đây là ví dụ. Vẫn còn sáu byte: |RFNppChỉnh sửa: Phải cập nhật câu trả lời chính của tôi; hình thức này là những gì tôi đã sử dụng.


1
Hoàn thành tốt. |RFNppcó thể cung cấp đầu ra được chỉ định trong 6 byte được giải nén, nhưng thật không may, không đóng gói.
đệ quy

1
@KevinCruijssen Yep. Rất tiếc.
Khuldraeseth na'Barya

1

J, 35 31 ký tự

,(](":@#,{.);.1~1,2~:/\])1!:1[1

Sử dụng:

   ,(](":@#,{.);.1~1,2~:/\])1!:1[1
heeeello
1h4e2l1o
   ,(](":@#,{.);.1~1,2~:/\])1!:1[1
woooorld
1w4o1r1l1d

Sử dụng các quy tắc trang web hiện đại và một chức năng, [:,(#,&":{.)/.~cho 15: Hãy thử trực tuyến!
Giô-na

1

Brachylog , 11 byte

ḅ⟨{lṫ}ch⟩ᵐc

Hãy thử trực tuyến!

(Nếu đầu ra thực sự phải ở trên thiết bị xuất chuẩn, hãy thêm một byte cho wcuối.)

          c    The output is the concatenation of
 ⟨    c ⟩ᵐ     the concatenated pairs of
  {lṫ}         length converted to a string
       h       and first element
ḅ        ᵐ     for every run in the input.


1

Lặp lại Python 3 , 115 99 97 byte

while 1:
 a=b='';k=0
 for c in input():e=a!=c;b+=(str(k)+a)*e;k+=1-k*e;a=c
 print(b[1:]+str(k)+a)

Hãy thử trực tuyến!

Python 3 đệ quy, 136 130 129 byte

f=lambda r,c,s,k=1:s and(c==s[0]and f(r,c,s[1:],k+1)or f(r+str(k)+c,s[0],s[1:]))or r[1:]+str(k)+c
while 1:print(f('','',input()))

Hãy thử trực tuyến!

Cách tiếp cận lặp lại có vẻ khá thành công, trong khi phiên bản đệ quy có nhiều chỗ để cải tiến.


Cách tiếp cận tốt đẹp! Có vẻ như whilevòng lặp trong mã của bạn chỉ ở đó để chứng minh đầu vào. Không có nó, mã của bạn vẫn còn hiệu lực. Trong trường hợp đó, vòng lặp không cần phải là một phần của mã và bạn có thể giảm ví dụ đầu tiên xuống còn 85 byte như vậy: Hãy thử trực tuyến!
Jitse

Ví dụ thứ hai của bạn có thể giảm xuống 121 byte như thế này: Hãy thử trực tuyến!
Jitse

Phải, vòng lặp while chỉ dành cho đầu vào theo chiều dọc. Nhưng câu hỏi yêu cầu phải đọc tất cả các dòng, không chỉ một, vì vậy việc đưa ra vòng lặp sẽ trái với quy tắc.
Movatica

1

05AB1E , 9 byte

|εÅγs.ιJ,

Hãy thử trực tuyến.

Hay cách khác:

|εÅγøí˜J,

Hãy thử trực tuyến.

Giải trình:

|          # Read all lines of input as list
 ε         # For-each over the lines:
  Åγ       #  Run-length encode, pushing the list of characters and lengths separately
    s      #  Swap so the characters at at the top and lengths below it
         #  Interleave the two lists
       J   #  Join the list of characters and lengths together to a single string
        ,  #  And output it with trailing newline

|εÅγ       # Same as above
    ø      #  Zip/transpose; creating pairs of [character, length]
     í     #  Reverse each pair to [length, character]
      ˜    #  Deep flatten the pairs to a single list
       J,  #  Join them together to a single string, and output it with trailing newline


0

Bash: 104 ký tự

while read s;do e=;while [[ $s ]];do c=${s:0:1};n=${s##+($c)};e+=$[${#s}-${#n}]$c;s=$n;done;echo $e;done

Chạy mẫu:

bash-4.2$ while read s;do e=;while [[ $s ]];do c=${s:0:1};n=${s##+($c)};e+=$[${#s}-${#n}]$c;s=$n;done;echo $e;done <<END
heeeello
woooorld
END
1h4e2l1o
1w4o1r1l1d

0

Zsh, 117

while read s;do n=1;for i in {1..$#s};do if [[ $s[i] != $s[i+1] ]];then echo -n $n$s[i];n=0;fi;((n++));done;echo;done

Chạy nó như thế này:

zsh script.zsh < infile

Bỏ chơi gôn

while read s; do                      # while stdin has more
  n=1                                 # repeat counter
  for i in {1..$#s}; do               # for each character
    if [[ $s[i] != $s[i+1] ]]; then   # same as next one?
      echo -n $n$s[i]                 # print if no
      n=0
    fi
    ((n++))
  done
  echo                                # newline between words
done

Những khoảng trắng đó có cần thiết không hoặc bạn có thể rút ngắn `if ['thành' if ['vv không?
mroman

Cấu [[trúc là một lệnh trên chính nó (như [) và phải được tách ra khỏi các lệnh khác. Đối với việc sử dụng [hơn [[, nó đòi hỏi các đối số được trích dẫn để bốn "cần phải được thêm vào.
Thor


0

Burlesque (17B)

{=[{J[-jL[Q}\m}WL

{=[{^^[~\/L[Sh}\m}WL

Phiên bản cũ hơn / thay thế và dài hơn:

{= [{^^ L [Sh \ / -] Sh. +} M [\ [} WL
{= [{^^ L [Sh \ / -] [-. +} M [\ [} WL
{= [{^^ L [Sh \ / - ~. +} M [\ [} WL
{= [{^^ L [Sh \ / -]. +} \ M} WL
{= [{^^ L [Sh \ / [~. +} \ M} WL
{= [{^^ L [Sh \ / [~ _ +} \ m} WL
{= [{^^ L [Sh \ / fc. +} \ M} WL
{= [{^^ L [Sh \ / - ~. +} \ M} WL
{= [{^^ L [Sh \ / -] \ /} \ m} WL


0

Võng mạc , 12 byte

(.)\1*
$.0$1

Hãy thử trực tuyến.

Giải trình:

Nhận một phần của 1 hoặc nhiều nhân vật giống nhau, bắt nhân vật trong nhóm bắt giữ 1.

(.)\1*

Thay thế nó bằng độ dài của tổng số trận đấu, được ẩn với ký tự từ nhóm chụp 1:

$.0$1


0

Python 3 , 84 byte

def f(s,c=1):i,*j=s;b=j[:1]==[i];print(end='%s%s'%(c,i)*(b^1));f(j,1+b*c)
f(input())

Hãy thử trực tuyến!

Giải trình

Kiểm tra xem các ký tự đầu tiên và thứ hai của chuỗi có bằng nhau không. Nếu có, hãy tăng bộ đếm lên 1. Nếu không, hãy in bộ đếm và mục đầu tiên và đặt lại bộ đếm thành 1. Trong cả hai trường hợp, hàm được gọi đệ quy với ký tự đầu tiên bị xóa.

Tăng lỗi khi kết thúc chuỗi.


Không có hạn chế I / O, nhưng với số byte tối thiểu:

Python 3,8 (tiền phát hành) , 70 byte

f=lambda s:'%s%s'%(len(s)-len(t:=s.lstrip(p:=s[0])),p)+f(t)if s else''

Hãy thử trực tuyến!

Python 3 tương đương (77 byte)

Giải trình

Loại bỏ tất cả các ký tự lặp lại từ đầu chuỗi. Sau đó, nó trả về một chuỗi chứa (1.) sự khác biệt về độ dài giữa chuỗi gốc và chuỗi bị tước; (2.) ký tự đầu tiên của chuỗi gốc; (3.) kết quả của hàm đệ quy được áp dụng cho chuỗi bị tước. Đệ quy kết thúc khi gặp một chuỗi rỗng.


0

[Scala (shell)], 150 byte

scala.io.Source.stdin.getLines.foreach(s=>println{val(x,y,z)=s.tail.foldLeft(("",s.head,1)){case((a,b,c),d)=>if(b==d)(a,b,c+1)else(a+c+b,d,1)};x+z+y})

Hãy thử trực tuyến!

Ở đây, Lambda de-golfed thuần túy (103 byte):

  s => {
    val (x,y,z) = s.tail.foldLeft(("", s.head, 1)) {
      case ((a, b, c), d) =>
        if (b == d)
          (a, b, c + 1)
        else
          (a + c + b, d, 1)
    }
    x+z+y
  }

0

Julia 1.1 , 94 84 81 byte

foldl(((n,l),c)->(c==l||print(n,l);((c==l&&n)+1,c)),readline()*'\n',init=("",""))

Hãy thử trực tuyến!


Đây là 80 byte . Tôi nghĩ rằng nó có thể đi ngắn hơn mặc dù
H.PWiz

Thật không may, mã của bạn không hoạt động trên Julia 1.1 đối với tôi. Tôi vẫn quản lý để có được 81 bằng cách thêm một thêm '\n' để readline()thay vì in tuple cuối cùng bằng tay
Simeon Schaub

0

CJam , 2 byte

e`

e`là một tích hợp để mã hóa chiều dài chạy. Đầu ra ngầm của CJam bỏ qua dấu ngoặc và do đó biến [[1 'h] [2 'e]]thành"1h2e"

Hãy thử trực tuyến!


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.