ANNNOUNNNCCCEEERRR VOICCCEEE


18

Напишите функцию, которая принимает строку букв и пробелов (не нужно обрабатывать не-буквы) и выполняет алгоритм перевода ANNOUNCER VOICE следующим образом:

  • Во-первых, все в верхнем регистре.
  • Для каждого слова
    • Удлините каждую группу согласных, утроив каждую букву; за исключением случаев, когда слово начинается с группы согласных, не удлиняйте эту группу. Например, otherдолжен стать, OTTTHHHEEERRRно motherдолжен стать MOTTTHHHEEERRR.
    • Удлините последний гласный, утроив его.
  • В обоих случаях удлинения , если вы утроите букву, сначала объедините ее с дубликатами букв с обеих сторон. Например, hillдолжен стать HIIILLLи bookkeeperдолжен стать BOOKKKEEPPPEEERRR.
  • Для целей этого вызова yсчитается согласной.
  • Уточнение / упрощение: Вы можете предположить, что каждая пара слов разделена одним пробелом и что входные данные не содержат последовательных пробелов и что входные данные не будут пустой строкой.
  • Самый короткий код выигрывает!

Тестовые векторы:

> sunday sunday
SUNNNDDDAAAYYY SUNNNDDDAAAYYY
> mia hamm
MIAAA HAAAMMM
> chester alan arthur
CHESSSTTTEEERRR ALLLAAANNN ARRRTTTHHHUUURRR
> attention please
ATTTENNNTTTIOOONNN PLEASSSEEE
> supercalifragilisticexpialidocious
SUPPPERRRCCCALLLIFFFRRRAGGGILLLISSSTTTICCCEXXXPPPIALLLIDDDOCCCIOUUUSSS
> moo
MOOO
> Aachen
AACCCHHHEEENNN
> Oooh
OOOHHH
> grifffest
GRIFFFEEESSSTTT
> k
K
> aaaabbbbc
AAAABBBBCCC

Вот эталонная реализация, на которую я бы перешел к ответу, за исключением того, что с сегодняшнего утра вопрос закрыт. :П

import itertools,re
def j(s):return re.match('^[AEIOU]+$',s)
def c(s):return ''.join(sum(([h,h,h]for h in[k for k,g in itertools.groupby(s)]),[]))
def v(s):
 while len(s)>=2 and s[-2]==s[-1]:s=s[:-1]
 return s+s[-1]+s[-1]
def a(n):
 r=''
 for w in n.split():
  if r:r+=' '
  ss=re.split('([AEIOU]+)', w.upper())
  for i,s in enumerate(ss):
   r += [v(s),s][any(j(t) for t in ss[i+1:])]if j(s)else[s,c(s)][i>0]
 return r
while 1:print a(raw_input('> '))

2
Просьба о будущем: пожалуйста, избегайте таких слов и словосочетаний, как группа согласных , объединение и удлинение . Ненемец, говорящий по-английски, как я, может нуждаться в словаре, чтобы понять ваш пост.
Деннис

Это должны быть «удлиненные» гласные :(
Адвокат дьявола

Что такое согласный кластер?
MilkyWay90

Ответы:


6

APL (Dyalog) , 175 байт

1' +'R' ''[AEIOU][^AEIOU]+ 'R{m/⍨1,3×2≠/m←⍵.Match}'([AEIOU])\1*([^AEIOU]*? )' ' [AEIOU]' ' [^ AEIOU]+' '([^AEIOU ])\1*'R'\1\1\1\2' '&' '&' '\1\1\1''$| |^'R'  '1(819⌶)⍞

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

 запрос на ввод символов

1(819⌶) преобразовать в верхний регистр (819 ≈ большой)

 передать результат дальше (служит для разделения строк и 1)

'$| |^'⎕R' 'R eplace:
 конец, любой пробел и начало
 → два пробела

 передать результат дальше (служит для разделения двух групп строк)

'([AEIOU])\1*([^AEIOU]*? )' ' [AEIOU]' ' [^ AEIOU]+' '([^AEIOU ])\1*'⎕R'\1\1\1\2' '&' '&' '\1\1\1'R eplace:
 любое количество одинаковых гласных и любое число не-гласных и пространство
 → гласной трижды и немодифицированные согласные
 пространство и гласный
 → себе
 пространство и согласной кластера
 → собой
 бег одинаковых согласных
 → три из них гласные звуки

'[AEIOU][^AEIOU]+ '⎕R{}R eplace:
 набор не гласных и пробел
 → результат следующей анонимной функции с пространством имен в качестве аргумента:
  ⍵.Match найденный текст
  m← присваивает m
  2≠/ парное отличие от
   умножения на три, а затем
  1, одно
  m/⍨ использование для репликацииm

 передать результат дальше (служит для разделения двух строк)

' +'⎕R' 'R eplace:
 один или несколько пробелов
 → с одним пробелом

1↓ опустить начальную букву (пробел)


Это работает? 1↓' +'⎕R' '⊢'[AEIOU][^AEIOU]+ '⎕R{m/⍨1,3×2≠/m←⍵.Match}'([AEIOU])\1*([^AEIOU]*? )' ' [AEIOU]' ' [^ AEIOU]+' '([^AEIOU ])\1*'⎕R(s,'\2')'&' '&'(s←6⍴'\1')⊢'$| |^'⎕R' '⊢1(819⌶)⍞
Захари

^ Сохраняет два байта, если это работает ^
Zacharý

5

JS (ES6), 138 134 129 байт

s=>s.toUpperCase()[r="replace"](/(\w)\1/g,"$1")[r](/[AEIOU](?=[^AEIOU]*( |$))/g,s=>s+s+s)[r](/\B./g,s=>/[AEIOU]/.test(s)?s:s+s+s)

WAAAYYY TOOO MAAANNNYYY BYYYTTTEEESSS. Содержит AEIOU3 раза, но я не могу играть в гольф в одном.

-4 байта благодаря HyperNeutrino

Ungolfed

function v(str){
    return str.toUpperCase().replace(/(\w)\1/g,"$1").replace(/[AEIOU](?=[^AEIOU]*( |$))/g,s=>s+s+s).replace(/\B./g,s=>[..."AEIOU"].includes(s)?s:s+s+s);
}

Я люблю писать, а не читать код.


1
"WAAAYYY TOOO MAAANNNYYY BYYYTTTEEESSSS" ... на первом месте, опережая APL.
Захари

Я не знаю JS, но вы можете заменить s=>/[AEIOU]/.test(s)на /[AEIOU]/.test?
musicman523

@ musicman523 к сожалению, нет, потому что это условие в выражении троичного оператора.
Около

К вашему сведению, ваша обработка согласных кластеров, кажется, немного неправильно; правильный вывод будет WAAAYYY TOOO MAAANNNYYY BYTEEESSS(т.е. не удлинять начальный кластер BYT).
Quuxplusone

Ну, был на первом месте.
Захари

5

APL, 90 байт

{1↓∊{s←{⍵⊂⍨1,2≠/⍵}⋄x↑⍨¨(3⌈≢¨s⍵)⌊≢¨x←s⍵/⍨(1+2×{⌽<\⌽⍵}∨~∧∨\)⍵∊'AEIOU'}¨w⊂⍨w=⊃w←' ',1(819⌶)⍵}

Объяснение:

  • 1(819⌶)⍵: преобразовать в верхний регистр
  • w⊂⍨w=⊃w←' ',: разделить на пробелы
  • {... : за каждое слово ...
    • s←{⍵⊂⍨1,2≠/⍵}: sэто функция, которая разбивает строку на группы смежных совпадающих символов
    • ⍵∊'AEIOU': отметить гласные
    • (... ): посмотреть, какие символы нужно дублировать
      • ~∧∨\: все согласные после первого гласного,
      • {⌽<\⌽⍵}: последний гласный
      • : умножить битовый вектор на два,
      • 1+: и добавить один. Теперь все выбранные персонажи имеют, 3а остальные имеют 1.
    • ⍵/⍨: повторить каждый символ на заданную сумму
    • x←s: разбить его на строки совпадающих символов и сохранить в x.
    • (3⌈≢¨s⍵): длина каждой группы совпадающих символов во входном слове, максимум 3.
    • ⌊≢¨: минимум этого и длина групп в x.
    • x↑⍨¨: сделать каждую группу такой длины
  • 1↓∊: сгладить результат и удалить первый символ (пробел, который был добавлен в начале, чтобы помочь с разбиением)

Вы победили Адама ... вау.
Захари

очень аккуратный! Если вы немного перемешаете его и пишете как программу (используя подсказку, предложенную Адамом), вы можете сбрить еще 15 байтов:1↓∊{c/⍨(≢¨g)⌈3×((⌽<\∘⌽)∨~∧∨\)'AEIOU'∊⍨c←⊃¨g←⍵⊂⍨1,2≠/⍵}¨w⊂⍨w=⊃w←' ',1(819⌶)⍞
Gil

3

Python, 417 байт

Вот эталонная реализация в Python. Не ужасно гольф.

import itertools,re
def j(s):return re.match('^[AEIOU]+$',s)
def c(s):return ''.join(sum(([h,h,h]for h in[k for k,g in itertools.groupby(s)]),[]))
def v(s):
 while len(s)>=2 and s[-2]==s[-1]:s=s[:-1]
 return s+s[-1]+s[-1]
def a(n):
 r=''
 for w in n.split():
  if r:r+=' '
  ss=re.split('([AEIOU]+)',w.upper())
  for i,s in enumerate(ss):
   r+=[v(s),s][any(j(t) for t in ss[i+1:])]if j(s)else[s,c(s)][i>0]
 return r

Тест с:

while True:
 print a(raw_input('> '))

Не следует ли вам хотя бы немного поиграть в гольф, убрав ненужные места и перейдя ssна S?
Захари

2

Python 3 , 238 байт

def f(s):
 s=s.upper();k=[s[0]];s=''.join(k+[s[i]for i in range(1,len(s))if s[i]!=s[i-1]])
 for i in range(1,len(s)):k+=[s[i]]*(3-2*(s[i]in'AEIOU'and i!=max(map(s.rfind,'AEIOU'))))
 return''.join(k)
print(' '.join(map(f,input().split())))

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


Можете ли вы сохранить байты, установив vв 'AEIOU'?
Захари

@ Zacharý Спасибо, но, к сожалению, это не меняет счет.
HyperNeutrino

О, пробелы вокруг первого v.
Захари

0

Perl 5 , 139 + 1 (-p) = 140 байт

$_=uc,s/^([^AEIOU]*)//,$s=$1,s/([^AEIOU])\1*/$1x(($q=length$&)>3?$q:3)/ge,s/.*?\K([AEIOU])\1*/$1x(($q=length$&)>3?$q:3)/e,print"$s$_ "for@F

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

Четный обрабатывает контрольный пример "aaaabbbbc" в соответствии с примером.

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