Исправление колье Froot Loop


47

Предположим, что вы натягиваете нитки Froot Loops для ожерелья, браслета, шнурка или чего-то еще. Есть 6 цветов контура: г - е изд, о диапазоне, у ellow, г Reen, б LUE и р urple. Вы хотите, чтобы ваша прядь начиналась с красного в самом левом углу, а цикл в порядке радуги шел вправо, заканчиваясь фиолетовым. То есть вы хотите сделать так, чтобы ваша нить могла быть представлена ​​строкой, roygbpповторенной несколько раз (возможно, 0).

Проблема в том, что вы уже натянули петли, а не в каком-то определенном порядке. Какие петли следует есть, а не есть, чтобы вы могли максимизировать количество правильных циклов радуги, идущих слева направо, с самой первой красной петлей и самой последней фиолетовой петлей?

Напишите программу или функцию, которая принимает произвольную строку символов roygbpи печатает или возвращает строку одинаковой длины с eтем, чтобы вместо циклов есть и nвместо циклов не есть.

Например, если ваша нить Froot Loop выглядела как

случайная цепь Froot Loop

вход будет

gorboypbgbopyroybbbogppbporyoygbpr

и, пройдя слева направо, мы можем найти 3 полных roygbpпоследовательности радуги, но некоторые петли нужно съесть. Таким образом, результат будет

eenenneennenennneeeeneennenennnnne

в результате получается идеальная 3-х тактная цепь:

3 радуги цикла Froot Loop пряди

Если на входе нет полных циклов радуги, то на выходе будут все e, и цепь заканчивается без петель. например, вход proygbимеет выход eeeeee. И наоборот, proygbpимеет выход ennnnnn.

Можно предположить, что все входные цепи имеют хотя бы одну петлю.

Самый короткий код в байтах побеждает.


1
@ Фатализировать Да. Обратите внимание на часть о максимизации количества циклов радуги. Иначе вы могли бы съесть их все.
Увлечения Кэлвина

15
Вы на самом деле сортировали и нарезали эти фруктовые петли, чтобы сделать фотографии, не так ли?
Мартин Эндер,

13
@ MartinBüttner Конечно
Увлечения Кэлвина

1
Должен ли каждый цикл радуги начинаться rили может oygbproygbprтакже претендовать?
2015 года

4
Да, но если они нанизаны на ожерелье или браслет, то наверняка их можно повернуть?
Питер Тейлор

Ответы:


11

Pyth, 31 байт

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

Невероятно неэффективно, объяснение скоро будет.

yUlzгенерирует все возможные подмножества всех возможных индексов z(вход) в порядке. Например, если вход abc:

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

Затем hf!находит первый Tв приведенном выше списке такой, что :jk.DzT"roygbp"kявляется ложным. .Dберет строку и список индексов и удаляет элементы этих индексов. Так и .D"abcd",1 3есть "ac". Так как .Dвозвращает список (что не должно иметь место, это будет исправлено в будущих версиях Pyth), я использую jk( kis ""), чтобы объединить его обратно в строку. :_"roygbp"kЧасть заменяет каждый экземпляр цикла с пустой строкой.

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

:*lz\n_\eзатем превращает этот список индексов в nnnneeenneneстроку.


55

Гексагония , 920 722 271 байт

Вы говорите, шесть разных видов фруктовых петель? Вот для чего была создана Гексагония.

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

Ладно не было О боже, что я сделал для себя ...

Этот код теперь является шестиугольником с длиной стороны 10 (он начался в 19). Вероятно, это может быть еще немного, возможно, даже до размера 9, но я думаю, что моя работа здесь выполнена ... Для справки, в источнике 175 действующих команд, многие из которых являются потенциально ненужными зеркалами (или были добавлены для отмены). команда с пути пересечения).

Несмотря на кажущуюся линейность, код на самом деле двумерный: Hexagony преобразует его в правильный шестиугольник (который также является допустимым кодом, но все пробелы в Hexagony являются необязательными). Вот развернутый код во всем его ... ну, я не хочу сказать "красота":

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

объяснение

Я даже не буду пытаться объяснить все запутанные пути выполнения в этой версии игры в гольф, но алгоритм и общий поток управления идентичны этой версии без правил, которую, возможно, будет легче изучить для действительно любопытных после того, как я объясню алгоритм:

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

Честно говоря, в первом абзаце я шутил только наполовину. Тот факт, что мы имеем дело с циклом из шести элементов, на самом деле очень помог. Модель памяти Hexagony представляет собой бесконечную гексагональную сетку, где каждое ребро сетки содержит целое число произвольной точности со знаком, инициализированное в ноль.

Вот схема расположения памяти, которую я использовал в этой программе:

введите описание изображения здесь

Длинный прямой бит слева используется как строка aс нулем в конце произвольного размера, связанная с буквой r . Пунктирные линии на других буквах представляют собой структуру такого же типа, каждая из которых повернута на 60 градусов. Первоначально указатель памяти указывает на край, обозначенный 1 , обращенный на север.

Первый линейный бит кода устанавливает внутреннюю «звезду» ребер в буквы, roygbpа также устанавливает начальное ребро так 1, чтобы мы знали, где цикл заканчивается / начинается (между pи r):

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

После этого мы снова на краю с надписью 1 .

Теперь общая идея алгоритма такова:

  1. Для каждой буквы в цикле продолжайте читать буквы из STDIN и, если они отличаются от текущей буквы, добавьте их в строку, связанную с этой буквой.
  2. Когда мы читаем письмо, которое в настоящее время ищем, мы сохраняем eна краю надпись с надписью ? , потому что пока цикл не завершен, мы должны предположить, что нам придется съесть и этого персонажа. После этого мы переместимся по кольцу к следующему персонажу в цикле.
  3. Есть два способа, которыми этот процесс может быть прерван:
    • Либо мы завершили цикл. В этом случае мы делаем еще один быстрый цикл по циклу, заменяя все те, что eв ? граничит с ns, потому что теперь мы хотим, чтобы этот цикл оставался на цепочке. Затем мы переходим к печати кода.
    • Или мы нажимаем EOF (который мы распознаем как отрицательный символьный код). В этом случае мы записываем отрицательное значение в ? край текущего символа (чтобы мы могли легко отличить его от обоих eи n). Затем мы ищем 1 ребро (чтобы пропустить остаток потенциально неполного цикла), а затем перейдем к печати кода.
  4. Код печати снова проходит цикл: для каждого символа в цикле он очищает сохраненную строку при печати eдля каждого символа. Тогда он движется к ? край, связанный с персонажем. Если оно отрицательное, мы просто завершаем программу. Если оно положительное, мы просто печатаем его и переходим к следующему символу. Как только мы завершим цикл, мы вернемся к шагу 2.

Еще одна вещь, которая может быть интересной, - это то, как я реализовал строки произвольного размера (потому что я впервые использую неограниченную память в Hexagony).

Представьте себе , что мы в каком - то момент , когда мы по- прежнему читаем символы для г (так что мы можем использовать схему как есть) и а [0] и 1 уже заполнены с персонажами (все северо-запад от них по - прежнему равен нулю ). Например, возможно, мы только что прочитали первые два символа ввода в эти края и теперь читаем a .ogy

Новый персонаж читается в краю. Мы используем ? край, чтобы проверить, равен ли этот символ r. (Здесь есть хитрый трюк: гексагония может легко различать только положительное и не положительное, поэтому проверка на равенство с помощью вычитания раздражает и требует как минимум двух ветвей. Но все буквы меньше, чем в 2 раза, поэтому мы можем сравнить значения, взяв по модулю, который даст только ноль, если они равны.)

Поскольку yотличается от r, мы перемещаем (немаркированный) край слева в и копируем yтуда. Теперь мы перемещаемся дальше по шестиугольнику, каждый раз копируя символ на одно ребро дальше, пока у нас не появится yкрай напротив in . Но теперь в [0] уже есть символ, который мы не хотим перезаписывать. Вместо этого мы «таскать» yвокруг следующего шестиугольника и проверить с 1 . Но там тоже есть персонаж, поэтому мы идем дальше с шестигранником. Теперь [2] по-прежнему равен нулю, поэтому мы копируемyвнутрь. Указатель памяти теперь перемещается назад вдоль строки к внутреннему кольцу. Мы знаем, когда достигли начала строки, потому что (немаркированные) ребра между a [i] равны нулю, тогда как ? положительно.

Это, вероятно, будет полезной техникой для написания нетривиального кода в Hexagony в целом.


12
...Ух ты. Просто вау.
Элиас Беневедес

1
Это может не выиграть соревнование по гольфу, но ... мужик, это
изящное

Так как группы точек в строке часто встречаются в источнике, возможно, вы могли бы добавить в язык функцию для кодирования точек по длине прогона или что-то для сокращения длины кода.
mbomb007

@ mbomb007 Игра в гольф на самом деле не так уж и важна в гексагонии. ;) Кроме того, у меня не осталось символов, чтобы отличить кодирование длин серий от реального кода ... (И я думаю, что в действительно хорошем коде для игры в гольф даже не было бы таких циклов без операций.)
Мартин Эндер

30

Гексагония , 169 байт

Я был вдохновлен ответом Мартина Бюттнера (это тоже его esolang) и решил, что я могу сделать это в размере 8 (я уверен, что это возможно и в размере 7, но это очень сложно. Я уже провел четыре дня без Остановись на этом.)

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

Выложены шестиугольно:

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

Программа фактически не использует #инструкцию, поэтому я использовал этот символ, чтобы показать, какие ячейки на самом деле не используются. Кроме того, каждая неоперативная ячейка, проходящая только в одном направлении, является зеркалом (например, _если проходить горизонтально), поэтому вы знаете, что все .символы перемещаются более чем в одном направлении.

объяснение

В начале мы выполняем последовательность инструкций r''o{{y''g{{b''p"")". Они немного разбросаны по всему коду, потому что я сжал их после того, как написал все остальное. Я использую ]для переключения на указатель на следующую инструкцию несколько раз; таким образом я могу по существу телепортироваться в другой угол шестиугольника. Вся остальная часть программы выполняется указателем команды № 3.

Теперь память выглядит следующим образом: важные ребра помечены именами, которые я буду использовать в этом объяснении:

расположение памяти рядом с началом программы

Помеченные края означают следующее:

  • in: Мы используем этот край для хранения символа, который мы читаем из STDIN.
  • %: Мы используем это ребро для выполнения операции по модулю над символом, считанным из STDIN ( in) и текущим «действительным» символом ( r, oи т. Д.), Что будет, 0если они равны. Я украл этот трюк из ответа Мартина Бюттнера, но остальная часть программы другая.
  • #: Пока мы читаем «недопустимые» символы (то есть цвета, которые нам нужны), мы увеличиваем этот край. Таким образом, этот край запоминает, сколько es нам нужно вывести позже.
  • r?: Всегда, 0за исключением того, где находится r(красная) часть. Это говорит нам, когда мы завершили цикл.

Программа протекает так:

  • Продолжайте читать символы. Если это не тот персонаж, которого мы сейчас ищем, увеличьте его #. В противном случае переходите к следующему сегменту памяти по часовой стрелке.
  • При переходе к следующему сегменту, если r?он положительный, мы совершили целую революцию. Сделайте полный раунд и выведите # es и 1 nна сегмент. Это устанавливает каждый #обратно 0. (Объект eпомещается на немаркированном ребре, но для этого nмы неправильно присваиваем #ребро, которое впоследствии мы установили, 0используя *(умножение), что работает, потому что мы знаем, что все %ребра в это время равны нулю.)
  • При чтении символа, если он не является положительным (т. Е. EOF), пройдите назад по кругу и выводите #+1 eс, пока не вернетесь к r?положительному положению, затем выйдите.

После полного запуска память выглядит примерно следующим образом в конце. Вы заметите ребра, содержащие 101(код ASCII e); один из inребер -1(EOF); все #ребра в 0; и указатель памяти заканчивается на положительном r?фронте.

расположение памяти в конце программы


15

Сетчатка , 148 85 79 байт

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

[^n]
e

Вы можете запустить это из одного исходного файла с -sфлагом интерпретатора.

объяснение

Давайте сначала разберемся с простыми вещами:

$
#roygbp

Добавляется #roygbpв конец строки, которую мы будем использовать для динамического вычисления цикла букв.

Следующий (длинный) шаг определяет, какие циклы сохранить, и заменяет их n. Мы немного посмотрим, как это работает.

#.*
<empty>

Это избавляет от нашего помощника по поиску в конце строки.

[^n]
e

Это заменяет все символы, которые не были заменены на втором шаге e, завершив преобразование.

Теперь вернемся ко второму шагу.

Базовая структура использует трюк, который я обнаружил несколько месяцев назад для замены выбранных символов в глобальном сопоставлении:

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

где ...соответствует произвольно сложному шаблону. Это соответствует символу, который должен быть заменен, .и затем начинает просмотр сзади (который вы должны читать справа налево). Взгляд назад захватывает все, вплоть до соответствующего персонажа, в группу prefix. Затем он переключается на просмотр вперед , который теперь начинается с начала строки и может содержать сложный шаблон. После символа, который мы хотим заменить в этом шаблоне, мы помещаем необязательный вид сзади , который проверяет, соответствует ли prefixгруппа здесь. Если это так, он захватывает пустую строку вflagгруппа. Если это не так, потому что это необязательно, это не влияет на состояние движка регулярных выражений и игнорируется. Наконец, после успешного сопоставления заглядывания остается только \k<flag>конец в конце, который соответствует, только если флаг был установлен в некоторой точке во время вычисления.

Теперь давайте немного развернем длинное регулярное выражение, используя именованные группы и режим свободного доступа:

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

Я надеюсь, что вы узнаете общий план сверху, поэтому нам нужно только взглянуть на то, что я заполнил ....

Мы хотим захватить следующего персонажа в цикле в группу char. Мы делаем это, также запоминая строку с #текущего символа в cycle. Чтобы получить следующий символ, мы используем поиск для поиска #. Теперь мы пытаемся сопоставить cycleи затем сопоставить следующий символ в char. Обычно это будет возможно, если только charне последний символ p. В этом случае \k<cycle>будет соответствовать весь остаток строки, и не останется символа для ввода char. Таким образом, движок возвращает назад, опускает обратную ссылку cycleи просто соответствует первому символу r.

Теперь у нас есть следующий символ в цикле char, мы ищем следующее возможное вхождение этого символа с .*?\k<char>. Это символы, которые мы хотим заменить, поэтому мы ставим prefixчек после него. Эти шаги (поиск следующего charв цикле, поиск следующего вхождения, установка флага, если это необходимо) теперь просто повторяются с помощью +.

Это на самом деле все, что нужно для нахождения циклической подпоследовательности, но мы также должны убедиться, что мы заканчиваем на p. Это довольно легко: просто проверить , что значение в настоящее время хранится в charматчах с pв конце строки с .*\k<char>$. Это также гарантирует, что наша строка поиска не будет использована для завершения неполного цикла, потому что нам нужен трейлинг pдля этой проверки.


7

Python 2 133 130 126 121 байт

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

Первый цикл получает циклы, а второй удаляет неполный цикл

Сохранено 3 байта благодаря JF и 5 из DLosc


Не могли бы вы объединить инициализацию rи nкак это: r=n=''?
JF

Назначение R=r.countне работает , как строки являются неизменными , так Rэто ''.countдаже тогда , когда rизменяется.
Рут Франклин

3

Perl 5, 76 65 байт

Щепотка чистых неразбавленных регулярных выражений.
Сначала находит то, что не следует есть. То, что осталось, можно съесть.

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

Контрольная работа

$ perl -p fruitloops.pl <<<gorboypbgbopyroybbbogppbporyoygbpr
eenenneennenennneeeeneennenennnnne

1
Мне нравится этот подход. Вместо [^o]*т. Д. Вы можете использовать .*?(не жадный квантификатор)?
DLosc

Отличный совет, спасибо! Я не знал, что не жадный квалификатор пригодится.
LukStorms

Если вы хотите избежать замены конечных пробелов, вы можете использовать \sвместо класса \nотрицательных символов первой версии.
DLosc 15.09.15

1
Тот же подход в Retina: r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p n$1n$2n$3n$4n$5n [^n\s] e(4 файла, 57 байт).
DLosc 15.09.15

О верно. \ s также включает переводы строки. Хороший улов. И приятно слышать, что Retina может по крайней мере победить Perl в своей собственной игре.
LukStorms

3

Луа, 101 байт

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

Творчески использует шаблоны Lua; Я думаю, что это интересный подход.

Он заменяет все не съеденные символы на «*», заменяет все буквенно-цифровые символы на «e», а затем заменяет все «*» на «n».


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``")

Скрипка проверена в Firefox. Я слышал, что Chrome поддерживает функции стрелок, но я еще не проверял это в Chrome.

Ungolfed:

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``
")

Chrome поддерживает функции стрелок, но ...пока еще не обозначен
DLosc 15.09.15

2

Гоук, 96

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

Создает шаблон поиска "([^r]*)r([^o]*)o([^y]*)y([^g]*)g([^b]*)b([^p]*)p"и замены "\\1n\\2n\\3n\\4n\\5n\\6n". После этой замены он объявляет всю еду («е»), которая не является частью полной радуги.

Эта комбинация автоматически гарантирует, что во время этой операции раны не будут повреждены, и в конце не появятся оторванные радуги.



1

CJam, 41 байт

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

Подход грубой силы, который пробует все варианты еды / не есть и выбирает тот, который приводит к самому длинному, действительному ожерелью.

Попробуйте онлайн в интерпретаторе CJam .


1

CJam, 50 байтов

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

Попробуйте онлайн

Это немного дольше, чем некоторые другие материалы, но это очень эффективно с линейной сложностью. Он просматривает входную строку и сопоставляет символы один за другим.

Основная часть алгоритма на самом деле довольно компактна. Около половины кода предназначено для удаления неполного цикла в конце.


1

C90, 142-146 байт (до 119 в зависимости от)

Работает в линейное время, чтобы эффективно съесть те фруктовые петли, которые не могут быть частью красивой радуги. Затем постпроцесс убивает любой частичный цикл в конце.

Вот четыре версии:

  • Версия 1 (146 байт), вызов с [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);}

  • Версия 2 (142 байта), вызывать с помощью [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);}
    Это позволяет вам определять свой собственный порядок радуги с любыми цветами, которые вы хотите, если они не являются nили e. Это на самом деле делает код короче!

  • Версия 3 (123 байта), назовите как версию 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);}
    эта дает вам как можно больше вашей радуги! Незавершенные следы радуги обещают! Мы не должны их есть!

  • Версия 4 (119 байт), вызов как версия 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);}
    То же, что и версия 3, но ТИПЫ РАДУГИ МОРА!

Небольшое ограничение: машина должна иметь подписанные символы (общий случай), а строка должна быть довольно короткой. Выводит трейлинг \nдля ясности.

Версия 1 является единственным, который четко передает требования, хотя версия 2 спорно. Версии 3 и 4 являются менее правильной (но все же забавной) интерпретацией вопроса.


1

Pyth, 38 байт

Я знаю, что это значительно дольше, чем ответ orlp, но этот работает за линейное время: о)

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

Попробуйте это здесь .

Вкратце, эта программа заменяет все символы после последнего 'p' пробелами, а затем выполняет итерацию по каждому символу в результирующей строке. Если символ является следующим в последовательности «roygbp», выведите «n», в противном случае выведите «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

Я изо всех сил пытался найти более короткий способ обработки входной строки. _>_zJв частности, чувствует себя неловко, но <Jzне дает нужную строку когда J == 0, т.е. когда ввод заканчивается буквой 'p'.


1

Haskell, 138 байт

g Является ли.

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

Я думаю, что вы можете сохранить некоторые байты, определив fи zкак инфикс: 'n'%'n'='n'и т. Д. Кроме того, некоторые скобки в определении gмогут быть удалены с помощью $.
Згарб

1

Javascript (ES6), 85 82 байта

Правило «ожерелье должно заканчиваться пурпуром» изначально было большим препятствием, увеличивая мой счет с 66 до 125, но я нашел более короткий путь (к счастью!).

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

Объяснение:

Этот код перебирает каждый символ на входе и заменяет каждый с помощью rили eс этой логикой:

  • Если позиция персонажа <= последняя позиция pИ, а персонаж следующий в радуге, оставьте его (замените его на n).
  • В противном случае съешьте его (замените его e).

Ungolfed:

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

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


0

Python 2, 254 байта

Loops!

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

Извините за каламбур. :П

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.