Tocar Zip, Zap, Zop

22

Há um pequeno jogo de aquecimento improvisado em que você se organiza em círculo e envia zips, zaps e zops por aí, apontando para uma pessoa e dizendo a próxima palavra na sequência; eles fazem o mesmo até que todos estejam aquecidos ou tanto faz.

Sua tarefa é criar um programa que dê a próxima palavra em sequência, dada uma palavra de entrada. (Zip -> Zap -> Zop -> Zip) Como existem várias maneiras diferentes de dizer essas três palavras e emoções que podem ser adicionadas a elas, seu programa deve imitar a duplicação de maiúsculas e minúsculas e carregar sufixos.

Para elaborar, sua entrada será um ou mais Zs, depois um ou mais Is, As ou Os (a mesma letra) e, em seguida, um ou mais Ps (todas as letras até este ponto podem estar em maiúsculas e minúsculas) seguidas por algum sufixo arbitrário (que pode estar vazio). Você deve deixar as execuções de Zs e Ps, bem como o sufixo exatamente como recebido, mas depois alterar Is para As, As para Os ou Os para Is, preservando o caso a cada etapa.

Casos de teste de exemplo

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

Regras e Notas

  • Você pode usar qualquer codificação de caracteres conveniente para entrada e saída, desde que ela suporte todas as letras ASCII e tenha sido criada antes deste desafio.
  • Você pode assumir que a palavra de entrada é alguma variante de Zip, Zap ou Zop. Todas as outras entradas resultam em comportamento indefinido.
    • Entradas válidas corresponderão totalmente à regex Z+(I+|A+|O+)P+.*(em caso misto)

Golfe feliz!

Beefster
fonte
2
ziop -> o que isso faz?
Joshua
2
@ Joshua Isso é inválido de acordo com a descrição (consulte "a mesma letra" ).
Arnauld
1
@ Arnauld: E o caso de teste para zoopzaap discorda da descrição.
Joshua
4
@Joshua Why? Isso se aplica apenas às vogais entre as primeiras ze as primeiras p. O sufixo pode conter qualquer coisa.
Arnauld

Respostas:

9

JavaScript (Node.js) ,  69 63 57  54 bytes

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

Experimente online!

Quão?

Nós processamos a cadeia de entrada s caractere por caractere.

Reutilizamos s como um sinalizador: assim que um valor numérico é armazenado nele, sabemos que não devemos atualizar mais nada.

Para identificar "p"(112) e "P"(80), usamos o fato de que seus códigos ASCII são múltiplos de 4 e os códigos ASCII das outras letras no início da cadeia ( "z", "Z"e vogais) não são.

Para transformar uma vogal com o código ASCII c em sua contraparte n mantendo z-a Zinalterada, usamos a seguinte função:

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'

Comentado

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
fonte
Como você criou essa função?
Thomas Hirsch
2
@ThomasHirsch Foi encontrado com uma função de busca por força bruta. O primeiro passo (multiplicação + 1º módulo) garante que os parâmetros dêem resultados idênticos para letras minúsculas e maiúsculas. O segundo passo (os próximos 2 módulos e a subtração) verifica se os valores delta corretos podem ser obtidos a partir daí.
Arnauld
6

C (gcc) ,  81 ... 61 48  46 bytes

Guardado 2 bytes graças a @Grimy

Porta da minha resposta JS . Saídas modificando a sequência de entrada.

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

Experimente online!

Comentado

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
fonte
-2 bytes
Grimmy 28/02
@ Grimy captura agradável, obrigado! (Tentei *++s%4em algum momento, mas esqueci a otimização resultante ...)
Arnauld
1
-3 bytes adicionais . Este também deve ser aplicável à sua resposta JS.
Grimmy
@ Grimy É bastante diferente do meu, então você pode postar isso como uma resposta separada.
Arnauld
5

Retina 0.8.2 , 21 bytes

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

Experimente online! Translitera letras até e inclusive a primeira p, embora a seção ze pnão esteja na seção de transliteração não seja afetada. O primeiro Oé citado porque normalmente se expande 13567e o segundo oé citado porque também é mágico; na primeira parte da transliteração, ela se expande para a outra string. A transliteração resultante é, portanto, de IAOIiaoipara, em AOIiaoiseguida, a remoção das letras de origem duplicadas resulta em IAOiaopara AOIaoi.

Neil
fonte
4

C, 43 bytes

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

Experimente online!

Baseado na resposta de Arnauld . Fiz uma pesquisa de força bruta para encontrar a fórmula mais curta que gera a => o, o => i, i => a, z => z.

Grimmy
fonte
3

R , 110 bytes 76

-36 bytes graças ao Krill

Esta função recebe uma entrada de uma sequência.

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

Experimente online!

CT Hall
fonte
1
A coleta da sequência de peças em R tende a ser muito longa ... Mas você economiza muitos bytes extraindo primeiro uma substring sque traduziremos e substituindo-a por uma cópia traduzida: 76 bytes
Kirill L.
@ KirillL., Ah, esse é o truque inteligente que eu estava tentando encontrar.
CT Hall
2

Perl 6 , 41 33 bytes

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

Experimente online!

Substituição simples que não diferencia maiúsculas de minúsculas para mudar a seção da vogal.

Brincadeira
fonte
1

Perl 5, 31 bytes

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

TIO

Nahuel Fouilleul
fonte
1

SNOBOL4 (CSNOBOL4) , 183 bytes

	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

Experimente online!

Giuseppe
fonte
1

C # (compilador interativo do Visual C #) , 60 bytes

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

Baseado na resposta C de Grimy.

Experimente online!

Modalidade de ignorância
fonte
1
Infelizmente, isso não funciona, pois também substitui as vogais no sufixo.
Emigna 27/02
Como o @Emigna afirma acima, isso substitui todas as aoivogais, em vez de apenas as anteriores à primeira p/ P. Uma coisa no golfe, no entanto: ("iao".IndexOf((char)(c|32))+1)%4pode ser-~"iao".IndexOf((char)(c|32))%4
Kevin Cruijssen 27/02
1

C / C ++ (compilador VC ++) 192 bytes

esta é uma tentativa bastante ingênua, mas de qualquer maneira

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

alguma versão um pouco mais legível é essa

#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
fonte
tio: tio.run/…
der bender
tio golfed: tio.run/…
der bender
0

Ruby , 40 bytes

$_[$&]=$&.tr"IAOiao","AOIaoi"if/z+.+?p/i

Experimente online!

Kirill L.
fonte
0

05AB1E (herdado) , 22 bytes

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

Experimente online ou verifique todos os casos de teste .

Definitivamente pode ser jogado um pouco mais ..

Usa a versão herdada de 05AB1E em vez da reescrita do Elixir, porque +mescla campos em listas do mesmo comprimento, enquanto a nova versão precisaria de uma junção zip com par‚øJ .

Explicação:

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
fonte
0

PHP, 30 bytes

muito simples para um TiO:

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

Corra como cano com -nF. Para o PHP 7.2, coloque a string literal entre aspas.

Titus
fonte
Isso translitera todas as oiavogais em vez de somente as anteriores à primeira p/ Pnão é?
Kevin Cruijssen