Гірлянда


38

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

Гірлянда слово це слово , яке може бути нанизані , як гірлянду, тому що вона закінчується тими ж буквами , що починається с. Ці групи листів можуть навіть перетинатися!

Наприклад, undergroundце гірлянда слово порядку 3, тому що вона починається і закінчується тим же 3 -х символів, und. Це означає, що її можна було б поєднати на зразок undergroundergrounderground....

alfalfa- це слово гірлянди теж! Це порядку 4. Починається і закінчується alfa. Це може бути нанизані так: alfalfalfalfa.

Процес, який я називаю garlandifying, - це коли ви визначаєте порядок 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

Піт, 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

Пітон, 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

чому б не зробити i=0;?
суперактор

@overactor де? Причина, що я використовую довжину, полягає в тому, що я хочу отримати повний рядок, а потім я хочу рухатись до жодної з нього, з підрядками, я не думаю, що я можу уникнути використання цього методу, і буду брати за це байт
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

Автоматичне оновлення відповіді sed ;-). Дотримуйтесь цієї підказки, щоб скинути два знаки з визначення мітки та гілки
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 байт

Функція, яка використовує регулярний вираз з перспективою і групою захоплення:

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

Детальне пояснення Далі йде розбивка реджексів за рядком:

//$'#/

Це підстановка з регулярними виразами, яка відповідає першому порожньому рядку (тобто початку рядка) і замінює його на все, що знаходиться праворуч від збігу ( $'), а за ним - хеш. Наприклад, він перетвориться onionна onion#onion.

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

Цей рядок знаходить розділ, який перекривається, шукаючи групу символів, що передують # ( (.+)), які однакові з іншого боку # ( \1). \ K просто означає "забудь, що я що-небудь відповідав", це означає, що він фактично не буде замінений в підстановці. Це ефективно, це означає, що ми просто додаємо # у позицію після того, як було знайдено перекриття, перетворюючись onion#onionу onion#on#ion.

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

Початкове "a" - це лише мітка для регулярного вираження. Після цього ми знаходимо перший # з подальшим символом ( .) і фіксуємо все після цього до наступного # ( .*#). Ми замінюємо це на все, що знаходиться праворуч від матчу, тобто останній жетон ($ '), за ним - # ( $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
Ласкаво просимо до головоломки програмування та коду для гольфу! Це питання є кодом гольфу, тому я пропоную вам "гольфувати" код, видаляючи зайві пробіли тощо, а потім додавати кількість байтів вашого коду до заголовка своєї публікації разом з мовою.
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()}

Дивно, як повернення до чогось наступного дня може допомогти

Безголовки:

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
Ласкаво просимо до обміну головоломок програмування та коду для гольфу! Вам не потрібно взагалі турбуватися про ефективність коду-гольфу , просто тривалість вашої програми. Тож повільна, неефективна версія цілком може бути найкращою тут (вона може внести освіжаючі зміни від "реальної роботи"!). Тому видаліть непотрібну пробіл і використовуйте однобуквені назви змінних - тоді читайте Поради щодо гольфу в JavaScript . Я думаю, що ти можеш багато зробити для цього в гольф - але ми любимо бачити непрограшну, коментовану версію, якщо ваш алгоритм розумний. Веселіться!
Toby Speight
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.