Conta il numero di vocali in ogni parola di una stringa


13

Questa è una sfida piuttosto semplice.

Sfida

L'input conterrà una stringa (no null o vuota) di lunghezza massima 100. Emette il numero di vocali in ogni parola della stringa, separate da spazi.

Regole

  • La stringa non avrà più di 100 caratteri di lunghezza.
  • La stringa conterrà solo alfabeti A-Z,a-z e può anche contenere spazi.
  • L'input deve essere consumato dal file stdin argomenti della riga di comando o.
  • L'output deve essere emesso in stdout .
  • È possibile scrivere un programma completo o una funzione che accetta input dal stdine genera il risultato.
  • Le vocali che il tuo programma / funzione deve contare sono aeioue AEIOU.

Casi 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

punteggio

Questo è , quindi vince l'invio più breve (in byte).


6
C'è un motivo per cui insisti su un formato I / O piuttosto restrittivo? Non tutte le lingue possono (convenientemente) interagire con STDIN e STDOUT. Abbiamo valori predefiniti per questo (che ovviamente sei libero di sovrascrivere se lo desideri), che consentono anche argomenti da riga di comando, argomenti di funzioni, valore di ritorno ecc. (Possono essere trovati anche nel tag wiki .)
Martin Ender

@ MartinBüttner, " C'è un motivo per cui insisti su un formato I / O piuttosto restrittivo? " - No. Mi piace solo stdincon stdout. Non mi piace "ottenere input" tramite gli argomenti della funzione. gli argomenti della riga di comando sembrano ok. L'ho aggiunto nel 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.Cosa intendi per vocali?
edc65,

Un singolo spazio finale è a posto?
Alex A.,

3
Usa la sandbox per le sfide proposte.
mbomb007,

Risposte:


8

Pyth, 17 byte

jdml@"aeiou"dcrzZ

Soluzione semplice. Provalo online: cablaggio dimostrativo o di prova

Spiegazione:

               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

Mi diverto sempre quando le persone scrivono una soluzione Pyth e la chiamano "Semplice" (anche se questo è certamente più facile da capire della maggior parte) +1
Christopher Wirt,

10

C, 113 108 103 96 byte

Grazie @ andrea-biondo per un risparmio di 5 byte particolarmente piacevole.

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

Questo sembra ancora un po 'gonfio, quindi spero di riuscire a liberarmi di qualche byte più tardi stasera.

La parte interessante è forse quella

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

sarà 1if cè una vocale ASCII (maiuscola o minuscola) e 0per altri caratteri a-zA-Z. Le c-65&31mappe di sottoespressione 'a'e 'A'a 0, 'b'e 'B'a 2, ecc. Quando aggiungiamo 33le vocali corrispondono 33, 37, 41, 47, 53rispettivamente ai numeri , che sono tutti (convenientemente) primi. Nel nostro intervallo solo questi numeri si divideranno 124701951 = 33*37*41*47*53, vale a dire solo per le vocali il resto di124701951%(...) sarà zero.

EDIT: In questo modo si può considerare l'espressione !(n%((c-65&31)+s))dove (n,s) = (124701951, 33)come determinare se il carattere cè una vocale. Nei commenti @ andrea-biondo ha sottolineato che la coppia (n,s) = (2016,28)può anche essere usata in questa espressione per determinare la vocalità. Lascerò la spiegazione attuale in termini di numeri primi sopra, ma il motivo per cui questa associazione più breve funziona è di nuovo perché nell'intervallo 28--53 gli unici numeri con fattori primi interamente nell'insieme dei fattori primi del 2016 sono 28, 32, 36, 42, 48, che corrispondono esattamente alle vocali.

EDIT2: altri 5 byte salvati poiché (c-65&31)+28possono essere abbreviati c%32+27.

EDIT3: convertito in un ciclo do-while per ottenere finalmente sotto i 100 byte.

Casi test:

$ ./vowelc "Questo è il primo caso di test"
1 1 1 1 1 2 
$ ./vowelc "uno più due è uguale a tre"
2 1 1 3 2 
$ ./vowelc "aeiou AEIOU"
5 5 
$ ./vowelc "psst"                     
0

OH MIO DIO! Questo è semplicemente fantastico! È possibile salvare più byte utilizzando l' a;esterno main. In questo modo, a ridurre alcuni byte in quanto non è necessario dichiarare ain main(...)ed inoltre, non hanno bisogno di inizializzare adal loop.
Spikatrix,

1
@CoolGuy: aviene reinizializzato in ogni ciclo, quindi non è possibile inizializzarlo una volta a zero dichiarando globale. Ho scritto un piccolo bruteforcer per trovare la (n, s)coppia più piccola tale che n%((c-65&31)+s)sia zero per le vocali e diverso da zero per le consonanti (az, AZ). Ho trovato (2016, 28)e sembra funzionare bene: !(2016%((c-65&31)+28))5 caratteri in meno. Comunque, soluzione molto bella :)
Andrea Biondo,

7

CJam, 21 19 byte

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

Come funziona :

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

Provalo online qui


6

R, 44 43 byte

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

Ungolfed + spiegazione:

# 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

30personaggi +1per -n.

Come un sacco di codice Perl, funziona da destra a sinistra. splitdividerà la linea immessa sullo spazio bianco. mapeseguirà il codice tra {}su ogni parola che è stata divisa. lcrende la parola minuscola. =~y/aeiou//ci darà il conteggio delle vocali. .$"aggiungerà uno spazio alla parola. sayquindi stampa tutte le parole!

Corri con:

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

4

Python 3, 65 byte

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

Molto semplice, abbastanza leggibile. wsta per parola, csta per carattere.


4

Perl: 30 caratteri

(Tipo di forze le regole: i numeri nell'output sono separati con tanti spazi quante erano le parole di input.)

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

Esecuzione di esempio:

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 caratteri

(Giusto per mostrare quanto sarebbe breve se non dimenticassi y///il valore di ritorno. Di nuovo. Ora vai e vota la risposta del chilemagic che mi ha ricordato y///il valore di ritorno. Di nuovo.)

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

Dang questo batte la mia risposta. Questo s!\w+!lc($&)=~y/aeiou//!gesi riduce a 27byte (26 caratteri +1 per il -p.
hmatt1

Sì grazie. Non posso più contare sulle dita quante volte ho dimenticato y///. :(
arte

3

Rubino, 38 byte

$><<$*.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

I / O tramite popup. Esegui lo snippet in Firefox per testarlo.

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

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

Un po 'noioso, ma in realtà competere per una volta? (PowerShell non fa distinzione tra maiuscole e minuscole per impostazione predefinita, woo)


Cordiali saluti, è necessario chiamare questo come echo <word> | code, dove <word> è la tua parola o frase
Pureferret

3

Bash - 85

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

Spiegazione

  • read l leggere una riga dall'input
  • for w in l divide la linea in parole usando il separatore di spazi bianchi
  • x=${w//[^aouieAOUIE]/} cancella tutto tranne le vocali dalla parola
  • ${#x} è la lunghezza della stringa risultante === numero di vocali

Sembra in qualche modo esagerato. Il requisito dice che l'input conterrà solo lettere e spazi. Quindi perché l'hai preparato per elaborare più righe di input? Senza while.. do.. donesarebbe più breve. Inoltre non è necessario l'ultimo /nella sostituzione del modello. E un singolo spazio letterale è più breve di quello che è stato citato. read l;for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo
arte

Sono d'accordo, ma la regola dice "È possibile scrivere un programma completo o una funzione che accetta input dallo stdin e genera il risultato". Quindi ho deciso di fare il programma completo. Modificherò la soluzione per salvare due byte)) Grazie!
Xuesheng,

3

Julia, 76 72 69 65 byte

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

Ungolfed + spiegazione:

# 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

Ciò includerà un singolo spazio finale, che mi è stato detto è legittimo.


2

Mathematica, 95 byte

Non vinceremo nessun concorso, ma ...

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

Conosci qualche compilatore online in cui ho potuto provare questo?
Spikatrix,

Non ce ne sono, ma puoi ottenere una prova gratuita qui .
LegionMammal978,

@CoolGuy Puoi eseguire il codice Mathematica (Wolfram Language) online se ottieni un account gratuito qui . (Non è sicuro che InputStringesista nell'interfaccia web, è una finestra di dialogo in Mathematica.)

@Calle Negli script Mathematica, InputStringprende la riga successiva di input.
LegionMammal978,

ok capisco. Beh, non sono ancora sicuro che funzionerà nel cloud notebook, ma almeno ora so perché viene utilizzato per stdin.

2

golflua, 55 byte

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

Corrispondenza di base del modello delle vocali dopo minuscole forzate. Un equivalente Lua (non golfizzato) sarebbe

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

A parte questo, per la versione Lua, in realtà sarebbe più breve di 2 caratteri da usare gsub('[aeiouAEIOU]','')e saltare lower().
Kyle Kanos,

2

R , 139 byte

Leggere / scrivere stdout () è terribile

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 non è poi così male . ;) Puoi usare cat()piuttosto che write(..., stdout()).
Alex A.

2

Python 3, 72 byte

Ispirato da @randomra 's risposta . È la stessa lunghezza leggermente più lunga, ma usando regex invece della comprensione dell'elenco. È anche meno leggibile.

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

Salva 7 byte: import re;print(*map(len,re.sub("[^aeiou ]","",input()).split())). (Usa newline invece che ;se vuoi.)
mbomb007

@ mbomb007 Deve essere insensibile al maiuscolo / minuscolo ( 2è il flag insensibile al maiuscolo / minuscolo) e diviso in " "modo che possano esserci 0 elementi di lunghezza

Ah, i miei test non erano abbastanza estesi per notarlo.
mbomb007,

2

PHP - 94

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

Versione Ungolfed

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

2

Objective-C, 223 byte

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

Non è il linguaggio più compatto, ma funziona.

Versione non compressa:

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

La tua sfida non è molto chiara (ma è interessante). presumo

  • Con il termine "vocale" si intende a, e, i, o,u .
  • La stringa non contiene spazi iniziali o finali

Codice:

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

2

rs , 50 byte

Questo non conta affatto; rs è stato caricato circa 2 settimane dopo la pubblicazione. Tuttavia, evidentemente questo non vincerebbe nulla, quindi è comunque bello.

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

Dimostrazione dal vivo.

L'implementazione è piuttosto semplice:

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

Grazie a kirbyfan64sos per avermi salvato 15 byte, mi ha davvero aiutato!
Nota che c'è uno spazio extra alla fine dell'output.


Puoi rimuovere la chiamata splitimpostando l'aggiunta $/=" ";e puoi cortocircuitare il prefisso del loop su while(<>). Con queste due modifiche, il codice diventa $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "}, risparmiando 14 byte!
kirbyfan64sos,

2

Haskell, 76 68 byte

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

Implementazione semplice, non sono sicuro che ci sia qualcosa da golf qui.


1

KDB (Q), 30 byte

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

Spiegazione

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

Test

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

1

Smalltalk - 66 72

Questo è in Smalltalk / X; i nomi di stdin e stdout possono essere diversi in squeak / pharo.

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

In Smalltalk / X (e molti altri dialetti), i simboli comprendono #valore :, quindi può essere abbreviato in 66 caratteri:

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

Se codificato come una funzione che ottiene la stringa come argomento "s":

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

Naturalmente, nel codice reale, si userebbe una funzione di utilità "f", che restituisce un vettore dei conteggi e lo stampa. Tuttavia, il formato di output non è esattamente quello che la sfida ha richiesto:

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

1

Python 2, 76 byte

L'ho fatto prima di vedere qualsiasi altra soluzione, quindi ho controllato per trovare due soluzioni P3 più brevi :( Limitazioni Darn P2.

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

1

PowerShell, 65 byte

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

test utilizzando il modello seguente dopo aver salvato come vowels.ps1

"the quick brown fox" | vowels.ps1

In questo modo si tratta di uno script reale e non solo di un frammento di codice che soddisfa in tal modo il vincolo:

"L'input deve essere utilizzato dagli argomenti stdin o della riga di comando."


1

Gelatina , 7 byte

Ḳf€ØcL€

Provalo online!

Trovato con l'aiuto di Mr. Xcoder in chat

Spiegazione

Ḳ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 l'output deve essere separato da spazio, quindi aggiungere Ka alla fine


0

SAS, 72

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

Il formato I / O restrittivo per questo fa davvero male questo perché è responsabile di 25 byte qui.


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

Questo non riesce per il terzo caso di test. Il tuo programma non sembra contare AEIOU.
Spikatrix,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.