Zip、Zap、Zopを再生する


22

少し即興のウォームアップゲームがあります。サークルに自分自身を配置し、ジップ、ザップ、およびゾップを人に向けて順番に次の単語を言うことで送信します。なんでも。

あなたの仕事は、入力単語を与えられた順番で次の単語を与えるプログラムを作成することです。(Zip-> Zap-> Zop-> Zip)これらの3つの単語とフレアを追加するさまざまな言い方があるため、プログラムは大文字と小文字の重複を模倣し、接尾辞を付ける必要があります。

詳しく説明すると、入力は1つ以上Zのs、1つ以上Iのs、As、またはOs(すべて同じ文字)、1つ以上Pのs(この時点までのすべての文字が大文字と小文字が混在する場合があります)に続きます任意のサフィックス(空の場合もあります)。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
@ジョシュアなんで?これは、先頭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バイト

@Grimyのおかげで2バイト節約

私の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ある時点で試してみましたが、結果の最適化を見落としていました...)
Arnauld

1
さらに-3バイト。これは、JSの回答にも適用できるはずです。
グリムミー

@Grimyそれは私のものとは十分に異なるため、これを別の回答として投稿することをお勧めします。
アーナウルド


5

Retina 0.8.2、21バイト

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

オンラインでお試しください!最初とを含む文字を音訳しpますが、zpは音訳セクションにないため、影響を受けません。O通常はに展開されるため、最初の部分が引用され13567、2番目の部分oも魔法であるため引用されます。文字変換の最初の部分では、他の文字列に展開されます。したがって、結果の音訳はfromからIAOIiaoitoにAOIiaoiなり、重複するソース文字を削除するとIAOiaotoになりAOIaoiます。




3

R110 76バイト

Krillのおかげで-36バイト

この関数は、1つの文字列の入力を受け取ります。

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

オンラインでお試しください!


1
Rの断片から文字列を収集することは非常に長くなる傾向があります...しかし、まずs翻訳するサブ文字列を抽出し、それを翻訳されたコピーに置き換えることで多くのバイトを節約できます
。76

@KirillL。、ああ、それは私が見つけようとしていた巧妙なトリックです。
CTホール







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

GrimyのC回答に基づいています。

オンラインでお試しください!


1
残念ながら、接尾辞の母音も置き換えるため、これは機能しません。
エミグナ

@Emignaが上記で述べているように、これはaoi最初のp/の前だけではなく、すべての- 母音を置き換えますP。しかし、ゴルフに一つのこと:("iao".IndexOf((char)(c|32))+1)%4することができ-~"iao".IndexOf((char)(c|32))%4
ケビンCruijssen

1

C / C ++(VC ++コンパイラ)192bytes

これはかなり単純な試みですが、とにかく

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




0

05AB1E(レガシー)、22 バイト

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

オンラインそれを試してみたり、すべてのテストケースを確認してください

間違いなくもう少しゴルフができます。

+同じバージョンのリストのフィールドをマージするため、Elixirの書き換えの代わりに05AB1Eのレガシーバージョンを使用しますが、新しいバージョンではペアの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しますか?
ケビンクルーッセン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.