Play Zip, Zap, Zop


22

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

Ваша задача - создать программу, которая дает следующее слово в последовательности, заданное входным словом. (Zip -> Zap -> Zop -> Zip) Поскольку существует множество различных способов произнесения этих трех слов и символов, которые могут быть добавлены к ним, ваша программа должна имитировать дублирование регистров и букв и содержать суффиксы.

Чтобы уточнить, ваш ввод будет один или несколько Zs, затем один или несколько Is, As или Os (все одинаковые буквы), затем один или несколько Ps (все буквы до этой точки могут быть в смешанном регистре), а затем некоторый произвольный суффикс (который может быть пустым). Вы должны оставить последовательности Zs и Ps, а также суффикс в том виде, в котором он был получен, но затем измените Is на As, As на Os или Os на Is, сохраняя регистр на каждом шаге.

Примеры тестовых случаев

zip         ==> zap
zAp         ==> zOp
ZOP         ==> ZIP
ZiiP        ==> ZaaP
ZZaapp      ==> ZZoopp
zzzzOoOPppP ==> zzzzIiIPppP
Zipperoni   ==> Zapperoni
ZAPsky      ==> ZOPsky
ZoPtOn      ==> ZiPtOn
zipzip      ==> zapzip
zapzopzip   ==> zopzopzip
zoopzaap    ==> ziipzaap

Правила и примечания

  • Вы можете использовать любую удобную кодировку символов для ввода и вывода, при условии, что она поддерживает все буквы ASCII и что она была создана до этого вызова.
  • Вы можете предположить, что входное слово - это некоторый вариант Zip, Zap или Zop. Все остальные входы приводят к неопределенному поведению.
    • Допустимые входные данные будут полностью соответствовать регулярному выражению Z+(I+|A+|O+)P+.*(в смешанном случае)

Счастливого гольфа!


2
ziop -> что это делает?
Джошуа

2
@ Джошуа Это недопустимо в соответствии с описанием (см. «Все те же буквы» ).
Арно

1
@Arnauld: И контрольный пример для zoopzaap не соответствует описанию.
Джошуа

4
@ Джошуа Почему? Это относится только к гласным между ведущими zи первыми p. Суффикс может содержать что угодно.
Арно

Ответы:


9

JavaScript (Node.js) ,  69 63 57  54 байта

s=>Buffer(s).map(c=>s|c%4<1?s=c:c+c*90%320%34%24-8)+''

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

Как?

Мы обрабатываем входную строку символ за символом.s

Мы повторно используем как флаг: как только в нем сохраняется числовое значение, мы знаем, что не должны обновлять что-либо еще.s

Для того, чтобы определить "p"(112) и "P"(80), мы используем тот факт , что их ASCII - коды являются кратными и ASCII коды других букв в начале строки ( , и гласные) не являются.4"z""Z"

Чтобы превратить гласный с кодом ASCII в его аналог , оставляя и не изменяя, мы используем следующую функцию:cnzZ

n=c+((((90×c)mod320)mod34)mod24)8

 letter | ASCII code |  * 90 | % 320 | % 34 | % 24 | - 8 | new letter
--------+------------+-------+-------+------+------+-----+-----------------------
   'i'  |     105    |  9450 |  170  |   0  |   0  |  -8 | 105 -  8 =  97 -> 'a'
   'a'  |      97    |  8730 |   90  |  22  |  22  |  14 |  97 + 14 = 111 -> 'o'
   'o'  |     111    |  9990 |   70  |   2  |   2  |  -6 | 111 -  6 = 105 -> 'i'
   'z'  |     122    | 10980 |  100  |  32  |   8  |   0 | 122 +  0 = 122 -> 'z'
   'I'  |      73    |  6570 |  170  |   0  |   0  |  -8 |  73 -  8 =  65 -> 'A'
   'A'  |      65    |  5850 |   90  |  22  |  22  |  14 |  65 + 14 =  79 -> 'O'
   'O'  |      79    |  7110 |   70  |   2  |   2  |  -6 |  79 -  6 =  73 -> 'I'
   'Z'  |      90    |  8100 |  100  |  32  |   8  |   0 |  90 +  0 =  90 -> 'Z'

комментарии

s =>                  // s = input string
  Buffer(s)           // convert it to a Buffer of ASCII codes
  .map(c =>           // for each ASCII code c in s:
    s |               //   if s is numeric
    c % 4 < 1 ?       //   or c is either 'p' or 'P':
      s = c           //     turn s into a numeric value and yield c
    :                 //   else:
      c +             //     update c
        c * 90 % 320  //     by applying the transformation function
        % 34 % 24     //     (see above)
        - 8           //
  ) + ''              // end of map(); coerce the Buffer back to a string

Как вы пришли к этой функции?
Томас Хирш

2
@ThomasHirsch Это было найдено с помощью функции поиска грубой силы. Первый шаг (умножение + 1-е по модулю) гарантирует, что параметры дают одинаковый результат как для строчных, так и для прописных букв. 2-й шаг (следующие 2 модуля и вычитание) проверяет, можно ли оттуда получить правильные значения дельты.
Арно

6

C (gcc) ,  81 ... 61 48  46 байтов

Сохранено 2 байта благодаря @Grimy

Порт моего JS ответа . Выходы путем изменения входной строки.

f(char*s){for(;*++s%4;*s+=*s*90%320%34%24-8);}

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

комментарии

f(char * s) {       // f = function taking the input string s
  for(;             //   for each character *s in s:
    *++s % 4;       //     advance the pointer; exit if *s is either 'p' or 'P' (it's safe 
                    //     to skip the 1st character, as it's guaranteed to be 'z' or 'Z')
    *s +=           //     update the current character:
      *s * 90 % 320 //       apply a transformation formula that turns
      % 34 % 24     //       a vowel into the next vowel in the sequence
      - 8           //       while leaving 'z' and 'Z' unchanged
  );                //   end of for()
}                   // end of function


@ Хороший улов, спасибо! (Я попытался *++s%4в какой-то момент, но упустил из виду итоговую оптимизацию ...)
Арно

1
Далее -3 байта . Это также должно быть применимо к вашему ответу JS.
Grimmy

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


5

Сетчатка 0.8.2 , 21 байт

iT`Io`A\OIia\oi`^.+?p

Попробуйте онлайн! Транслитерирует буквы вплоть до первого p, включая zи pнет в разделе транслитерации, поэтому не затрагивается. Первый Oцитируется, потому что он обычно расширяется, 13567а второй oцитируется, потому что он тоже магический; в первой части транслитерации он расширяется до другой строки. Таким образом, в результате транслитерация от IAOIiaoiдо AOIiaoiпоследующего удаления дубликатов исходных писем результатов IAOiaoдля AOIaoi.




3

R , 110 76 байт

-36 байт благодаря Крилю

Эта функция принимает на вход одну строку.

function(a)sub(s<-sub('z+(.+?)p.*','\\1',a,T),chartr('aioAIO','oaiOAI',s),a)

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


1
Сбор строки из фрагментов в R имеет тенденцию быть очень длинным ... Но вы экономите много байтов, сначала извлекая подстроку, sкоторую мы будем переводить, а затем заменяя ее переведенной копией: 76 байтов
Кирилл Л.

@KirillL. Ах, это умный трюк, который я пытался найти.
Зал CT







1

C # (интерактивный компилятор Visual C #) , 60 байт

n=>{for(int i=0;n[i]%4>0;)n[i]^=(char)(n[i++]%16*36%98%22);}

Основано на ответе С Грими.

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


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

Как сказано выше в @Emigna, это заменяет все aoiгласные, а не только те, что перед первым p/ P. Однако одно дело в гольфе: ("iao".IndexOf((char)(c|32))+1)%4может быть-~"iao".IndexOf((char)(c|32))%4
Кевин Круйссен

1

C / C ++ (компилятор VC ++) 192 байта

это довольно наивная попытка, но в любом случае

void f(char*I){int c[]={-8,14,6},B=1,v[]={105,97,111},j=0;for(*I;*I>0&B;I++){if(*I==80|*I==112){B=0;break;}if(*I==90|*I==122){}else{for(j;j<3;j++){if(*I==v[j]|*I==v[j]-32){*I+=c[j];break;}}}}}

немного более читаемая версия это

#include "stdafx.h"

void f(char * theString)
{
    signed int change[] = {'a'-'i','o'-'a','o'-'i'}; // add this to the vowel to get the next one
    char theVowels[] = {'i','a','o'};
    int breaker = 1;
    printf("Input %s\n",theString);
    for (int i = 0;(theString[i] != '\0') && breaker; i++)
    {
        switch (theString[i])
        {
            case 'Z': /*fall through*/
            case 'z': break;
            case 'P': /*fall through*/
            case 'p': breaker = 0;
                      break; 
            default: 
            {
                for (int j = 0; j < 3; j++)
                {
                    if ((theString[i] == theVowels[j]) || (theString[i]==(theVowels[j]-'a'+'A')))
                    {
                        theString[i] += change[j];
                        break;
                    }
                }
            }
            break;
        }

    }
    printf("Output %s\n",theString);
}
int main()
{
    char theString[]= "zzzzIIIIp0815-4711"; // a test string
    f(theString);
    return 0;
}


tio golfed: tio.run/…
der bender


0

05AB1E (наследие) , 22 байта

l'pkIg‚£ć…iaoDÀ‚Du+`‡ì

Попробуйте онлайн или проверьте все контрольные примеры .

Можно определенно играть в гольф немного больше ..

Использует унаследованную версию 05AB1E вместо перезаписи Elixir, потому что +объединяет поля в списках одинаковой длины, тогда как для новой версии вместо этого потребуется парное соединение zip-join‚øJ .

Объяснение:

l                       # Lowercase the (implicit) input-string
                        #  i.e. "ZipPeroni" → "zipperoni"
 'pk                   '# Get the index of the first "p"
                        #  i.e. "zipperoni" → 2
    Ig                 # Pair it with the length of the entire input-string
                        #  i.e. 2 and "zipperoni" → [2,9]
       £                # Split the (implicit) input-string into parts of that size
                        #  i.e. "ZipPeroni" and [2,9] → ["Zi","pPeroni"]
        ć               # Extract head: push the head and remainder separately to the stack
                        #  i.e. ["Zi","pPeroni"] → ["pPeroni"] and "Zi"
         iao           # Push string "iao"
             DÀ         # Duplicate, and rotate it once towards the left: "aoi"
                       # Pair them up: ["iao","aoi"]
                Du      # Duplicate and transform it to uppercase: ["IAO","AOI"]
                  +     # Python-style merge them together: ["iaoIAO","aoiAOI"]
                   `    # Push both strings to the stack
                       # Transliterate; replacing all characters at the same indices
                        #  i.e. "Zi", "iaoIAO" and "aoiAOI" → "Za"
                     ì  # Prepend it to the remainder (and output implicitly)
                        #  i.e. ["pPeroni"] and "Za" → ["ZapPeroni"]

0

PHP, 30 байт

слишком просто для TiO:

<?=strtr($argn,oiaOIA,iaoIAO);

Беги как труба с -nF. Для PHP 7.2 заключайте строковые литералы в кавычки.


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