Graj w Zip, Zap, Zop

22

Jest trochę ulepszonej gry rozgrzewkowej, w której ustawiasz się w kręgu i wysyłasz zamki błyskawiczne, zaps i zopsy, wskazując na osobę i wypowiadając następne słowo w sekwencji, a następnie robią to samo, dopóki wszyscy się nie rozgrzeją lub cokolwiek.

Twoim zadaniem jest stworzenie programu, który poda kolejne słowo w sekwencji, podając słowo wejściowe. (Zip -> Zap -> Zop -> Zip) Ponieważ istnieje wiele różnych sposobów wypowiedzenia tych trzech słów i sprytów, które można do nich dodać, twój program powinien naśladować powielanie liter i liter oraz nosić sufiksy.

W celu rozwinięcia, dane wejściowe będą wynosić jeden lub więcej Zs, następnie jeden lub więcej Is, As lub Os (cała ta sama litera), następnie jeden lub więcej Ps (wszystkie litery do tego momentu mogą być pisane wielkimi literami), po których następuje jakiś dowolny sufiks (który może być pusty). Należy pozostawić serie ZS i PS, jak również przyrostek dokładnie tak odbierane, ale następnie zmień IS do AS, AS do OS lub OS, aby Is, przy zachowaniu sprawy na każdym kroku.

Przykładowe przypadki testowe

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

Zasady i uwagi

  • Możesz użyć dowolnego wygodnego kodowania znaków dla danych wejściowych i wyjściowych, pod warunkiem, że obsługuje on wszystkie litery ASCII i że został utworzony przed tym wyzwaniem.
  • Możesz założyć, że słowo wejściowe jest odmianą Zip, Zap lub Zop. Wszystkie pozostałe dane wejściowe powodują niezdefiniowane zachowanie.
    • Prawidłowe dane wejściowe będą w pełni pasować do wyrażenia regularnego Z+(I+|A+|O+)P+.*(w przypadku mieszanym)

Wesołego golfa!

Wołowina
źródło
2
ziop -> co to robi?
Joshua
2
@Joshua To jest nieprawidłowe zgodnie z opisem (patrz „cała ta sama litera” ).
Arnauld
1
@Arnauld: A przypadek testowy dla zoopzaap nie zgadza się z opisem.
Jozuego
4
@Joshua Dlaczego? Dotyczy to tylko samogłosek między wiodącymi za pierwszymi p. Sufiks może zawierać wszystko.
Arnauld

Odpowiedzi:

9

JavaScript (Node.js) ,  69 63 57  54 bajtów

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

Wypróbuj online!

W jaki sposób?

Możemy przetwarzać ciąg wejściowy s znak po znaku.

Ponownie wykorzystujemy s jako flagę: jak tylko wartość liczbowa zostanie w nim zapisana, wiemy, że nie możemy aktualizować niczego innego.

Aby zidentyfikować "p"(112) i "P"(80), używamy fakt, że ich kody ASCII są wielokrotnością 4 i kody ASCII innych liter na początku łańcucha ( "z", "Z"i samogłoski) nie są.

Obrócić samogłoskę kodzie ASCII c do jego odpowiednika n pozostawiając zi Zzmian używamy następujące funkcje:

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'

Skomentował

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
Arnauld
źródło
Jak wymyśliłeś tę funkcję?
Thomas Hirsch
2
@ThomasHirsch Znaleziono z funkcją wyszukiwania z użyciem siły. Pierwszy krok (mnożenie + 1. moduł) zapewnia, że ​​parametry dają identyczny wynik zarówno dla małych, jak i wielkich liter. Drugi krok (kolejne 2 moduły i odejmowanie) sprawdza, czy można uzyskać z tego prawidłowe wartości delta.
Arnauld
6

C (gcc) ,  81 ... 61 48  46 bajtów

Zaoszczędź 2 bajty dzięki @Grimy

Port mojej odpowiedzi JS . Wyjście poprzez modyfikację ciągu wejściowego.

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

Wypróbuj online!

Skomentował

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
Arnauld
źródło
-2 bajty
Grimmy
@Grimy Nice catch, dzięki! ( *++s%4W pewnym momencie próbowałem, ale przeoczyłem wynikową optymalizację ...)
Arnauld
1
Dalsze -3 bajty . Ten powinien również dotyczyć odpowiedzi JS.
Grimmy
@Grimy Jest wystarczająco różny od mojego, więc możesz opublikować to jako osobną odpowiedź.
Arnauld
5

Retina 0.8.2 , 21 bajtów

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

Wypróbuj online! Transliteruje litery do pierwszej włącznie p, chociaż zi pnie są w sekcji transliteracji, więc nie ma to wpływu. Pierwszy Ojest cytowany, ponieważ zwykle się rozwija, 13567a drugi ojest cytowany, ponieważ również jest magiczny; w pierwszej części transliteracji rozwija się do drugiego łańcucha. Wynikowa transliteracja jest zatem od IAOIiaoido AOIiaoimomentu usunięcia zduplikowanych liter źródłowych w wyniku IAOiaodo AOIaoi.

Neil
źródło
4

C, 43 bajty

f(char*s){for(;*++s%4;*s^=*s%16*36%98%22);}

Wypróbuj online!

Na podstawie odpowiedzi Arnaulda . Przeprowadziłem wyszukiwanie metodą brute-force, aby znaleźć najkrótszą formułę, która zmienia a => o, o => i, i => a, z => z.

Ponury
źródło
3

R , 110 76 bajtów

-36 bajtów dzięki Krillowi

Ta funkcja przyjmuje dane wejściowe jednego ciągu.

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

Wypróbuj online!

CT Hall
źródło
1
Zbieranie ciągu z kawałków w R jest zwykle bardzo długie ... Ale oszczędzasz dużo bajtów, najpierw wyodrębniając podciąg, sktóry będziemy tłumaczyć, a następnie zastępując go przetłumaczoną kopią: 76 bajtów
Kirill L.
@KirillL., Ach, to sprytna sztuczka, którą próbowałem znaleźć.
CT Hall
2

Perl 6 , 41 33 bajtów

{S:i{.+?p}=$/~~tr/iaoIAO/aoiAOI/}

Wypróbuj online!

Proste podstawianie bez rozróżniania wielkości liter w celu przesunięcia sekcji samogłoski.

Jo King
źródło
1

Perl 5, 31 bajtów

s/.+?p/$&=~y,iaoIAO,aoiAOI,r/ei

TIO

Nahuel Fouilleul
źródło
1

SNOBOL4 (CSNOBOL4) , 183 bajty

	INPUT (BREAK('Pp') SPAN('Pp')) . P REM . S
A	P 'a' ='o'	:S(A)
Z	P 'A' ='O'	:S(Z)F(P)
I	P 'i' ='a'	:S(I)
K	P 'I' ='A'	:S(K)F(P)
O	P 'o' ='i'	:S(O)
L	P 'O' ='I'	:S(L)
P	OUTPUT =P S
END

Wypróbuj online!

Giuseppe
źródło
1

C # (interaktywny kompilator Visual C #) , 60 bajtów

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

Na podstawie odpowiedzi C Grimy'ego.

Wypróbuj online!

Wcielenie ignorancji
źródło
1
To niestety nie działa, ponieważ zastępuje również samogłoski w sufiksie.
Emigna
Jak zaznaczono powyżej @Emigna, to zastępuje wszystkie aoi-owowyki, a nie tylko te przed pierwszym p/ P. Jedną rzeczą do golfa: ("iao".IndexOf((char)(c|32))+1)%4może być-~"iao".IndexOf((char)(c|32))%4
Kevin Cruijssen
1

C / C ++ (kompilator VC ++) 192 bajty

jest to raczej naiwna próba, ale i tak

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

jest to nieco bardziej czytelna wersja

#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;
}
der bender
źródło
tio: tio.run/…
der bender
tio golfed: tio.run/…
der bender
0

05AB1E (starsza wersja) , 22 bajty

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

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Można zdecydowanie zagrać w golfa trochę więcej ..

Używa starszej wersji 05AB1E zamiast przepisywania Elixir, ponieważ +łączy pola na listach o tej samej długości, podczas gdy nowa wersja wymagałaby zamiast tego pary-zip-join‚øJ .

Wyjaśnienie:

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"]
Kevin Cruijssen
źródło
0

PHP, 30 bajtów

zbyt proste jak na TiO:

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

Uruchom jako potok z -nF. W PHP 7.2 wstaw literały ciągów w cudzysłów.

Tytus
źródło
To transliteruje wszystkie oiasamogłoski zamiast tylko tych przed pierwszym p/ P, prawda?
Kevin Cruijssen