Comptez le nombre de voyelles dans chaque mot d'une chaîne

13

C'est un défi assez facile.

Défi

L'entrée contiendra une chaîne (non nullou vide) d'une longueur maximale de 100. Produisez le nombre de voyelles dans chaque mot de la chaîne, séparées par des espaces.

Règles

  • La chaîne ne dépassera pas 100 caractères.
  • La chaîne ne contient que alphabets A-Z, a-zet peut également contenir des espaces.
  • L'entrée doit être consommée à partir des stdinarguments de ligne de commande ou.
  • La sortie doit être sortie dans le stdout.
  • Vous pouvez écrire un programme complet ou une fonction qui prend une entrée dans le stdinet produit le résultat.
  • Les voyelles que votre programme / fonction doit compter sont aeiouet AEIOU.

Cas de 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
psst                            --> 0
the quick brown fox jumped over the lazy dog --> 1 2 1 1 2 2 1 1 1

Notation

Il s'agit de , donc la soumission la plus courte (en octets) l'emporte.

Spikatrix
la source
6
Y a-t-il une raison pour laquelle vous insistez sur un format d'E / S plutôt restrictif? Toutes les langues ne peuvent pas (commodément) interagir avec STDIN et STDOUT. Nous avons des valeurs par défaut pour cela (que vous êtes bien sûr libre de remplacer si vous le souhaitez), qui autorisent également l'argument de ligne de commande, l'argument de fonction, la valeur de retour, etc. (Ils peuvent également être trouvés dans le wiki wiki .)
Martin Ender
@ MartinBüttner, " Y a-t-il une raison pour laquelle vous insistez sur un format d'E / S plutôt restrictif? " - Non. J'aime juste stdinavec stdout. Je n'aime pas "obtenir d'entrée" via les arguments de la fonction. les arguments de la ligne de commande semblent corrects. Je l'ai ajouté dans le post.
Spikatrix
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.Qu'entendez-vous par voyelles?
edc65
Un seul espace de fuite est-il correct?
Alex A.
3
Utilisez le bac à sable pour les défis proposés.
mbomb007

Réponses:

8

Pyth, 17 octets

jdml@"aeiou"dcrzZ

Solution simple. Essayez-le en ligne: démonstration ou test harnais

Explication:

               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
la source
Cela m'amuse toujours quand les gens écrivent une solution Pyth et l'appellent "Simple" (Bien que celle-ci soit certes plus facile à saisir que la plupart) +1
Christopher Wirt
10

C, 113 108 103 96 96 octets

Merci @ andrea-biondo pour une économie particulièrement agréable de 5 octets.

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

Cela semble toujours un peu gonflé, donc j'espère que je pourrai le réduire quelques octets plus tard ce soir.

La partie intéressante est peut-être que

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

sera 1si cest une voyelle ASCII (majuscule ou minuscule), et 0pour les autres caractères a-zA-Z. La sous-expression c-65&31mappe 'a'et 'A'vers 0, 'b'et 'B'vers 2, etc. Lorsque nous ajoutons 33les voyelles correspondent 33, 37, 41, 47, 53respectivement aux nombres , qui sont tous (commodément) premiers. Dans notre gamme, seuls ces nombres se diviseront 124701951 = 33*37*41*47*53, c'est-à-dire que pour les voyelles, le reste 124701951%(...)sera nul.

EDIT: De cette façon, on peut considérer l'expression !(n%((c-65&31)+s))(n,s) = (124701951, 33)comme déterminer si le personnage cest une voyelle. Dans les commentaires @ andrea-biondo a souligné que la paire (n,s) = (2016,28)peut également être utilisée dans cette expression pour déterminer la voyelle. Je vais laisser l'explication actuelle en termes de nombres premiers ci-dessus, mais la raison pour laquelle cet appariement plus court fonctionne est à nouveau parce que dans la plage 28--53, les seuls nombres avec des facteurs premiers entièrement dans l'ensemble des facteurs premiers de 2016 sont 28, 32, 36, 42, 48, qui correspondent précisément aux voyelles.

EDIT2: 5 autres octets enregistrés depuis (c-65&31)+28peuvent être raccourcis c%32+27.

EDIT3: converti en boucle do-while pour finalement le faire descendre en dessous de 100 octets.

Cas de test:

$ ./vowelc "Ceci est le premier cas de test"
1 1 1 1 1 2 
$ ./vowelc "un plus deux égale trois"
2 1 1 3 2 
$ ./vowelc "aeiou AEIOU"
5 5 
$ ./vowelc "psst"                     
0
CL-
la source
OMG! C'est tout simplement génial! Vous pouvez enregistrer plus d'octets en utilisant l' a;extérieur main. De cette façon, vous réduisez certains octets car vous n'avez pas besoin de déclarer adans main(...)et aussi, pas besoin d'initialiser à apartir de la boucle.
Spikatrix
1
@CoolGuy: aest réinitialisé à chaque boucle, vous ne pouvez donc pas l'initialiser une fois à zéro en déclarant global. J'ai écrit un petit bruteforcer pour trouver la plus petite (n, s)paire telle que n%((c-65&31)+s)zéro pour les voyelles et non nulle pour les consonnes (az, AZ). J'ai trouvé (2016, 28)et cela semble bien fonctionner: !(2016%((c-65&31)+28))est 5 caractères plus court. Quoi qu'il en soit, très belle solution :)
Andrea Biondo
7

CJam, 21 19 octets

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

Comment ça marche :

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

Essayez-le en ligne ici

Optimiseur
la source
6

R, 44 43 octets

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

Non golfé + explication:

# 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.
la source
5

Perl, 35 34 31

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

30caractères +1pour -n.

Comme beaucoup de code Perl, cela fonctionne de droite à gauche. splitdivisera la ligne entrée sur les espaces. mapexécutera le code entre {}sur chaque mot qui a été divisé. lcrend le mot en minuscule. =~y/aeiou//nous donnera le nombre de voyelles. .$"ajoutera un espace au mot. sayimprime ensuite tous les mots!

Courir avec:

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

Python 3, 65 octets

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

Très simple, assez lisible. wreprésente le mot, creprésente le caractère.

randomra
la source
4

Perl: 30 caractères

(Type de force les règles: les nombres dans la sortie sont séparés avec autant d'espaces que les mots d'entrée.)

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

Exemple d'exécution:

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 caractères

(Juste pour montrer à quel point ce serait court si je n'oublie pas la y///valeur de retour de. Encore une fois. Maintenant, allez voter pour la réponse de chilemagic qui m'a rappelé la y///valeur de retour de.

s|\w+|lc($&)=~y/aeiou//|ge
homme au travail
la source
Dang cela bat ma réponse. Cela s!\w+!lc($&)=~y/aeiou//!gele réduit à 27octets (26 caractères +1 pour le -p.
hmatt1
Oui merci. Je ne peux plus compter sur mes doigts combien de fois j'ai oublié y///. :(
manatwork
3

Rubis, 38 octets

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

Usage:

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

JavaScript ( ES6 ), 68

E / S via popup. Exécutez l'extrait dans Firefox pour tester.

// 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
la source
3

Rebol - 70

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

PowerShell, 35 octets

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

Un peu ennuyeux, mais en compétition pour une fois? (PowerShell ne respecte pas la casse par défaut, woo)

Nacht - Rétablir Monica
la source
Pour info, vous devez appeler cela comme echo <word> | code, où <mot> est votre mot ou expression
Pureferret
3

Coup - 85

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

Explication

  • read l lire une ligne de l'entrée
  • for w in l divise la ligne en mots à l'aide du séparateur d'espaces
  • x=${w//[^aouieAOUIE]/} supprime tout sauf les voyelles du mot
  • ${#x} est la longueur de la chaîne résultante === nombre de voyelles
xuesheng
la source
Se sent en quelque sorte exagéré. L'exigence indique que l'entrée ne contiendra que des lettres et des espaces. Alors pourquoi l'avez-vous préparé pour traiter plusieurs lignes d'entrée? Sans while.. do.. doneserait plus court. Pas non plus besoin du dernier /dans la substitution de modèle. Et un seul espace littéral est échappé plus court que cité. read l;for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo
manatwork
Je suis d'accord, mais la règle dit: «Vous pouvez écrire un programme complet ou une fonction qui prend l'entrée de la stdin et génère le résultat. J'ai donc décidé de faire le programme complet. Je vais modifier la solution pour économiser deux octets)) Merci!
xuesheng
3

Julia, 76 72 69 65 octets

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

Non golfé + explication:

# 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

Cela comprendra un seul espace de fuite, dont on me dit qu'il est légitime.

Alex A.
la source
2

Mathematica, 95 octets

Je ne gagnerai aucun concours, mais ...

Print@StringRiffle[ToString[#~StringCount~Characters@"aeiouAEIOU"]&/@StringSplit@InputString[]]
LegionMammal978
la source
Connaissez-vous des compilateurs en ligne où je pourrais tester cela?
Spikatrix
Il n'y en a pas, mais vous pouvez obtenir un essai gratuit ici .
LegionMammal978
@CoolGuy Vous pouvez exécuter le code Mathematica (Wolfram Language) en ligne si vous obtenez un compte gratuit ici . (Pas sûr cependant qu'il InputStringexiste dans l'interface Web, c'est une boîte de dialogue dans Mathematica.)
@Calle Dans les scripts Mathematica, InputStringprend la ligne d'entrée suivante.
LegionMammal978
OK je vois. Eh bien, je ne sais toujours pas si cela fonctionnera dans le bloc-notes cloud, mais au moins maintenant, je sais pourquoi il est utilisé pour stdin.
2

golflua, 55 octets

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

Correspondance de base des voyelles après les minuscules forcées. Un équivalent (non golfé) de Lua serait

line=io.read()
for word in line:lower():gmatch("%w+") do
   _,c=word:gsub("[aeiou]",'')
   io.write(c," ")
end
Kyle Kanos
la source
Soit dit en passant, pour la version Lua, ce serait en fait 2 caractères plus courts à utiliser gsub('[aeiouAEIOU]','')et à sauter lower().
Kyle Kanos
2

R , 139 octets

La lecture / écriture de stdout () est 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
la source
R n'est pas si mal . ;) Vous pouvez utiliser cat()plutôt que write(..., stdout()).
Alex A.
2

Python 3, 72 octets

Inspiré par @randomra de réponse . C'est la même longueur légèrement plus longue, mais en utilisant l'expression régulière au lieu de la compréhension de la liste. C'est aussi moins lisible.

import re
print(*map(len,re.sub("[^aeiou ]","",input(),0,2).split(" ")))
Communauté
la source
Enregistrer 7 octets: import re;print(*map(len,re.sub("[^aeiou ]","",input()).split())). (Utilisez la nouvelle ligne au lieu de ;si vous le souhaitez.)
mbomb007
@ mbomb007 Il doit être insensible à la casse ( 2est l'indicateur insensible à la casse) et divisé par " "afin qu'il puisse y avoir 0
Ah, mes tests n'étaient pas assez approfondis pour le remarquer.
mbomb007
2

PHP - 94

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

Version non golfée

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

Objective-C, 223 octets

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

Pas le langage le plus compact, mais ça marche.

Version non compressée:

- (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
la source
2

Matlab, 73 octets

Votre défi n'est pas très clair (mais il est intéressant). je suppose

  • Par "voyelle" vous voulez dire a, e, i, o, u.
  • La chaîne ne contient pas d'espaces de début ou de fin

Code:

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

rs , 50 octets

Cela ne compte pas vraiment; rs a été téléchargé environ 2 semaines après sa publication. Cependant, évidemment, cela ne gagnerait rien de toute façon, donc c'est toujours cool.

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

Démo en direct.

L'implémentation est assez simple:

*[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
la source
2

Perl, 60 45

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

Merci à kirbyfan64sos de m'avoir sauvé 15 octets - ça m'a vraiment aidé!
Notez qu'il y a un espace supplémentaire à la fin de la sortie.

ASCIIThenANSI
la source
Vous pouvez supprimer l'appel à spliten définissant l'ajout $/=" ";et vous pouvez raccourcir le préfixe de boucle à while(<>). Avec ces deux changements, le code devient $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "}, économisant 14 octets!
kirbyfan64sos
2

Haskell, 76 68 octets

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

Mise en œuvre simple, je ne sais pas s'il y a quelque chose à jouer au golf ici.

ThreeFx
la source
1

KDB (Q), 30 octets

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

Explication

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

Tester

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

Smalltalk - 66 72

C'est dans Smalltalk / X; les noms de stdin et stdout peuvent être différents dans squeak / pharo.

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

Dans Smalltalk / X (et de nombreux autres dialectes), les symboles comprennent #value :, donc il peut être abrégé en 66 caractères:

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

Si codé comme une fonction qui obtient la chaîne comme argument "s":

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

Bien sûr, en code réel, on utiliserait une fonction utilitaire "f", qui retourne un vecteur des comptes, et l'imprimerait. Cependant, le format de sortie n'est alors pas exactement ce que le défi demandait:

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

Python 2, 76 octets

J'ai fait cela avant de voir toute autre solution, puis j'ai vérifié pour trouver deux solutions P3 qui sont plus courtes :( Limitations Darn P2.

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

PowerShell, 65 octets

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

tester en utilisant le modèle ci-dessous après avoir enregistré en tant que vowels.ps1

"the quick brown fox" | vowels.ps1

De cette façon, c'est un script réel et pas seulement un extrait de code satisfaisant ainsi la contrainte:

"L'entrée doit être consommée à partir des arguments stdin ou de la ligne de commande."

Bevo
la source
1

Gelée , 7 octets

Ḳf€ØcL€

Essayez-le en ligne!

Trouvé avec l'aide de M. Xcoder dans le chat

Explication

Ḳ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 sortie doit être séparée par des espaces, ajoutez un Kà la fin

caird coinheringaahing
la source
0

SAS, 72

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

Le format d'E / S restrictif pour celui-ci fait vraiment mal à celui-ci car il est responsable de 25 octets ici.

Oeuf frit
la source
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
la source
Cela échoue pour le troisième cas de test. Votre programme ne semble pas compter AEIOU.
Spikatrix