Mainkan Zip, Zap, Zop

22

Ada sedikit permainan pemanasan improvisasi di mana Anda mengatur diri Anda dalam lingkaran dan mengirim ritsleting, zaps, dan zops dengan menunjuk ke seseorang dan mengucapkan kata berikutnya dalam urutan, kemudian mereka melakukan hal yang sama sampai Anda semua melakukan pemanasan atau terserah.

Tugas Anda adalah membuat program yang memberikan kata berikutnya dalam urutan yang diberikan kata input. (Zip -> Zap -> Zop -> Zip) Karena ada banyak cara berbeda untuk mengatakan tiga kata dan kata-kata yang dapat ditambahkan ini, program Anda harus meniru duplikasi huruf dan huruf serta membawa sufiks.

Untuk menguraikan, input Anda akan menjadi satu atau lebih Zs, kemudian satu atau lebih Is, As, atau Os (semua huruf yang sama), lalu satu atau lebih Ps, (semua huruf hingga titik ini mungkin dalam kasus campuran) diikuti oleh beberapa akhiran yang berubah-ubah (yang mungkin kosong). Anda harus membiarkan run Zs dan Ps, serta sufiks persis seperti yang diterima, tetapi kemudian mengubah Is ke As, As ke Os, atau Os ke Is, menjaga case pada setiap langkah.

Contoh Kasus Uji

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

Aturan dan Catatan

  • Anda dapat menggunakan pengkodean karakter yang mudah untuk input dan output, asalkan mendukung semua huruf ASCII dan dibuat sebelum tantangan ini.
  • Anda dapat menganggap kata input adalah beberapa varian Zip, Zap, atau Zop. Semua input lainnya menghasilkan perilaku yang tidak terdefinisi.
    • Input yang valid akan sepenuhnya cocok dengan regex Z+(I+|A+|O+)P+.*(dalam kasus campuran)

Selamat Golf!

Beefster
sumber
2
ziop -> apa fungsinya?
Joshua
2
@ Yosua Ini tidak valid sesuai dengan deskripsi (lihat "semua huruf yang sama" ).
Arnauld
1
@Arnauld: Dan test case untuk zoopzaap tidak setuju dengan deskripsi.
Joshua
4
@ Yosua Kenapa? Ini hanya berlaku untuk vokal antara zyang pertama dan yang pertama p. Akhiran bisa berisi apa saja.
Arnauld

Jawaban:

9

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

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

Cobalah online!

Bagaimana?

s karakter demi karakter.

s sebagai bendera: segera setelah nilai numerik disimpan di dalamnya, kita tahu bahwa kita tidak harus memperbarui apa pun.

"p""P"4"z""Z" dan vokal) tidak.

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'

Berkomentar

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
sumber
Bagaimana Anda menemukan fungsi itu?
Thomas Hirsch
2
@ThomasHirsch Ditemukan dengan fungsi pencarian brute-force. Langkah pertama (multiplikasi + modulo 1) memastikan bahwa parameter memberikan hasil yang identik untuk huruf kecil dan besar. Langkah ke-2 (2 modulos berikutnya dan pengurangan) memeriksa apakah nilai delta yang benar dapat diperoleh dari sana.
Arnauld
6

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

Disimpan 2 byte berkat @Grimy

Port jawaban JS saya . Output dengan memodifikasi string input.

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

Cobalah online!

Berkomentar

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
sumber
-2 byte
Grimmy
@Grimy Tangkapan bagus, terima kasih! (Saya memang mencoba *++s%4di beberapa titik tetapi mengabaikan optimasi yang dihasilkan ...)
Arnauld
1
Selanjutnya -3 byte . Yang ini juga harus berlaku untuk jawaban JS Anda.
Grimmy
@ Grimy Ini cukup berbeda dari saya, jadi Anda mungkin ingin memposting ini sebagai jawaban terpisah.
Arnauld
5

Retina 0.8.2 , 21 byte

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

Cobalah online! Menerjemahkan surat hingga dan termasuk yang pertama p, meskipun zdan ptidak ada di bagian transliterasi sehingga tidak terpengaruh. Yang pertama Odikutip karena biasanya mengembang 13567dan yang kedua odikutip karena itu juga sihir; di bagian pertama transliterasi ia meluas ke string lain. Oleh karena itu transliterasi yang dihasilkan dari IAOIiaoiuntuk AOIiaoikemudian menghapus duplikat sumber surat IAOiaoke AOIaoi.

Neil
sumber
4

C, 43 byte

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

Cobalah online!

Berdasarkan jawaban Arnauld . Saya melakukan pencarian brute-force untuk menemukan rumus terpendek yang mengubah a => o, o => i, i => a, z => z.

Grimmy
sumber
3

Japt , 22 20 byte

-2 byte terima kasih kepada Oliver

r"%v+"_d`i¬iao¯`pu}"

Cobalah online!

Khusus ASCII
sumber
3

R , 110 76 byte

-36 bytes terima kasih kepada Krill

Fungsi ini mengambil input dari satu string.

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

Cobalah online!

CT Hall
sumber
1
Mengumpulkan string dari potongan-potongan dalam R cenderung sangat panjang ... Tetapi Anda menyimpan banyak byte dengan terlebih dahulu mengekstraksi substring syang akan kami terjemahkan, dan kemudian menggantinya dengan salinan terjemahan: 76 byte
Kirill L.
@ KirillL., Ah itu trik pintar yang saya coba temukan.
CT Hall
2

Perl 6 , 41 33 byte

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

Cobalah online!

Substitusi case-insensitive sederhana untuk menggeser bagian vokal.

Jo King
sumber
1

Perl 5, 31 byte

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

TIO

Nahuel Fouilleul
sumber
1

SNOBOL4 (CSNOBOL4) , 183 byte

	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

Cobalah online!

Giuseppe
sumber
1

C # (Visual C # Interactive Compiler) , 60 byte

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

Didasarkan atas jawaban Grimy C.

Cobalah online!

Perwujudan Ketidaktahuan
sumber
1
Sayangnya ini tidak berfungsi karena menggantikan vokal di sufiks juga.
Emigna
Sebagai @Emigna menyatakan di atas, ini menggantikan semua- aoivokal, bukan hanya yang sebelum p/ pertama P. Namun satu hal untuk golf: ("iao".IndexOf((char)(c|32))+1)%4bisa-~"iao".IndexOf((char)(c|32))%4
Kevin Cruijssen
1

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

ini adalah upaya yang agak naif tetapi tetap

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

beberapa Versi yang sedikit lebih mudah dibaca adalah ini

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

Ruby , 40 byte

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

Cobalah online!

Kirill L.
sumber
0

05AB1E (warisan) , 22 byte

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

Cobalah secara online atau verifikasi semua kasus uji .

Pasti bisa bermain golf sedikit lebih ..

Menggunakan versi lawas 05AB1E alih-alih penulisan ulang Elixir, karena +menggabungkan bidang dalam daftar dengan panjang yang sama, sedangkan versi baru akan membutuhkan pair-zip-join‚øJ sebagai gantinya.

Penjelasan:

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

PHP, 30 byte

terlalu sederhana untuk TiO:

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

Jalankan sebagai pipa dengan -nF. Untuk PHP 7.2, masukkan string literal ke dalam tanda kutip.

Titus
sumber
Ini mentransliterasikan semua oiavokal bukan hanya yang sebelum p/ P, bukan?
Kevin Cruijssen