15
\$\begingroup\$

Concept

Remembering numbers can be difficult. Remembering a word may be easier. In order to memorize big numbers, I created a way to pronounce them in a leetspeak-like way.

Rules

Each digit is first replaced by its corresponding letter:

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

After the replacement, two additional things are done to improved pronunciation:

  • Between two consonants, a U is added.

  • Between two vowels, a N is added.

Examples/test cases

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

What's impossible

  • Letters and numbers mixed in the same word
  • Two successive consonants or two successive vowels
  • Letters that are not in the list above
  • Other characters

Rules

The goal of this is to create a 2-way translator for this concept.

  • Your program must first understand by itself if it's letter-to-number or number-to-letter translation.
  • It must check for the entry to be properly formed.
  • If everything is correct, display the translation.
  • Else, display an error message, nothing, return a falsey value or crash the program.

Details

  • The input number/string can be entered in whatever format you want (stdin, argument, ...)
  • This is , so shortest answer wins.
  • Standard loopholes are forbidden.
\$\endgroup\$
17
  • 11
    \$\begingroup\$ Shouldn't GIGATESTER be GIGATESUTER? \$\endgroup\$
    – kamoroso94
    Commented Jun 2, 2017 at 10:35
  • 6
    \$\begingroup\$ Usually, we don't ask for the entry to be 'properly formed', as it's just extra code for no good reason (see the meta question for good challenge recommendations). Additionally, what does 'properly formed' mean? \$\endgroup\$
    – Okx
    Commented Jun 2, 2017 at 10:39
  • 11
    \$\begingroup\$ If input validation is required, you should include a decent batch of test cases of invalid inputs (especially letter-only inputs that are almost valid). I expect that this will actually be the main part of the challenge in many languages. \$\endgroup\$ Commented Jun 2, 2017 at 10:44
  • 2
    \$\begingroup\$ I agree with @MartinEnder that you should add some test cases for invalid cases, like AB23; AEI; BB; Z; ACE; giga; !@#$; -123; etc. Also, based on the validation rules, we can convert 6164735732 => GIGATESTER, but GIGATESTER will result in a false value, because of ST (two successive consonants rule). The way your challenge is currently set up, the main part of the challenge is the validation, instead of the conversion. I'm fine with that, but the validation should be defined a bit better in that case. \$\endgroup\$ Commented Jun 2, 2017 at 14:59
  • 2
    \$\begingroup\$ Your program must first undersand by itself if it's letter-to-number or number-to-letter translation. So the translation has to be two-way? The preceding text and the test cases suggest only number to letter \$\endgroup\$
    – Luis Mendo
    Commented Jun 2, 2017 at 15:21

19 Answers 19

5
\$\begingroup\$

JavaScript (ES6), 130 bytes

Takes input as a string in both translation ways. Returns either the translation as a string or false in case of an invalid input.

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

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)

console.log(f("512431"))          // SIRANENI
console.log(f("834677081"))       // BENAGUTUTOBI
console.log(f("3141592"))         // ENINANISUPUR
console.log(f("1234567890"))      // IRENASUGUTUBUPO
console.log(f("6164735732"))      // GIGATESUTER

console.log(f("SIRANENI"))        // 512431 
console.log(f("BENAGUTUTOBI"))    // 834677081
console.log(f("ENINANISUPUR"))    // 3141592
console.log(f("IRENASUGUTUBUPO")) // 1234567890
console.log(f("GIGATESUTER"))     // 6164735732

console.log(f("AB23"))            // false
console.log(f("AEI"))             // false
console.log(f("ZZ"))              // false

\$\endgroup\$
3
  • \$\begingroup\$ If it doesn't work perfectly, don't post it. \$\endgroup\$
    – Okx
    Commented Jun 2, 2017 at 12:30
  • \$\begingroup\$ Hopefully now working as expected. \$\endgroup\$
    – Arnauld
    Commented Jun 2, 2017 at 12:55
  • \$\begingroup\$ ... or crash when there are reserved regexp characters in input. Still valid though \$\endgroup\$
    – edc65
    Commented Jun 7, 2017 at 9:25
3
\$\begingroup\$

Python 3, 147 bytes

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)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Japt v1.4.5, 61 59 92 85 84 70 68 52 bytes

Assumes, as implied by the test cases, that the input will always be, or result in, a positive integer - i.e. not 0.

Outputs false for invalid string inputs containing at least one valid letter, throws an overflow error for all others.


"OIREASGTBP"
Ñ?UsV e"%v"²_ínuÃe"%V"²_íuu:U¶ßU=nV)©U

Try it (Includes all test cases)


  • 2 4 bytes saved thank to obarakon, who also convinced me to take this up again after I abandoned it earlier. I wish he hadn't!
  • 33 26 25 23(!) 7 bytes sacrificed to check input validity.

Explanation

We can avoid explicitly removing N & U before trying to convert a string to a number thanks to the way Japt's custom base conversion works. Unlike the native parseInt function which stops parsing when it encounters an invalid character and returns the result up to that point, when using a custom base invalid characters are ignored and parsing continues from the next valid character.

\n"..."\nÑ?UsV e"%v"²_ínuÃe"%V"²_íuu:U¶ßU=nV)©U     :Implicit input of integer or string U
\n                                                  :Prevent input value of U from being overridden
  "..."\n                                           :Assign the string "OIREASGTBP" to variable V
         Ñ                                          :Multiply the input by 2
          ?                                         :If truthy (not NaN)
           UsV                                      :  Convert U to a string in custom base V
               e                                    :  Recursively replace all occurrences of
                "%v"                                :    Literal "%v"
                    ²                               :    Duplicate, giving the Japt RegEx class for /[AEIUO][AEIOU]/g
                     _                              :    Pass each match through the following function
                      í                             :      Interleave with
                       n                            :        Literal "n"
                        u                           :        Uppercase
                         Ã                          :  End replace
                          e"%V"²                    :  Recursively replace all occurrences of /[^AEIOU][^AEIOU]/g
                                _                   :  Pass each match through the following function
                                 íuu                :    Interleave with "u" uppercased
                                    :               :Else
                                     U¶             :  Check U for equality with
                                       ß            :    Recursive call with argument
                                        U=          :      Reassign to U
                                          nV        :      Convert U from a base-V string to an integer
                                            )       :    End recursive call
                                             ©U     :  Logical AND with U
\$\endgroup\$
0
1
\$\begingroup\$

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

-2 bytes thanks to @Cyoce

-17 more bytes thanks to an idea by @Cyoce

-6 bytes thanks to @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;}

Try it online!

Ugh, java replacement is so verbose.

Function which takes a string and returns the string translated from number -> letter or vice versa. Crashes on invalid input (you can see this in the tio example where it outputs the correct values for the first 10 test cases and then crashes with a divide by zero error which shows in the debug view)

Ungolfed (the first and last term of the for loop are pulled out for readability)

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

The regex for matching the numbers is simple, but here is the regex for matching the letters to numbers case

(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]
\$\endgroup\$
4
  • \$\begingroup\$ Not that it significantly improves your massive byte count, but you can remove the parentheses around (s)-> \$\endgroup\$
    – Cyoce
    Commented Jun 2, 2017 at 17:29
  • \$\begingroup\$ @Cyoce every byte helps \$\endgroup\$
    – PunPun1000
    Commented Jun 2, 2017 at 17:38
  • \$\begingroup\$ since all your branches of the if statement are assignments (which return a value), try replacing the if...else if...else with the conditional operator ?:, prefacing it with Object _= to make it a valid statement. Not sure if this would actually help the byte count, but I think it will. \$\endgroup\$
    – Cyoce
    Commented Jun 2, 2017 at 17:57
  • \$\begingroup\$ Two small things you can golf. You can remove the String t, because you only use it once. So t.charAt(i)+"" becomes "OIREASGTBP".charAt(i)+"" (-4 bytes). And you can place the last line inside the for-loop after the i<9; inside the for-loop declaration. So it becomes for(;i<9;s=b?s.replace(v,c):s.replace(c,v)){ (-1 byte). Oh, and you can put the s=b?... that comes right after the int i=-1; inside the for-loop as well: for(s=b?...;i<9;... (-1 byte). \$\endgroup\$ Commented Jun 6, 2017 at 6:51
1
\$\begingroup\$

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

Explanation

First, we surround digits with _ (for vowels) or = (for consonants).

If we didn't make any substitutions, we are converting letters to digits, so it's a simple substitution, and delete U and N. Then quit.

Otherwise, we branch to label a, where we deal with consecutive vowels and then consecutive consonants. Then transform digits to letters, and delete the marker characters we introduced in the first step.

\$\endgroup\$
1
\$\begingroup\$

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;

Run as pipe with -nR or try it online.

breakdown

$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
\$\endgroup\$
0
1
\$\begingroup\$

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) for a bug-fix (doesn't happen often that the byte-count decreases when I fix a bug in my code.. :D)

EDIT: Uses a different approach than @PunPun1000's Java answer by first creating the return-String in a for-loop over the characters, and then uses a more abstract regex to validate it in the return-ternary (the input is either all digits, or are the given vowels and consonants alternating (so without any adjacent vowels nor consonants).

Explanation:

Try it here.

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

The validation regex:

(([AEIOU][BGNPRST])*[AEIOU]?)|(([BGNPRST][AEIOU])*[BGNPRST]?)|\\d*
\$\endgroup\$
1
  • \$\begingroup\$ Should "NO" & "US" not be considered invalid? \$\endgroup\$
    – Shaggy
    Commented Oct 15 at 16:36
1
\$\begingroup\$

APL (Dyalog Unicode), 71 bytes

' '~⍨,({' ',2{∧/x←'AEIOU'∊⍨⍺⍵:'N'⋄∧/~x:'U'⋄' '}/⍵},⍪)'OIREASGTBP'[⍎¨⍕⎕]

Try it online!

This turned out surprisingly short!

Uses ⎕IO←0 (0-indexing).

Explanation

' '~⍨,({' ',2{∧/x←'AEIOU'∊⍨⍺⍵:'N'⋄∧/~x:'U'⋄' '}/⍵},⍪)'OIREASGTBP'[⍎¨⍕⎕]
                                                                  ⍎¨⍕⎕  get the digits of the input
                                                     'OIREASGTBP'[    ] map to the correct letters
      {' ',2{∧/x←'AEIOU'∊⍨⍺⍵:'N'⋄∧/~x:'U'⋄' '}/⍵},⍪                     join the following with the tabled argument:
                                              /⍵                        map pairs of the argument to:
           2 ∧/x←'AEIOU'∊⍨⍺⍵:'N'                                        N if vowel pair,
                                ⋄∧/~x:'U'                               U if consonant pair,
                                         ⋄' '                           space otheriwse.
       ' ',                                                             prepend a space
    ,                                                                   flatten the result
' '~⍨                                                                   remove all spaces
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 155 bytes

$v="AEIO]";$c="RSGTBP]";$,=OIREASGTBP;eval"/[^0-9$,UN]|[^$v N|N[^$v|[^$c U|U[^$c|^[NU]|[NU]\$/x||y/0-9$,UN/$,0-9/d+s/[$v\\K(?=[$v)/N/g+s/[$c\\K(?=[$c)/U/g"

Try it online!

Recognizes some invalid inputs that the other Perl entry does not. Outputs the string unchanged if it is not valid.

\$\endgroup\$
1
\$\begingroup\$

Casio BASIC (Casio fx-9750GIII), 224 216 bytes

"OIREASGTBP"→Str 1
?→Str 2
"RSGTBP"→Str 3
"StrSrc(Str 3,StrMid(Str 1,B,1"→fn1
"StrSrc(Str 3,StrMid(Str 1,A,1"→fn2
For 1→I To StrLen(Str 2
1+Exp(StrMid(Str 2,I,1))→A
If I≠1
Then 1+Exp(StrMid(Str 2,I-1,1))→B
fn1fn2⟹Str 4+"U"→Str 4
Not (fn1+fn2⟹Str 4+"N"→Str 4
IfEnd
Str 4+StrMid(Str 1,A,1→Str 4
Next
Locate 1,1,Str 4
\$\endgroup\$
0
\$\begingroup\$

05AB1E, 76 bytes

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

Try it online!

Returns the falsy value 0 for invalid input.

\$\endgroup\$
0
\$\begingroup\$

Bash, 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

Try it online!

Less golfed:

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
\$\endgroup\$
0
\$\begingroup\$

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Perl, 127 bytes

126 bytes + 1 byte command line

$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

Usage:

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

Should follow all the challenge rules - can accept letters or numbers and will error (division by zero) if validation fails

\$\endgroup\$
1
  • \$\begingroup\$ Validation has false positives on input NO and US. \$\endgroup\$
    – Value Ink
    Commented Jun 3, 2017 at 1:05
0
\$\begingroup\$

Ruby, 205+1 = 206 bytes

Uses the -p flag for +1 byte. Now with an exhaustive input validation system.

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)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ This doesn't seem to convert letters to numbers, nor does it do any validation! \$\endgroup\$
    – Jarmex
    Commented Jun 3, 2017 at 0:03
  • \$\begingroup\$ @Jarmex oops, added validation! It's a huge validation check but I don't have much choice in the matter \$\endgroup\$
    – Value Ink
    Commented Jun 3, 2017 at 0:58
0
\$\begingroup\$

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)

Try it online!

There's a lot of room for improvement, I know.

\$\endgroup\$
0
\$\begingroup\$

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

explanation:

  • map input to a list of int
  • map list of int to their position in the alphabet
  • reduce list by adding accumulator, plus an element of a dicttuple, plus the current element
    • the dicttuple is a truth table based on two elements, being vowel or not
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 120

A function taking input as a string. It returns the properly translated string if the input is valid, else false or the function crashes.

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

Less golfed

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>

\$\endgroup\$
0
\$\begingroup\$

C#, 205 bytes

using System.Text.RegularExpressions;void F(int i){var r="";while(i>0){r="OIREASGTBP"[i%10]+r;i/=10;}Console.Write(Regex.Replace(Regex.Replace(r,"([^AEIO])(?=[^AEIO])","$1U"),"([AEIO])(?=[AEIO])","$1N"));}

Try it online!

Explanation:

using System.Text.RegularExpressions;

void F(int i)
{
    
    var r = "";
    while (i > 0)
    {
        r = "OIREASGTBP"[i % 10] + r; // Add the next char to the pronounceable string (from last to first)
        i /= 10;
    }

    Console.Write(
        Regex.Replace(
            Regex.Replace(r, "([^AEIO])(?=[^AEIO])", "$1U"), // Put a U between two consecutive consonants
            "([AEIO])(?=[AEIO])",
            "$1N" // Put an N between two consecutive vowels
        )
    );
}

```
\$\endgroup\$
1
  • \$\begingroup\$ Solutions needs to be able to work both ways, converting numbers to word and words to numbers. \$\endgroup\$
    – Shaggy
    Commented Oct 15 at 15:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.