Произносить цифры

14

концепция

Запоминание цифр может быть трудным. Вспомнить слово может быть проще. Для запоминания больших чисел я создал способ произносить их в стиле буквального разговора.

правила

Каждая цифра сначала заменяется соответствующей буквой:

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

После замены делаются две дополнительные вещи для улучшения произношения:

  • Между двумя согласными Uдобавляется.

  • Между двумя гласными Nдобавляется.

Примеры / тесты

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

Что невозможно

  • Буквы и цифры смешаны в одном слове
  • Два последовательных согласных или два последовательных гласных
  • Письма, которых нет в списке выше
  • Другие персонажи

правила

Цель этого - создать двухсторонний переводчик для этой концепции.

  • Ваша программа должна сначала понять, переводится ли она на цифру или цифру.
  • Он должен проверить правильность формирования записи.
  • Если все правильно, покажите перевод.
  • Иначе, отобразить сообщение об ошибке, ничего, вернуть значение фальси или завершить работу программы.

Детали

  • Введенное число / строку можно вводить в любом формате, который вы хотите (стандартный, аргумент, ...)
  • Это , поэтому выигрывает самый короткий ответ.
  • Стандартные лазейки запрещены.
SteeveDroz
источник
11
Не должно GIGATESTERбыть GIGATESUTER?
kamoroso94
5
Обычно мы не просим, ​​чтобы запись была «правильно сформирована», поскольку это просто дополнительный код без веской причины (см. Мета-вопрос для хороших рекомендаций по вызовам). Кроме того, что означает «правильно сформированный»?
Okx
9
Если требуется проверка входных данных, вы должны включить приличную партию тестовых случаев недопустимых входных данных (особенно буквенных входных данных, которые почти действительны). Я ожидаю, что это на самом деле будет основной частью проблемы во многих языках.
Мартин Эндер
2
Я согласен с @MartinEnder, что вы должны добавить несколько тестовых случаев для недопустимых случаев, например AB23;AEI; BB; Z; ACE; giga; !@#$; -123; и т.д. Кроме того, на основе правил валидации мы можем преобразовать 6164735732 => GIGATESTER, но GIGATESTERэто приведет к ложному значению из-за ST(правила двух последовательных согласных). То, как ваша задача в настоящее время настроена, основной частью задачи является проверка, а не преобразование. Я в порядке с этим, но в этом случае проверка должна быть определена немного лучше.
Кевин Круйссен,
2
Ваша программа должна сначала понять, переводится ли она на цифру или цифру в букву. То есть перевод должен быть двусторонним? Предыдущий текст и контрольные примеры предполагают только цифру к букве
Луис Мендо

Ответы:

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)

демонстрация

Arnauld
источник
Если это не работает идеально, не размещайте это.
Okx
Надеюсь, сейчас работает как положено.
Арно
... или сбой при наличии зарезервированных символов регулярного выражения на входе. Все еще в силе, хотя
edc65
2

Japt , 61 59 92 85 84 байта

Я нахожусь в автономном режиме в течение большей части (длинных) выходных, если с этим будут обнаружены какие-либо проблемы, пожалуйста, попросите мод удалить его для меня до тех пор, пока я не смогу это исправить.

Принимает ввод как строку для обеих операций и возвращает строку как для, так и falseдля недопустимого ввода. Предполагается, что числовые входные данные всегда будут содержать несколько цифр, добавьте 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

Попробуйте это: цифры -> буквы или буквы -> цифры


  • 2 4 байта спасены благодаря obarakon , который также убедил меня снова заняться этим после того, как я отказался от него ранее. Я бы хотел, чтобы он этого не сделал!
  • 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
@ Emigna: Ах, черт возьми! Вы можете себе представить, что после того, как мы сгорели первым «Правилом», мы бы подумали прочитать остальные правила! : \ Я взял раздел «Что невозможно», чтобы подразумевать, что нам не придется обрабатывать какие-либо из этих пунктов. Исправление в ближайшее время.
Лохматый
1

Java (OpenJDK 8) , 416 410 399 382 376 370 байт

-2 байта благодаря @Cyoce

-17 больше байтов благодаря идее @Cyoce

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

Попробуйте онлайн!

Тьфу, замена Java так многословна.

Функция, которая принимает строку и возвращает строку, переведенную из числа -> буквы или наоборот. Сбои при неверном вводе (вы можете увидеть это в примере tio, где он выводит правильные значения для первых 10 тестовых случаев, а затем падает с ошибкой деления на ноль, которая отображается в представлении отладки)

Ungolfed (первый и последний члены цикла 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]
PunPun1000
источник
Не то чтобы это значительно улучшило ваше количество байтов, но вы можете убрать круглые скобки(s)->
Cyoce
@Cyoce помогает каждый байт
PunPun1000
поскольку все ваши ветви ifоператора являются присваиваниями (которые возвращают значение), попробуйте заменить if... else if... elseусловным оператором ?:, предварительно добавив его, Object _=чтобы сделать его допустимым оператором. Не уверен, поможет ли это на самом деле подсчет байтов, но я думаю, что это поможет.
Cyoce
Две маленькие вещи, которые вы можете играть в гольф. Вы можете удалить строку 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 байт ).
Кевин Круйссен
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
Titus
источник
1

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

РЕДАКТИРОВАТЬ: Использует другой подход, чем Java-ответ @ PunPun1000, сначала создавая возвращаемую строку в цикле for для символов, а затем использует более абстрактное регулярное выражение для проверки его в возвращаемой троице (входные данные представляют собой либо все цифры, или чередуются заданные гласные и согласные (то есть без каких-либо смежных гласных или согласных).

Объяснение:

Попробуй это здесь.

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

Баш ,241 238 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
marcosm
источник
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

Должен следовать всем правилам вызова - может принимать буквы или цифры и будет ошибка (деление на ноль), если проверка не пройдена

Jarmex
источник
Проверка имеет ложные срабатывания на входе NOи US.
Value Ink
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)

Попробуйте онлайн!

Я знаю, что есть много возможностей для совершенствования.

LyricLy
источник
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

объяснение

Сначала мы окружаем цифры с _(для гласных) или =(для согласных).

Если мы не делали никаких подстановок, мы конвертируем буквы в цифры, так что это простая подстановка, и удаляем Uи N. Тогда выходи.

В противном случае мы разветвляемся на метку 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 на их позиции в алфавите
  • уменьшить список, добавив аккумулятор, плюс элемент dict кортежа, плюс текущий элемент
    • ДИКТ Кортеж таблица истинности основана на двух элементах, будучи гласным или нет
Setop
источник
0

JavaScript (ES6), 120

Функция, принимающая ввод в виде строки. Возвращает правильно переведенную строку, если ввод верен, в противном случае - ложь или сбой функции.

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>

edc65
источник