花环化


38

花环的话

一个花环字是可以像一个花环被串成一个词,因为它与它开头相同的字母结束。这些字母甚至可以重叠!

例如,underground是花环顺序词3,因为它以相同的3个字符开头和结尾und。这意味着它可以像一样串在一起undergroundergrounderground...

alfalfa也是花环字!它的阶数为4。它的开始和结束是alfa。它可以串在一起,像这样:alfalfalfalfa

我称其为“ n花环化”的过程是,一旦确定花环词的顺序,就采用原始词并添加使它循环成花环n时间所需的句段。因此,由于onion是顺序2花环词,您需要onion将第一个2字母切掉,ion然后将其添加到结束2时间中onionionion

目的

制作一个程序或函数,该程序或函数标准输入或函数自变量中获取输入,并打印出或返回经过加字处理的单词。

所有单词均为小写,单词的最高顺序为length(word) - 1

示例I / O

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

这是,因此最少的字节数获胜。


2
任何N个字母的单词都以与其结尾相同的N个字母开头。应该考虑的最大订购量是多少?
feersum

@feersum最大顺序是单词的长度-1.将其添加到主要帖子中。
卡德,2015年

我是否只需要打印花环?还是我可以打印它和一个例外?
DeadChex

@DeadChex应该没有例外。
卡德2015年

1
@LuisMendo它应该适用于任意长的单词。
卡德,2015年

Answers:


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标志的一个文件来运行。

四个替换对执行以下操作:

  • 单词重复,因此我们也可以搜索重叠。
  • 将单词分割后追加到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;
    }
}

欢迎提出建议。


作为我自己的笔记,可以将String ops移入for循环以在分号上保存一两个字节
DeadChex 2015年

为什么不i=0;呢?
演员

@overactor在哪里?我使用长度的原因是因为我想要完整的String,然后我不希望使用完整的String,对于子字符串,我认为我无法避免在此方法中使用它,因此会占用字节数
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个字符
Digital Trauma

尝试过,但恐怕建议仅适用于没有无标签跳转到代码末尾的情况。[过一会儿…]好吧,再想一想,为什么我试图一次处理多条输入线?
manatwork

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 #)

详细说明 以下是正则表达式的逐行细分:

//$'#/

这是一个正则表达式替换,它匹配第一个空字符串(即字符串的开头),并将其替换为match($')右侧的所有内容,后跟一个哈希。例如,它将onion变为onion#onion

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

此行通过查找紧接#((.+))之前与#()另一侧相同的一组字符来找到重叠的部分\1。\ K只是表示“忘记我匹配了任何东西”,这意味着它实际上不会在替换中被替换。有效地,这意味着我们只要在找到重叠部分后在位置添加#,就onion#onion变成onion#on#ion

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

首字母“ a”只是正则表达式的标签。此后,我们找到第一个#后跟一个字符(.),并捕获此后的所有内容,直到下一个#(.*#)。我们将其替换为匹配项右边的所有内容,即最后一个标记($'),后跟#($1),然后第二个标记减去一个字符(我们将其视为计数器,每次迭代将其减少)。对于onion#on#ion,我们在其上反向引用的两个标记显示在方括号中,整个正则表达式匹配的部分位于管道之间:onion|(#)o(n#)|ion。然后,我们将匹配的位(在管道之间)替换为$'(匹配右边的所有内容,即“ ion”),然后是$ 1(#),然后是$ 2(n#),这意味着我们最终得到了onion|(ion)(#)(n#)|ion(括号显示替换字符串中的三个标记)。

如果正则表达式在第一个交替中(管道之前的所有内容)都无法匹配,则必须将计数器的计数减为零,这意味着第二个标记内没有字符。相反,我们看一下模式的第二部分#.*。这只是用#替换第一个#之后的所有内容$'$1$2。由于此替换没有创建反向引用,并且在匹配项的右边也没有任何内容(.*匹配项直到字符串的结尾),因此我们终止匹配项并返回结果。

//a

这只是前一行的指针,确保我们继续执行正则表达式替换,直到不再匹配为止。


3

jQuery 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_))
 .*/

那样做,视网膜和SED !!!!;)

由于@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
欢迎来到编程难题和Code Golf!这个问题是代码问题,所以我建议您通过删除不必要的空格等来“寻找”代码,然后在代码标题中连同语言一起添加代码的字节数。
lirtosiast

1
得到它了。谢谢你的指导。下次我会记住这一点。
Alam

“打高尔夫球”还为时不晚。如果单击答案下方的“编辑”按钮,仍然可以删除不必要的空格并添加字节数。
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堆栈交换!您无需担心代码高尔夫球的效率,而只需要担心程序的长度。因此,缓慢,低效的版本可能是最好的版本(它可以对“实际工作”做出令人耳目一新的更改!)。因此,删除不必要的空格,并使用单字母变量名称-然后阅读JavaScript中打高尔夫球的技巧。我认为您可以做很多事情,但是,如果您的算法很聪明,我们确实希望看到未打高尔夫的评论版。玩得开心!
Toby Speight 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.