播放Zip,Zap,Zop


22

有一个临时改进的热身游戏,您可以将自己排列成一个圆圈,并通过指向一个人并说出序列中的下一个单词来发送拉链,快速键和快速键,然后他们进行相同的操作,直到所有人热身或随你。

您的任务是创建一个程序,该程序在给定输入单词的情况下按顺序给出下一个单词。(Zip-> Zap-> Zop-> Zip)由于可以使用多种不同的方式来表达这三个单词和风格,因此程序应模仿大小写和字母重复并带有后缀。

详细地说,您输入的内容将是一个或多个Zs,然后是一个或多个Is,As或Os(都相同的字母),然后是一个或多个Ps(到目前为止所有字母都可能是混合大小写),然后是一些任意的后缀(可能为空)。您应该完全保留Zs和Ps的行程以及后缀,但应将s 更改为Is,将As 更改AOs,或将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
齐奥普->这是做什么的?
约书亚州

2
@Joshua根据说明,这是无效的(请参阅“所有相同的字母”)。
Arnauld

1
@Arnauld:Zoopzaap的测试用例与描述不同。
约书亚州

4
@约书亚为什么?这仅适用于领先的元音z的和第一p。后缀可以包含任何内容。
Arnauld,

Answers:


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码的倍数4,并在字符串的开头其他字母的ASCII码("z""Z"和元音)都没有。

要将ASCII码为c的元音保留为nzZ保持不变,我们使用以下函数:

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

您是如何提出该功能的?
Thomas Hirsch

2
@ThomasHirsch发现它具有蛮力搜索功能。第一步(乘法+第一个模)确保小写和大写参数的结果相同。第二步(接下来的2个模和减法)检查是否可以从那里获得正确的增量值。
Arnauld

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答案。
Grimmy

@Grimy它与我的区别足够大,因此您可能需要将此作为单独的答案发布。
Arnauld


5

视网膜0.8.2,21字节

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

在线尝试!音译直到第一个字母(包括第一个字母)p,尽管zp不在音译部分,因此不受影响。第一个O被引用是因为它通常扩展到13567,第二个o被引用是因为它也是魔术;在音译的第一部分中,它会扩展到另一个字符串。因此,产生的音译是从IAOIiaoi到,AOIiaoi然后删除重复的原始字母导致IAOiaoAOIaoi




3

R110 76字节

-36字节归功于Krill

此函数需要输入一个字符串。

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

在线尝试!


1
从R中的片段中收集字符串通常会很长...但是,通过首先提取一个s我们将要翻译的子字符串,然后将其替换为翻译后的副本,您可以节省很多字节:76个字节
Kirill L.

@KirillL。,啊,那是我想要找到的聪明技巧。
CT厅







1

C#(Visual C#交互式编译器),60字节

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

基于Grimy的C答案。

在线尝试!


1
不幸的是,这无法正常工作,因为它也替换了后缀中的元音。
Emigna

如上述@Emigna所述,这将替换所有- aoi元音,而不是仅替换第一个p/ 之前的那些P。但是,打高尔夫球的一件事是:("iao".IndexOf((char)(c|32))+1)%4可以-~"iao".IndexOf((char)(c|32))%4
Kevin 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;
}

蒂奥:tio.run/...
DER德尔

蒂奥golfed:tio.run/...
DER德尔


0

05AB1E(旧版),22 字节

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

在线尝试验证所有测试用例

绝对可以打更多的高尔夫球..

使用05AB1E的旧版本而不是Elixir重写,因为+合并了相同长度列表中的字段,而新版本则需要使用pair-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,不是吗?
Kevin Cruijssen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.