Pronuncie números


14

Conceito

Lembrar números pode ser difícil. Lembrar uma palavra pode ser mais fácil. Para memorizar grandes números, criei uma maneira de pronunciá-los de maneira semelhante ao leetspeak.

Regras

Cada dígito é substituído primeiro pela sua letra correspondente:

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

Após a substituição, duas coisas adicionais são feitas para melhorar a pronúncia:

  • Entre duas consoantes, a Ué adicionado.

  • Entre duas vogais, a Né adicionado.

Exemplos / casos de teste

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

O que é impossível

  • Letras e números misturados na mesma palavra
  • Duas consoantes sucessivas ou duas vogais sucessivas
  • Letras que não estão na lista acima
  • Outros personagens

Regras

O objetivo deste é criar um tradutor bidirecional para esse conceito.

  • Seu programa deve primeiro entender por si mesmo se é tradução de letra para número ou número para letra.
  • Ele deve verificar se a entrada é formada corretamente.
  • Se tudo estiver correto, exiba a tradução.
  • Senão, exiba uma mensagem de erro, nada, retorne um valor falsey ou trava o programa.

Detalhes

  • O número / string de entrada pode ser inserido no formato que você desejar (stdin, argumento, ...)
  • Isso é , então a resposta mais curta vence.
  • As brechas padrão são proibidas.

11
Não deveria GIGATESTERser GIGATESUTER?
precisa saber é o seguinte

5
Geralmente, não solicitamos que a entrada seja 'adequadamente formada', pois é apenas um código extra sem uma boa razão (consulte a meta questão para obter boas recomendações de desafios). Além disso, o que significa 'adequadamente formado'?
Okx

9
Se a validação de entrada for necessária, você deve incluir um lote decente de casos de teste de entradas inválidas (especialmente entradas somente de letra que são quase válidas). Espero que essa seja realmente a parte principal do desafio em muitos idiomas.
Martin Ender

2
Concordo com o @MartinEnder que você deve adicionar alguns casos de teste para casos inválidos, como AB23; AEI; BB; Z; ACE; giga; !@#$; -123; etc. Além disso, com base nas regras de validação, podemos converter 6164735732 => GIGATESTER, mas GIGATESTERresultará em um valor falso, devido a ST(regra de duas consoantes sucessivas). Da maneira como seu desafio está configurado atualmente, a parte principal do desafio é a validação, em vez da conversão. Estou bem com isso, mas a validação deve ser definida um pouco melhor nesse caso.
Kevin Cruijssen

2
Seu programa deve primeiro compreender por si mesmo se é tradução de letra para número ou número para letra. Então a tradução tem que ser de mão dupla? O texto anterior e os casos de teste sugerem apenas número para letra
Luis Mendo

Respostas:


5

JavaScript (ES6), 130 bytes

Recebe entrada como uma string nas duas formas de conversão. Retorna a tradução como uma sequência ou falseno caso de uma entrada inválida.

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)

Demo


Se não funcionar perfeitamente, não o publique.
Okx 02/06/19

Espero que agora esteja funcionando como esperado.
Arnauld

... ou trava quando há caracteres de regexp reservados na entrada. Ainda válido embora
edc65

2

Japt , 61 59 92 85 84 bytes

Estou offline durante a maior parte do fim de semana (longo), se mais problemas forem descobertos com isso, peça a um mod para excluí-lo para mim até que eu possa corrigi-lo.

Recebe a entrada como uma sequência de caracteres para ambas as operações e retorna uma sequência de caracteres para falseentradas inválidas ou inválidas. Assume que as entradas numéricas sempre conterão vários dígitos, adicione 1 byte substituindo por Un<space>se isso não for válido. Retorna falsepara o caso de teste, GIGATESTERmas, de acordo com as regras, essa entrada deve ser inválida.


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

Experimente: Números -> Letras ou Letras -> Números


  • 2 4 bytes salvos, obrigado a obarakon , que também me convenceu a retomar isso depois que o abandonei anteriormente. Eu gostaria que ele não tivesse!
  • 33 26 25 bytes (!) Sacrificados implementando uma correção rápida (isto é, ainda não foi totalmente aproveitada) para verificar a validade da entrada.

Explicação

(Ainda a ser atualizado para a versão mais recente)

                          :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

Não parece manipular a entrada inválido, comoAEI
Emigna

@Emigna: Ah, droga! Você imagina que, depois de ter sido queimado pela primeira "regra" inicialmente, teríamos pensado em ler o restante das regras! : \ Peguei a seção "O que é impossível" para sugerir que não precisaríamos lidar com nenhum desses pontos. Fix em breve.
Shaggy


1

Java (OpenJDK 8) , 416 410 399 382 376 370 bytes

-2 bytes graças a @Cyoce

-17 mais bytes graças a uma ideia de @Cyoce

-6 bytes graças a @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;}

Experimente online!

Ugh, a substituição de java é tão detalhada.

Função que pega uma string e retorna a string traduzida do número -> letra ou vice-versa. Falha na entrada inválida (você pode ver isso no exemplo tio, em que ele gera os valores corretos para os 10 primeiros casos de teste e trava com um erro de divisão por zero, que é exibido na exibição de depuração)

Ungolfed (o primeiro e o último termo do loop for são extraídos para facilitar a leitura)

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

A regex para correspondência dos números é simples, mas aqui está a regex para correspondência das letras com os números

(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]

Não que isso melhore significativamente sua contagem maciça de bytes, mas você pode remover os parênteses ao redor(s)->
Cyoce

@Cyoce every byte ajuda
PunPun1000

Como todas as suas ramificações da ifinstrução são atribuições (que retornam um valor), tente substituir o if... else if... elsepelo operador condicional ?:, precedendo-o por Object _=para torná-lo uma instrução válida. Não tenho certeza se isso realmente ajudaria a contagem de bytes, mas acho que sim.
Cyoce 2/17

Duas pequenas coisas que você pode jogar golfe. Você pode remover a String t, porque você a usa apenas uma vez. Então t.charAt(i)+""se torna "OIREASGTBP".charAt(i)+""( -4 bytes ). E você pode colocar a última linha dentro do loop for após a i<9;declaração dentro do loop for. Assim, torna-se for(;i<9;s=b?s.replace(v,c):s.replace(c,v)){( -1 byte ). Ah, e você também pode colocar o s=b?...que vem logo após o int i=-1;loop for: for(s=b?...;i<9;...( -1 byte ).
Kevin Cruijssen

1

PHP; 129 127 267 259 228 bytes

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

Execute como pipe -nRou experimente online .

demolir

$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

Java 8, 312 308 304 301 294 290 bytes

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 bytes (308 → 304) para uma correção de bug (não ocorre frequentemente que a contagem de bytes diminui quando eu corrigo um bug no meu código ..: D)

EDIT: usa uma abordagem diferente da da resposta Java @ PunPun1000, primeiro criando a String de retorno em um loop for sobre os caracteres e, em seguida, usa uma regex mais abstrata para validá-la no ternário de retorno (a entrada tem todos os dígitos, ou as vogais e consoantes fornecidas são alternadas (portanto, sem vogais nem consoantes adjacentes).

Explicação:

Experimente aqui.

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

A regex de validação:

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

0

05AB1E , 76 bytes

.•.Ÿ^91Ý•Ul„nuSKDXSKg0QVvXyk}JYP©0Êi®}¤«SXuèŒ2ùv…U NSy0èìžMuyåOè})Jᨹd_iQ®P

Experimente online!

Retorna o valor falso 0para entrada inválida.


0

Bater ,241 238 235 bytes

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

Experimente online!

Menos golfe:

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 bytes

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

Experimente online!


0

Perl, 127 bytes

126 bytes + linha de comando de 1 byte

$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

Uso:

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

Deve seguir todas as regras do desafio - pode aceitar letras ou números e cometerá um erro (divisão por zero) se a validação falhar


A validação possui falsos positivos na entrada NOe US.
Value Ink

0

Ruby , 205 + 1 = 206 bytes

Usa o -psinalizador para +1 byte. Agora, com um sistema exaustivo de validação de entrada.

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)

Experimente online!


Isso não parece converter letras em números, nem faz nenhuma validação!
Jarmex

@Jarmex oops, validação adicionada! É uma verificação de validação enorme, mas eu não tenho muita escolha na matéria
Valor de tinta

0

Python 3, 741 bytes

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)

Experimente online!

Há muito espaço para melhorias, eu sei.


0

sed, 123 bytes

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

Explicação

Primeiro, envolvemos dígitos com _(para vogais) ou= (para consoantes).

Se não fizemos nenhuma substituição, estamos convertendo letras em dígitos, portanto é uma substituição simples e exclua UeN . Então saia.

Caso contrário, passamos a rotular a, onde lidamos com vogais consecutivas e depois consoantes consecutivas. Transforme os dígitos em letras e exclua os caracteres do marcador que introduzimos na primeira etapa.


0

Python3, 246 bytes

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

explicação:

  • mapeie a entrada para uma lista de int
  • mapear a lista de int para sua posição no alfabeto
  • reduzir lista adicionando acumulador, além de um elemento de um dict tupla de , além do elemento atual
    • a tupla de ditado é uma tabela verdade baseada em dois elementos, sendo vogal ou não

0

JavaScript (ES6), 120

Uma função que recebe entrada como uma string. Retorna a string traduzida corretamente se a entrada for válida, caso contrário, false ou se a função travar.

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

Menos golfe

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
}

Teste

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>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.