Garlandification


38

Слова гирлянды

Гирлянда слово это слово , которое может быть нанизанные , как гирлянду, потому что она заканчивается теми же буквами , что начинается с. Эти группы букв могут даже перекрываться!

Например, undergroundэто гирлянда слово порядка 3, потому что она начинается и заканчивается тем же 3 -х символов, und. Это означает, что это может быть связано как undergroundergrounderground....

alfalfaэто тоже слово гирлянды! Это порядка 4. Он начинается и заканчивается alfa. Это может быть нанизанные так: alfalfalfalfa.

Процесс, который я называю гирляндой, заключается в том, что, когда вы определяете порядок nслова гирлянды, вы берете оригинальное слово и добавляете сегмент, необходимый для того, чтобы оно повторялось как время гирлянды n. Итак, поскольку onionэто 2слово порядка гирлянд, вы должны взять onion, отрубить первые 2буквы, чтобы получить ionи добавить их к конечному 2времени, чтобы получить onionionion.

Задача

Создайте программу или функцию, которая принимает входные данные из стандартного ввода или аргумента функции и печатает или возвращает слово с гирляндой.

Все слова будут в нижнем регистре, и самый высокий возможный порядок для слова length(word) - 1.

Пример ввода / вывода

"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флагом.

Четыре пары замещения делают следующее:

  • Дублирующее слово, чтобы мы могли искать совпадения тоже.
  • Добавьте слово, разделенное на 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;
    }
}

Предложения приветствуются.


Как примечание для себя, строковые операции можно переместить в цикл for, чтобы сохранить один или два байта на
точках

почему бы не сделать i=0;?
переигрыватель

@ Верактор где? Причина, по которой я использую длину, заключается в том, что мне нужна полная строка, а затем я хочу перейти ни к чему из этого, с подстрокой, я не думаю, что смогу избежать ее использования в этом методе и возьму за нее штраф в байтах
DeadChex

2
Я хотел вырваться из внешнего цикла.
переигрыватель

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

Автоматическое upvote sed ответ ;-). Следуйте этому совету, чтобы отбросить 2 символа из определения и ветви вашего ярлыка
Digital Trauma

Пробовал, но я боюсь, что совет только для тех случаев, когда у вас нет переходов без меток к концу кода. [Чуть позже ...] Хорошо, подумав еще раз, почему я пытался обрабатывать несколько строк ввода одновременно?
Манатворк

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

Матлаб: 97 89 82 байта

Функция, которая использует регулярное выражение с lookbehind и группой захвата:

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/

Начальная буква «а» - это просто метка для регулярного выражения. После этого мы находим первый #, за которым следует один символ ( .), и фиксируем все после этого до следующего # ( .*#). Мы заменяем это всем справа от совпадения, то есть последним токеном ($ '), за которым следует # ( $1), за которым следует второй токен без символа (мы рассматриваем это как счетчик, уменьшая его при каждой итерации). В случае лука # # на ион, две лексемы мы на обратной ссылки приведены в скобках, и секция весь регулярное выражение соответствует между трубами: onion|(#)o(n#)|ion. Затем мы заменяем биты, с которыми мы сопоставляем (между каналами) $'(все справа от совпадения, то есть 'ion'), затем $ 1 (#), затем $ 2 (n #), что означает, что мы заканчиваем onion|(ion)(#)(n#)|ion(скобки показывают три жетона в строке замены).

Если регулярное выражение не соответствует первому чередованию (все до конвейера), мы должны уменьшить наш счетчик до нуля, то есть во втором токене нет символов. Вместо этого мы смотрим на вторую часть шаблона #.*. Это просто заменяет все после первого # с $'$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

RS , 51 48 байт

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

ПРИНЯТЬ ЭТО, РЕТИНА И САМ !!!!! ;)

Отрезать 3 байта благодаря @randomra.

Живая демоверсия и тестовые случаи.

Обратите внимание, что jackhammerтестовый пример не существует. В веб-интерфейсе есть ошибка обработки пробелов, из-за которой выводится неверный вывод. Оффлайн версия 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

С

#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
Понял. Спасибо за направление. Я буду помнить это в следующий раз.
Алам

Еще не поздно «сыграть в гольф». Если вы нажмете кнопку «Изменить» под вашим ответом, вы все равно сможете удалить ненужные пробелы и добавить счетчик байтов.
DJMcMayhem

Не intподразумевается ли в (достаточно старых версиях) C?
Восстановить Монику

0

Groovy 75 57 55 байтов

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

Удивительно, как возвращение к чему-то на следующий день может помочь

Ungolfed:

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» . Я думаю, что вы можете многое сделать для игры в гольф, но нам нравится видеть версию с комментариями, если ваш алгоритм умный. Повеселись!
Тоби Спейт
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.