Pronuncia i numeri


14

Concetto

Ricordare i numeri può essere difficile. Ricordare una parola può essere più semplice. Al fine di memorizzare grandi numeri, ho creato un modo per pronunciarli in un modo simile al leetspeak.

Regole

Ogni cifra viene prima sostituita dalla lettera corrispondente:

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

Dopo la sostituzione, vengono fatte altre due cose per migliorare la pronuncia:

  • Tra due consonanti, Uviene aggiunta una.

  • Tra due vocali, Nviene aggiunta una.

Esempi / casi di test

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

Cosa è impossibile

  • Lettere e numeri mescolati nella stessa parola
  • Due consonanti successive o due vocali successive
  • Lettere che non figurano nell'elenco sopra
  • Altri caratteri

Regole

L'obiettivo di questo è quello di creare un traduttore a 2 vie per questo concetto.

  • Il tuo programma deve prima capire da solo se è una traduzione da lettera a numero o da numero a lettera.
  • Deve verificare che la voce sia correttamente formata.
  • Se tutto è corretto, visualizza la traduzione.
  • Altrimenti, visualizza un messaggio di errore, niente, restituisce un valore false o arresta in modo anomalo il programma.

Dettagli

  • Il numero / stringa di input può essere inserito in qualsiasi formato desiderato (stdin, argomento, ...)
  • Questo è , quindi vince la risposta più breve.
  • Sono vietate le scappatoie standard.

11
Non dovrebbe GIGATESTERessere GIGATESUTER?
kamoroso94,

5
Di solito, non chiediamo che la voce sia "correttamente formata", in quanto è solo un codice aggiuntivo senza una buona ragione (vedi la meta domanda per buoni consigli sulle sfide). Inoltre, cosa significa "formato correttamente"?
Okx,

9
Se è richiesta la convalida dell'input, è necessario includere un batch decente di casi di test di input non validi (in particolare input di sola lettera che sono quasi validi). Mi aspetto che questa sarà la parte principale della sfida in molte lingue.
Martin Ender,

2
Sono d'accordo con @MartinEnder che è necessario aggiungere alcuni casi di test per casi non validi, come AB23; AEI; BB; Z; ACE; giga; !@#$; -123; ecc. Inoltre, in base alle regole di convalida, possiamo convertire 6164735732 => GIGATESTER, ma GIGATESTERrisulterà in un valore falso, a causa di ST(regola delle due consonanti successive). Il modo in cui la sfida è attualmente impostata, la parte principale della sfida è la convalida, anziché la conversione. Sto bene, ma la validazione dovrebbe essere definita un po 'meglio in quel caso.
Kevin Cruijssen,

2
Il tuo programma deve prima capire da solo se è una traduzione da lettera a numero o da numero a lettera. Quindi la traduzione deve essere bidirezionale? Il testo precedente e i casi di test suggeriscono solo un numero alla lettera
Luis Mendo,

Risposte:


5

JavaScript (ES6), 130 byte

Accetta l'input come stringa in entrambi i modi di traduzione. Restituisce la traduzione come stringa o falsein caso di input non valido.

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)

dimostrazione


Se non funziona perfettamente, non pubblicarlo.
Okx,

Spero che ora funzioni come previsto.
Arnauld,

... o crash quando ci sono caratteri regexp riservati nell'input. Ancora valido però
edc65

2

Japt , 61 59 92 85 84 byte

Sono offline per la maggior parte del (lungo) fine settimana, se vengono rilevati altri problemi con questo, chiedi a una mod di eliminarlo per me fino a quando posso risolverlo.

Prende l'input come stringa per entrambe le operazioni e restituisce una stringa per entrambi o falseper input non valido. Supponiamo che gli input numerici contengano sempre più cifre, aggiungere 1 byte sostituendo con Un<space>se non valido. Restituisce falseper il test case GIGATESTERma, secondo le regole, dovrebbe essere un input non valido.


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

Prova: numeri -> lettere o lettere -> numeri


  • 2 4 byte salvati grazie a obarakon , che mi ha anche convinto a riprenderlo dopo averlo abbandonato prima. Vorrei che non lo avesse fatto!
  • 33 26 25 (!) Byte sacrificati implementando una correzione rapida (cioè, ancora da golfare completamente) per verificare la validità dell'input.

Spiegazione

(Ancora da aggiornare all'ultima versione)

                          :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

Non sembra gestire input non validi comeAEI
Emigna,

@Emigna: Ah, dannazione! Immagineresti che, dopo essere stati bruciati dalla prima "Regola" inizialmente, avremmo pensato di leggere il resto delle regole! : \ Ho preso la sezione "Cosa è impossibile" per implicare che non avremmo dovuto gestire nessuno di questi punti.
Shaggy,

2

Python 3 , 147 byte

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)

Provalo online!


1

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

-2 byte grazie a @Cyoce

-17 byte in più grazie a un'idea di @Cyoce

-6 byte grazie 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;}

Provalo online!

Ugh, la sostituzione di Java è così dettagliata.

Funzione che accetta una stringa e restituisce la stringa tradotta dal numero -> lettera o viceversa. Si arresta in modo anomalo su input non valido (è possibile vederlo nell'esempio di tio in cui genera i valori corretti per i primi 10 casi di test e quindi si arresta in modo anomalo con un errore di divisione per zero che viene mostrato nella vista di debug)

Ungolfed (il primo e l'ultimo termine del ciclo for vengono estratti per leggibilità)

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

La regex per la corrispondenza dei numeri è semplice, ma qui è la regex per la corrispondenza delle lettere al caso dei numeri

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

Non che migliora significativamente il numero di byte massicci, ma è possibile rimuovere le parentesi in giro(s)->
Cyoce

@Cyoce aiuta ogni byte
PunPun1000,

poiché tutti i rami ifdell'istruzione sono assegnazioni (che restituiscono un valore), prova a sostituire if... else if... elsecon l'operatore condizionale ?:, sostituendolo con Object _=per renderlo un'istruzione valida. Non sono sicuro che questo possa effettivamente aiutare il conteggio dei byte, ma penso che lo farà.
Cyoce,

Due piccole cose che puoi giocare a golf. Puoi rimuovere la stringa t, perché la usi solo una volta. Così t.charAt(i)+""diventa "OIREASGTBP".charAt(i)+""( -4 byte ). E puoi inserire l'ultima riga all'interno del for-loop dopo l' i<9;interno della dichiarazione for-loop. Quindi diventa for(;i<9;s=b?s.replace(v,c):s.replace(c,v)){( -1 byte ). Oh, e puoi mettere anche quello s=b?...che viene subito dopo l' int i=-1;interno del for-loop: for(s=b?...;i<9;...( -1 byte ).
Kevin Cruijssen,

1

PHP; 129 127 267 259 228 byte

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

Esegui come pipe -nRo provalo online .

abbattersi

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

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 byte (308 → 304) per una correzione di bug (non accade spesso che il conteggio dei byte diminuisca quando correggo un bug nel mio codice ..: D)

EDIT: utilizza un approccio diverso rispetto alla risposta Java di @ PunPun1000 creando prima la stringa di ritorno in un ciclo for sui caratteri, quindi utilizza una regex più astratta per convalidarla nel ritorno-ternario (l'input è costituito da tutte le cifre, oppure si alternano le vocali e le consonanti date (quindi senza vocali o consonanti adiacenti).

Spiegazione:

Provalo qui.

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

La regex di validazione:

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

0

05AB1E , 76 byte

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

Provalo online!

Restituisce il valore errato 0per input non valido.


0

Bash ,241 238 235 byte

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

Provalo online!

Meno golf:

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 byte

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

Provalo online!


0

Perl, 127 byte

126 byte + 1 byte riga di comando

$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

Dovrebbe seguire tutte le regole della sfida - può accettare lettere o numeri e errore (divisione per zero) se la validazione fallisce


La convalida ha falsi positivi su input NOe US.
Value Ink

0

Rubino , 205 + 1 = 206 byte

Utilizza il -pflag per +1 byte. Ora con un sistema di convalida degli input esaustivo.

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)

Provalo online!


Questo non sembra convertire lettere in numeri, né convalida!
Jarmex,

@Jarmex oops, aggiunta convalida! È un enorme controllo di convalida ma non ho molta scelta in merito
Value Ink,

0

Python 3, 741 byte

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)

Provalo online!

C'è molto margine di miglioramento, lo so.


0

sed, 123 byte

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

Spiegazione

Innanzitutto, circondiamo le cifre con _(per vocali) o =(per consonanti).

Se non abbiamo effettuato alcuna sostituzione, stiamo convertendo le lettere in cifre, quindi è una semplice sostituzione, e cancelliamo Ue N. Quindi esci.

Altrimenti, ci ramifichiamo per etichettare a, dove trattiamo vocali consecutive e quindi consonanti consecutive. Quindi trasforma le cifre in lettere ed elimina i caratteri marcatori introdotti nel primo passaggio.


0

Python3, 246 byte

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

spiegazione:

  • mappare l'input in un elenco di int
  • mappa l'elenco di int alla loro posizione nell'alfabeto
  • riduci la lista aggiungendo accumulatore, più un elemento di un dict tupla , più l'elemento corrente
    • la tupla dict è una tabella di verità basata su due elementi, vocale o no

0

JavaScript (ES6), 120

Una funzione che accetta input come stringa. Restituisce la stringa tradotta correttamente se l'input è valido, altrimenti false o la funzione si arresta in modo anomalo.

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

Meno golf

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
}

Test

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.