Подсчитайте количество гласных в каждом слове строки


13

Это довольно простой вызов.

Вызов

Ввод будет содержать строку (не nullпустую) максимальной длины 100. Выведите количество гласных в каждом слове строки, разделенных пробелами.

правила

  • Длина строки не должна превышать 100 символов.
  • Строка будет содержать только алфавиты A-Z, a-zа также может содержать пробелы.
  • Входные данные должны быть получены из stdinаргументов или командной строки.
  • Вывод должен быть выведен в stdout.
  • Вы можете написать полную программу или функцию, которая принимает входные данные stdinи выводит результат.
  • Гласные , что ваши потребности программы / функции для подсчета числа являются aeiouи AEIOU.

Тестовые случаи

This is the first test case     --> 1 1 1 1 1 2
one plus two equals three       --> 2 1 1 3 2
aeiou AEIOU                     --> 5 5
psst                            --> 0
the quick brown fox jumped over the lazy dog --> 1 2 1 1 2 2 1 1 1

счет

Это , поэтому выигрывает самое короткое представление (в байтах).


6
Есть ли причина, по которой вы настаиваете на довольно ограниченном формате ввода / вывода? Не каждый язык может (удобно) взаимодействовать с STDIN и STDOUT. У нас есть по умолчанию для этого (которые вы, конечно , переопределять , если вы хотите), которые также позволяют аргумент командной строки, аргумент функции, возвращаемое значение и т.д. (они также могут быть найдены в теге вики .)
Мартин Эндер

@ MartinBüttner, « Есть ли причина, по которой вы настаиваете на довольно ограниченном формате ввода / вывода? » - Нет. Мне просто нравится stdinс stdout. Я не люблю "получать ввод" через аргументы функции. аргументы командной строки кажутся нормальными. Я добавил это в пост.
Spikatrix

4
Википедия: The name "vowel" is often used for the symbols that represent vowel sounds in a language's writing system, particularly if the language uses an alphabet. In writing systems based on the Latin alphabet, the letters A, E, I, O, U, and sometimes Y are all used to represent vowels. However, not all of these letters represent vowels in all languages.Что вы подразумеваете под гласными?
edc65

Одиночный трейлинг в порядке?
Алекс А.

3
Используйте Песочницу для Предложенных Испытаний.
mbomb007

Ответы:


8

Pyth, 17 байт

jdml@"aeiou"dcrzZ

Простое решение. Попробуйте онлайн: демонстрация или тестовая привязь

Объяснение:

               z   input
              r Z  convert to lower-case
             c     split at spaces
  m                map each word d to:
    @"aeiou"d         filter d for chars in "aeiou"
   l                  length
jd                 join by spaces and implicitly print

Меня всегда забавляет, когда люди пишут решение Pyth и называют его «Прямолинейным» (хотя это, по общему признанию, легче понять, чем большинство) +1
Кристофер Вирт

10

C 113 108 103 96 байт

Спасибо @ andrea-biondo за особенно хорошее сохранение 5 байтов.

main(a,v,c)char**v;{do{for(a=0;c=*v[1]++%32;2016%(c+27)||a++);printf("%d ",a);}while(v[1][-1]);}

Это все еще кажется раздутым, так что, надеюсь, я смогу записать его немного позже, сегодня вечером.

Интересная часть, пожалуй,

!(124701951%((c-65&31)+33))

будет, 1если cгласный ASCII (в верхнем или нижнем регистре), а 0для других символовa-zA-Z . Подвыражение c-65&31карты 'a'и 'A'в 0, 'b'и 'B'в 2, и т.д. Когда мы добавим 33гласные соответствуют номерам , 33, 37, 41, 47, 53соответственно, все из которых (удобно) первична. В нашем диапазоне будут делиться только такие числа 124701951 = 33*37*41*47*53, т. Е. Только для гласных остаток 124701951%(...)будет равен нулю.

РЕДАКТИРОВАТЬ: Таким образом, можно рассмотреть выражение !(n%((c-65&31)+s))где, (n,s) = (124701951, 33)как определение, cявляется ли символ гласным. В комментариях @ andrea-biondo указал, что пара (n,s) = (2016,28)может также использоваться в этом выражении для определения гласности. Я оставлю текущее объяснение в терминах простых чисел, приведенных выше, но причина, по которой это более короткое спаривание работает снова, заключается в том, что в диапазоне 28--53 единственные числа с простыми коэффициентами, полностью входящими в набор простых факторов 2016 года, составляют 28, 32 36, 42, 48, которые точно соответствуют гласным.

EDIT2: еще 5 байтов сохранены, так как (c-65&31)+28могут быть сокращены до c%32+27.

EDIT3: преобразован в цикл do-while, чтобы в итоге получить его ниже 100 байт.

Тестовые случаи:

$ ./vowelc "Это первый тестовый пример"
1 1 1 1 1 2 
$ ./vowelc "один плюс два равняется трем"
2 1 1 3 2 
$ ./vowelc "aeiou AEIOU"
5 5 
$ ./vowelc "psst"                     
0

О, МОЙ БОГ! Это просто потрясающе! Вы можете сохранить больше байтов, используя a;снаружи main. Таким образом, вы уменьшаете несколько байт , как вам не нужно объявлять aв main(...)а также, не нужно инициализировать aиз цикла.
Спикатрикс

1
@CoolGuy: aповторно инициализируется в каждом цикле, поэтому вы не можете инициализировать его один раз в ноль, объявив global. Я написал небольшой брутфорсер, чтобы найти наименьшую (n, s)пару, такую n%((c-65&31)+s)как ноль для гласных и ненулевой для согласных (az, AZ). Я нашел, (2016, 28)и это, кажется, работает хорошо: !(2016%((c-65&31)+28))на 5 символов короче. Во всяком случае, очень хорошее решение :)
Андреа Биондо

7

CJam, 21 19 байтов

r{el_"aeiou"--,Sr}h

Как это работает :

r{               }h    e# Read the first word and enter a do-while loop
  el_                  e# Convert the word into lower case and take a copy of it
     "aeiou"           e# All small caps vowels
            -          e# Remove all vowels from the copied word
             -         e# Remove all non-vowels from the original word
              ,        e# At this point, we have a string with all vowels of the word
                       e# Simply take its length
               S       e# Put a space after the number of vowel
                r      e# Read the next word. This serves as the truthy condition for the
                       e# do-while loop for us as if there are no word left, this returns
                       e# null/falsy and the do-while loop is exited

Попробуйте онлайн здесь


6

R, 44 43 байта

cat(nchar(gsub("[^aeiou]","",scan(,""),T)))

Ungolfed + объяснение:

# Read a string from STDIN. scan() automatically constructs a vector
# from input that contains spaces. The what= argument specifies that
# a string will be read rather than a numeric value. Since it's the
# second specified argument to scan(), we can simply do scan(,"").

s <- scan(what = "")

# For each word of the input, remove all consonants using gsub(),
# which is vectorized over its input argument.

g <- gsub("[^aeiou]", "", s, ignore.case = TRUE)

# Print the number of remaining characters in each word to STDOUT
# using cat(), which automatically separates vector values with a
# single space.

cat(nchar(g))

5

Perl, 35 34 31

say map{lc=~y/aeiou//.$"}split

30символы +1для -n.

Как и в большинстве Perl-кода, это работает справа налево. splitразделит введенную строку на пробел. mapбудет запускать код между {}каждым словом, которое было разделено. lcделает слово строчным. =~y/aeiou//даст нам количество гласных. .$"добавит пробел к слову. sayзатем печатает все слова!

Бежать с:

echo 'aeiou AEIOU' | perl -nE'say map{lc=~y/aeiou//.$"}split'

4

Python 3, 65 байт

print(*[sum(c in'aeiouAEIOU'for c in w)for w in input().split()])

Очень просто, довольно читабельно. wобозначает слово, cобозначает характер.


4

Perl: 30 символов

(Вид силы правил: числа в выходных данных разделены таким же количеством пробелов, как и входные слова.)

s|\w+|@{[$&=~/[aeiou]/gi]}|ge

Образец прогона:

bash-4.3$ while read s; do printf '%-30s --> ' "$s"; perl -pe 's|\w+|@{[$&=~/[aeiou]/gi]}|ge' <<< "$s"; done < test-case.txt
This is the first test case    --> 1 1 1 1 1 2
one plus two equals three      --> 2 1 1 3 2
aeiou AEIOU                    --> 5 5
psst                           --> 0

Perl: 27 символов

(Просто , чтобы показать , как мало было бы , если бы я не забыл о y///«s возвращаемого значения. Снова. Теперь иди и upvote chilemagic » s ответ , который напомнил мне о y///«s возвращаемого значения. Снова.)

s|\w+|lc($&)=~y/aeiou//|ge

Черт побери мой ответ. Это s!\w+!lc($&)=~y/aeiou//!geприводит к 27байтам (26 символов +1 для -p.
hmatt1

Да, спасибо. Я больше не могу рассчитывать на мои пальцы, сколько раз я забыл y///. :(
manatwork

3

Рубин, 38 байт

$><<$*.map{|x|x.count'AIUEOaiueo'}*' '

Использование:

mad_gaksha@madlab /tmp/ $ ruby t.rb This is the first test case
1 1 1 1 1 2

3

JavaScript ( ES6 ), 68

Ввод / вывод через всплывающее окно. Запустите фрагмент в Firefox для проверки.

// As requested by OP

alert(prompt().replace(/\w+/g,w=>w.replace(/[^aeiou]/ig,'').length))

// Testable
f=s=>s.replace(/\w+/g,w=>w.replace(/[^aeiou]/ig,'').length)

test=[
 ['This is the first test case','1 1 1 1 1 2']
,['one plus two equals three','2 1 1 3 2']
,['aeiou AEIOU', '5 5']
]  

out=x=>O.innerHTML+=x+'\n'

test.forEach(t=>{
  r=f(t[0])
  out('Test '+ ['Fail','OK'][0|r==t[1]]
      +'\nInput:  '+ t[0]
      +'\nOutput: '+r
      +'\nCheck:  '+t[1]+'\n')
})
<pre id=O></pre>



3

PowerShell, 35 байт

%{($_-replace"[^aeiou]",'').length}

В некотором роде скучно, но на самом деле конкурировать за один раз? (По умолчанию PowerShell нечувствителен к регистру)


К вашему сведению, вам нужно назвать это как echo <word> | codeгде <слово> - ваше слово или фраза
Pureferret

3

Баш - 85

while read l;do for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo;done

объяснение

  • read l читать одну строку из ввода
  • for w in l разбивает строку на слова с помощью разделителя пробелов
  • x=${w//[^aouieAOUIE]/} удаляет из слова все, кроме гласных
  • ${#x} длина полученной строки === количество гласных

Чувствуется как-то перестарался. Требование говорит, что вход будет содержать только буквы и пробелы. Так почему вы подготовили его для обработки нескольких строк ввода? Без while.. do.. doneбыло бы короче. Также не нужно последнее /при замене шаблона. И один буквальный пробел короче, чем указано. read l;for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo
Манатворк

Я согласен, но правило гласит: «Вы можете написать полную программу или функцию, которая принимает входные данные от стандартного ввода и выводит результат». Поэтому я решил составить полную программу. Я отредактирую решение, чтобы сохранить два байта)) Спасибо!
Сюэшэн

3

Юлия, 76 72 69 65 байт

for w=split(readline()) print(count(i->i"aeiouAEIOU",w)," ")end

Ungolfed + объяснение:

# Read a string from STDIN and split it into words
s = split(readline())

# For each word in the string...
for w in s
    # Get the number of vowels of any case in the word
    c = count(i -> i  "aeiouAEIOU", w)

    # Print the number of vowels identified
    print(c, " ")
end

Это будет включать в себя один пробел, который, как мне сказали, является законным.


2

Mathematica, 95 байт

Не собираюсь выигрывать конкурсы, но ...

Print@StringRiffle[ToString[#~StringCount~Characters@"aeiouAEIOU"]&/@StringSplit@InputString[]]

Вы знаете какие-нибудь онлайн-компиляторы, где я мог бы это проверить?
Spikatrix

Там нет, но вы можете получить бесплатную пробную версию здесь .
LegionMammal978

@CoolGuy Вы можете запустить код Mathematica (Wolfram Language) онлайн, если получите бесплатную учетную запись здесь . (Не уверен, что InputStringсуществует в веб-интерфейсе, это диалоговое окно в Mathematica.)

@Calle В сценариях Mathematica InputStringзанимает следующую строку ввода.
LegionMammal978

да я вижу. Ну, все еще не уверен, будет ли это работать в облачном ноутбуке, но по крайней мере теперь я знаю, почему он используется для стандартного ввода.

2

golflua, 55 байт

~@W I.r():l():gm("%w+")_,c=W:g("[aeiou]",'')I.w(c,' ')$

Базовое сопоставление с гласными после принудительной строчной буквы. Эквивалент Lua (ungolfed) будет

line=io.read()
for word in line:lower():gmatch("%w+") do
   _,c=word:gsub("[aeiou]",'')
   io.write(c," ")
end

Кроме того, для версии Lua было бы на 2 символа короче, чтобы использовать gsub('[aeiouAEIOU]','')и пропустить lower().
Кайл Канос

2

R 139 байт

Чтение / запись stdout () ужасно

s=function(x,y)strsplit(x,y)[[1]]
write(unlist(Map(function(x)sum(x%in%s("AIUEOaiueo","")),Map(s,s(readLines("stdin")," "),"")),),stdout())

Р не так и плохо . ;) Вы можете использовать, cat()а не write(..., stdout()).
Алекс А.

2

Python 3, 72 байта

Вдохновленный @randomra «s ответ . Это та же длина, немного длиннее, но с использованием регулярных выражений вместо понимания списка. Это также менее читабельно.

import re
print(*map(len,re.sub("[^aeiou ]","",input(),0,2).split(" ")))

Сохранить 7 байт: import re;print(*map(len,re.sub("[^aeiou ]","",input()).split())). (Используйте новую ;
строку

@ mbomb007 Он должен быть без учета регистра ( 2это флаг без учета регистра) и разбиваться на части, " "чтобы можно было иметь длину 0

Ах, мои тесты не были достаточно обширными, чтобы заметить это.
mbomb007

2

PHP - 94

foreach(explode(' ',$argv[1]) as$d){preg_match_all('/[aeiou]/i',$d,$v);echo count($v[0]).' ';}

Неуправляемая версия

$a = explode(' ',$argv[1]);
foreach($a as $d) {
    preg_match_all('/[aeiou]/i', $d, $v);
    echo count($v[0]).' ';
}

2

Objective-C, 223 байта

-(void)p:(NSString*)s{NSArray*a=[s componentsSeparatedByString:@" "];for(NSString*w in a){int c=0;for(int i=0;i<w.length;i++){if([@"aeiouAEIOU"containsString:[w substringWithRange:NSMakeRange(i,1)]]){c++;}}NSLog(@"%d",c);}}

Не самый компактный язык, но он работает.

Несжатая версия:

- (void)p:(NSString*)s{
    NSArray*a=[s componentsSeparatedByString:@" "];
    for (NSString*w in a) {
        int c=0;
        for (int i=0;i<w.length;i++) {
            if ([@"aeiouAEIOU" containsString:
                 [w substringWithRange:NSMakeRange(i, 1)]]) {
                c++;
            }
        }
        NSLog(@"%d",c);
    }
}

2

Matlab, 73 байта

Ваша задача не очень понятна (но она интересна). Я предполагаю, что

  • Под "гласный" вы имеете в виду a, e, i, o, u.
  • Строка не содержит начальных или конечных пробелов

Код:

diff(find(regexprep([' ' input('','s') ' '],'[^aeiouAEIOU ]','')==' '))-1

2

RS , 50 байтов

Это не совсем считается; RS был загружен через 2 недели после публикации. Тем не менее, очевидно, что это все равно ничего не выиграет, так что все равно круто.

*[aeiou]/_
(^| )[^_\s]+ |$/ 0
[^_\s0]/
(_+)/(^^\1)

Живая демоверсия.

Реализация довольно проста:

*[aeiou]/_            Replace all vowels with underscores.
(^| )[^_\s]+ |$/ 0    Replace words that have no vowels with a zero.
[^_\s0]/              Remove all other letters.
(_+)/(^^\1)           Convert the underscore sequences into numbers (e.g. '___' to 3).

2

Perl, 60 45

$/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "

Спасибо kirbyfan64sos за то, что я сэкономил 15 байтов - это действительно помогло!
Обратите внимание, что в конце вывода есть дополнительное место.


Вы можете удалить вызов split, установив добавление $/=" ";, и можете замкнуть префикс цикла на while(<>). С этими двумя изменениями код становится $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "}, сохраняя 14 байтов!
kirbyfan64sos

2

Haskell, 76 68 байт

f=interact$unwords.map(show.length).filter(`elem`"aeiouAEIOU").words

Простая реализация, не уверен, есть ли здесь что-нибудь для гольфа.


1

KDB (Q), 30 байтов

{sum@'lower[" "vs x]in"aeiou"}

объяснение

            " "vs x              / split x string by space
      lower[       ]             / lower case
                    in"aeiou"    / check vowel
 sum@'                           / sum each booleans
{                            }   / lambda

Тестовое задание

q){sum@'lower[" "vs x]in"aeiou"}"This is the first test case"
1 1 1 1 1 2i

1

Smalltalk - 66 72

Это в Smalltalk / X; имена для stdin и stdout могут отличаться в squeak / pharo.

Stdin nextLine subStrings do:[:w|(w count:[:c|c isVowel])print.' 'print]

В Smalltalk / X (и многих других диалектах) символы понимают #value:, поэтому его можно сократить до 66 символов:

 Stdin nextLine subStrings do:[:w|(w count:#isVowel)print.' 'print]

Если кодируется как функция, которая получает строку в качестве аргумента "s":

[:s|s subStrings do:[:w|(w count:#isVowel)print.' 'print]]

Конечно, в реальном коде можно было бы использовать служебную функцию «f», которая возвращает вектор отсчетов, и печатать это. Тем не менее, выходной формат тогда не совсем то, что требовал запрос:

f := [:s|s subStrings collect:[:w|(w count:#isVowel)]].
(f value: Stdin nextLine) print.

1

Python 2, 76 байт

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

print' '.join(`sum(y in'aeiouAEIOU'for y in x)`for x in raw_input().split())

1

PowerShell, 65 байт

($input-split'\s'|%{($_-split''-match'a|e|i|o|u').count})-join' '

протестируйте с помощью шаблона ниже после сохранения как vowels.ps1

"the quick brown fox" | vowels.ps1

Таким образом, это настоящий скрипт, а не просто фрагмент кода, удовлетворяющий таким образом ограничению:

Msgstr "Ввод должен быть получен из аргументов стандартного ввода или командной строки."


1

Желе , 7 байт

Ḳf€ØcL€

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

Найдено с помощью мистера Xcoder в чате

объяснение

Ḳf€ØcL€ - Main link. Argument: s (a string)  e.g. "aeiou AEIOU"
Ḳ       - Split the input on spaces               ["aeiou", "AEIOU"]
   Øc   - Generate the string "AEIOUaeiou" 
 f€     - Filter out consonants from €ach         ["aeiou", "AEIOU"]
     L€ - Length of €ach                          [5, 5]

Если выходные данные должны быть разделены пробелами, тогда добавьте a Kв конец


0

САС, 72

data;infile stdin;file stdout;input c$@@;x=countc(c,'aeiou','i');put x@;

Ограничительный формат ввода / вывода для этого действительно вредит этому, поскольку он отвечает за 25 байтов здесь.


0

C # 186

public class a{public static void Main(string[] a){Console.Write(string.Join(" ",Console.ReadLine().Split(' ').Select(x=>x.ToCharArray().Count(y=>"aeoui".ToCharArray().Contains(y)))));}}

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