ガーランド化


38

ガーランドの言葉

花輪の言葉は、それはそれで始まる同じ文字で終わっているため、花輪のようにつなぎ合わせすることができます言葉です。これらの文字のグループは重複することもあります!

たとえば、underground3、同じ3文字で開始および終了するため、順序のガーランド語ですund。これは、のように一緒に張ることができることを意味しundergroundergrounderground...ます。

alfalfaガーランドの言葉も!順序は4です。開始と終了はalfaです。次のように連結できますalfalfalfalfa

私がガーランド化と呼ぶプロセスnは、ガーランドの単語の順序を決定したら、元の単語を取得し、それをガーランドn回としてループさせるために必要なセグメントを追加することです。だから、onion順序2ガーランドの単語なので、取得onionする最初の2文字を切り取りion、取得する終了2時間に追加しますonionionion

目的

作成したプログラムや機能からの入力を受け取り、標準入力または関数の引数とプリントアウトしたりgarlandified言葉を返しました。

すべての単語は小文字であり、単語の最高位はlength(word) - 1です。

I / Oの例

"onion"       --> "onionionion"
"jackhammer"  --> "jackhammer"
"abracadabra" --> "abracadabracadabracadabracadabracadabra"
""            --> ""
"zvioz"       --> "zviozvioz"
"alfalfa"     --> "alfalfalfalfalfalfa"
"aaaa"        --> "aaaaaaa"

これはなので、最小バイト数が勝ちます。


2
N文字の単語は、それが終わるN文字と同じ文字で始まります。考慮すべき最大順序は何ですか?
feersum

@feersum最大の順序は単語の長さ-1です。それをメインの投稿に追加しました。
ケード

ガーランドだけを印刷する必要がありますか?または、おそらくそれと例外を印刷できますか?
DeadChex

@DeadChex例外はありません。
ケード

1
@LuisMendo任意の長い単語に対して機能するはずです。
カデ

回答:


12

Pyth、19 18バイト

+z*>Kf!xz>zT1zl>zK

オンラインで試す:デモンストレーションまたはテストハーネス

説明:

+z*>Kf!xz>zT1zl>zK   implicit: z = input string
     f      1        find the first number T >= 1, which satisfies:
         >zT            all but the first T chars of z
       xz               index of ^ in z
      !                 == 0
    K                store in K
                     the order is length(z) - K
   >K        z       the last K chars
  *                  repeated
              l>zK   len(all but the last K chars) times
+z                   insert z at the beginning

14

Python、60バイト

f=lambda s,i=1:s.find(s[i:])and f(s,i+1)or(len(s)-i)*s[:i]+s

より良いことを望んでいたが、まあ。s.findここではきちんと動作しnot s.startswithます。


12

網膜、58バイト

.+
$0#$0
(.*)(.+)#.*\1$
$0#$1#$2-
+`\w#(\w*)-
#$1-$1
#.*-
<empty line>

各行は独自のファイルに移動する必要がありますが、-sフラグを使用してコードを1つのファイルとして実行できます。

4つの置換ペアは次のことを行います。

  • 重複する単語も検索できるように、単語を複製します。
  • order文字数で分割された単語を追加します。
  • 最後のパートorderタイムを追加します。
  • 元の単語と最後に追加された部分を保持し、他のすべてを削除します。

例の文字列は次のonionとおりです。

onion
onion#onion
onion#onion#on#ion-
onion#onion##ion-ionion
onionionion

10

Haskell、64バイト

g s=[b>>a|(a,b)<-map(`splitAt`s)[1..],and$zipWith(==)s b]!!0++s

テスト:

λ: g "onion"       == "onionionion"
True
λ: g "jackhammer"  == "jackhammer"
True
λ: g "abracadabra" == "abracadabracadabracadabracadabracadabra"
True
λ: g ""            == ""
True
λ: g "zvioz"       == "zviozvioz"
True
λ: g "alfalfa"     == "alfalfalfalfalfalfa"
True
λ: g "aaaa"        == "aaaaaaa"
True

10

Java、160 157バイト

static void g(String s){int i=s.length(),o;for(String p=s;i-->0;)if(s.endsWith(s.substring(0,i))){for(o=i;o-->0;)p+=s.substring(i);System.out.print(p);i=0;}}

入出力:

 g("abracadabra"); --> "abracadabracadabracadabracadabracadabra"

読みやすくするためにスペースを空けてタブで区切っています。

static void g(String s){
int i=s.length(),o;
for(String p=s;i-->0;)
    if(s.endsWith(s.substring(0,i))){
        for(o=i;o-->0;)
            p+=s.substring(i);
        System.out.print(p);
        i=0;
    }
}

提案を歓迎します。


私自身の注意として、文字列
演算を

どうしてi=0;
オーバーアクター

@overactorどこ?私は完全な文字列をしたいし、私は私は私はこの方法でそれを使用して避けることができるとは思わないし、それのためにバイトのペナルティがかかりますサブストリングと、それのどれに向かって移動したいので、私は長さを使用する理由がある
DeadChex

2
外側のforループから抜け出すつもりでした。
オーバーアクター

8

Sed:87 84文字

(83文字のコード+ 1文字のコマンドラインオプション。)

h
s/(.*)./& \1/
T
s/(.+) \1.*/ \1 \1/
t
g
q
:
s/^([^ ]+)(.*)[^ ]$/\1 \1\2/
t
s/ //g

サンプル実行:

bash-4.3$ sed -r 'h;s/(.*)./& \1/;T;s/(.+) \1.*/ \1 \1/;t;g;q;:;s/^([^ ]+)(.*)[^ ]$/\1 \1\2/;t;s/ //g' <<< 'underground'
undergroundergroundergrounderground

sed回答の自動賛成票;-)。このヒントに従ってください、あなたのラベル定義と枝から2つの文字を削除するには
デジタルトラウマ

試してみましたが、アドバイスは、コードの最後までラベルなしでジャンプできない場合にのみ役立つと思います。[少し後で…] OK、もう一度考えてみて、なぜ複数の入力行を一度に処理しようとしたのですか?
マナトワーク

7

CJam、24 23バイト

q_:Q,{~)Q>Q\#!},W>~_Q>*

q_:Q                       e# Read the input, take a copy and store it in Q too
    ,{        },           e# Take the length of the input and filter [0 .. len - 1] array
      ~)                   e# Same as number * -1
        Q>                 e# Take last number characters. Call this string S
          Q\#!             e# See if Q starts with S. After the filter, we will only have
                           e# those numbers from [0 .. len - 1] array which are valid orders
                W>~        e# Take the last order number, if exists.
                   _Q>*    e# Garlandify the input order times.

何かから始めるために

こちらからオンラインでお試しください


5

Matlab:97 89 82バイト

後読みおよびキャプチャグループで正規表現を使用する関数:

function t=f(s)
n=sum(regexp(s,'(.*$)(?<=^\1.+)'))-1;t=[s(repmat(1:n,1,end-n)) s];

それは、sum空の文字列の入力(変換処理するために必要とされている[]中に0)。

例:

> f('onion'), f('jackhammer'), f('abracadabra'), f(''), f('zvioz'), f('alfalfa'), f('aaaa')
ans =
onionionion
ans =
jackhammer
ans =
abracadabracadabracadabracadabracadabra
ans =
   Empty string: 1-by-0
ans =
zviozvioz
ans =
alfalfalfalfalfalfa
ans =
aaaaaaa

4

REGXY、53 49バイト

正規表現置換ベースの言語であるREGXYを使用します

//$'#/
/.(.+)#\1\K/#/
a/(#).(.*#)|#.*/$'$1$2/
//a

概要: 多数の正規表現が適用されます。実行例は次のようになります。

onion (input)
onion#onion (line 1 regex)
onion#on#ion (line 2 regex - find the repeated section and separate with #)
onionion#n#ion (line 3 regex - the length of the middle token is the garland order, remove a character and append the third token onto the original string on the left)
onionionion##ion (line 4 regex is a pointer to line 3 - repeat the previous again)
onionionion##ion (line 4 regex is a pointer to line 3 - strip everything after and including the #)

詳細説明 以下は、正規表現の行ごとの内訳です。

//$'#/

これは、最初の空の文字列(つまり、文字列の先頭)に一致する正規表現の置換であり、一致の右側にあるすべてのもの($')とそれに続くハッシュに置き換えます。例えば、それが変わりますoniononion#onion

/.(.+)#\1\K/#/

この行は、#((.+))の反対側で同じ#()の直前にある文字のグループを検索することにより、重複するセクションを見つけ\1ます。\ Kは単に「私が何かに一致したことを忘れる」という意味で、実際には置換で置き換えられないことを意味します。これは事実上、重複が見つかった後に位置に#を追加するだけで、に変わることを意味onion#oniononion#on#ionます。

a/(#).(.*#)|#.*/$'$1$2/

最初の「a」は正規表現の単なるラベルです。この後、最初の#の後に1文字(.)が続き、次の#(.*#)までのすべてをキャプチャします。これをマッチの右側のすべてのもの、つまり最後のトークン($ ')に続けて#($1)が続き、2番目のトークンから文字を除いたものに置き換えます(これをカウンターとして扱い、繰り返しごとに減らします)。onion#on#ionの場合、後方参照する2つのトークンは括弧内に示され、正規表現全体が一致するセクションはパイプの間にありますonion|(#)o(n#)|ion。次に、一致するビット(パイプ間)を$'(一致の右側のすべて、つまり「ion」)、$ 1(#)、$ 2(n#)の順に置き換えonion|(ion)(#)(n#)|ionます。置換文字列の3つのトークン)。

正規表現が最初の交替(パイプの前のすべて)で一致しない場合、カウンターをゼロに減らさなければなりません。つまり、2番目のトークン内に文字がありません。代わりに、パターンの2番目の部分を見てください#.*。これは、最初の#以降のすべてを単にに置き換えます$'$1$2。この代替によって作成された後方参照はなく、一致の右側に何もない(.*文字列の最後まで一致する)ため、一致を終了して結果を返します。

//a

これは前の行への単なるポインタであり、それ以上一致しなくなるまで正規表現の置換を実行し続けます。


3

jq 1.5:91文字

(87文字のコード+ 4文字のコマンドラインオプション。)

.+. as$t|[range(1;length)|select($t[:.]==$t[-.:])]|(max//0)as$i|[range($i)|$t[$i:]]|add

サンプル実行:

bash-4.3$ jq -R -r -f judy.jq <<< 'underground'
undergroundergroundergrounderground

3

rs51 48バイト

(.+)/\1 \1
(.+)(.+) .+\1$/\1(\2)^^((^^\1_))
 .*/

それを、レティーナとセッド!!!!! ;)

@randomraのおかげで3バイトを切り捨てます。

ライブデモとテストケース。

jackhammerテストケースが存在しないことに注意してください。Webインターフェースのスペース処理にバグがあり、不正確な出力を印刷する原因になります。オフラインバージョンはrsそれを正しく処理します。

51バイトバージョン:

(.+)/\1 \1
^(.+)(.+) (.+)\1$/\1(\2)^^((^^\1_))
 .*/

オリジナルのライブデモとテストケース。


@randomraが更新されました。ありがとう!
kirbyfan64sos

2

JavaScript(ES6)、95バイト

f=s=>{for(e=i=s.length;i&&e;)s+=s.slice(--i).repeat(!(e=!s.endsWith(s.slice(0,i)))*i);return s}

デモ

現在のところFirefoxのみ:

f = s => {
  for (e = i = s.length; i && e;) s += s.slice(--i).repeat(!(e = !s.endsWith(s.slice(0, i))) * i);
  return s
}

console.log = x => X.innerHTML += x + '\n';

console.log(f('onion'));
console.log(f('jackhammer'));
console.log(f('abracadabra'));
console.log(f(''));
console.log(f('zvioz'));
console.log(f('alfalfa'));
console.log(f('aaaa'));
<pre id=X></pre>


2

JavaScript(ES6)、82バイト

g=(s,i=t=s.length)=>s.endsWith(c=s.slice(0,--i))?c+s.slice(i-t).repeat(i+1):g(s,i)

[ES6を学び、この課題に対する再帰的な解決策を見つけることに興味を持っていたため、元の回答を削除しました]

g=(s,i=t=s.length)=>s.endsWith(c=s.slice(0,--i))?c+s.slice(i-t).repeat(i+1):g(s,i)

console.log(g('onion'));
console.log(g('jackhammer'));
console.log(g('abracadabra'));
console.log(g(''));
console.log(g('zvioz'));
console.log(g('alfalfa'));
console.log(g('aaaa'));


1

CoffeeScript + ES6、77バイト

JavaScriptの答えと同じアプローチ。

f=(s,e=i=s.length)->s+=s[i..].repeat !(e=!s.endsWith s[...i])*i while--i&&e;s

0

C

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
    char *str   = NULL;
    char *p     = NULL;
    int len     = 0 ;
    int i       = 0;
    int j       = 0;
    int k       = 0;
    int loop    = 0;

    if (argc == 1 )
        return 0;

    str = argv[1];
    len = strlen(str);

    if (len %2) {
        loop = len/2 + 1;
    }
    else {
        loop = len/2;
    }


    p = &str[len/2];
    for (i = 0; i < loop ; i++) {
        if (str[k] == *(p++)) {
            k++;
        }
        else
            k = 0;
    }

    printf("k = %d\n", k);
    printf("%s", str);
    p = &str[k];
    for (j =0; j < k ; j++) {
        printf("%s", p);
    }
    return 0;
}

ゴルフ:195バイト-GCC

main(int c,char**a){
char *s=a[1],*p;int i=0,j=0,k=0,z,l=strlen(a[1]);
z=l%2?-~(l/2):l/2;p=&s[l/2];
for(;i<z;i++)k=s[k]==*(p++)?-~k:0;
printf("k=%d\n",k);puts(s);p= &s[k];
for(;j<k;j++)puts(p);}

5
プログラミングパズルとコードゴルフへようこそ!この質問はコードゴルフです。不要な空白などを削除してコードを「ゴルフ」し、投稿のタイトルに言語とともにコードのバイトカウントを含めることをお勧めします。
リルトシアスト

1
とった。指示ありがとうございます。次回も念頭に置いておきます。
アラム

それは「ゴルフ」するのに遅すぎません。回答の下にある[編集]ボタンをクリックしても、不要な空白を削除してバイトカウントを追加できます。
DJMcMayhem

int(十分に古いバージョンの)C では暗黙的ではありませんか?
モニカの

0

Groovy 75 57 55バイト

f={w->x=w;w.find{x-=it;!w.indexOf(x)};w+(w-x)*x.size()}

翌日に何かに戻ることが、どのように役立つか驚くべきこと

ゴルフをしていない:

f = {w ->

//Set x equal to w
    x=w

//Loop through the characters of w until we return true
    w.find {

//set x equal to x minus the first instance of the current character, i.e.     the word minus the first character
        x-=it

//Returns the index of the first occurance of the string of chars x, when this is 0 (false) we want to return true, so negate it
        !w.indexOf(x)
    }

//When we've escaped the loop, if we've found a match return the word plus the word minus the match multiplied by the lengh of the match.
    w+(w-x)*x.size()     
}

-1

誰かがそれをテストするためにJSのコードを必要とする場合。注:効率を高めるために、文字列を最後から最後まで走査しました。

"use strict";

var garlandify = function(inputString){
    var stringLength = inputString.length;  
    var savedString = inputString;

    for( var i=1; i<stringLength; i++ ){
         var endIndex = Math.abs(i) * -1;       
         if( inputString.startsWith( inputString.substr(endIndex) ) ){
              for( var j=1; j<=i; j++){
                  savedString += inputString.substr(i, stringLength );
              }
              console.log(savedString);         
         }  
    }
};

garlandify("onion");

4
プログラミングパズル&コードゴルフスタック交換へようこそ!code-golfの効率を心配する必要はありません。プログラムの長さだけです。そのため、ここでは低速で非効率的なバージョンが最適です(「実際の作業」からさわやかな変更を加えることができます!)。したがって、不要な空白を削除し、1文字の変数名を使用してから、JavaScriptでのゴルフのヒントを読んでください。これをゴルフするためにできることはたくさんあると思いますが、アルゴリズムが賢い場合は、コメントなしのコメントなしのバージョンをご覧ください。楽しむ!
トビースパイト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.