Praming Puzles & Colf: Ngưng tụ một chuỗi


25

Dành một chút thời gian trên trang web này, tôi đã đến để tận hưởng mọi thứ càng ngắn càng tốt. Đó có thể là lý do tại sao gần đây tôi bị xúc phạm bởi các chuỗi chứa cùng một ký tự nhiều lần. Công việc của bạn là viết một hàm hoặc chương trình ngưng tụ một chuỗi đã cho theo các quy tắc sau:

  • Bắt đầu với một ngưng tụ 0 , đó là tìm cặp đầu tiên (ngoài cùng bên trái) của cùng một ký tự với 0 ký tự khác giữa chúng. Nếu tìm thấy một cặp như vậy, loại bỏ một trong hai ký tự và khởi động lại thuật toán bằng cách thực hiện một ngưng tụ 0 khác . Nếu không tìm thấy cặp nào như vậy, hãy tiến hành bước tiếp theo. Ví dụ:
    programming-C0-> programing
    aabbcc-C0-> abbcc
    test-C0->test

  • Sau đó thực hiện ngưng tụ 1 , đó là tìm cặp đầu tiên của cùng một ký tự với 1 ký tự khác giữa chúng. Nếu một cặp như vậy được tìm thấy, loại bỏ một trong số chúng và tất cả các ký tự giữa chúng và khởi động lại với độ ngưng tụ 0 . Nếu không tìm thấy cặp nào như vậy, hãy tiến hành bước tiếp theo. Ví dụ:
    abacac-C1-> acac
    java-C1->ja

  • Tiếp tục với một ngưng tụ 2 và cứ thế đến một ngưng tụ n với n là độ dài của chuỗi gốc, mỗi lần khởi động lại sau khi ngưng tụ đã loại bỏ một số chữ cái. Ví dụ:
    programing-C2-> praming
    abcdafg-C3->afg

Chuỗi kết quả được gọi là ngưng tụ và chứa mỗi ký tự nhiều nhất một lần.


Đầu vào:

Một chuỗi chữ thường của ký tự ascii có thể in được.

Đầu ra:

Các chuỗi ngưng tụ theo các quy tắc trên.

Ví dụ:

examples     -> es
programming  -> praming
puzzles      -> puzles
codegolf     -> colf
andromeda    -> a
abcbaccbabcb -> acb
if(x==1):x++ -> if(x+
fnabnfun     -> fun
abcdefae     -> abcde

Ví dụ chi tiết để làm rõ cách thức hoạt động của thuật toán:

fnabnfun -C0-> fnabnfun -C1-> fnabnfun -C2-> fnfun -C0-> fnfun -C1-> fun -C0-> fun 
 -C1-> fun -C2-> ... -C8-> fun

abcbaccbabcb -C0-> abcbacbabcb -C0-> abcbacbabcb -C1-> abacbabcb -C0-> abacbabcb 
 -C1-> acbabcb -C0-> acbabcb -C1-> acbcb -C0-> acbcb -C1-> acb -C0-> acb 
 -C1-> ... -C12-> acb

Cách tiếp cận của bạn không phải thực hiện thuật toán từ phía trên miễn là giải pháp của bạn và thuật toán trả về cùng một đầu ra cho tất cả các đầu vào được phép. Đây là một thách thức .


Cảm ơn @Linus vì những bình luận hữu ích trong hộp cát!


@MartinEnder Trường hợp thử nghiệm của Riley vẫn cần thiết, bởi vì đó là giải pháp Retina duy nhất của tôi không hoạt động.
mbomb007

@ mbomb007 À, tôi hiểu rồi. Điểm tốt.
Martin Ender

Chuỗi đầu vào có bao giờ chứa các ký tự không in được như dấu cách không?
mbomb007

@ mbomb007 Không, chỉ giả sử các ký tự ascii có thể in được là ổn.
Laikoni

@ mbomb007 Tuy nhiên, theo như tôi biết, một khoảng trắng được coi là ký tự ascii có thể in được, ví dụ ở đây .
Laikoni

Câu trả lời:


6

JavaScript (ES6), 74 byte

f=
(s,n=0,m=s.match(`(.).{${n}}\\1`))=>s[n]?m?f(s.replace(...m)):f(s,n+1):s
;
<input oninput=o.textContent=f(this.value)><pre id=o>


Rất đẹp, ngắn hơn những gì tôi nghĩ.
Sản phẩm ETH

5

Perl, 38 31 30 29 byte

Điều này sẽ khiến các ngôn ngữ không chơi gôn bị bỏ lại phía sau ...

-1 $-[0]cảm ơn Riley

-1 @{-}cảm ơn Dada

Bao gồm +1 cho -p

Cung cấp đầu vào trên STDIN

condense.pl:

#!/usr/bin/perl -p
s/(.)\K.{@{-}}\1// while/./g

Phiên bản 27 byte này sẽ hoạt động nhưng không phải vì perl không nội suy @-trong regex (xem /programming/39521060/why-are-etc-not-interpiated-in-strings )

#!/usr/bin/perl -p
s/(.)\K.{@-}\1// while/./g

Làm thế nào để @{\@-}một phần làm việc? Tôi nghĩ rằng @-đã nắm giữ các chỉ số của mỗi trận đấu, vậy làm thế nào để nó "đếm" trên mỗi lần lặp. Ngoài ra, nếu bạn in @{\@-}trước và sau mỗi lần thay thế, nó chỉ in 1 hoặc 2.
Riley

1
@Riley /./gTiến trình tăng thêm 1 trong chuỗi mỗi lần, ngoại trừ khi chuỗi thay đổi, thì nó sẽ được đặt lại về 0. Nếu bạn in @-sau /./gnhưng trước đó s///bạn sẽ thấy nó tăng lên (sử dụng thử nghiệm trong đó chuỗi còn lại đủ lớn)
TonMedel

In ấn $-[0]cho những con số tôi mong đợi. Có @{\@-}hành động như vậy $-[0]vì bối cảnh regex nhưng không phải khi in vì một số lý do? $-[0]là một byte ngắn hơn @{\@-}nếu chúng giống nhau.
Riley

"@{\@-}"không giống như @{\@-}(không có ").
Riley

@Riley Không, nhưng "@{\@-}"cũng giống như "@-". Và điều này cũng đúng với sự thay thế regex nhưng không phải vậy. Simularly $-[0]nên làm việc nhưng không. Tái bút: Có lẽ bạn bằng cách nào đó đã áp dụng bối cảnh vô hướng @-khi bạn thực hiện bản in của mình, vì vậy bạn luôn có 1 hoặc 2
TonMedel

3

CJam , 35 byte

rL{_,{{(_@_@#I={I)>]sj}*}h]s}fI}j

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


rL{                            }j   | run recursion on input
   _,{                      }fI     | for I from 0 to length(input)
      {                 }h]s        | one pass & clean up
       (_@                          | slice and store leading element A
          _@#I={      }*            | if next A is I steps away
                I)>                 | slice off I+1 element
                   ]sj              | clean up & recursion

Bạn có thể thấy sự ngưng tụ riêng lẻ bằng cách chèned


2

Python 2, 117 104 101 byte

Đệ quy làm thay thế cần thiết. Tôi xây dựng regex một cách linh hoạt.

import re
def f(s,i=0):t=re.sub(r"(.)%s\1"%("."*i),r"\1",s);e=s==t;return i>len(t)and t or f(t,i*e+e)

Dùng thử trực tuyến


Hai dòng trả về có thể được cô đọng lại thành return i>len(t) and t or s!=t and f(t) or f(t,i+1)một mạng lưới -4 byte
Quelklef

Có thể loại bỏ 2 byte khác bằng cách thay đổi nó thànhreturn t if i>len(t)else s!=t and f(t)or f(t,i+1))
Quelklef

Thậm chí nhiều hơn e=s==t;return i>len(t)and t or f(t,i*e+e)và sau đó bạn có thể xóa i=0định nghĩa hàm, nhưng bạn sẽ phải gọi với 0 bắt đầu.
Quelklef

Tôi sẽ giả định rằng bốn không gian ở đó không phải vì bạn đang sử dụng bốn không gian mà vì SE tự động mở rộng chúng. Nếu không phải như vậy, bạn có thể thay đổi tất cả các khoảng trắng của mình thành các tab hoặc một khoảng trống cho -9 byte.
Vụ kiện của Quỹ Monica

@Quelklef Các meta cấm lấy tham số bổ sung.
mbomb007

1

Perl 53 52

Bao gồm +1 cho -p

for($i=0;$i<length;){$i=(s/(.).{$i}\1/\1/)?0:$i+1;}

Hãy thử nó trên ideone .


1

Toán học, 101 byte

NestWhile[i=0;StringReplace[#,a_~~_~RepeatedNull~i++~~a_:>a,1]&,#,SameQ,2,ByteCount@#]&~FixedPoint~#&

Cần có một cách để làm cho nó ngắn hơn ...


1

PHP, 90 byte

for($s=$argv[$c=1];$s[$i=++$i*!$c];)$s=preg_replace("#(.).{{$i}}\\1#","$1",$s,1,$c);echo$s;

hoặc 92 byte

for($s=$argv[1];$s[$i];$i=++$i*!$c)$s=preg_replace("#(.).{".+$i."}\\1#","$1",$s,1,$c);echo$s;   

1
1) phiên bản đầu tiên: +$ithay vì $i+=0(-2). 2) forvòng lặp thay vì whilecó thể lưu hai byte và cho phép loại bỏ xoăn (-4). 3) $i=++$i*!$cthay vì $i=$c?0:$i+1(-1). 4) \\2là không cần thiết, loại bỏ dấu ngoặc đơn (-2). 5) Bạn có thể cho phép giới hạn 9thay vì 1tốc độ (+0)
Tít

@Titus ý tưởng rất hay. Tôi đã không thấy điều này Cảm ơn bạn
Jörg Hülsermann

Bây giờ tôi nghĩ lại ... +$ikhông hoạt động trong mọi trường hợp. Hãy thử hammer. PHP khôngnt phàn nàn về các dấu ngoặc rỗng trong regex; nhưng nó không phù hợp như mong muốn. Nhân tiện: tôi đếm 91, không phải 90. Nhưng hãy thử số 1 mới)for($s=$argv[$c=1];$s[$i=++$i*!$c];)
Tít

@Titus Có thực sự tôi quay lại $i+=0và sẽ thử đề xuất của bạn sau. Có ý nghĩa gì với búa?
Jörg Hülsermann

@Titus ổn vấn đề tương tự nếu puzzlehoặc một cái gì đó khác như thế (.)//1nhưng không sao với đề xuất của bạn hoặc$i´=0
Jörg Hülsermann

1

Ruby, 75 64 57 byte

(56 byte mã + ptùy chọn dòng lệnh.)

Sử dụng phép nội suy chuỗi bên trong regex để kiểm soát độ dài của các trận đấu được thay thế.

i=0
~/(.).{#{i}}\1/?sub($&,$1)&&i=0: i+=1while i<$_.size

Kiểm tra:

$ ruby -p condense.rb <<< fnabnfun
fun

1

Haskell , 97 88 byte

(0?)
(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s<m=s|a<-s!drop m s=sum[m+1|a==s]?a

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


Bersion 97 byte cũ:

(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s==m=s|a<-s!drop m s=(last$0:[m+1|a==s])?a
c=(0?)

Hãy thử nó trên ideone .

Giải trình:

(a:s)!(b:t)|a==b = a:t         --perform condensation
           |1<3  = a:s!t       --recursively compare further
 s   ! _         = s           --no condensation performed

Các (!)chức năng thực hiện một n-ngưng tụ khi đưa ra một chuỗi một lần toàn bộ và một lần với các nhân vật n đầu tiên loại bỏ, ví dụ abcdbecdbecho một 2-ngưng tụ, bởi đệ quy so sánh hai nhân vật hàng đầu.

m?s|length s==m   = s         --stop before performing length-s-condensation
   |a <- s!drop m s           --a is the m-condensation of s
    = (last$0:[m+1|a==s])?a   --disguised conditional:
                              -- if a==s       if the m-condensation did not change s
                              -- then (m+1)?a  then perform m+1-condensation
                              -- else 0?a      else restart with a 0-condensation

c=(0?)                        -- main function, initialise m with 0
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.