Praming Puzles&Colf:Condense a String


25

このサイトで少し時間を過ごして、できるだけ短いものを楽しむようになりました。これが、同じ文字を複数回含む文字列に最近気分を害した理由かもしれません。あなたの仕事は、次のルールに従って特定の文字列を圧縮する関数またはプログラムを書くことです。

  • 0-condensationで開始しますつまり、同じ文字の最初(左端)のペアを探し、その間に他の文字はありません。そのようなペアが見つかった場合、2つの文字のいずれかを削除し、別の0-condensationを実行してアルゴリズムを再起動します。そのようなペアが見つからない場合は、次の手順に進みます。例:
    programming-C0-> programing
    aabbcc-C0-> abbcc
    test-C0->test

  • 次に1凝縮を実行します。つまり、同じ文字の最初のペアを探し、その間に他の1つの文字があります。そのようなペアが見つかった場合、それらの1つとそれらの間のすべての文字を削除し、0-condensationで再開します。そのようなペアが見つからない場合は、次の手順に進みます。例:
    abacac-C1-> acac
    java-C1->ja

  • 凝縮がいくつかの文字を削除した後に再起動するたびに、nが元の文字列の長さである2凝縮などをn 凝縮まで続けます。例:-C2-> -C3->
    programingpraming
    abcdafgafg

結果の文字列は凝縮と呼ば、各文字が最大1回含まれます。


入力:

印刷可能な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に感謝します!


@MartinEnder Rileyのテストケースは、Retinaソリューションが機能しない唯一のテストケースであるため、まだ必要です。
mbomb007

@ mbomb007ああ、なるほど。いい視点ね。
マーティンエンダー

入力文字列にスペースなどの印刷できない文字が含まれることはありますか?
mbomb007

@ mbomb007いいえ、印刷可能なアスキー文字のみを想定するのは問題ありません。
ライコニ

@ mbomb007しかし、私が知る限り、スペース印刷可能なアスキー文字と見なされます
ライコニ

回答:


6

JavaScript(ES6)、74バイト

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>


非常に素晴らしく、思っていたよりも短い。
ETHproductions

5

Perl、38 31 30 29バイト

これにより、ゴルフ以外の言語がはるかに遅れるはずです...

ライリーの$-[0]おかげで-1

ダダの@{-}おかげで-1

+1を含む -p

STDINに入力する

condense.pl

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

この27バイトバージョンは動作するはずですが、perlが@-正規表現で補間しないため動作しません(/programming/39521060/why-are-etc-not-interpolated-in-stringsを参照)

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

@{\@-}部品はどのように機能しますか?@-各マッチのインデックスを保持していると思ったので、繰り返しごとにどのように「カウントアップ」しますか。また、@{\@-}各置換の前後に印刷する場合、1または2のみが印刷さ
ライリー

1
@Riley /./g文字列内の1によって進行するたびに、時に文字列の変更を除き、それのリセット0にあなたが印刷すると@-/./gが、前にs///(残りの文字列が十分な大きさであるテストを使用)、あなたはそれが上がって表示されます
トンホスペル16

印刷$-[0]すると、私が期待する数字が得られます。正規表現コンテキストの@{\@-}ように動作し$-[0]ますが、何らかの理由で印刷するときは動作しませんか?同じ場合$-[0]よりも1バイト短くなり@{\@-}ます。
ライリー

"@{\@-}"とは異なります@{\@-}(なし")。
ライリー

@Rileyいいえ、ただし"@{\@-}"と同じ"@-"です。また、これは正規表現の置換にも当てはまりますが、そうではありません。同様に動作する$-[0]はずですが、動作しません。PS:おそらく@-、印刷を行ったときにスカラーコンテキストが何らかの形で適用されていたので、常に1または2になった
Ton Hospel


2

Python 2、117 104 101バイト

必要な置換を再帰的に実行します。正規表現を動的に構築します。

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)

オンラインで試す


2つの戻り行は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))
削る

さらに、関数定義のをe=s==t;return i>len(t)and t or f(t,i*e+e)削除することもできi=0ますが、0 startで呼び出す必要があります。
Quelklef

4つのスペースを使用しているためではなく、SEが自動的に拡張するため、4つのスペースがあると想定します。そうでない場合は、すべてのスペースをタブまたは-9バイトの単一スペースに変更できます。
ファンドモニカの訴訟

@Quelklefメタは追加のパラメーターの取得を禁止します。
mbomb007


1

Mathematica、101バイト

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

これを短くする方法があるはずです...


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)最初のバージョン:(-2)の+$i代わり$i+=0。2)forループではなくwhile2バイトを節約し、curlyを削除できます(-4)。3)(-1 )の$i=++$i*!$c代わり$i=$c?0:$i+1。4)\\2不要です。括弧を削除します(-2)。5)速度の9代わりに制限を許可することができます1(+0)
タイタス

@タイタス非常に良いアイデア。ありがとうございました
ヨルクヒュルサーマン

もう一度考えて+$iみると… すべてのケースで機能するとは限りません。試してくださいhammer。PHPは、正規表現の空の中括弧については文句を言いません。しかし、望みどおりには一致しません。ちなみに、私は90ではなく91を数えます。しかし、新しい1)を試してくださいfor($s=$argv[$c=1];$s[$i=++$i*!$c];)
タイタス

@Titusはい、私は戻って$i+=0あなたの提案を後で試します。ハンマーとはどういう意味ですか?
ヨルグヒュルサーマン

@タイタスは、同じ問題があれば、puzzleまたは何か他のもの(.)//1がいいのですが、あなたの提案や問題ではいいです$i´=0
ヨルグ・ヒュルサーマン

1

ルビー、75 64 57バイト

(56バイトのコード+ pコマンドラインオプション。)

正規表現内で文字列補間を使用して、置換される一致の長さを制御します。

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

テスト:

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

1

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

イデオンで試してみてください

説明:

(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つの主要文字を比較することにより、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.