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


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

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

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

правила

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

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

Детали

  • Введенное число / строку можно вводить в любом формате, который вы хотите (стандартный, аргумент, ...)
  • Это , поэтому выигрывает самый короткий ответ.
  • Стандартные лазейки запрещены.

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)

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


Если это не работает идеально, не размещайте это.
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]

Не то чтобы это значительно улучшило ваше количество байтов, но вы можете убрать круглые скобки(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

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


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

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

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


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

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>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.