发音数字


14

概念

记住数字可能很困难。记住一个单词可能会更容易。为了记住大数字,我创建了一种以类似leetspeak的方式发音的方法。

规则

每个数字首先用其对应的字母替换:

0 => O
1 => I
2 => R
3 => E
4 => A
5 => S
6 => G
7 => T
8 => B
9 => P

替换后,还做了另外两件事以提高发音:

  • 在两个辅音之间U添加a。

  • 在两个元音之间,N添加a。

实例/测试案例

512431 => SIRANENI
834677081 => BENAGUTUTOBI
3141592 => ENINANISUPUR
1234567890 => IRENASUGUTUBUPO
6164817 => GIGABIT

不可能的事

  • 字母和数字混合在同一个单词中
  • 两个连续的辅音或两个连续的元音
  • 不在上面列表中的字母
  • 其他字符

规则

的目标是为此概念创建2路转换器。

  • 您的程序必须首先自己理解字母到数字还是数字到字母的翻译。
  • 它必须检查条目是否正确形成。
  • 如果一切正确,请显示译文。
  • 否则,显示错误消息,不显示任何内容,返回假值或使程序崩溃。

细节

  • 输入数字/字符串可以按照您想要的任何格式输入(stdin,自变量,...)
  • 这是,因此最短的答案会获胜。
  • 禁止出现标准漏洞。

11
GIGATESTER应该GIGATESUTER吗?
kamoroso94

5
通常,我们不要求条目“格式正确”,因为它只是多余的代码,没有充分的理由(有关挑战性建议的详细信息,请参见meta问题)。另外,“正确形成”是什么意思?
Okx

9
如果需要输入验证,则应包括相当数量的无效测试用例输入(尤其是几乎有效的纯字母输入)。我希望这实际上将成为许多语言中挑战的主要部分。
Martin Ender

2
我同意@MartinEnder,您应该为无效案例添加一些测试案例,例如AB23; AEI; BB; Z; ACE; giga; !@#$;-123; 同样,基于验证规则,我们可以转换6164735732 => GIGATESTER,但GIGATESTER由于ST(两个连续的辅音规则)而将导致错误的值。当前设置挑战的方式,挑战的主要部分是验证而不是转换。我对此表示满意,但在这种情况下,验证应该定义得更好。
凯文·克鲁伊森

2
如果程序是字母到数字或数字到字母的翻译,则必须首先自己理解。所以翻译必须是双向的?前面的文本和测试用例仅显示字母数字
Luis Mendo

Answers:


5

JavaScript(ES6),130个字节

两种翻译方式都将输入作为字符串。以字符串形式或false在输入无效的情况下返回转换。

f=(n,k)=>(t=n.replace(/./g,(c,i)=>1/n?(!i|p^(p=27>>c&1)?'':'UN'[p])+s[c]:~(x=s.search(c))?x:'',p=s='OIREASGTBP'),k)?t==k&&n:f(t,n)

演示版


如果效果不理想,请不要发布。
Okx

希望现在能按预期工作。
Arnauld

...或在输入中保留了regexp字符时崩溃。虽然仍然有效
edc65

2

Japt61 59 92 85 84字节

在整个较长的周末中,我一直处于离线状态,如果发现此问题还有其他问题,请让我的Mod删除它,直到可以修复为止。

需要输入为两种操作字符串,并返回两个字符串,以及或false无效input.Assumes号输入将始终包含多个数字,加1个字节替换使用Un<space>,如果这是无效的。返回false测试用例,GIGATESTER但根据规则,该输入应为无效输入。


V="OIREASGTBP"UÉ?¡VgXÃe"%v"²_i1'NÃe"%V"²_i1'UÃ:!Uè"%v%v|%V%V|[^{V}NU]" ©Ur"N|U" £VaX

尝试: 数字->字母字母->数字


  • 感谢obarakon节省了2 4字节,他还说服了我在早些时候放弃它之后再次使用它。我希望他没有!
  • 33 牺牲 26 25(!)个字节来实施快速修复(即尚未完全打高尔夫球)以检查输入的有效性。

说明

(尚未更新为最新版本)

                          :Implicit input of string U.
V="..."                   :Assign the string of letters to variable V, in order.
UÉ                        :Subtract 1 from U, which will give a number (truthy) if the input is a number or NaN (falsey) if the input is a string.
?                         :If it's a number then
¡                         :    Map over the input string, replacing each character (digit) with ...
VgX                       :      the character in string V at index X, the current digit.
à                        :    End mapping.
e                         :    Recursively replace ...
"%v"²                     :      every occurrence of 2 vowels (RegEx) ...
_i1'N                     :      with the current match with an "N" inserted at index 1.
à                        :    End replacement.
e                         :    Another recursive replacement of ...
"%V"²                     :      every occurrence of 2 non-vowel characters (i.e., consonants) ...
_i1'U                     :      with the current match with a "U" inserted at index 1.
à                        :    End replacement.
:                         :Else, if it's a string then
Uè"%v%v|%V%V|[^{V}NU]"    :    Count the number of matches of 2 successive vowels OR 2 successive non-vowels OR any character not in contained in string V plus N & U.
                          :    (The longest part of this code is the fecking input validation!)
?                         :    If that count is greater than 0 then
T                         :       Return 0.
:                              Else
Ur"N|U"                   :        Replace every occurrence of "N" OR "U" in string U with nothing.
£                         :        Map over the string, replacing each character (letter) with ...
VaX                       :         the index of the current character X in string V.
                          :Implicit output of resulting string

似乎AEI
未处理

@Emigna:啊,该死!您会想象,在最初被第一个“ Rule”烧掉之后,我们会想到阅读其余规则!:\我采取了“不可能的事”部分,以表示我们不必处理任何这些要点。很快就解决了。
毛茸茸的

2

Python 3,147字节

lambda c:c in"0134"
def f(n):
 o="";a=b=1-x(n[0])
 for i in n:
  a=x(i)
  if a==b:o+="UN"[a]
  o+="OIREASGTBP"["0123456789".index(i)];b=a
 print(o)

在线尝试!


1

的Java(OpenJDK的8) 416 410 399 382 376 370字节

-2个字节,感谢@Cyoce

@Cyoce的想法多了-17个字节

-6个字节,感谢@KevinCruijssen

s->{String c="[RSGTBP]",v="[OIEA]",o="([256789])",e="([0134])";boolean b=s.matches("(c$|v$|(c|vN)(?=v)|(cU|v)(?=c))+".replace("c",c).replace("v",v));int i=-1;for(s=b?s.replaceAll("[UN]",""):s.matches("[0-9]+")?s.replaceAll(e+"(?="+e+")","$1N").replaceAll(o+"(?="+o+")","$1U"):i/0+"";i<9;s=b?s.replace(v,c):s.replace(c,v)){c=++i+"";v="OIREASGTBP".charAt(i)+"";}return s;}

在线尝试!

replacement,java替换太冗长了。

该函数接受一个字符串,并返回从数字->字母翻译过来的字符串,反之亦然。输入无效时崩溃(您可以在tio示例中看到此错误,该示例在前10个测试用例中输出正确的值,然后在调试视图中显示除以零的错误而崩溃)

取消高尔夫(for循环的第一项和最后一项被抽出以提高可读性)

s-> {
    String c="[RSGTBP]", v="[OIEA]", o="([256789])", e="([0134])"; 
    boolean b=s.matches("(c$|v$|(c|vN)(?=v)|(cU|v)(?=c))+".replace("c",c).replace("v",v)); // lovely regex, explained below
    int i=-1;
    s= b? 
        s.replaceAll("[UN]",""); // remove N's and U's
        :s.matches("[0-9]+")?
        s.replaceAll(e+"(?="+e+")","$1N").replaceAll(o+"(?="+o+")","$1U"); // add N's and U's for separating vowels and consonants
        :i/0+""; // throw an error, looks like a sting for the ternary
    for(;i<9;) { 
        c=++i+"";
        v="OIREASGTBP".charAt(i)+"";
        s=b?s.replace(v,c):s.replace(c,v); // if it started with numbers, go to letters, or vice versa
    }
    return s;
}

用于匹配数字的正则表达式很简单,但这是用于将字母与数字匹配的正则表达式

(c$|v$|(c|vN)(?=v)|(cU|v)(?=c))+
(                             )+   every part of the word is
 c$                                a consonant at the end of the word
   |v$                             or a vowel at the end of the word
      |(c|vN)(?=v)                 or a consonant or a vowel + N followed by a vowel
                  |(cU|v)(?=c)     or a consonant + U or a vowel followed by a consonant


with c = [RSGTBP] and v = [OIEA]

并不是说它可以显着提高大量字节数,但您可以删除括号周围的内容(s)->
Cyoce

@Cyoce每个字节都有帮助
PunPun1000

由于if语句的所有分支都是赋值(返回值),请尝试用条件运算符替换if... else if...,else并在其?:前面加上前缀Object _=以使其成为有效的语句。不知道这是否真的有助于字节计数,但我认为会。
Cyoce

您可以打高尔夫的两件事。您可以删除String t,因为您只能使用一次。因此t.charAt(i)+""变为"OIREASGTBP".charAt(i)+""-4个字节)。您可以将最后一行放在for循环中,i<9;位于for循环内部。因此它变为for(;i<9;s=b?s.replace(v,c):s.replace(c,v)){-1字节)。哦,你可以把s=b?...该之后来到int i=-1;里面的for循环,以及:for(s=b?...;i<9;...-1字节)。
Kevin Cruijssen

1

PHP; 129个127 267 259 228字节

$l=IOREASGTBP;$n=1023456789;ctype_digit($s=$argn)?:$s=preg_replace("#U|N#","",strtr($o=$s,$l,$n));for($r=$c=($t=strtr($s,$n,$l))[$i++];$d=$t[$i++];)$r.=((trim($c,AEIO)xor$x=trim($d,AEIO))?X:UN[!$x]).$c=$d;echo$o?$o==$r?$s:"":$r;

与管道一起运行-nR在线尝试

分解

$l=IOREASGTBP;$n=1023456789;
# if not digits, translate letters to digits and remember original
ctype_digit($s=$argn)?:$s=preg_replace("#U|N#","",strtr($o=$s,$l,$n));
# translate digits to letters:
for($r=$c=($t=strtr($s,$n,$l))                      # result = first letter
    [$i++];$d=$t[$i++];)                            # loop through letters
    $r.=((trim($c,AEIO)xor$x=trim($d,AEIO))?"":UN[!$x]) # append delimiter if needed
        .$c=$d;                                         # append next letter
# 
echo
    $o              # if original was remembered,
        ?$o==$r         # compare original to final result
            ?$s         # if equal, print digits
            :X          # else print X (as error message)
        :$r;        # else print letters

1

爪哇8,312个 308 304 301 294 290字节

s->{String r="",x="([AEIOU])",y="([BGNPRST])",z="0O1I2R3E4A5S6G7T8B9P";for(int c:s.getBytes())r+=c!=78&c!=85?z.charAt((c=z.indexOf(c)+(c<58?1:-1))<0?0:c):"";return s.matches("(("+x+y+")*"+x+"?)|(("+y+x+")*"+y+"?)|\\d*")?r.replaceAll(x+"(?="+x+")","$1N").replaceAll(y+"(?="+y+")","$1U"):"";}

-4个字节(308→304)以进行错误修复(在我修复代码中的错误时,字节数通常不会减少。.:D)

编辑:使用与@ PunPun1000的Java答案不同的方法,首先在字符的for循环中创建return-String,然后使用更抽象的正则表达式在return三进制中对其进行验证(输入要么是全数字,还是给定的元音和辅音交替出现(因此没有任何相邻的元音或辅音)。

说明:

在这里尝试。

s->{                                   // Method with String parameter and String return-type
  String r="",                         //  Result-String
    x="([AEIOU])",y="([BGNPRST])",     //  Two temp Strings for the validation-regex
    z="0O1I2R3E4A5S6G7T8B9P";          //  And a temp-String for the mapping
  for(int c:s.getBytes())              //  Loop over the characters of the input-String
    r+=                                //   Append to the result-String:
       c!=78&c!=85?                    //    If the character is not 'N' nor 'U':
        z.charAt(                      //     Get the character from the temp-String `z`
         (c=z.indexOf(c)+              //      by getting the character before or after the current character
            +(c<58?1:-1))              //      based on whether it's a digit or not
             <0?0:c)                   //      and a 0-check to prevent errors on incorrect input like '!@#'
       :                               //    Else:
        "";                            //     Append nothing
                                       //  End of loop (implicit / single-line body)
  return s.matches("(("+x+y+")*"+x+"?)|(("+y+x+")*"+y+"?)|\\d*")?
                                       //  If the input is valid
                                       //  (Only containing the vowels and consonants of `x` and `y`, without any adjacent ones. Or only containing digits)
    r                                  //   Return the result
     .replaceAll(x+"(?="+x+")","$1N")  //    after we've added 'N's if necessary
     .replaceAll(y+"(?="+y+")","$1U")  //    and 'U's if necessary
   :"";                                //  Or return an Empty String if invalid
}                                      // End of method

验证正则表达式:

(([AEIOU][BGNPRST])*[AEIOU]?)|(([BGNPRST][AEIOU])*[BGNPRST]?)|\\d*


0

241238 235字节

q=OIREASGTBP;[[ $1 == +([0-9]) ]]&&(x=`tr 0-9 $q<<<$1`;m={B,G,P,R,S,T};n={A,E,I,O};for i in `eval echo $m$m$n$n`;{ a=${i::1};b=${i:1:1};x=${x//$a$b/$a'U'$b};a=${i:2:1};b=${i:3:1};x=${x//$a$b/$a'N'$b};};echo $x)||tr $q 0-9<<<$1|tr -d UN

在线尝试!

少打高尔夫球:

q=OIREASGTBP;                          save string in q
[[ $1 == +([0-9]) ]]&&(                if argument 1 is only digits
x=`tr 0-9 $q<<<$1`;                    save in x each digit translated to corresponding letter
m={B,G,P,R,S,T};
n={A,E,I,O};
for i in `eval echo $m$m$n$n`;{        generates all combinations of vowels and consonants
                                       BBAA BBAE ... TTOI TTOO
   a=${i::1};                          saves first consonant in a
   b=${i:1:1};                         saves second consonant in b
   x=${x//$a$b/$a'U'$b};               insets U between consonants
   a=${i:2:1};                         saves first vowel in a
   b=${i:3:1};                         saves second vowel in b
   x=${x//$a$b/$a'N'$b};               inserts N between vowels
};
echo $x                               echoes result
)||                                   if argument contains letters
  tr $q 0-9<<<$1|tr -d UN             translates letter to corresponding number and deletes U and N

0

PHP,268字节

$v=OIEA;$l=RSGTBP;$d="0134256789";$c=ctype_digit;$p=preg_replace;echo!$c($a=$argn)?$c($e=strtr($p(["#\d|[$v]{2,}|[$l]{2,}#","#[$v]\KN(?=[$v])#","#[$l]\KU(?=[$l])#"],[_,"",""],$a),$v.$l,$d))?$e:_:$p(["#[$v](?=[$v])#","#[$l](?=[$l])#"],["$0N","$0U"],strtr($a,$d,$v.$l));

在线尝试!


0

Perl,127个字节

126个字节+ 1个字节的命令行

$i="AEIOU]";$;=OIREASGTBP;1/!/[^$;NU\d]|[$i{2}|[^\d$i{2}/;eval"y/0-9$;NU/$;0-9/d";s/[$i\K(?=[$i)/N/g;s/[^N\d$i\K(?=[^\d$i)/U/g

用法:

 echo -n "512431" | perl -p entry.pl

应该遵循所有挑战规则-可以接受字母或数字,并且如果验证失败,则会出错(除以零)


验证对输入NO和的误判US
价值墨水

0

红宝石 205 + 1 = 206字节

使用-p+1字节的标志。现在具有详尽的输入验证系统。

d,w=%w"0-9 OIREASGTBP"
~/^\d+$/?($_.tr!d,w
gsub /([#{a='AEIO])(?=\g<1>)'}/,'\0N'
gsub /([^#{a}/,'\0U'):(+~/^(([AEIO])(N(?=[AEIO])|(?=\g<4>)|$)|([RSGTBP])(U(?=\g<4>)|(?=\g<2>|$)))+$/;$_.tr!("NU","").tr!w,d)

在线尝试!


这似乎没有将字母转换为数字,也没有进行任何验证!
Jarmex

@Jarmex哎呀,添加了验证!这是一个巨大的验证检查,但我没有太多选择
Value Ink

0

Python 3,741字节

from functools import reduce;c=0;e="";n="NU";v="AEIOU";l="OIREASGTBPNU";x=('0','O'),('1','I'),('2','R'),('3','E'),('4','A'),('5','S'),('6','G'),('7','T'),('8','B'),('9','P');s=input()
try:
    int(s);y=reduce(lambda a,kv:a.replace(*kv),x,s)
    for i in y:
        e+=i
        if i in v:
            z=True
            try:
                if y[c+1] in v:e+="N"
            except:
                pass
        else:
            z=False
            try: 
                if not y[c+1] in v:e+="U"
            except:
                pass
        c+=1
except:
    for i in s:
        if not i in l:
            p
    y=reduce(lambda a,kv:a.replace(*kv[::-1]),x,s)
    for i in y: 
        if not i in n:e+=i
print(e)

在线尝试!

我知道还有很多改进的余地。


0

sed,123字节

s/[0134]/_&_/g
s/[25-9]/=&=/g
ta
y/OIREASGTBPU/0123456789N/
s/N//g
q
:a
s/__/N/g
s/==/U/g
y/0123456789_/OIREASGTBP=/
s/=//g

说明

首先,我们用 _(用于元音)或=(对于辅音)。

如果我们不进行任何替换,我们会将字母转换为数字,所以这是一个简单的替换,然后删除 UN。然后退出。

否则,我们分支到label a,在这里我们处理连续的元音,然后处理连续的辅音。然后将数字转换为字母,并删除我们在第一步中引入的标记字符。


0

Python3,246个字节

v=lambda x:x in"AEIO"
V="OIREASGTBP"
i=input()
r=__import__("functools").reduce
print(r(lambda x,y:x+(("U",""),("","N"))[v(x[-1])][v(y)]+y,map(lambda x:V[x],map(int,i)))if i.isdigit()else r(lambda x,y:x*10+V.index(y),filter(lambda x:x in V,i),0))    

说明:

  • 将输入映射到int列表
  • 将int映射到其在字母表中的位置
  • 通过添加累加器以及字典元素来减少列表元组的元素以及当前元素来
    • 字典元组是基于两个元素,作为元音或不是一个真值表

0

JavaScript(ES6),120

将输入作为字符串的函数。如果输入有效,则返回正确翻译的字符串,否则返回false或函数崩溃。

n=>(t=n=>n.replace(/./g,d=>1/d?(v-(v=d<5&d!=2)?'':'UN'[v])+z[d]:~(a=z.search(d))?a:'',v=2,z='OIREASGTBP'))(q=t(n))==n&&q

少打高尔夫球

n => 
{
  var t = n => { // function to translate, no check for invalid input
    var v = 2; // 1 = digit map to vowel, 0 = digit map to consonant, start with 2
    var z = 'OIREASGTBP'; // digits mapping
    return n.replace(/./g,
      d => 1/d // digit / alpha check
        ? ( // if digit
            w = v, // save previous value of v
            v = d < 5 & d != 2, // check if current digit will map to wovel or consonant
            (w != v 
             ? '' // if different - wovel+consonant or consonant+wovel or start of input
             : 'UN'[v] // if equal, insert required separator
            ) + z[d] // add digit translation
          )
        : ( // if alpha
             a = z.search(d), // look for original digit. Could crash if d is a reserved regexp char (not valid input)
             a != -1 ? a : '' // if digit found add to output, else do nothing
          )
    )
  }

  var q = t(n); // translate input an put in q
  if (t(q) == n) // translate again, result must be == to original input
    return q; // if ok return result
  else
    return false; // else return false
}

测试

var F=
n=>(t=n=>n.replace(/./g,d=>1/d?(v-(v=d<5&d!=2)?'':'UN'[v])+z[d]:~(a=z.search(d))?a:'',v=2,z='OIREASGTBP'))(q=t(n))==n&&q

;`512431 => SIRANENI
834677081 => BENAGUTUTOBI
3141592 => ENINANISUPUR
1234567890 => IRENASUGUTUBUPO
6164817 => GIGABIT`
.split('\n')
.forEach(x => {
  var [a,b] = x.match(/\w+/g)
  var ta = F(a)
  var tb = F(b)
  console.log(a==tb ? 'OK':'KO', a + ' => '+ ta)
  console.log(b==ta ? 'OK':'KO', b + ' => '+ tb)
})

function go() {
  O.textContent = F(I.value)
}

go()
<input id=I value='NUNS' oninput='go()'>
<pre id=O></pre>

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.