String.prototype.isRepeated


41

更新isaacgのPyth提出が勝者です!


あなたの多くはString.prototype.repeat、あなたができる方法を持っているJavaScriptのよりクールなバージョンが町にあることを聞いたに違いありません(ES6を読んでください)

"Hello, World!".repeat(3)

そして得る

"Hello, World!Hello, World!Hello, World!"

出力として。

あなたの仕事は、文字列がそのような変換の下でなくなったかどうかを検出する選択した言語で関数またはプログラムを書くことです。

すなわち、入力文字列nは、より小さい文字列の正確な時間の繰り返しとして表すことができます。(関数のreturnステートメントまたはSTDOUTとしての)出力は、文字列が小さい文字列の繰り返しとして表現できない場合、文字列ができる場合は虚偽である必要があります。

サンプル入力:

"asdfasdfasdf"  // true
"asdfasdfa"     // false
"ĴĴĴĴĴĴĴĴĴ"     // true
"ĴĴĴ123ĴĴĴ123"  // true
"abcdefgh"      // false

最後の入力がfalseであることに注意してください。したがってn1

完全なルール

  • 文字列を入力するための任意の言語で関数/プログラムを書く(関数の引数/コマンドライン引数/ STDINを介して)文字列
  • 与えられた文字列が、より小さな文字列の正確な繰り返しによって形成され、少なくとも2回繰り返される場合、真理値を返します。
  • 入力文字列の最大サイズは、理想的には無限大です
  • 文字列には、可能なすべてのASCII文字を含めることができます
  • これはため、文字の最小コードが勝ちます。

何を「」-空の文字列-返す必要がありますか?(空の文字列のコピーが無限に含まれています。)
billpg

@billpg falsy値
オプティマイザー14

あなたは票でタイブレークしていますか?一般的な慣行は、私が考える以前の提出です(まあ、タイイングスコアまでゴルフをした最初の提出)。しかし、それがどこでもデフォルトのタイブレーカーとして書き留められているかどうかはわかりませんので、最終的にはあなた次第です。
マーティンエンダー14

投稿の間隔はわずか30分です。私はそれが勝つために十分であるとは思わないでしょう:)。その時間は今は変わらないので、投票はできるので、投票で行きました
オプティマイザー14

この質問はxnorに名前を変更する必要があります:)彼は男です!
シルヴィブルセア14

回答:


16

パイス、9

/:+zz1_1z

または

}z:+zz1_1

これらはどちらも@xnorのpythonの回答の厳密な翻訳です。ただし、STDINから入力を取得して出力する点が異なります。最初のものは次と同等です:

z = input()
print((z+z)[1:-1].count(z))

Falseの場合は0、Trueの場合は1。

2行目は次と同等です。

z = input()
print(z in (z+z)[1:-1])

Falseの場合はFalse、Trueの場合はTrue。

Pythの公式コンパイラーには2番目のコンパイラーに関連するバグがあり、これにパッチを適用したばかりであるため、最初の公式の提出物です。


そのバグについて通知する方法を探していました(ブール値は出力されません)。最初のことを考えていなかったし、使用xが長すぎた...
デニス14

はい、バグは修正されました。また、バグを報告する場合は、githubサイトで問題を開くことをお勧めします。github.com
isaacg1

ああ、そこにある。私はGitHubの周りに自分の道を知らず、右側のナビゲーションパネルに気付かなかった...
デニス14

81

パイソン(24)

lambda s:s in(s+s)[1:-1]

文字列がそれ自体の部分文字列が2回連結されているかどうかをチェックし、最初と最後の文字を削除して、些細な一致を回避します。そうである場合、それはそれ自体の非自明な巡回置換でなければならず、したがって繰り返されるセグメントの合計でなければなりません。


8
Golfscriptへの些細な翻訳が10個の文字を生成:..+);(;\?)
ジャスティン

3
これがどのように機能するのかはよくわかりません。これが文字列をどのように処理するかを手動で説明した例を教えてください。
Nzall

8
@NateKerkhofsが取るabcabcs+sに変換しabcabcabcabcます。[1:-1]両端のチョップを得ましたbcabcabcabcab。そして、そのサブストリングとしてs in ...見つけようとしますabcabc。この部分文字列は、元の半分のどちらにも見つからないため、両方とも短縮されているため、両方の半分にまたがる必要があります。特に、開始前に独自の終了が必要です。これは、同一の(繰り返した)部分文字列で構成する必要があることを意味します。
マーティンエンダー14

6
あなたはそれを2倍にした後にそれを切り刻みます。abとなりababになりba、それはfalseを返しますのでながら、aaとなりaaaaになっaatrueを返します。
histocrat

1
@SargeBorschそれはまったく同じように動作します:qweqweqwein weqweqweqweqweqwis Trueです。
XNOR

30

正規表現(ECMAScriptフレーバー)、11バイト

正規表現の仕事のようですね!

^([^]+)\1+$

ここでテストしてください。

ECMAScriptを選んだのは、それが[^]あらゆる文字に一致する唯一のフレーバー(私が知っている)だからです。他のすべてで、私はどちらかの動作を変更するフラグを必要があるだろう.か、使用[\s\S]3文字より長くです。

フラグのカウント方法によって、もちろん1バイト短くなる場合があります。例えば、パターン+フラグをカウントしている場合(例えば、区切り文字を無視する場合)、PCRE / Perlの同等物は

/^(.+)\1+$/s

これは区切り文字を無視して10バイトです。

ここでテストしてください。

これは、サブストリングの少なくとも2回の繰り返しで構成されるストリングのみに一致します。

完全な26バイトのES6関数を次に示しますが、正規表現の送信は一般に有効であることを維持しています。

f=s->/^([^]+)\1+$/.test(s)

^(.+)\1+$私のために動作します。これは9バイトです。それはあなたのために機能しませんか?
オプティマイザー14

@Optimizer改行を含む文字列を試してください。
マーティンエンダー14

試しましたasd\nasd\nasd\n。動作する
オプティマイザー14

@Optimizer refiddle.com/refiddles/5417fb2475622d4df7e70a00私には動作しないようです(動作しないはずです)
Martin Ender 14

うん、それは機能しません。多分それは\ 私が\n手動で書くときを逃れる
オプティマイザー14

12

CJam、9

q__+)@+#)

xnorのアイデアに似ています。

q      " Read input. ";
__+    " Duplicate twice and concatenate them together. ";
)      " Remove the last character of the longer string. ";
@+     " Insert that character at the beginning of the shorter string. ";
#)     " Find the shorter string in the longer string, and increase by one. ";


なぜ決勝戦が必要なの)ですか?私は、その持っていることが合理的で-1平均FALSEと> = 0平均TRUE考える
デジタルトラウマ

@DigitalTrauma CJamでは0は偽物だと思います... gやなどの演算子にとっては?
jimmy23013 14

@DigitalTrauma:必要かどうかは最終的にはOPに依存しますが、CJamでは厳密に言えばゼロのみが偽物と見なされます。
デニス14

@ user23013 @Dennisしかし、#検索演算子はどうですか?確かにその結果は、成功対失敗の観点からも「真実」なのでしょうか?
デジタル外傷14

7

APL、11

2<+/x⍷,⍨x←⍞

説明
は、画面からの文字列入力を受け取り、
x←変数に割り当てて、結果の文字列で検索x
,⍨する文字列自体
x⍷を連結しxます。一致の開始位置にある1と他の場所にある0で構成される配列を返します。
+/合計
2<が2より大きい場合、配列チェックを合計します(2つの些細な一致があるため)


7

CJam、10バイト

CJamのバグを見つけました。私の最初の答えは、おそらくもう少しゴルフできるでしょう。

q__+(;);\#

FALSEの場合は-1、TRUEの場合は> = 0を出力します


5
クラブへようこそ!
デニス14

5

GolfScript、10バイト

..+(;);\?)

xnorの賢いアイデアのさらに別の実装。


ハハハ、私はこれを1分前に投稿しました:codegolf.stackexchange.com/questions/37851/…。回答として投稿することを考えましたが、些細な翻訳は面白くないと思いました。
ジャスティン14

今回は新しい回答もチェックしましたが、新しいコメントはチェックしませんでした...あなたのコードには欠けて)います。一致しない場合、印刷されます-1。それを回答として投稿する場合は、喜んで削除します。
デニス14

)回答を投稿する直前にコメントを追加しました(コメントを編集しました)
ジャスティン14

1
(CJam中)改良版:q__+)@+#)。GolfScriptでは機能しません。
jimmy23013 14

1
@ user23013:もうありません。私はちょうどそれを投稿するつもりでした!あまりにも多くのCJammersが...そこに今ではありますP
デニス


3

純粋なbash、30バイト

@xnorの賢い答えの単純な移植

[[ ${1:1}${1:0: -1} =~ "$1" ]]

終了コードは、TRUEの場合は0、FALSEの場合は1です。

$ for s in 'Hello, World!Hello, World!Hello, World!' 'asdfasdfasdf' 'asdfasdfa' 'ĴĴĴĴĴĴĴĴĴ' 'ĴĴĴ123ĴĴĴ123' 'abcdefgh'; do echo "./isrepeated.sh "\"$s\"" returns $(./isrepeated.sh "$s"; echo $?)"; done
./isrepeated.sh "Hello, World!Hello, World!Hello, World!" returns 0
./isrepeated.sh "asdfasdfasdf" returns 0
./isrepeated.sh "asdfasdfa" returns 1
./isrepeated.sh "ĴĴĴĴĴĴĴĴĴ" returns 0
./isrepeated.sh "ĴĴĴ123ĴĴĴ123" returns 0
./isrepeated.sh "abcdefgh" returns 1
$ 

=~内に[[ ... ]]あるbashのでは正規表現演算子。ただし、「パターンの任意の部分を引用して、文字列として一致させることができます」。aiはbashの場合によくあることですが、引用符を正しく付けることは非常に重要です。ここでは、正規表現の一致ではなく、文字列のサブマッチをチェックするだけです。


3

TI-BASIC-32

トークン化された言語を試してみると思いました。Ansの文字列で実行し、falseの場合は0を返し、trueの場合は繰り返し文字列の長さを返します。

inString(sub(Ans+Ans,1,2length(Ans)-1),sub(Ans,length(Ans),1)+Ans

驚くべきことに、ワンライナーです。


しかし...しかし...私はTI-BASICを使用するつもりだった:P +1
Timtech 14

@Timtechさて、TI-BASICで文字列操作を試みている人に注意してください。TI-BASICで文字列操作を試みないでください。:P作成と最適化がとても大変でした。
ジョサイアWinslow 14

良いアイデア。文字列操作は、最も難しいことの1つです。しかし、私はこのようないくつかの答えを投稿したので、私は今あなたが競争相手を持っていると思います;)
Timtech 14

かかって来い!:P
ジョサイアウィンズロー14

3

ECMAScript 6(189)

(function(){var S=String.prototype,r=S.repeat;S.isRepeated=function(){return!1};S.repeat=function(c){var s=new String(r.call(this,c));if(c>1)s.isRepeated=function(){return!0};return s}}());

 

< console.log("abc".isRepeated(),"abc".repeat(10).isRepeated());
> false true

確かにこれが唯一の有効なソリューションですか?たとえば、単語(文字列)nanaは必ずしもから作成されるわけではありません"na".repeat(2)


"nana"そうではありませんが、問題は.repeat使用されたかどうかをテストすることではありません。むしろ、文字列が繰り返されるかどうか
オプティマイザー14

私は知っている、私はちょうど賢い
馬鹿に

2

ECMAScript 6(34 36

もう1つのES6の答えですが、xnorのトリックを使用しrepeatたり使用したりすることはありません

f=i=>(i+i).slice(1,-1).contains(i)

FirefoxなどのES6対応ブラウザーのコンソールで実行する必要があります。


2

C 85

l,d;f(s){return l=strlen(s),strstr(d,strcpy(strcpy(d=alloca(l*2+1),s)+l,s)-1)-d-l+1;}

非常に長いことが判明しましたが、外部関数は常にそのようです。私は、すべての文字列関数をループまたは再帰関数に置き換えることができると思いました。しかし、私の経験では、それは長くなり、率直に言って、私はそれを試してみたいとは思わないでしょう。

いくつかの研究の後、高性能のソリューションを見ましたが、xnorのソリューションほど賢くはありませんでした。オリジナルであるために...私はcで同じ考えを書き直しました。

説明:

int length, 
    duplicate;
int is_repetition(char *input)
{
    // length = "abc" -> 3
    length = strlen(input);
    // alloca because the function name is as long as "malloc" 
    // but you don't have to call free() because it uses the stack
    // to allocate memory
    // duplicate = x x x x x x + x
    duplicate = alloca(length*2 + 1);
    // duplicate = a b c 0 x x + x
    strcpy(duplicate, input);
    // duplicate = a b c a b c + 0
    strcpy(duplicate + length, input);
    if (strstr(duplicate,duplicate + length - 1) != duplicate + length - 1)
        // repetition
        // e.g. abab -> abababab -> aba[babab]
        // -> first occurence of [babab] is not aba[babab]
        // but a[babab]ab -> this is a repetition
        return 1;
    else
        // not repetition
        // e.g. abc -> abcabc -> ab[cabc]
        // -> first occurence of [cabc] is ab[cabc]
        // it matches the last "cabc"
        return 0;
}

1

ECMAScript 6(59 62 67 73

勝者ではありませんが、repeat関数を実際に使用するこの質問に対して、ES6には実際に少なくとも1つの答えがあるはずです。

f=i=>[...i].some((_,j)=>i.slice(0,j).repeat(i.length/j)==i)

FirefoxなどのES6対応ブラウザーのコンソールで実行する必要があります。

多くの不必要な反復を行いますが、なぜそれを避けるためだけに長くするのですか?

  • 編集#1:数バイトを関数に変換して保存しました。オプティマイザーに感謝します!
  • 編集#2:より多くのバイトを節約するためのスプレッド演算子のトリックのhslに感謝します!
  • 編集#3:さらに3バイトのRob W.に感謝します!

そこにさらにバイトを保存する関数に変換することができます
オプティマイザー14

@Optimizer確かに、「stdin」である必要はないと思います。あなたの名前まであなたのライブ:)
インゴビュルク14

私はこれをテストしていませんが、あなたは使用することができるはずスプレッドオペレータをするために[...i]代わりにi.split('')
NinjaBearMonkey

1
@hslクレイジー、それは動作します。スプレッド演算子がそのように機能することを知りませんでした。もともと私は必死にそれを使用して範囲を持つ配列を作成しようとしました0..N。ありがとう!
インゴ・バーク

1
.slice(0,j)は、より短い1文字です.substr(0,j)。さらに、整数への変換は不要と思わ|0れます(|02 ^ 31を超える繰り返しでは失敗するため、実際に使用するとメソッドの有用性が低下します)。
ロブW 14


0

Java 8、28バイト

s->s.matches("(?s)(.+)\\1+")

オンラインでお試しください。

説明:

入力文字列が正規表現に一致するかどうかを確認します。ここで、文字列全体に一致するようにString#matches暗黙的に追加さ^...$れます。
正規表現自体の説明:

^(s?)(.+)\1+$
^                Begin of the string
 (s?)            Enable DOTALL-mode, where `.` also matches new-lines
     (           Open capture group 1
      .+          One or more characters
        )        Close capture group 1
         \1+     Plus the match of the capture group 1, one or more times
            $    End of the string

したがって、サブストリングが2回以上繰り返されているかどうかを基本的にチェックします(改行をサポート)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.