Praming Puzles & Colf: กลั่นตัวเป็นสตริง


25

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

  • เริ่มต้นด้วยการควบแน่น 0ซึ่งจะมองหาคู่แรก (ซ้ายสุด) ของอักขระเดียวกันโดยมี 0 อักขระอื่น ๆ อยู่ระหว่างพวกเขา หากพบคู่ดังกล่าวให้ลบหนึ่งในสองตัวอักษรและเริ่มอัลกอริทึมใหม่โดยดำเนินการควบแน่น 0อีกครั้ง หากไม่พบคู่ดังกล่าวให้ทำตามขั้นตอนต่อไป ตัวอย่าง:
    programming-C0-> programing
    aabbcc-C0-> abbcc
    test-C0->test

  • จากนั้นดำเนินการควบแน่นที่ 1ซึ่งจะค้นหาคู่แรกของอักขระเดียวกันโดยมีอักขระอีก 1 ตัวอยู่ระหว่างกัน หากคู่ดังกล่าวจะพบว่าหนึ่งลบของพวกเขาและทุกตัวอักษรระหว่างพวกเขาและเริ่มต้นใหม่กับ0 การควบแน่น หากไม่พบคู่ดังกล่าวให้ทำตามขั้นตอนต่อไป ตัวอย่าง:
    abacac-C1-> acac
    java-C1->ja

  • ดำเนินการต่อด้วยการควบแน่น 2 ครั้งและอื่น ๆ จนถึงการควบแน่นแบบnโดยที่nคือความยาวของสตริงเดิมทุกครั้งที่เริ่มการทำงานใหม่หลังจากการควบแน่นได้นำตัวอักษรบางตัวออก ตัวอย่าง:
    programing-C2-> praming
    abcdafg-C3->afg

สตริงผลลัพธ์ถูกเรียกย่อและมีอักขระแต่ละตัวมากที่สุด


การป้อนข้อมูล:

สตริงตัวพิมพ์เล็กของอักขระ ASCII ที่พิมพ์ได้

เอาท์พุท:

ข้นสตริงตามกฎดังกล่าวข้างต้น

ตัวอย่าง:

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

ตัวอย่างโดยละเอียดเพื่อให้ชัดเจนว่าอัลกอริทึมทำงานอย่างไร:

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

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


ขอบคุณ@Linusสำหรับความคิดเห็น sandbox ที่เป็นประโยชน์!


@MartinEnder Riley ของกรณีทดสอบยังคงเป็นสิ่งที่จำเป็นเพราะมันเป็นทางออกเดียวที่จอประสาทตาของฉันไม่ทำงาน
mbomb007

@ mbomb007 อ่าเข้าใจแล้ว จุดดี.
Martin Ender

สตริงอินพุตจะมีอักขระที่ไม่สามารถพิมพ์ได้เช่นช่องว่างหรือไม่
mbomb007

@ mbomb007 ไม่การสมมติว่าอักขระ ASCII ที่พิมพ์ได้นั้นใช้ได้
Laikoni

@ mbomb007 แต่เท่าที่ผมรู้ว่าพื้นที่จะถือว่าเป็นอักขระ ASCII พิมพ์เช่นที่นี่
Laikoni

คำตอบ:



5

Perl, 38 31 30 29 ไบต์

สิ่งนี้ควรทิ้งภาษาที่ไม่ใช่กอล์ฟไว้ข้างหลัง ...

-1 เพื่อ$-[0]ขอบคุณRiley

-1 สำหรับ@{-}ขอบคุณดาดา

รวม +1 สำหรับ -p

ให้อินพุตบน STDIN

condense.pl:

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

รุ่น 27 ไบต์นี้ควรใช้งานได้ แต่ไม่ได้เป็นเพราะ Perl ไม่ได้สอดแทรก@-ใน regex (ดู/programming/39521060/why-are-etc-not-interpolated-in-strings )

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

วิธีการที่ไม่@{\@-}ทำงานส่วนหนึ่ง? ฉันคิดว่า@-จัดดัชนีของการแข่งขันแต่ละนัดดังนั้น "นับถอยหลัง" ในทุกรอบซ้ำได้อย่างไร นอกจากนี้หากคุณพิมพ์@{\@-}ก่อนและหลังการทดแทนแต่ละครั้งจะพิมพ์ 1 หรือ 2 เท่านั้น
Riley

1
@Riley /./gความคืบหน้า 1 ในสตริงในแต่ละครั้งยกเว้นเมื่อสตริงเปลี่ยนแล้วมันจะถูกรีเซ็ตเป็น 0 หากคุณพิมพ์@-หลังจาก/./gแต่ก่อนที่s///คุณจะเห็นมันขึ้นไป (ใช้การทดสอบที่สตริงที่เหลืออยู่มีขนาดใหญ่พอ)
Ton Hospel

การพิมพ์$-[0]ให้ตัวเลขที่ฉันต้องการ ไม่@{\@-}กระทำเช่น$-[0]เพราะบริบท regex แต่ไม่เมื่อพิมพ์ด้วยเหตุผลบางอย่าง? $-[0]เป็นไบต์ที่สั้นกว่า@{\@-}หากเหมือนกัน
Riley

"@{\@-}"ไม่เหมือนกับ@{\@-}(โดยไม่มี")
Riley

@Riley ไม่มี แต่เป็นเช่นเดียวกับ"@{\@-}" "@-"และนี่ควรเป็นจริงสำหรับการทดแทน regex ด้วย แต่ไม่ใช่ Simularly $-[0]ควรจะทำงาน แต่ไม่ได้ PS: คุณอาจใช้บริบทสเกลาร์กับ@-เมื่อคุณพิมพ์ดังนั้นคุณจะได้ 1 หรือ 2 เสมอ
Ton Hospel

3

CJam , 35 ไบต์

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

ลองออนไลน์!


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

คุณสามารถดูการควบแน่นแต่ละรายการได้โดยการใส่ed


2

Python 2, 117 104 101 ไบต์

ทำการทดแทนที่จำเป็นซ้ำ ๆ ฉันสร้าง regex แบบไดนามิก

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)

ลองออนไลน์


เส้นคืนสองเส้นสามารถรวมตัวreturn i>len(t) and t or s!=t and f(t) or f(t,i+1)เป็นสุทธิ -4 ไบต์
Quelklef

สามารถลบได้อีก 2 ไบต์โดยเปลี่ยนเป็นreturn t if i>len(t)else s!=t and f(t)or f(t,i+1))
Quelklef

มากยิ่งขึ้นe=s==t;return i>len(t)and t or f(t,i*e+e)แล้วคุณสามารถลบi=0ในคำจำกัดความของฟังก์ชั่น แต่คุณจะต้องโทรด้วย 0 เริ่มต้น
Quelklef

ฉันจะสมมติว่าช่องว่างทั้งสี่นั้นไม่ใช่เพราะคุณกำลังใช้ช่องว่างสี่ช่อง แต่เนื่องจาก SE ขยายพื้นที่เหล่านั้นโดยอัตโนมัติ หากไม่ใช่กรณีนี้คุณสามารถเปลี่ยนช่องว่างทั้งหมดเป็นแท็บหรือเว้นวรรคเดียวสำหรับ -9 ไบต์
คดีฟ้องร้องกองทุนโมนิก้า

@Quelklef เมตาห้ามการรับพารามิเตอร์เพิ่มเติม
mbomb007



1

PHP, 90 ไบต์

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

หรือ 92 ไบต์

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

1
1) รุ่นแรก: +$iแทน$i+=0(-2) 2) forลูปแทนwhileสามารถบันทึกสองไบต์และอนุญาตให้ลบ curlys (-4) 3) $i=++$i*!$cแทน$i=$c?0:$i+1(-1) 4) \\2ไม่จำเป็นต้องลบวงเล็บ (-2) 5) คุณสามารถอนุญาตให้ จำกัด9แทน1ความเร็ว (+0)
Titus

@Titus ความคิดที่ดีมาก ฉันไม่เห็นสิ่งนี้ขอบคุณ
JörgHülsermann

ตอนนี้ฉันคิดอีกครั้ง ... +$iไม่ทำงานในทุกกรณี ลองhammerดู PHP ไม่ได้บ่นเกี่ยวกับเครื่องหมายวงเล็บเปล่าใน regex; แต่มันไม่ตรงกับที่ต้องการ โดยวิธีการ: ฉันนับ 91 ไม่ใช่ 90 แต่ลองใหม่ 1)for($s=$argv[$c=1];$s[$i=++$i*!$c];)
ติตัส

@Tiess ใช่แล้วฉันจะกลับไป$i+=0และจะลองข้อเสนอของคุณในภายหลัง ค้อนหมายถึงอะไร
JörgHülsermann

@Titus โอเคปัญหาเดียวกันถ้ามีpuzzleอย่างอื่น(.)//1แต่มันก็โอเคกับข้อเสนอของคุณหรือ$i´=0
JörgHülsermann

1

Ruby, 75 64 57 ไบต์

(56 ไบต์ของรหัส + pตัวเลือกบรรทัดคำสั่ง)

การใช้การแก้ไขสตริงภายใน regex เพื่อควบคุมความยาวของการแข่งขันที่ถูกแทนที่

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

ทดสอบ:

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

1

Haskell , 97 88 ไบต์

(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

ลองออนไลน์!


รุ่นเก่า 97 ไบต์:

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

ลองบน ideone

คำอธิบาย:

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

(!)ฟังก์ชั่นการดำเนินการอย่างใดอย่างหนึ่ง n การควบแน่นเมื่อได้รับสตริงครั้งเดียวทั้งหมดและครั้งเดียวกับตัวอักษร n แรกเอาออกเช่นabcdbeและcdbeสำหรับ 2 ควบแน่นโดยซ้ำเปรียบเทียบทั้งสองตัวละครนำ

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