[Question]
  [
There's a little improv warm up game where you arrange yourselves in a circle and send zips, zaps, and zops around by pointing to a person and saying the next word in the sequence, then they do the same until all of you are warmed up or whatever.
Your task is to create a program that gives the next word in sequence given an input word. (Zip --> Zap --> Zop --> Zip) Since there's a lot of different ways to say these three words and flairs that can be added to them, your program should imitate case and letter duplication and carry suffixes.
To elaborate, your input will be one or more `Z`s, then one or more `I`s, `A`s, or `O`s (all the same letter), then one or more `P`s, (all letters up to this point may be in mixed case) followed by some arbitrary suffix (which may be empty). You should leave the runs of `Z`s and `P`s, as well as the suffix exactly as received, but then change the `I`s to `A`s, `A`s to `O`s, or `O`s to `I`s, preserving case at each step.
## Example Test Cases
```
zip         ==> zap
zAp         ==> zOp
ZOP         ==> ZIP
ZiiP        ==> ZaaP
ZZaapp      ==> ZZoopp
zzzzOoOPppP ==> zzzzIiIPppP
Zipperoni   ==> Zapperoni
ZAPsky      ==> ZOPsky
ZoPtOn      ==> ZiPtOn
zipzip      ==> zapzip
zapzopzip   ==> zopzopzip
zoopzaap    ==> ziipzaap
```
## Rules and Notes
* You may use any convenient character encoding for input and output, provided that it supports all ASCII letters and that it was created prior to this challenge.
* You may assume the input word is some variant of Zip, Zap, or Zop. All other inputs result in undefined behavior.
	+ Valid inputs will full-match the regex `Z+(I+|A+|O+)P+.*` (in mixed case)
Happy Golfing!
  
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), ~~69 63 57~~ 54 bytes
```
s=>Buffer(s).map(c=>s|c%4<1?s=c:c+c*90%320%34%24-8)+''
```
[Try it online!](https://tio.run/##ZZBBa8JAEIXv/opcwiaK2moOtjSK3nLaPee2rIlMazNDVgsN/vd0U4aIzoO9fHzsG96n/bHetUCXeYPHqq/z3ufbw7Wuqzbx6eLbUuLyrb@5OPt43fncvbuZm769xOtVeFm8yuabdKZU77DxeK4WZzwldaI6IBVx0jRaLqPO0uRZ2gtJC6nU5kkqCyMkgNFiyVppBUhcyVaJSPKuEI3aEBnFd4UUUAxEVhNVLTag7tVMhLo3/uv3oV8PRHhoLrp58GAgEznyuPM4ciDCCxRZZQ@ZCDXs0YWV1P1LgH/S/wE "JavaScript (Node.js) – Try It Online")
### How?
We process the input string \$s\$ character by character.
We reuse \$s\$ as a flag: as soon as a numeric value is stored in it, we know that we must not update anything else.
To identify `"p"` (112) and `"P"` (80), we use the fact that their ASCII codes are multiples of \$4\$ and the ASCII codes of the other letters at the beginning of the string (`"z"`, `"Z"` and vowels) are not.
To turn a vowel with ASCII code \$c\$ into its counterpart \$n\$ while leaving `z` and `Z` unchanged, we use the following function:
$$n=c+((((90\times c) \bmod 320)\bmod 34)\bmod 24)-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'
```
### Commented
```
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
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~81 ... 61 48~~ 46 bytes
*Saved 2 bytes thanks to [@Grimy](https://codegolf.stackexchange.com/users/6484/grimy)*
Port of my [JS answer](https://codegolf.stackexchange.com/a/180470/58563). Outputs by modifying the input string.
```
f(char*s){for(;*++s%4;*s+=*s*90%320%34%24-8);}
```
[Try it online!](https://tio.run/##lZI/a8MwEMX3fAqhYvCfuCmOhxa3hYyepDltB6HEydFUEpZLqUO@et1zERnkweqBBDq930MPncwPUg43oOTpc7cnj7bbgb49Pg9NLI@iTW1ybnQbV2mW2aisUps9pTZ9uIvWBa4yKsr8PqkuA6iOfAhQcULOC0JGltiXdfFW4cmaFu@b2C4J7cFQ4iqpCDZxd/c0sq@KLsnYIqsV6YXx6c0/aObTW8aD6W3NfRrgis/SQkxw7Bn3@ll8q7WZZMdimnFjOJ3NjlVDPWonKYzZt1oBDUnhtL7Hhtv378AobNT6Bpp3TAUawKidTtF1kAKmCLW@ATa185g10E7re@An9fipNOQRAH/axWX4kc1JHOyQf/0C "C (gcc) – Try It Online")
### Commented
```
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
```
[Answer]
# [Stax](https://github.com/tomtheisen/stax), 19 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
Ç╛√êΣ%,╖FP╚`=Lh←⌡·ƒ
```
[Run and debug it](https://staxlang.xyz/#p=80befb88e4252cb74650c8603d4c681bf5fa9f&i=zip%0AzAp%0AZOP%0AZiiP%0AZZaapp%0AzzzzOoOPppP%0AZipperoni%0AZAPsky%0AZoPtOn%0Azipzip%0Azapzopzip%0Azoopzaap&a=1&m=2)
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 21 bytes
```
iT`Io`A\OIia\oi`^.+?p
```
[Try it online!](https://tio.run/##JYuxCsMwDER3/UegUMgvBE8lkzxkEqFYQwZRsI4kS/3zjprecHc8ePt2WtU@PF6l21JmL2nl2XR1K@/xOaH3ZqCWQMKZxCxKVBEsws4Z@HFg270aScrH50vi@eRK4d66ovn/eWzoFw "Retina 0.8.2 – Try It Online") Transliterates letters up to and including the first `p`, although the `z` and `p` aren't in the transliteration section so aren't affected. The first `O` is quoted because it normally expands to `13567` and the second `o` is quoted because it too is magic; in the first part of the transliteration it expands to the other string. The resulting transliteration is therefore from `IAOIiaoi` to `AOIiaoi` then removing the duplicate source letters results in `IAOiao` to `AOIaoi`.
[Answer]
# C, 43 bytes
```
f(char*s){for(;*++s%4;*s^=*s%16*36%98%22);}
```
[Try it online!](https://tio.run/##lZLNasMwEITveYpFwWA7SUOdElLcFnL0STq7PyCUOFmaSsJyKXXIq9eVi8hBPljdg0Cr@YYdtGJxEKKbohSnz90eHkyzQ3VzfOqqWBx5nZrkXKk6ztPZzER3eWreHlMT3a7T1Tq630RZluSXDmUDHxxlnMB5AtCDYJ5X2Wtub0bX9r2KzRxIi5qAqyQH27SneyeReZFkDn0Llktoufbp7T9o6tMlZcF0WTCfRrziozTnA9z2tJt@FC@V0oPstqiiTGtGRrPbKrDotYMUWu9rJZGEpHBa32PLzPt3YBTaa30DxRoqAw2w1w636LpIAVtktb6BbSrnMWqgnNb3sJ/U2k8lIUMg/mknl@5HVCd@MN3i6xc)
Based on [Arnauld's answer](https://codegolf.stackexchange.com/a/180472/6484). I did a brute-force search to find the shortest formula that turns a => o, o => i, i => a, z => z.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~22~~ 20 bytes
-2 bytes thanks to [Oliver](https://codegolf.stackexchange.com/users/61613/oliver)
```
r"%v+"_d`i¬iao¯`pu}"
```
[Try it online!](https://tio.run/##y0osKPn/v0hJtUxbKT4lIfPQmszE/EPrEwpKa5X@/49WqsosUNJRqnIEkVH@ASAyMxNMRSUmFoDlgMA/3z@goAAiW1CQWpSflwliOwYUZ1eCGPkBJf55ILWZBVADEwuq8mHsfCALaBgu4Vgu3VwA "Japt – Try It Online")
[Answer]
# [R](https://www.r-project.org/), 110 76 bytes
-36 bytes thanks to Krill
This function takes an input of one string.
```
function(a)sub(s<-sub('z+(.+?)p.*','\\1',a,T),chartr('aioAIO','oaiOAI',s),a)
```
[Try it online!](https://tio.run//##Vc69DoIwEADg3adwK5WWxJ3EdHRqByfCcgKGiwl3KTDIy9dSMOotl@9@cueDL3V4zEMzIQ0ZyHG@Z2Op1ySWPCvyi@TiJJSo67NQoG5SNT34yWcCkMzVxhYBWnMVapQKZIidBVnI4xaH1ebflXUfJyLuTqoAOM6nxRiWrGN2W6FC5s7TgOt8Khg3Pl8/2@QmO3wdX9m@SQBeaPdWoMh4br@GrEG3XadbIt1CL2R4Aw "R – Try It Online")
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~41~~ 33 bytes
```
{S:i{.+?p}=$/~~tr/iaoIAO/aoiAOI/}
```
[Try it online!](https://tio.run/##XY@xCoMwEIbn3lNkKNJS0K1DwRbHTAl0y5ZB4WjrHepiRF/dntaK7Q0J3xfycz/n1fM8vloVFSpVY3e/YBefbtyn@2QYmipBTzoziSfMjE76saBKHZ5Y5vVRdbCrfaviqIB@DMjqO2l6VcEzhOzPGQZn7I9z2oJDtD/Oe5FyMm@kI2LJlDFkLLP9ZMpo1BNLDnNeUYlrzsLgMls/2k2YmRgc2caUG40Tg3RZ6yxdhGG6aHmZNS0MQVYLsu76AXHmNw "Perl 6 – Try It Online")
Simple case-insensitive substitution to shift the vowel section.
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~81~~ 78 bytes
```
lambda s,p='iaoIAO':''.join(('aoiAOI'+c)[(p:=p*(ord(c)%4)).find(c)]for c in s)
```
[Try it online!](https://tio.run/##JYs9T8QwEER7/wo3yLscinRAgSKlSJnKqc0hZPJxt3fH7soJRfLngwNTzDyN9HSZL8Ivb5q2sTpt9/j91Uc7PWnlKEpTe1c6V1yFGMBFodo37tDhO2hZ6SNI6qHDh1fEYiTe@WOUZDtLbCfcdv7cOUU@D3B8xtJYTcQzjECsPzMg4raSmrVWE3xrAlGuEKPmL8eLb1X3X3VIwmRC3U63xQRpZ88mu3961FX@SfJm/Rc "Python 3.8 (pre-release) – Try It Online")
# [Python 2](https://docs.python.org/2/), 98 bytes
```
lambda s:''.join(('aoiAOI'+c)[(-~-('p'in s[:i].lower())*'iaoIAO').find(c)]for i,c in enumerate(s))
```
[Try it online!](https://tio.run/##ZY@xTsMwEIb3PIUVBttAI9GxUpAyZnLmlAqZ1CkHre/kpELNwKuHM2kUFW456ft8v/zTpX9Hvx7b/GU82tPb3opuI2X2geCVkhahMKV8aPRWrb5XSpIEL7rtBnbZEb9cUFrfS7BYFkbqrAW/V43etRgEPDaC3zp/Prlge6c6rccoXiMO1h@celrrTSIogO9Fq8DTuefAMR2AUjHPXZ4/i8FSkg7FP2wY16b6g@uyYgyw8AlbGzkvmoMmXiNSzOcxaCoiPpzyeUooI4mBRC6gh3QJvBKWRdV9Xm5STSRssOqNvzEQSRJrLk3nmkzY8MZZTgavhCX/duAO6XIG8Et@AA "Python 2 – Try It Online")
[Answer]
# [Java (JDK)](http://jdk.java.net/), 52 bytes
```
s->{for(int i=0;s[++i]%4>0;)s[i]^=s[i]%16*36%98%22;}
```
[Try it online!](https://tio.run/##bU1ba8IwFH7vrzgIgXorzg3Z7CqIz6MF31o6yGrrjtokJKlDxd@eJW0ZjC2Qc/ku5zvQM50edkeDteBSw8HuQaPxFIxC7w9WNazQyNm/pNKypLWjvOJElYI3igxuHoBoPk5YgNJU23bmuIPacv5WS2T7LAcq92rYSgE2nKmmLuVr8Ulllq@ggsio6epWcekj04DRLFTZeIw5eVrNwqHKMH@PXCUPi9Hjgrw8k/k8vJuwvedsXZCLWf7KAuhC2qYgcmSg@cZuaynpxR@Gva4KaFGUQvut8gfeXpQu64A3OhA2Qlf@gKglEEXYYOKuTYCVX9Dl997efPfcvxtzRWGua2HSODEpoi0ppcJi9sU8ToRwuBCl5AxNuk7U8WJSnuiYOW9rp@LKu4nbbu3f "Java (JDK) – Try It Online")
* Port of Grimy's C answer. Make sure to upvote his answer!
[Answer]
# Perl 5, 31 bytes
```
s/.+?p/$&=~y,iaoIAO,aoiAOI,r/ei
```
[TIO](https://tio.run/##JYuhDgIxEET9fgfBXKEKSUjlqa2uq6jYHOlO2jNXwadTFhgxM3nJQ2nP25zdX5cH/Ol8fx1Osq6BXVYJvLrmi8w5BDQCKHGkJGKVcoYxCytH4MuB0rQKpRD7dlDSuHMlc396xtD/U1vT34pdtPZ5wQc)
[Answer]
# [SNOBOL4 (CSNOBOL4)](http://www.snobol4.org/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
```
[Try it online!](https://tio.run/##Jc4xC8IwEAXgOfkVtyW3ODkJHU6MEFKTo2kHs9WtIEbw/xN76fQeH294v0991fe5NeUjLzPY6@QoWMNfg5CZ4lERTsAwuceeWZNiMKuBwVSjLtkS6iJEQqlTwbtl1F54E147e9RByAtRp3Ask3AV3jon1KNQEvKdRtSs0jLLz4H3Hy7eWivEOTz/ "SNOBOL4 (CSNOBOL4) – Try It Online")
[Answer]
# [Python 2](https://docs.python.org/2/), 84 bytes
```
f=lambda s,r='':s[0]in'pP'and r+s or f(s[1:],r+('aoiAOI'+s[0])['iaoIAO'.find(s[0])])
```
[Try it online!](https://tio.run/##RZCxbsUgDEXn9ivYnCioajtGSqWMTDAHMVClUa32YQvS4eXnUwJJy3TPvbYx8H39pPC678vw7W/vsxdJxgGgT/bZYQA24MMsYpcERbE0yb70TsauAU84agXdUdhaQE9q1PC0YJib4rl2X3IPBpaCflbOSlgLGzJIAZtncFJkHivrkydtDp6UORmxGt5fTpZcmqaJiK85@WjShrmUH6hQFTznMH9ECliHXVCz0aSvewl0UdUls@pQXCyq3oP8/4RDVTdr@gvogprlJbe8cokQq3auf3zgiGGtPwTD8JYLliZTu/8C "Python 2 – Try It Online")
[Answer]
# [C# (Visual C# Interactive Compiler)](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#csc), 60 bytes
```
n=>{for(int i=0;n[i]%4>0;)n[i]^=(char)(n[i++]%16*36%98%22);}
```
Based off of Grimy's C answer.
[Try it online!](https://tio.run/##JUzfS8MwEH7PX9GXssRhmVOGo6ZQxAdBaNGBkNnBkWXuUC4hDcI69rfXq97Dd999P87217bHsbYJPT3YI8RtVx30SLo6H3yUSClDvShpi11@Vy1KNbGdllNUST7m8y6/WV3drvL1fb5cqvIyloKrDuxR/kDMIEPKnql4dbDf@CfaS1W8hW9McvZBM6XOYkolDcXG1zHCSSp@IBPje8TkXpCc7FNE@iwePVlI7LF5GQcMYqiDME0rDCKDAQis8TS@aUOY9BBc9ITC1G3/dRLGt6khwd2/OoTB/zPPm@u/ "C# (Visual C# Interactive Compiler) – Try It Online")
[Answer]
# C/C++ (VC++ compiler) 192bytes
this is a rather naive try but anyway
```
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;}}}}}
```
some slightly more readable Version is this
```
#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;
}
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), 40 bytes
```
$_[$&]=$&.tr"IAOiao","AOIaoi"if/z+.+?p/i
```
[Try it online!](https://tio.run/##XY9BCsIwEEX3OUUJpRu1PUGVLLNK1hGRCAqD0BnaumgOb5zUWFpnkfBeyGd@/7pNMZbXc1ld2rKqx15qZcCj3EtltEeQ8GjCrt6dqIEYA1Dxm7Y9FsGTCOrPGRLO2I1z2goHYDfOe5Z8Eq2kQyTO5DFoLJH9ZvJo0Ik5h@jeYwdLTmbhlB2e0yrMJBYO7Wi6lYbEgrssdXIXZpEuzC@zxswi8GqB110@AMz8RhoBuyEe6AM "Ruby – Try It Online")
[Answer]
# [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/wiki/Commands), 22 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
l'pkIg‚£ć…iaoDÀ‚Du+`‡ì
```
[Try it online](https://tio.run/##MzBNTDJM/f8/R70g2zP9UcOsQ4uPtD9qWJaZmO9yuAHIdynVTnjUsPDwmv//ozILAlKL8vMyAQ) or [verify all test cases](https://tio.run/##MzBNTDJM/V9TVmmvpPCobZKCkn2ly/8c9YLsyvRHDbMOLT7S/qhhWWZivsvhBiDfpVQ74VHDwsNr/uv8r8os4KpyLOCK8g/gisrMBBJRiYkFQDEg8M/3DygoAIkXFKQW5edlckU5BhRnV3JF5QeU@OdxAfWCtScWVOVDWPlAGqgdAA).
Can definitely be golfed a bit more..
Uses the legacy version of 05AB1E instead of the Elixir rewrite, because `+` merges fields in same-length lists, whereas the new version would need a [pair-zip-join `‚øJ`](https://tio.run/##yy9OTMpM/f8/R70g2zP9UcOsQ4uPtD9qWJaZmO9yuAHIdykFEod3eCU8alh4eM3//1GZBQGpRfl5mQA) instead.
**Explanation:**
```
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"]
```
[Answer]
# PHP, 30 bytes
too simple for a TiO:
```
<?=strtr($argn,oiaOIA,iaoIAO);
```
Run as pipe with `-nF`. For PHP 7.2, put the string literals in quotes.
]