Garlandification

38

Słowa wianek

Słowo girlanda jest słowem, które mogą być nawleczone razem jak wianka, ponieważ kończy się z tymi samymi literami to zaczyna się. Te grupy liter mogą się nawet pokrywać!

Na przykład, undergroundjest słowem girlanda porządku 3, ponieważ zaczyna i kończy się na samych 3 znaków und. Oznacza to, że można go połączyć razem undergroundergrounderground....

alfalfato także słowo wianek! Jest z rzędu 4. Zaczyna się i kończy na alfa. Może być nawleczone razem tak: alfalfalfalfa.

Proces, który nazywam girlandingiem, polega na tym, że gdy określisz kolejność nsłowa girlandy, bierzesz oryginalne słowo i dodajesz segment wymagany do zapętlenia go jako nczasów girlandy . Ponieważ onionjest to 2słowo wianek na zamówienie , weź onion, odetnij pierwsze 2litery, aby je zdobyć, ioni dodaj je do czasów ostatecznych, 2aby je zdobyć onionionion.

Cel

Stwórz program lub funkcję, która pobiera dane ze standardowego wejścia lub argumentu funkcji i wypisuje lub zwraca słowo girlandowane.

Wszystkie słowa będą pisane małymi literami, a najwyższa możliwa kolejność słów length(word) - 1.

Przykład I / O

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

To jest , więc wygrywa najmniejsza liczba bajtów.

Kade
źródło
2
Każde słowo składające się z N liter zaczyna się od tych samych N liter, z którymi się kończy. Jakie jest maksymalne zamówienie, które należy wziąć pod uwagę?
feersum
@feersum Maksymalna kolejność to długość słowa - 1. Dodano to do głównego postu.
Kade
Czy muszę wydrukować tylko girlandę? czy może mogę wydrukować i wyjątek?
DeadChex,
@DeadChex Nie powinno być wyjątków.
Kade,
1
@LuisMendo Powinno działać dla dowolnie długich słów.
Kade,

Odpowiedzi:

12

Pyth, 19 18 bajtów

+z*>Kf!xz>zT1zl>zK

Wypróbuj online: Demonstracja lub Uprząż testowa

Objaśnienia:

+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
Jakube
źródło
14

Python, 60 bajtów

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

Miałem nadzieję na lepsze, ale no cóż. s.finddziała starannie tutaj zamiast not s.startswith.

Sp3000
źródło
12

Siatkówka , 58 bajtów

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

Każda linia powinna przejść do własnego pliku, ale możesz uruchomić kod jako jeden plik z -sflagą.

Cztery pary podstawień wykonują następujące czynności:

  • Zduplikowane słowo, abyśmy mogli wyszukiwać nakładki.
  • Dołącz słowo podzielone według orderliczby znaków.
  • Dołącz ostatnie pół orderetatu.
  • Zachowaj oryginalne słowo i ostatnio dołączoną część i upuść wszystko inne.

Łańcuch określa przykład onion:

onion
onion#onion
onion#onion#on#ion-
onion#onion##ion-ionion
onionionion
randomra
źródło
10

Haskell, 64 bajty

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

Testy:

λ: 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
MtnViewMark
źródło
10

Java, 160 157 bajtów

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;}}

Wejście wyjście:

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

Odstępy i tabulatory dla czytelności:

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;
    }
}

Sugestie mile widziane.

DeadChex
źródło
Jako notatkę dla mnie,
operacje
dlaczego nie zrobić i=0;?
overactor
@overactor gdzie? Powodem, dla którego używam długości jest to, że chcę pełnego ciągu znaków, a następnie chcę przejść do żadnego z nich, z podciągiem nie sądzę, żebym mógł uniknąć użycia go w tej metodzie i weźmie za to karę bajtową
DeadChex
2
Chciałem wyrwać się z zewnętrznej pętli.
overactor
8

Sed: 87 84 znaków

(Kod 83 znaków + opcja wiersza poleceń 1 znak.)

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

Przykładowy przebieg:

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
człowiek w pracy
źródło
Automatyczny głos odpowiedzi sed ;-). Postępuj zgodnie z tą wskazówką, aby usunąć 2 znaki z definicji etykiety i oddziału
Digital Trauma
Próbowałem, ale obawiam się, że rada dotyczy tylko przypadków, w których nie ma skoków bez etykiety na koniec kodu. [Trochę później…] Ok, zastanawiając się jeszcze raz, dlaczego próbowałem przetworzyć wiele linii wejściowych jednocześnie?
manatwork
7

CJam, 24 23 bajty

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.

Żeby zacząć od czegoś ...

Wypróbuj online tutaj

Optymalizator
źródło
5

Matlab: 97 89 82 bajtów

Funkcja wykorzystująca wyrażenie regularne z lookbehind i grupą przechwytującą:

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

Jest sumto potrzebne do obsługi danych wejściowych z pustym ciągiem (konwersja []na 0).

Przykłady:

> 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
Luis Mendo
źródło
4

REGXY, 53 49 bajtów

Używa REGXY , języka opartego na podstawieniu wyrażenia regularnego

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

Omówienie: zastosowano wiele wyrażeń regularnych. Przykładowy przebieg wyglądałby następująco:

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

Szczegółowe wyjaśnienie Poniżej przedstawiono podział wyrażeń regularnych według wierszy:

//$'#/

Jest to podstawienie wyrażenia regularnego, które dopasowuje pierwszy pusty ciąg (tj. Początek łańcucha) i zastępuje go wszystkim po prawej stronie match ( $'), po którym następuje skrót. Na przykład zamieni się onionw onion#onion.

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

Ta linia znajduje sekcję, która zachodzi na siebie, szukając grupy znaków bezpośrednio poprzedzających # ( (.+)), które są takie same po drugiej stronie # ( \1). \ K oznacza po prostu „zapomnij, że coś dopasowałem”, co oznacza, że ​​tak naprawdę nie zostanie zastąpione przez podstawienie. W efekcie oznacza to, że po znalezieniu nakładki dodajemy # do pozycji, zamieniając się onion#onionw onion#on#ion.

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

Początkowe „a” jest tylko etykietą wyrażenia regularnego. Następnie znajdujemy pierwszy #, a następnie pojedynczy znak ( .) i przechwytujemy wszystko do następnego # ( .*#). Zastępujemy to wszystkim po prawej stronie dopasowania, tj. Ostatnim tokenem ($ '), a następnie znakiem # ( $1), a następnie drugim tokenem bez znaku (traktujemy to jako licznik, zmniejszając go z każdą iteracją). W przypadku cebuli # na # jonów, dwa żetony na my wsteczne są pokazane w nawiasach, a sekcja całe mecze regex jest między rurami: onion|(#)o(n#)|ion. Następnie zamieniamy pasujące bity (między rurami) na $'(wszystko po prawej stronie dopasowania, tj. „Jon”), następnie 1 $ (the #), a następnie 2 $ (n #), co oznacza, że ​​otrzymujemy onion|(ion)(#)(n#)|ion(nawiasy kwadratowe pokazują trzy tokeny w ciągu zastępującym).

Jeśli wyrażenie regularne nie pasuje do pierwszej alternacji (wszystko przed potokiem), musimy zmniejszyć nasz licznik do zera, co oznacza, że ​​w drugim tokenie nie ma żadnych znaków. Zamiast tego, możemy spojrzeć na drugą część wzoru, #.*. To po prostu zastępuje wszystko po pierwszym # $'$1$2. Ponieważ nie ma żadnych odwołań wstecznych utworzonych przez tę alternatywę, a po prawej stronie dopasowania nie ma nic ( .*dopasowania do końca łańcucha), kończymy dopasowanie i zwracamy wynik.

//a

Jest to tylko wskaźnik do poprzedniej linii, zapewniający kontynuowanie podstawiania wyrażenia regularnego, dopóki nie będzie już pasować.

Jarmex
źródło
3

jq 1,5: 91 znaków

(Kod 87 znaków + opcja wiersza poleceń 4 znaki).

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

Przykładowy przebieg:

bash-4.3$ jq -R -r -f judy.jq <<< 'underground'
undergroundergroundergrounderground
człowiek w pracy
źródło
3

rs , 51 48 bajtów

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

WEŹ, ŻE RETINA I SED !!!!! ;)

Odetnij 3 bajty dzięki @randomra.

Prezentacje na żywo i przypadki testowe.

Pamiętaj, że jackhammernie ma tam przypadku testowego. Wystąpił błąd w obsłudze spacji w interfejsie internetowym, który powoduje, że drukuje nieprawidłowe dane wyjściowe. Wersja offline rsobsługuje to poprawnie.

Wersja 51-bajtowa:

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

Wersje demonstracyjne i testowe na żywo dla oryginału.

kirbyfan64sos
źródło
@randomra Zaktualizowano. Dzięki!
kirbyfan64sos
2

JavaScript (ES6), 95 bajtów

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

Próbny

Firefox tylko na razie:

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>

lodowisko. dozorca 6
źródło
2

JavaScript (ES6), 82 bajty

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

[Usunąłem pierwotną odpowiedź, ponieważ nauczyłem się ES6 i chciałem znaleźć rekurencyjne rozwiązanie tego wyzwania]

Przykład

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'));

Rick Hitchcock
źródło
1

CoffeeScript + ES6, 77 bajtów

Takie samo podejście jak moja odpowiedź JavaScript.

f=(s,e=i=s.length)->s+=s[i..].repeat !(e=!s.endsWith s[...i])*i while--i&&e;s
lodowisko. dozorca 6
źródło
0

do

#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;
}

Gra w golfa: 195 bajtów - 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);}
Alam
źródło
5
Witamy w Programowaniu zagadek i Code Golf! To pytanie dotyczy kodu golfowego, więc sugeruję, aby „golfować” swój kod, usuwając niepotrzebne białe znaki itp., A następnie dołączyć liczbę bajtów kodu w tytule wpisu wraz z językiem.
lirtosiast
1
Rozumiem. Dziękuję za wskazówkę. Będę o tym pamiętać następnym razem.
Alam
Nie jest za późno na „golfa”. Jeśli klikniesz przycisk „edytuj” pod swoją odpowiedzią, nadal możesz usunąć niepotrzebne białe znaki i dodać liczbę bajtów.
DJMcMayhem
Czy nie jest intukryty w (wystarczająco starych wersjach) C?
Przywróć Monikę
0

Groovy 75 57 55 bajtów

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

Niesamowite, jak powrót do czegoś następnego dnia może pomóc

Nie golfowany:

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()     
}
dbramwell
źródło
-1

W przypadku, gdy ktoś potrzebuje kodu w JS, aby go przetestować. Uwaga: przejrzałem ciąg od końca, aby zwiększyć wydajność:

"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");
TalwinderSingh
źródło
4
Witamy na stronie Programowanie łamigłówek i wymiany stosów kodów golfowych! Nie musisz martwić się o efektywność gry w golfa , tylko o długość swojego programu. Tak więc powolna, nieefektywna wersja może być tutaj najlepsza (może dokonać odświeżającej zmiany z „prawdziwej pracy”!). Usuń niepotrzebne białe znaki i użyj jednoliterowych nazw zmiennych - a następnie przeczytaj Wskazówki dotyczące gry w golfa w JavaScript . Myślę, że możesz wiele zrobić, aby zagrać w golfa - ale lubimy patrzeć na nieposkromioną, skomentowaną wersję, jeśli Twój algorytm jest sprytny. Baw się dobrze!
Toby Speight