Mocowanie naszyjnika z pętli frotte

47

Załóżmy, że naciągasz sznur Froot Loops na naszyjnik, bransoletę, sznurowadło lub cokolwiek innego. Dostępnych jest 6 kolorów pętli: r ed, o range, y ellow, g reen, b lue i p urple. Chcesz, aby twoje pasmo zaczynało się od czerwieni po lewej stronie i kręciło się w tęczowej kolejności w prawo, kończąc na fioletowym. Oznacza to, że chcesz to zrobić, aby twój łańcuch mógł być reprezentowany przez ciąg roygbppowtórzony kilka razy (być może 0).

Problem polega na tym, że już naciągnąłeś pętle, a nie w określonej kolejności. Które pętle należy jeść, a nie jeść, aby zmaksymalizować liczbę prawidłowych cykli tęczy od lewej do prawej, przy pierwszej czerwonej pętli i ostatniej fioletowej pętli?

Napisz program lub funkcję, która pobierze dowolny ciąg znaków roygbpi wypisze lub zwróci ciąg o tej samej długości z ezamiast pętli do zjedzenia i nzamiast pętli do zjedzenia.

Na przykład, jeśli wyglądało twoje pasmo Pętli Froota

losowe pasmo Pętli Froota

wejście byłoby

gorboypbgbopyroybbbogppbporyoygbpr

i przechodząc od lewej do prawej możemy znaleźć 3 kompletne roygbpsekwencje tęczy, ale niektóre pętle muszą zostać zjedzone. Tak więc wynik byłby

eenenneennenennneeeeneennenennnnne

w wyniku czego powstaje idealny 3-cyklowy ciąg:

3 tęczowe pasmo Froot Loop

Jeśli na wejściu nie ma pełnych cykli tęczy, wówczas wynik byłby cały ei nici skończyłyby się bez pętli. np. wejście proygbma wyjście eeeeee. I odwrotnie, proygbpma wynik ennnnnn.

Możesz założyć, że wszystkie łańcuchy wejściowe mają co najmniej jedną pętlę.

Najkrótszy kod w bajtach wygrywa.

Hobby Calvina
źródło
1
@Fatalize Yes. Zwróć uwagę na część dotyczącą maksymalizacji liczby cykli tęczy. W przeciwnym razie mógłbyś zjeść je wszystkie.
Calvin's Hobbies
15
Właściwie posortowałeś i nawlec te pętle owocowe, żeby zrobić zdjęcia, prawda?
Martin Ender,
13
@ MartinBüttner Oczywiście
hobby Calvina
1
Czy każdy cykl tęczy musi zaczynać się od, rczy oygbproygbprteż może się kwalifikować?
orlp
4
Tak, ale jeśli są naciągnięte na naszyjnik lub bransoletę, z pewnością można je obracać?
Peter Taylor,

Odpowiedzi:

11

Pyth, 31 bajtów

:*lz\nhf!:jk.DzT"roygbp"kyUlz\e

Niesamowicie nieefektywne, wyjaśnienia wkrótce.

yUlzgeneruje wszystkie możliwe podzbiory wszystkich możliwych wskaźników z(wejściowych) w kolejności. Np. Jeśli dane wejściowe to abc:

[[], [0], [1], [2], [0, 1], [0, 2], [1, 2], [0, 1, 2]]

Następnie hf!znajduje pierwszą Tz powyższej listy, która :jk.DzT"roygbp"kjest fałszywa. .Dpobiera ciąg i listę indeksów i usuwa elementy z tych indeksów. Tak .D"abcd",1 3jest "ac". Ponieważ .Dzwraca listę (która nie powinna tak być, zostanie naprawiona w przyszłych wersjach Pytha), używam jk( kis ""), aby połączyć ją z powrotem w ciąg. :_"roygbp"kCzęść zastąpi każde wystąpienie cyklu z pustym ciągiem.

Ponieważ pusty ciąg jest fałszywy, powyższe akapity wyjaśniają, w jaki sposób znajduję najmniejszy zestaw wskaźników potrzebnych do zjedzenia, aby uzyskać ciąg składający się tylko z cykli.

:*lz\n_\enastępnie zamienia tę listę indeksów w nnnneeenneneciąg.

orlp
źródło
55

Sześciokąt , 920 722 271 bajtów

Mówisz, że jest sześć różnych rodzajów pętli owocowych? To, co Hexagony została wykonana za.

){r''o{{y\p''b{{g''<.{</"&~"&~"&<_.>/{.\.....~..&.>}<.._...=.>\<=..}.|>'%<}|\.._\..>....\.}.><.|\{{*<.>,<.>/.\}/.>...\'/../==.|....|./".<_>){{<\....._>\'=.|.....>{>)<._\....<..\..=.._/}\~><.|.....>e''\.<.}\{{\|./<../e;*\.@=_.~><.>{}<><;.(~.__..>\._..>'"n{{<>{<...="<.>../

Okej, nie było. O Boże, co ja sobie zrobiłem ...

Ten kod jest teraz sześciokątem o długości boku 10 (zaczął od 19). Prawdopodobnie może być jeszcze trochę w golfa, może nawet do rozmiaru 9, ale myślę, że moja praca została wykonana tutaj ... Dla odniesienia, w źródle znajduje się 175 faktycznych poleceń, z których wiele jest potencjalnie niepotrzebnymi kopiami lustrzanymi (lub zostały dodane, aby anulować wydać polecenie ze ścieżki krzyżowej).

Pomimo pozornej liniowości kod jest w rzeczywistości dwuwymiarowy: sześciokąt przekształci go w zwykły sześciokąt (co jest również poprawnym kodem, ale wszystkie białe znaki są opcjonalne w sześciokącie). Oto rozwinięty kod w całym ... no cóż, nie chcę mówić „piękno”:

          ) { r ' ' o { { y \
         p ' ' b { { g ' ' < .
        { < / " & ~ " & ~ " & <
       _ . > / { . \ . . . . . ~
      . . & . > } < . . _ . . . =
     . > \ < = . . } . | > ' % < }
    | \ . . _ \ . . > . . . . \ . }
   . > < . | \ { { * < . > , < . > /
  . \ } / . > . . . \ ' / . . / = = .
 | . . . . | . / " . < _ > ) { { < \ .
  . . . . _ > \ ' = . | . . . . . > {
   > ) < . _ \ . . . . < . . \ . . =
    . . _ / } \ ~ > < . | . . . . .
     > e ' ' \ . < . } \ { { \ | .
      / < . . / e ; * \ . @ = _ .
       ~ > < . > { } < > < ; . (
        ~ . _ _ . . > \ . _ . .
         > ' " n { { < > { < .
          . . = " < . > . . /

Wyjaśnienie

Nie będę nawet próbował wyjaśniać wszystkich zawiłych ścieżek wykonania w tej wersji golfowej, ale algorytm i ogólny przepływ sterowania są identyczne z tą wersją bez golfa, która może być łatwiejsza do nauki dla naprawdę ciekawych po wyjaśnieniu algorytmu:

                 ) { r ' ' o { { \ / ' ' p { . . .
                . . . . . . . . y . b . . . . . . .
               . . . . . . . . ' . . { . . . . . . .
              . . . . . . . . \ ' g { / . . . . . . .
             . . . . . . . . . . . . . . . . . . . . .
            . . . . . . . . . . . . . . . . . . . . . .
           . . . . . . . . > . . . . < . . . . . . . . .
          . . . . . . . . . . . . . . > . . ) < . . . . .
         . . . . . . . . . . / = { { < . . . . ( . . . . .
        . . . . . . . . . . . ; . . . > . . . . . . . . . <
       . . . . . . . . . . . . > < . / e ; * \ . . . . . . .
      . . . . . . . . . . . . @ . } . > { } < . . | . . . . .
     . . . . . / } \ . . . . . . . > < . . . > { < . . . . . .
    . . . . . . > < . . . . . . . . . . . . . . . | . . . . . .
   . . . . . . . . _ . . > . . \ \ " ' / . . . . . . . . . . . .
  . . . . . . \ { { \ . . . > < . . > . . . . \ . . . . . . . . .
 . < . . . . . . . * . . . { . > { } n = { { < . . . / { . \ . . |
  . > { { ) < . . ' . . . { . \ ' < . . . . . _ . . . > } < . . .
   | . . . . > , < . . . e . . . . . . . . . . . . . = . . } . .
    . . . . . . . > ' % < . . . . . . . . . . . . . & . . . | .
     . . . . _ . . } . . > } } = ~ & " ~ & " ~ & " < . . . . .
      . . . \ . . < . . . . . . . . . . . . . . . . } . . . .
       . \ . . . . . . . . . . . . . . . . . . . . . . . < .
        . . . . | . . . . . . . . . . . . . . . . . . = . .
         . . . . . . \ . . . . . . . . . . . . . . . . / .
          . . . . . . > . . . . . . . . . . . . . . . . <
           . . . . . . . . . . . . . . . . . . . . . . .
            _ . . . . . . . . . . . . . . . . . . . . .
             . . . . . . . . . . . . . . . . . . . . .
              . . . . . . . . . . . . . . . . . . . .
               . . . . . . . . . . . . . . . . . . .
                . . . . . . . . . . . . . . . . . .
                 . . . . . . . . . . . . . . . . .

Szczerze mówiąc, w pierwszym akapicie żartowałem tylko w połowie. Fakt, że mamy do czynienia z cyklem sześciu elementów, był naprawdę wielką pomocą. Model pamięci Hexagony jest nieskończoną heksagonalną siatką, w której każda krawędź siatki zawiera liczbę całkowitą o dowolnej dokładności, zinicjalizowaną do zera.

Oto schemat układu pamięci, której użyłem w tym programie:

wprowadź opis zdjęcia tutaj

Długi prosty bit po lewej stronie jest używany jako ciąg zakończony 0 ao dowolnym rozmiarze, który jest powiązany z literą r . Linie przerywane na innych literach reprezentują ten sam rodzaj struktury, każda obrócona o 60 stopni. Początkowo wskaźnik pamięci wskazuje krawędź oznaczoną 1 , zwróconą na północ.

Pierwszy, liniowy bit kodu ustawia wewnętrzną „gwiazdę” krawędzi na litery, roygbpa także ustawia początkową krawędź na 1, tak abyśmy wiedzieli, gdzie cykl się kończy / zaczyna (pomiędzy pi r):

){r''o{{y''g{{b''p{

Następnie wracamy do krawędzi oznaczonej jako 1 .

Ogólna idea algorytmu jest następująca:

  1. Dla każdej litery w cyklu czytaj dalej litery STDIN i, jeśli różnią się one od bieżącej litery, dołącz je do ciągu związanego z tą literą.
  2. Kiedy czytamy list, którego obecnie szukamy, przechowujemy ena brzegu etykietę ? , ponieważ dopóki cykl się nie zakończy, musimy założyć, że będziemy musieli także zjeść tę postać. Następnie przejdziemy przez pierścień do następnej postaci w cyklu.
  3. Proces ten można przerwać na dwa sposoby:
    • Albo zakończyliśmy cykl. W takim przypadku wykonujemy kolejną szybką rundę w cyklu, zastępując wszystkie te ez pola ? krawędzie z ns, ponieważ teraz chcemy, aby ten cykl pozostał na naszyjniku. Następnie przechodzimy do drukowania kodu.
    • Lub trafiamy EOF (który rozpoznajemy jako kod znaku ujemnego). W takim przypadku zapisujemy wartość ujemną w ? krawędź obecnego znaku (dzięki czemu możemy łatwo odróżnić go od obu ei n). Następnie szukamy 1 krawędzi (aby pominąć pozostałą część potencjalnie niepełnego cyklu) przed przejściem do drukowania kodu.
  4. Kod drukujący przechodzi ponownie przez cykl: dla każdego znaku w cyklu usuwa zapisany ciąg podczas drukowania edla każdego znaku. Następnie przenosi się do ? krawędź związana z postacią. Jeśli jest ujemny, po prostu kończymy program. Jeśli jest pozytywny, po prostu go drukujemy i przechodzimy do następnej postaci. Po zakończeniu cyklu wracamy do kroku 2.

Inną rzeczą, która może być interesująca, jest to, jak zaimplementowałem łańcuchy o dowolnym rozmiarze (ponieważ po raz pierwszy użyłem nieograniczonej pamięci w Hexagony).

Wyobraźmy sobie, że jesteśmy w pewnym momencie, dokąd jeszcze czyta znaki dla R (tak, możemy użyć schemat jak jest) i A [0] i 1 zostały już wypełnione znaków (wszystko na północny-zachód z nich jest nadal zerem ). Np. Może właśnie przeczytaliśmy pierwsze dwa znaki wejścia do tych krawędzi i teraz czytamy a .ogy

Nowy znak jest odczytywany w na krawędzi. Używamy ? krawędzi, aby sprawdzić, czy ten znak jest równy r. (Jest tu sprytna sztuczka: sześciokąt może łatwo rozróżniać między dodatnim i dodatnim, więc sprawdzanie równości poprzez odejmowanie jest denerwujące i wymaga co najmniej dwóch gałęzi. Ale wszystkie litery są mniejsze niż współczynnik 2, więc możemy porównać wartości, biorąc modulo, który da zero tylko wtedy, gdy będą równe.)

Ponieważ yróżni się od r, przechodzimy do (nie znakowanych) od lewej krawędzi w i skopiować ytam. Przechodzimy teraz bliższe okolice sześciokąta, kopiując znak jedną krawędź dodatkowo za każdym razem, dopóki mamy yna przeciwległej krawędzi w . Ale teraz w [0] jest już postać, której nie chcemy zastępować. Zamiast tego, „drag” THE ywokół następnego sześciokąta i sprawdzić się 1 . Ale jest tam też postać, więc idziemy o kolejny sześciokąt dalej. Teraz [2] wciąż wynosi zero, więc kopiujemyyw tym. Wskaźnik pamięci przesuwa się teraz wzdłuż sznurka w kierunku pierścienia wewnętrznego. Wiemy, kiedy osiągnęliśmy początek łańcucha, ponieważ (nieznakowane) krawędzie między a [i] są zerowe, podczas gdy ? jest pozytywny.

Prawdopodobnie będzie to przydatna technika do pisania nietrywialnego kodu w Hexagony w ogóle.

Martin Ender
źródło
12
...łał. Po prostu łał.
Elias Benevedes
1
To może nie wygrać w golfa, ale ... stary, to
fajne
Ponieważ wydaje się, że grupy kropek w rzędzie często występują w źródle, być może możesz dodać do języka funkcję kodowania kropek w czasie wykonywania lub coś, co zmniejszy długość kodu.
mbomb007,
@ mbomb007 Gra w golfa nie jest tak naprawdę priorytetem w Hexagony. ;) Poza tym nie mam żadnych znaków, które mogłyby odróżnić kodowanie długości przebiegu od rzeczywistego kodu ... (I myślę, że naprawdę dobrze golfowany kod nie miałby nawet takich ciągów braków).
Martin Ender
30

Sześciokąt , 169 bajtów

Zainspirowałem się odpowiedzią Martina Büttnera (to także jego esolang) i zdecydowałem, że mogę to zrobić w rozmiarze 8. (Jestem przekonany, że jest to również możliwe w rozmiarze 7, ale jest to bardzo trudne. Spędziłem już cztery dni -stop na tym.)

r'.'o\|{##|_#{#>\_{b{"]_\..<>"<>\/><#y/''"_<.}]''/'\>)}}.\}}'{<"\\#_#/<|##|#@#"p><n'>"{,<##g#_/#'.\<\##'#{(.<#e;#"\##%\\(};/*#>.)\>##_/"{__\}#>}=\#>=<|>##)|###_'#\"{__\\

Rozłożony sześciokątnie:

       r ' . ' o \ | {
      # # | _ # { # > \
     _ { b { " ] _ \ . .
    < > " < > \ / > < # y
   / ' ' " _ < . } ] ' ' /
  ' \ > ) } } . \ } } ' { <
 " \ \ # _ # / < | # # | # @
# " p > < n ' > " { , < # # g
 # _ / # ' . \ < \ # # ' # {
  ( . < # e ; # " \ # # % \
   \ ( } ; / * # > . ) \ >
    # # _ / " { _ _ \ } #
     > } = \ # > = < | >
      # # ) | # # # _ '
       # \ " { _ _ \ \

Program tak naprawdę nie korzysta z #instrukcji, więc użyłem tego znaku, aby pokazać, które komórki są faktycznie nieużywane. Co więcej, każda komórka no-op, która jest przemierzana tylko w jednym kierunku, jest lustrem (np. _Jeśli przemierzana jest poziomo), więc wiesz, że wszystkie .postacie są przemierzane w więcej niż jednym kierunku.

Wyjaśnienie

Na początku wykonujemy sekwencję instrukcji r''o{{y''g{{b''p"")". Są one rozrzucone nieco przypadkowo w całym kodzie, ponieważ wcisnąłem je po napisaniu wszystkiego innego. Używam ]kilka razy, aby przejść do wskaźnika następnej instrukcji; w ten sposób mogę zasadniczo teleportować się do innego rogu sześciokąta. Cała reszta programu jest wykonywana za pomocą wskaźnika instrukcji nr 3.

Pamięć wygląda teraz następująco, z ważnymi krawędziami oznaczonymi nazwami, których użyję w tym objaśnieniu:

układ pamięci przy starcie programu

Oznaczone krawędzie oznaczają:

  • in: Używamy tej krawędzi do przechowywania znaku, który czytamy ze STDIN.
  • %: Używamy tej krawędzi, aby wykonać operację modulo na charakter czytać ze standardowego wejścia ( in) i aktualną „ważny” charakter ( r, oetc.), co będzie 0, jeśli są one równe. Ukradłem tę sztuczkę z odpowiedzi Martina Büttnera, ale reszta programu jest inna.
  • #: Dopóki czytamy „nieprawidłowe” znaki (tj. Kolory, które musimy jeść), zwiększamy tę krawędź. Zatem ta krawędź pamięta, ile es potrzebujemy później.
  • r?: Zawsze 0oprócz miejsca, w którym znajduje się r(czerwona) część. To informuje nas o zakończeniu cyklu.

Program przebiega w ten sposób:

  • Czytaj dalej znaki. Jeśli nie jest to postać, której obecnie szukamy, zwiększ #. W przeciwnym razie przejdź do następnego segmentu pamięci w kolejności zgodnej z ruchem wskazówek zegara.
  • Przechodząc do następnego segmentu, jeśli r?jest pozytywny, dokonaliśmy całej rewolucji. Zrób kompletną rundę i wyjdź # esi 1 nna segment. Spowoduje to #przywrócenie każdego z nich do 0. (The eumieszcza się na nieoznakowanego krawędzi, ale dla nnas sprzeniewierzeniu się #przewagę, którą ustawiony 0przy użyciu *(mnożenie), który działa później, bo wiemy, że wszystkie %krawędzie są równe zero w tym czasie).
  • Czytając znak, jeśli nie jest on dodatni (tj. EOF), idź do tyłu przez okrąg i wypisz #+1 es, aż wrócisz do miejsca, w którym r?jest dodatni, a następnie wyjdź.

Po zakończeniu uruchomienia pamięć na końcu wygląda mniej więcej w następujący sposób. Zauważysz krawędzie zawierające 101(kod ASCII e); jedna z inkrawędzi to -1(EOF); wszystkie #krawędzie mają wartość 0; i wskaźnik pamięci kończy się na dodatniej r?krawędzi.

układ pamięci na końcu programu

Timwi
źródło
15

Retina , 148 85 79 bajtów

$
#roygbp
.(?<=(?=((?=.*#(\2?(.))).*?\3(?<=^\5())?)+.*\3$)(.*))\4
n
#.*

[^n]
e

Możesz uruchomić to z jednego pliku źródłowego z -sflagą interpretera.

Wyjaśnienie

Najpierw usuńmy proste rzeczy:

$
#roygbp

Dołącza #roygbpna końcu ciągu, którego użyjemy do dynamicznego obliczenia cyklu liter.

Kolejny (długi) krok wymyśla, które pętle należy zachować, i zastępuje je n. Za chwilę przyjrzymy się, jak to działa.

#.*
<empty>

Pozbywa się to naszego pomocnika wyszukiwania na końcu łańcucha.

[^n]
e

Zastępuje to wszystkie postacie, które nie zostały zastąpione w drugim kroku e, kończąc transformację.

Wróćmy teraz do drugiego kroku.

Podstawowa struktura wykorzystuje sztuczkę, którą odkryłem kilka miesięcy temu, aby zastąpić wybrane postacie w globalnym dopasowaniu:

.(?<=(?=...(?<=^\k<prefix>(?<flag>))?...)^(?<prefix>.*))\k<flag>

gdzie ...odpowiada dowolnie złożonemu wzorowi. To pasuje do znaku, który ma zostać zamieniony, .a następnie zaczyna szukać (za co należy przeczytać od prawej do lewej). Lookbehind przechwytuje wszystko, aż do dopasowanej postaci w grupie prefix. Następnie przełącza się na spojrzenie w przyszłość , które zaczyna się od początku łańcucha i może zawierać złożony wzór. Po znaku, który chcemy zastąpić w tej strukturze, kładziemy opcjonalnego wygląd tyłek , który sprawdza, czy prefixgrupa pasuje tutaj. Jeśli tak, przechwytuje pusty ciąg doflagGrupa. Jeśli nie, ponieważ jest opcjonalny, w ogóle nie wpływa na stan silnika wyrażeń regularnych i jest ignorowany. Wreszcie, po pomyślnym dopasowaniu lookahead pozostaje tylko \k<flag>koniec, który pasuje tylko wtedy, gdy flaga została ustawiona w pewnym momencie podczas obliczeń.

Teraz cofnijmy trochę długi regex, używając nazwanych grup i trybu wolnego miejsca:

.
(?<=
  (?=
    (?:
      (?=
        .*#
        (?<cycle>
          \k<cycle>?
          (?<char>)
        )
      )
      .*?
      \k<char>
      (?<=^\k<prefix>(?<flag>))?
    )+
    .*
    \k<char>$
  )
  (?<prefix>.*)
)
\k<flag>

Mam nadzieję, że rozpoznajesz ogólny zarys z góry, więc musimy tylko spojrzeć na to, co wpisałem ....

Chcemy uchwycić następną postać z cyklu do grupy char. Robimy to poprzez zapamiętywanie ciągu od #do bieżącego znaku w cycle. Aby uzyskać następną postać, używamy lookahead do wyszukiwania #. Teraz próbujemy dopasować, cyclea następnie dopasować następny znak w char. Zazwyczaj będzie to możliwe, chyba że charjest to ostatni znak p. W takim przypadku \k<cycle>dopasuje całą pozostałą część łańcucha i nie pozostanie żadna postać do przechwycenia char. Tak więc silnik cofa się, pomija odniesienie do cyclei po prostu dopasowuje pierwszy znak r.

Teraz mamy kolejną postać w cyklu char, szukamy następnego możliwego wystąpienia tej postaci za pomocą .*?\k<char>. Są to postacie, które chcemy zastąpić, więc prefixsprawdzamy po nim. Te kroki (znajdź następny charw cyklu, wyszukaj następne jego wystąpienie, ustaw flagę, jeśli to właściwe) są teraz po prostu powtarzane za pomocą +.

To właściwie wszystko, aby znaleźć cykliczną podsekwencję, ale musimy również upewnić się, że zakończymy na p. Jest to dość łatwe: wystarczy sprawdzić, czy wartość przechowywana obecnie w jest charzgodna z wartością pna końcu ciągu z .*\k<char>$. Zapewnia to również, że nasz ciąg wyszukiwania nie jest używany do zakończenia niekompletnego cyklu, ponieważ pdo tego sprawdzenia potrzebujemy znaku końca .

Martin Ender
źródło
7

Python 2, 133 130 126 121 bajtów

r=n=''
for c in input():r+='en'[c=='roygbp'[r.count('n')%6]]
for c in r:n+=['e',c][n.count('n')<r.count('n')/6*6]
print n

Pierwsza pętla otrzymuje cykle, a druga usuwa niepełny cykl

Zaoszczędzono 3 bajty dzięki JF i 5 z DLosc

Ruth Franklin
źródło
Nie możesz połączyć inicjalizacji ri ntak r=n='':?
JF
Przypisywanie R=r.countnie działa jako ciągi są niezmienne tak Rjest ''.count, nawet jeśli rzostanie zmieniony.
Ruth Franklin
3

Perl 5, 76 65 bajtów

Szczypta czystych nierozcieńczonych wyrażeń regularnych.
Najpierw znajduje to, czego nie należy jeść. To, co pozostaje, jest do zjedzenia.

s/r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p/n$1n$2n$3n$4n$5n/g;s/[^n\s]/e/g

Test

$ perl -p fruitloops.pl <<<gorboypbgbopyroybbbogppbporyoygbpr
eenenneennenennneeeeneennenennnnne
LukStorms
źródło
1
Lubię to podejście. Zamiast [^o]*itp. Czy możesz użyć .*?(niepochodni kwantyfikator)?
DLosc
Świetna wskazówka, dzięki! Nie wiedziałem, że nie chciwy kwalifikator się przyda.
LukStorms
Jeśli chcesz uniknąć zamiany końcowych spacji, możesz użyć \szamiast \nw klasie znaków ujemnych pierwszej wersji.
DLosc
1
To samo podejście w Retina: r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p n$1n$2n$3n$4n$5n [^n\s] e(4 pliki, 57 bajtów).
DLosc
No tak. \ s obejmuje również linie. Dobry chwyt I dobrze słyszeć, że Retina może przynajmniej pokonać Perla we własnej grze.
LukStorms
3

Lua, 101 bajtów

s=arg[1]:gsub("r(.-)o(.-)y(.-)g(.-)b(.-)p.-","*%1*%2*%3*%4*%5*"):gsub("%w","e"):gsub("*","n")print(s)

Kreatywnie wykorzystuje wzory Lua; Myślę, że to ciekawe podejście.

Zastępuje wszystkie niejedzone znaki „*”, zastępuje wszystkie znaki alfanumeryczne „e”, a następnie zastępuje wszystkie „*” s „n”.

Trebuchette
źródło
2

JavaScript (ES6), 118

a=>eval("b=[...a],d=0,e=b.map(f=>f=='roygbp'[d%6]?'n'[++d&0]:'e');for(i=e.length-1;i&&b[i]!='p';e[i--]='e');e.join``")

Skrzypce przetestowane w przeglądarce Firefox. Słyszę, że Chrome obsługuje teraz funkcje strzałek, ale nie przetestowałem tego jeszcze w Chrome.

Nie golfowany:

input=>eval("
    array = [...input],
    rainbow_index = 0,
    mapped = array.map( item=>
        item == 'roygbp'[rainbow_index%6] ? 'n'[++rainbow_index&0] : 'e'
        // when we encounter an item of the rainbow, do not eat and start using
        // the next rainbow item, otherwise eat
    );
    // go through backwards and eat until we find a 'p' indicating the last
    // complete loop
    for(i = mapped.length - 1; i && array[i]!='p'; mapped[i--] = 'e');

    mapped.join``
")
DankMemes
źródło
Chrome obsługuje funkcje strzałek, ale najwyraźniej nie ma ...jeszcze notacji.
DLosc
2

gawk, 96

{for(;c=substr("roygbp",++i,1);r=r"\\"i"n")p=p"([^"c"]*)"c;$0=gensub(p,r,"g");gsub(/[^n]/,"e")}1

Konstruuje wzorzec wyszukiwania "([^r]*)r([^o]*)o([^y]*)y([^g]*)g([^b]*)b([^p]*)p"i zamienia "\\1n\\2n\\3n\\4n\\5n\\6n". Po tej zamianie deklaruje wszystko jedzenie („e”), co nie jest częścią kompletnej tęczy.

Ta kombinacja automatycznie zapewnia, że ​​podczas tej operacji nie zostaną uszkodzone żadne tęcze, a na końcu nie pojawią się odcięte tęcze.

Cabbie407
źródło
1

Pyth, 42 bajty

Jf-Z=+Zq@zT@"roygbp"ZUzs.e@"en"}k<J*6/lJ6z

Wypróbuj online: Demonstracja

Jakube
źródło
1

CJam, 41 bajtów

2r:R,m*{R.*s__,6/"roygbp"*=\,~*}$0="en"f=

Podejście brutalnej siły, które wypróbowuje wszystkie odmiany jedzenia / niejedzenia i wybiera tę, która daje najdłuższy, prawidłowy naszyjnik.

Wypróbuj online w interpretatorze CJam .

Dennis
źródło
1

CJam, 50 bajtów

l{"roygbp"T=={'nT):T;}{'e}?}%W%_'ne=6%{_'n#'et}*W%

Wypróbuj online

Jest to nieco dłużej niż w przypadku niektórych innych zgłoszeń, ale jest bardzo wydajne przy liniowej złożoności. Skanuje ciąg wejściowy i dopasowuje znaki jeden po drugim.

Podstawowa część algorytmu jest w rzeczywistości dość zwarta. Około połowa kodu służy do usunięcia niepełnego cyklu na końcu.

Reto Koradi
źródło
1

C90, 142-146 bajtów (do 119, zależnie)

Działa w czasie liniowym, aby skutecznie zjeść te pętle owocowe, które nie mogą być częścią ładnej tęczy. Następnie postproces zabija każdą częściową pętlę na końcu.

Oto cztery wersje:

  • Wersja 1 (146 bajtów), połączenie z [name] [string]:
    main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}

  • Wersja 2 (142 bajty), wywołaj z [name] [string] [rainbow order]:
    main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
    To pozwala zdefiniować własne uporządkowanie tęczy z dowolnymi kolorami, o ile nie są nlub e. To sprawia, że ​​kod jest krótszy!

  • Wersja 3 (123 bajty), zadzwoń jak wersja 1:
    main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
    ta daje jak najwięcej tęczy! Niekompletne opadające tęcze obiecują! Nie powinniśmy ich jeść!

  • Wersja 4 (119 bajtów), wywołanie jak wersja 2:
    main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
    Taki sam jak wersja 3, ale TYPY MOAR RAINBOW!

Niewielkie ograniczenie: maszyna musi mieć podpisane znaki (ogólny przypadek), a ciąg znaków musi być dość krótki. Wyprowadza końcowe \ndla jasności.

Wersja 1 jest jedyną, która wyraźnie spełnia wymagania, chociaż wersja 2 jest dyskusyjna. Wersje 3 i 4 są mniej poprawną (ale wciąż zabawną) interpretacją pytania.

imallett
źródło
1

Pyth, 38 bajtów

Wiem, że jest to znacznie dłużej niż odpowiedź orlp, ale ta działa w czasie liniowym: o)

u+G?qH@"roygbp"/G\n\n\e+_>_zJx_z\p*Jdk

Wypróbuj tutaj .

W skrócie, ten program zastępuje wszystkie znaki po ostatnim „p” spacjami, a następnie iteruje każdy znak w powstałym ciągu. Jeśli znak jest następnym w sekwencji „roygbp”, wypisz „n”, w przeciwnym razie wypisz „e”.

                                          Implicit: z=input(), d=' ', k=''
                            Jx_z\p        Find number of chars after last p, store in J
                        _>_zJ             Take all but J chars of the input
                       +          *Jd     Append J spaces
u                                    k    Reduce on the above, starting with ''
               /G\n                       Count 'n' in output so far
      @"roygbp"                           Take relevant char from sequence string (modulus indexing)
   ?qH                                    Does the current char equal the above?
 +G                \n\e                   Select 'n' or 'e' as appropriate and append

Z trudem znajdowałem krótszy sposób przetwarzania ciągu wejściowego. _>_zJw szczególności czuje się niezręcznie, ale <Jznie podaje wymaganego ciągu, kiedy J == 0, tj. gdy wejście kończy się na „p”.

Sok
źródło
1

Haskell, 138 bajtów

g czy to.

f(c:r)(h:t)|c==h='n':(f(r++[c])t)|0<1='e':(f(c:r)t)
f _""=""
z 'n' 'n'='n'
z a b='e'
r=reverse
g s=zipWith z(f"roygbp"s)(r$f"pbgyor"(r s))
Leif Willerts
źródło
Myślę, że możesz zapisać niektóre bajty, definiując fi zjako infiks: 'n'%'n'='n'itd. Niektóre nawiasy w definicji gmożna usunąć za pomocą $.
Zgarb
1

JavaScript (ES6), 85 82 bajtów

Reguła „naszyjnik musi kończyć się fioletem” była początkowo wielką przeszkodą, podnosząc mój wynik z 66 do 125, ale znalazłem krótszą drogę (na szczęście!).

s=>(i=j=0,s.replace(/./g,x=>s.lastIndexOf`p`>=j++&x=='roygbp'[i%6]?(i++,'n'):'e'))

Wyjaśnienie:

Ten kod zapętla każdy znak na wejściu i zastępuje każdy z tą logiką rlub ez nią:

  • Jeśli pozycja postaci to <= ostatnia pozycja p, ORAZ postać jest następną w tęczy, zachowaj ją (zamień na n).
  • W przeciwnym razie zjedz go (zamień na e).

Nie golfowany:

function a(s) {
  var i=0, j=0, r='';
  t = t.replace(/./g, function (x) {
    if (s.lastIndexOf('p') >= j++ && x == 'roygbp'.charAt(i)) {
      i++;
      i %= 6;
      return 'n';
    } else {
      return 'e';
    }
  });
  return r;
}

Sugestie mile widziane!

ETHprodukcje
źródło
0

Python 2, 254 bajty

Pętle!

i=raw_input();r='roygbp';l='r';d=''
for n in i:
 if n==l:d+='n';l=r[(r.index(l)+1)%6]
 else:d+='e'
d=list(d)[::-1];p=(r.index(l)+1)%6;
for s in range(len(d)):
 if d[s]=='n'and p-1:d[s]='e';p-=1
if d.count('n')<6:print'e'*len(d)
else:print''.join(d[::-1])

Przepraszam za kalambur. : P

Zach Gates
źródło