Порахуйте кількість голосних у кожному слові рядка


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%(...)нулю.

EDIT: Таким чином можна розглядати вираз, !(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: Перетворюється на цикл "час роботи", щоб остаточно отримати його нижче 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з циклу.
Spikatrix

1
@CoolGuy: aповторно ініціалізується в кожному циклі, тому ви не можете ініціалізувати його один раз до нуля, оголосивши глобальним. Я написав маленького грубої думки, щоб знайти найменшу (n, s)пару таку, яка n%((c-65&31)+s)для голосних і нульова для приголосних (нуль, 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)))

Недоліковані + пояснення:

# 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//!ge27-p
зводить

Так дякую. Я вже не можу порахувати на пальцях, скільки разів я забув y///. :(
манатура


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 є нечутливим, ву)


FYI, вам потрібно назвати подібне echo <word> | code, де <word> - ваше слово чи фраза
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
манастирські роботи

Я погоджуюсь, але правило говорить: "Ви можете написати повну програму або функцію, яка приймає введення з stdin та видає результат." Тому я вирішив зробити повну програму. Я відредагую рішення, щоб зберегти два байти)) Дякую!
xuesheng

3

Джулія, 76 72 69 65 байт

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

Недоліковані + пояснення:

# 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

Математика, 95 байт

Не збирається вигравати жодних конкурсів, але ...

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

Чи знаєте ви які-небудь онлайн-компілятори, де я міг би це перевірити?
Spikatrix

Немає таких, але ви можете отримати безкоштовну пробну версію тут .
LegionMammal978

@CoolGuy Ви можете запустити код Mathematica (Wolfram Language) в Інтернеті , якщо ви отримаєте безкоштовний аккаунт тут . (Не впевнений, що InputStringіснує у веб-інтерфейсі, проте це діалог у Mathematica.)

@Calle У сценаріях Mathematica InputStringбере наступний рядок введення.
LegionMammal978

Добре, я бачу. Я все ще не впевнений, чи буде він працювати у хмарному зошиті, але принаймні зараз я знаю, чому його використовують для stdin.

2

гольфлуа, 55 байт

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

Базовий збіг голосних після примусових малих літер. Еквівалент Луа був би (безгольовий)

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

В іншому випадку, для версії Lua, вона фактично буде на два символи коротше, щоб використовувати gsub('[aeiouAEIOU]','')та пропускати далі lower().
Кайл Канос


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

Матлаб, 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

Перл, 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

КДБ (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

Малий розмова - 66 72

Це в Smalltalk / X; назви stdin і stdout можуть бути різними в писку / фаро.

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, які є коротшими :( обмеження Darn 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

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

"Введення має використовуватися з аргументів stdin або командного рядка."


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

SAS, 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.
Spikatrix
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.