Грайте 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
@Joshua Це недійсне згідно опису (див. "Все те саме письмо" ).
Арнольд

1
@Arnauld: І тестовий випадок для zoopzaap не погоджується з описом.
Джошуа

4
@Joshua Чому? Це стосується лише голосних голосів між провідними 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


@Grimy Хороший улов, дякую! (Я намагався *++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., Ах, це розумна хитрість, яку я намагався знайти.
Зал КТ







1

C # (Visual C # Interactive Compiler) , 60 байт

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

На основі відповіді Грімі на С.

Спробуйте в Інтернеті!


1
Це, на жаль, не працює, оскільки замінює голосні також у суфіксі.
Емінья,

Як зазначає @Emigna вище, це замінює всі aoi-vowels, а не лише ті, що передують першому 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.