Cuenta el número de vocales en cada palabra de una cadena

13

Este es un desafío bastante fácil.

Desafío

La entrada contendrá una cadena (no nullvacía) de una longitud máxima de 100. Emite el número de vocales en cada palabra de la cadena, separadas por espacios.

Reglas

  • La cadena no tendrá más de 100 caracteres de longitud.
  • La cadena sólo contendrá alfabetos A-Z, a-zy también puede contener espacios.
  • La entrada se debe consumir desde los stdinargumentos de la línea de comando o.
  • La salida debe salir en el stdout.
  • Puede escribir un programa completo, o una función que tome la entrada del stdiny salga el resultado.
  • Las vocales que su programa / función necesita contar son aeiouy AEIOU.

Casos de prueba

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

Puntuación

Este es el , por lo que gana el envío más corto (en bytes).

Spikatrix
fuente
66
¿Hay alguna razón por la que insiste en un formato de E / S bastante restrictivo? No todos los idiomas pueden (convenientemente) interactuar con STDIN y STDOUT. Tenemos valores predeterminados para esto (que, por supuesto, puede anular si lo desea), que también permiten el argumento de la línea de comandos, el argumento de la función, el valor de retorno, etc. (También se pueden encontrar en el wiki de la etiqueta ).
Martin Ender
@ MartinBüttner, " ¿Hay alguna razón por la que insiste en un formato bastante restrictiva de E / S? " - No. Yo al igual que stdincon stdout. No me gusta "obtener información" a través de los argumentos de la función. los argumentos de la línea de comandos parecen estar bien Lo he añadido a la publicación.
Spikatrix
44
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.¿Qué quieres decir con vocales?
edc65
¿Está bien un solo espacio final?
Alex A.
3
Usa el Sandbox para los desafíos propuestos.
mbomb007

Respuestas:

8

Pyth, 17 bytes

jdml@"aeiou"dcrzZ

Solución directa. Pruébelo en línea: demostración o prueba de arnés

Explicación:

               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
Jakube
fuente
Siempre me divierte cuando la gente escribe una solución Pyth y la llaman "Directa" (aunque esta es ciertamente más fácil de entender que la mayoría) +1
Christopher Wirt
10

C, 113108103 96 bytes

Gracias @ andrea-biondo por un ahorro particularmente agradable 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]);}

Esto todavía se siente un poco hinchado, así que espero poder descifrar algunos bytes más tarde esta noche.

La parte interesante es quizás que

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

será 1si ces una vocal ASCII (mayúscula o minúscula) y 0para otros caracteres a-zA-Z. La subexpresión c-65&31mapas 'a'y 'A'a 0, 'b'y 'B'a 2, etc. Cuando añadimos 33las vocales corresponden a los números 33, 37, 41, 47, 53, respectivamente, todos los cuales son (convenientemente) prime. En nuestro rango solo esos números se dividirán124701951 = 33*37*41*47*53 , es decir, solo para vocales, el resto 124701951%(...)será cero.

EDITAR: De esta manera, uno puede considerar la expresión !(n%((c-65&31)+s))donde (n,s) = (124701951, 33)determina si el personaje ces una vocal. En los comentarios, @andrea-biondo señaló que la pareja(n,s) = (2016,28) también se puede usar en esta expresión para determinar la vocalidad. Dejaré la explicación actual en términos de números primos anteriores, pero la razón por la que funciona este emparejamiento más corto es porque en el rango 28-53 los únicos números con factores primos enteramente en el conjunto de factores primos de 2016 son 28, 32, 36, 42, 48, que corresponden precisamente a las vocales.

EDIT2: otros 5 bytes guardados ya que (c-65&31)+28se pueden acortar ac%32+27 .

EDITAR3: convertido a un bucle do-while para finalmente llegar a menos de 100 bytes.

Casos de prueba:

$ ./vowelc "Este es el primer caso de prueba"
1 1 1 1 1 2 
$ ./vowelc "uno más dos es igual a tres"
2 1 1 3 2 
$ ./vowelc "aeiou AEIOU"
5 5 
$ ./vowelc "psst"                     
0 0
CL-
fuente
¡DIOS MIO! ¡Esto es simplemente increíble! Puede guardar más bytes usando a;afuera main. De esta forma, reducir algunos bytes, ya que no es necesario declarar aen main(...)y también, no es necesario inicializar adesde el bucle.
Spikatrix
1
@CoolGuy: ase reinicia en cada ciclo, por lo que no puede inicializarlo una vez a cero al declarar global. Escribí un pequeño bruteforcer para encontrar el (n, s)par más pequeño tal que n%((c-65&31)+s)sea ​​cero para las vocales y no cero para las consonantes (az, AZ). Encontré (2016, 28)y parece funcionar bien: !(2016%((c-65&31)+28))es 5 caracteres más corto. De todos modos, muy buena solución :)
Andrea Biondo
7

CJam, 21 19 bytes

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

Cómo 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

Pruébalo en línea aquí

Optimizador
fuente
6

R, 44 43 bytes

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

Ungolfed + explicación:

# 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))
Alex A.
fuente
5

Perl, 35 34 31

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

30personajes +1para -n.

Al igual que muchos códigos Perl, esto funciona de derecha a izquierda. splitdividirá la línea ingresada en el espacio en blanco. mapejecutará el código entre {}cada palabra que se dividió. lchace que la palabra sea minúscula. =~y/aeiou//nos dará el recuento de vocales. .$"agregará un espacio a la palabra. sayluego imprime todas las palabras!

Corre con:

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

Python 3, 65 bytes

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

Muy sencillo, bastante legible. wsignifica palabra, csignifica carácter.

randomra
fuente
4

Perl: 30 caracteres

(Tipo de fuerza las reglas: los números en la salida se separan con tantos espacios como las palabras de entrada).

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

Ejecución de muestra:

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

(Solo para mostrar lo corto que sería si no me olvidara del y///valor de retorno. Nuevamente. Ahora ve y vota la respuesta de chilemagic que me recordó el y///valor de retorno. Otra vez).

s|\w+|lc($&)=~y/aeiou//|ge
hombre trabajando
fuente
Dang esto supera mi respuesta. Esto s!\w+!lc($&)=~y/aeiou//!gelo reduce a 27bytes (26 caracteres +1 para -p.
hmatt1
Si gracias. Ya no puedo contar con mis dedos cuántas veces me olvidé y///. :(
manatwork
3

Rubí, 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
blutorange
fuente
3

JavaScript ( ES6 ), 68

E / S a través de una ventana emergente. Ejecute el fragmento en Firefox para probar.

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

edc65
fuente
3

Rebol - 70

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

PowerShell, 35 bytes

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

¿Un poco aburrido, pero en realidad compitiendo por una vez? (PowerShell no distingue entre mayúsculas y minúsculas por defecto, woo)

Nacht - Restablece a Monica
fuente
Para su información, debe llamar a esto como echo <word> | code, donde <word> es su palabra o frase
Pureferret
3

Golpe - 85

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

Explicación

  • read l leer una línea de entrada
  • for w in l divide la línea en palabras usando un separador de espacios en blanco
  • x=${w//[^aouieAOUIE]/} borra todo excepto las vocales de la palabra
  • ${#x} es la longitud de la cadena resultante === número de vocales
xuesheng
fuente
Se siente de alguna manera exagerado. El requisito dice que la entrada contendrá solo letras y espacios. Entonces, ¿por qué lo preparó para procesar múltiples líneas de entrada? Sin while.. do.. donesería más corto. Tampoco se necesita el último /en la sustitución del patrón. Y un espacio literal único se escapa más corto de lo citado. read l;for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo
manatwork
Estoy de acuerdo, pero la regla dice 'Puedes escribir un programa completo, o una función que toma la entrada del stdin y genera el resultado'. Así que he decidido hacer el programa completo. Editaré la solución para guardar dos bytes)) ¡Gracias!
xuesheng
3

Julia, 76 72 69 65 bytes

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

Ungolfed + explicación:

# 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

Esto incluirá un único espacio final, que me dicen es legítimo.

Alex A.
fuente
2

Mathematica, 95 bytes

No voy a ganar ningún concurso, pero ...

Print@StringRiffle[ToString[#~StringCount~Characters@"aeiouAEIOU"]&/@StringSplit@InputString[]]
LegionMammal978
fuente
¿Conoces algún compilador en línea donde pueda probar esto?
Spikatrix
No hay ninguno, pero puedes obtener una prueba gratuita aquí .
LegionMammal978
@CoolGuy Puede ejecutar el código de Mathematica (Wolfram Language) en línea si obtiene una cuenta gratuita aquí . (Sin InputStringembargo, no estoy seguro de que exista en la interfaz web, es un diálogo en Mathematica.)
@Street En los scripts de Mathematica, InputStringtoma la siguiente línea de entrada.
LegionMammal978
OK veo. Bueno, todavía no estoy seguro de si funcionará en el cuaderno en la nube, pero al menos ahora sé por qué se usa para stdin.
2

golflua, 55 bytes

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

Coincidencia de patrones básicos de vocales después de minúsculas forzadas. Un equivalente de Lua (sin golf) sería

line=io.read()
for word in line:lower():gmatch("%w+") do
   _,c=word:gsub("[aeiou]",'')
   io.write(c," ")
end
Kyle Kanos
fuente
Como comentario aparte, para la versión Lua, en realidad serían 2 caracteres más cortos para usar gsub('[aeiouAEIOU]','')y omitir lower().
Kyle Kanos
2

R , 139 bytes

Leer / escribir stdout () es terrible

s=function(x,y)strsplit(x,y)[[1]]
write(unlist(Map(function(x)sum(x%in%s("AIUEOaiueo","")),Map(s,s(readLines("stdin")," "),"")),),stdout())
Vlo
fuente
R no es tan malo . ;) Puede usar en cat()lugar de write(..., stdout()).
Alex A.
2

Python 3, 72 bytes

Inspirado por la respuesta de @randomra . Es la misma longitud un poco más larga, pero usa expresiones regulares en lugar de comprensión de listas. También es menos legible.

import re
print(*map(len,re.sub("[^aeiou ]","",input(),0,2).split(" ")))
Comunidad
fuente
Guardar 7 bytes: import re;print(*map(len,re.sub("[^aeiou ]","",input()).split())). (Use nueva línea en lugar de ;si lo desea.)
mbomb007
@ mbomb007 Debe ser insensible a mayúsculas y minúsculas ( 2es el distintivo de mayúsculas y minúsculas) y dividido por " "lo que puede haber 0 cosas de longitud
Ah, mis pruebas no fueron lo suficientemente extensas como para notar eso.
mbomb007
2

PHP - 94

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

Versión sin golf

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

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

No es el lenguaje más compacto, pero funciona.

Versión sin comprimir:

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

Matlab, 73 bytes

Su desafío no está muy claro (pero es interesante). Estoy asumiendo

  • Por "vocal" quiere decir a, e, i, o,u .
  • La cadena no contiene espacios iniciales o finales

Código:

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

rs , 50 bytes

Esto no cuenta del todo; rs fue cargado alrededor de 2 semanas después de que esto fue publicado. Sin embargo, evidentemente esto no ganaría nada de todos modos, por lo que sigue siendo genial.

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

Demo en vivo.

La implementación es bastante sencilla:

*[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).
kirbyfan64sos
fuente
2

Perl, 60 45

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

Gracias a kirbyfan64sos por salvarme 15 bytes, ¡eso realmente ayudó!
Tenga en cuenta que hay un espacio adicional al final de la salida.

ASCIIThenANSI
fuente
Puede eliminar la llamada a splitmediante la configuración de agregar $/=" ";, y puede acortar el prefijo de bucle a while(<>). ¡Con esos dos cambios, el código se convierte en un $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "}ahorro de 14 bytes!
kirbyfan64sos
2

Haskell, 76 68 bytes

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

Implementación directa, no estoy seguro si hay algo para jugar golf aquí.

ThreeFx
fuente
1

KDB (Q), 30 bytes

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

Explicación

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

Prueba

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

Smalltalk - 66 72

Esto está en Smalltalk / X; Los nombres de stdin y stdout pueden ser diferentes en squeak / pharo.

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

En Smalltalk / X (y muchos otros dialectos), los símbolos entienden #value :, por lo que pueden abreviarse a 66 caracteres:

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

Si se codifica como una función que obtiene la cadena como argumento "s":

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

Por supuesto, en código real, uno usaría una función de utilidad "f", que devuelve un vector de los recuentos, e imprime eso. Sin embargo, el formato de salida no es exactamente lo que pidió el desafío:

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

Python 2, 76 bytes

Hice esto antes de ver cualquier otra solución, luego verifiqué para encontrar dos soluciones P3 que son más cortas :( Limitaciones de P2.

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

PowerShell, 65 bytes

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

prueba usando el siguiente patrón después de guardar como vowels.ps1

"the quick brown fox" | vowels.ps1

De esta manera, es un script real y no solo un fragmento de código, lo que satisface la restricción:

"La entrada debe consumirse a partir de los argumentos de línea de comando o stdin".

Bevo
fuente
1

Jalea , 7 bytes

Ḳf€ØcL€

Pruébalo en línea!

Encontrado con ayuda del Sr. Xcoder en el chat

Explicación

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

Si la salida debe estar separada por espacios, agregue Ka al final

caird coinheringaahing
fuente
0

SAS, 72

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

El formato de E / S restrictivo para este realmente perjudica a este, ya que es responsable de 25 de los bytes aquí.

Huevo frito
fuente
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)))));}}
DLeh
fuente
Esto falla para el tercer caso de prueba. Su programa no parece contar AEIOU.
Spikatrix