Conte o número de vogais em cada palavra de uma sequência


13

Este é um desafio bastante fácil.

Desafio

A entrada conterá uma sequência (não nullvazia ou) de comprimento máximo 100. Emita o número de vogais em cada palavra da sequência, separadas por espaços.

Regras

  • A cadeia não terá mais de 100 caracteres.
  • A string conterá somente alfabetos A-Z, a-ze também pode conter espaços.
  • A entrada deve ser consumida a partir dos stdinargumentos da linha de comandos.
  • A saída deve ser emitida no stdout.
  • Você pode escrever um programa completo ou uma função que recebe entrada do stdine gera o resultado.
  • As vogais que seu programa / função precisa contar são aeioue AEIOU.

Casos de teste

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

Pontuação

Isso é , então o envio mais curto (em bytes) vence.


6
Existe uma razão pela qual você insiste em um formato de E / S bastante restritivo? Nem todos os idiomas podem (convenientemente) interagir com STDIN e STDOUT. Temos padrões para isso (que você pode substituir, se desejar), que também permitem argumentos de linha de comando, argumentos de funções, valores de retorno etc. (Eles também podem ser encontrados no tag wiki .)
Martin Ender

@ MartinBüttner, " Existe uma razão pela qual você insistir em um formato bastante restritivo I / O? " - Não. Eu apenas gosto stdincom stdout. Eu não gosto de "obter entrada" através dos argumentos da função. argumentos de linha de comando parece ok. Eu adicionei no post.
Spikatrix 21/05

4
WIKIPEDIA: 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.O que você quer dizer com vogais?
edc65 21/05

Há um único espaço à direita?
Alex A.

3
Use a Sandbox para os desafios propostos.
Mbomb007 22/05

Respostas:


8

Pitão, 17 bytes

jdml@"aeiou"dcrzZ

Solução simples. Experimente on-line: demonstração ou equipamento de teste

Explicação:

               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

Ele sempre me diverte quando as pessoas escrevem uma solução Pyth e chamá-lo de "Simples" (Embora este é reconhecidamente mais fácil de entender do que a maioria) +1
Christopher Wirt

10

C, 113 108 103 96 bytes

Obrigado @ andrea-biondo por uma economia particularmente agradável de 5 bytes.

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

Isso ainda parece meio inchado, então espero que eu consiga baixar alguns bytes mais tarde esta noite.

A parte interessante é talvez que

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

será 1if cé uma vogal ASCII (maiúscula ou minúscula) e 0para outros caracteres a-zA-Z. A subexpressão c-65&31mapeia 'a'e 'A'para 0, 'b'e 'B'para 2etc. Quando adicionamos 33as vogais correspondem aos números 33, 37, 41, 47, 53respectivamente, todos (convenientemente) primos. No nosso intervalo, apenas esses números serão divididos 124701951 = 33*37*41*47*53, ou seja, apenas para as vogais o restante 124701951%(...)será zero.

EDIT: Desta forma, pode-se considerar a expressão !(n%((c-65&31)+s))onde (n,s) = (124701951, 33)determina se o personagem cé uma vogal. Nos comentários, @ andrea-biondo apontou que o par (n,s) = (2016,28)também pode ser usado nesta expressão para determinar o vowelhood. Deixarei a explicação atual em termos de números primos acima, mas a razão pela qual esse emparelhamento mais curto funciona é novamente porque no intervalo de 28 a 53 os únicos números com fatores primos inteiramente no conjunto de fatores primos de 2016 são 28, 32, 36, 42, 48, que correspondem precisamente às vogais.

EDIT2: Outros 5 bytes salvos desde que (c-65&31)+28podem ser reduzidos para c%32+27.

EDIT3: convertido em um loop do-while para finalmente obtê-lo abaixo de 100 bytes.

Casos de teste:

$ ./vowelc "Este é o primeiro caso de teste"
1 1 1 1 1 2 
$ ./vowelc "um mais dois é igual a três"
2 1 1 3 2 
$ ./vowelc "aeiou AEIOU"
5 5 
$ ./vowelc "psst"                     
0 0

AMD! Isso é incrível! Você pode salvar mais bytes usando a;fora main. Dessa forma, você reduzir alguns bytes que você não precisa declarar aem main(...)e também, não precisam para inicializar aa partir do loop.
Spikatrix 21/05

1
@CoolGuy: aé reinicializado a cada loop, então você não pode inicializá-lo uma vez para zero declarando global. Eu escrevi um pequeno bruteforcer para encontrar o menor (n, s)par tal que n%((c-65&31)+s)é zero para vogais e diferente de zero para consoantes (az, AZ). Descobri (2016, 28)e parece funcionar bem: !(2016%((c-65&31)+28))são 5 caracteres mais curtos. Enfim, solução muito legal :) #
Andrea Biondo 21/15

7

CJam, 21 19 bytes

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

Como funciona :

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

Experimente online aqui


6

R, 44 43 bytes

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

Ungolfed + explicação:

# 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

30caracteres +1para -n.

Como muitos códigos Perl, isso funciona da direita para a esquerda. splitdividirá a linha inserida no espaço em branco. mapexecutará o código entre {}cada palavra que foi dividida. lctorna a palavra minúscula. =~y/aeiou//nos dará a contagem de vogais. .$"acrescentará um espaço à palavra. saydepois imprime todas as palavras!

Correr com:

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

4

Python 3, 65 bytes

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

Muito simples, bastante legível. wsignifica palavra, csignifica caráter.


4

Perl: 30 caracteres

(Tipo de força as regras: os números na saída são separados com tantos espaços quanto as palavras de entrada).

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

Exemplo de execução:

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 caracteres

(Apenas para mostrar quão curto seria se eu não esquecesse y///o valor de retorno de. Mais uma vez. Agora vá e vote novamente na resposta da chilemagic , que me lembrou y///o valor de retorno de.

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

Dang isso bate minha resposta. Isso s!\w+!lc($&)=~y/aeiou//!gereduz para 27bytes (26 caracteres +1 para o -p.
hmatt1

Sim obrigado. Não posso mais contar com meus dedos quantas vezes esqueci y///. :(
manatwork

3

Ruby, 38 bytes

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

Uso:

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

3

JavaScript ( ES6 ), 68

E / S via pop-up. Execute o trecho no Firefox para testar.

// 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

Rebol - 70

print map-each n split input" "[c: 0 find-all n charset"aeiou"[++ c]c]

3

PowerShell, 35 bytes

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

Meio chato, mas realmente competindo pela primeira vez? (Por padrão, o PowerShell não diferencia maiúsculas de minúsculas)


FYI, você needto chamar isto como echo <word> | code, onde <word> é a sua palavra ou frase
Pureferret

3

Bash - 85

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

Explicação

  • read l leia uma linha da entrada
  • for w in l divide a linha em palavras usando o separador de espaço em branco
  • x=${w//[^aouieAOUIE]/} exclui todas as vogais, exceto as da palavra
  • ${#x} é o comprimento da sequência resultante === número de vogais

Parece de alguma forma exagerado. O requisito diz que a entrada conterá apenas letras e espaços. Então, por que você o preparou para processar várias linhas de entrada? Sem while.. do.. doneseria mais curto. Também não é necessário o último /na substituição de padrão. E um único espaço literal é mais curto que o citado. read l;for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo
Manatwork 23/05

Concordo, mas a regra diz 'Você pode escrever um programa completo ou uma função que recebe a entrada do stdin e gera o resultado'. Então eu decidi fazer o programa completo. Vou editar a solução para salvar dois bytes)) Obrigado!
Xuesheng # 23/15

3

Julia, 76 72 69 65 bytes

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

Ungolfed + explicação:

# 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

Isso incluirá um único espaço à direita, que me disseram ser legítimo.


2

Mathematica, 95 bytes

Não vai ganhar nenhum concurso, mas ...

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

Você conhece algum compilador on-line onde eu possa testar isso?
Spikatrix # 21/15

Não há, mas você pode obter uma avaliação gratuita aqui .
LegionMammal978

@CoolGuy Você pode executar o código do Mathematica (Wolfram Language) on-line se tiver uma conta gratuita aqui . (Não InputStringexiste certeza na interface da Web, é uma caixa de diálogo no Mathematica.) #

@Calle Nos scripts do Mathematica, InputStringassume a próxima linha de entrada.
LegionMammal978

OK eu vejo. Ainda não tenho certeza se funcionará no notebook em nuvem, mas pelo menos agora eu sei por que está sendo usado para o stdin.

2

golflua, 55 bytes

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

Correspondência básica de vogais após minúsculas forçadas. Um equivalente Lua (não destruído) seria

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

Como um aparte, para a versão Lua, na verdade, seriam 2 caracteres mais curtos para usar gsub('[aeiouAEIOU]','')e pular lower().
Kyle Kanos #

2

R , 139 bytes

Ler / escrever stdout () é terrível

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

R não é tão ruim . ;) Você pode usar em cat()vez de write(..., stdout()).
Alex A.

2

Python 3, 72 bytes

Inspirado por @randomra 's resposta . Tem o mesmo comprimento um pouco mais, mas usando regex em vez de compreensão de lista. Também é menos legível.

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

Salve 7 bytes: import re;print(*map(len,re.sub("[^aeiou ]","",input()).split())). (Uso de nova linha, em vez de ;se você quiser.)
mbomb007

@ mbomb007 Ele precisa ser insensível caso ( 2é o caso da bandeira insensitive) e dividir por " "assim lá pode ser 0 comprimento coisas

Ah, meus testes não foram extensos o suficiente para perceber isso.
Mbomb007 29/05

2

PHP - 94

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

Versão ungolfed

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

2

Objective-C, 223 bytes

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

Não é a linguagem mais compacta, mas funciona.

Versão não compactada:

- (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 bytes

Seu desafio não é muito claro (mas é interessante). Estou assumindo

  • Por "vogal" você quer dizer a, e, i, o, u.
  • A sequência não contém espaços à esquerda ou à direita

Código:

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

2

rs , 50 bytes

Isso não conta muito; O rs foi enviado cerca de 2 semanas após o lançamento. No entanto, evidentemente, isso não ganharia nada, então ainda é legal.

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

Demonstração ao vivo.

A implementação é bastante direta:

*[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 "

Obrigado a kirbyfan64sos por me salvar 15 bytes - isso realmente ajudou!
Observe que há um espaço extra no final da saída.


Você pode remover a chamada splitconfigurando a adição $/=" ";e pode colocar o prefixo do loop em curto while(<>). Com essas duas alterações, o código se torna $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "}, economizando 14 bytes!
precisa saber é o seguinte

2

Haskell, 76 68 bytes

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

Implementação direta, não tenho certeza se há algo para jogar aqui.


1

KDB (Q), 30 bytes

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

Explicação

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

Teste

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

1

Smalltalk - 66 72

Isso está no Smalltalk / X; os nomes para stdin e stdout podem ser diferentes em squeak / pharo.

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

No Smalltalk / X (e em muitos outros dialetos), os símbolos entendem #value :, portanto, pode ser abreviado para 66 caracteres:

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

Se codificado como uma função que obtém a string como argumento "s":

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

Obviamente, no código real, alguém usaria a função utilitário "f", que retorna um vetor das contagens e imprime isso. No entanto, o formato de saída não é exatamente o que o desafio solicitou:

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

1

Python 2, 76 bytes

Eu fiz isso antes de encontrar qualquer outra solução, depois verifiquei para encontrar duas soluções P3 mais curtas :( Limitações P2 malditas.

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

1

PowerShell, 65 bytes

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

teste usando o padrão abaixo após salvar como vowels.ps1

"the quick brown fox" | vowels.ps1

Dessa forma, é um script real e não apenas um trecho de código, satisfazendo a restrição:

"A entrada deve ser consumida a partir dos argumentos stdin ou da linha de comando."


1

Geléia , 7 bytes

Ḳf€ØcL€

Experimente online!

Encontrado com a ajuda do Sr. Xcoder em chat

Explicação

Ḳ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]

Se a saída precisar ser separada por espaço, anexe Ka no final


0

SAS, 72

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

O formato restritivo de E / S para este realmente prejudica este, pois é responsável por 25 dos bytes aqui.


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

Isso falha no terceiro caso de teste. Seu programa parece não contar AEIOU.
Spikatrix
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.