计算字符串中每个单词的元音数量


13

这是一个相当容易的挑战。

挑战

输入将包含null最大长度为100 的字符串(非或为空)。输出字符串中每个单词的元音数量,以空格分隔。

规则

  • 该字符串的长度不能超过100个字符。
  • 该字符串将仅包含字母A-Za-z也可以包含空格。
  • 输入必须通过stdin或命令行参数使用。
  • 输出必须在中输出stdout
  • 您可以编写完整的程序,也可以编写从中获取输入stdin并输出结果的函数。
  • 您的程序/功能需要计算的元音为aeiouAEIOU

测试用例

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
您坚持使用限制性很强的I / O格式是否有原因?并非每种语言都可以(方便地)与STDIN和STDOUT交互。我们对此具有默认值(当然,如果您愿意的话,可以随意重写),它还允许命令行参数,函数参数,返回值等。(它们也可以在标记Wiki中找到。)
Martin Ender

@MartinBüttner,“ 有你为什么坚持一个相当严格的I / O格式的原因是什么? ” -不,我只是喜欢stdinstdout。我不喜欢通过函数参数“获取输入”。命令行参数似乎还可以。我已将其添加到帖子中。
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

一个尾随的空间可以吗?
Alex A.

3
将沙盒用于建议的挑战。
mbomb007

Answers:


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
Christopher Wirt 2015年

10

C,113108103 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'23333, 37, 41, 47, 53124701951 = 33*37*41*47*53124701951%(...)

编辑:通过这种方式,可以!(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:因为(c-65&31)+28可以缩短为,所以保存了另外5个字节c%32+27

EDIT3:转换为do-while循环,以使其最终低于100字节。

测试用例:

$ ./vowelc“这是第一个测试用例”
1 1 1 1 1 2 
$ ./vowelc“一加二等于三”
2 1 1 3 2 
$ ./vowelc“ aeiou AEIOU”
5 5 
$ ./vowelc“ psst”                     
0

我的天啊!太棒了!您可以使用a;outside 节省更多字节main。这样,您减少了一些字节,因为您不需要在其中声明amain(...)并且也不需要a从循环初始化。
Spikatrix 2015年

1
@CoolGuy:a在每个循环中都会重新初始化,因此您不能通过声明global将其初始化为零。我写了一个小的暴力破解者,找到最小的(n, s)一对n%((c-65&31)+s),元音为零,辅音为非零(az,AZ)。我发现(2016, 28)它似乎运行良好:!(2016%((c-65&31)+28))短5个字符。无论如何,非常好的解决方案:)
Andrea Biondo

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的返回值,将会有多短。再次。现在,继续向上评论chilemagic答案,使我想起y///'s'的返回值。)

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

this,这胜过我的回答。这s!\w+!lc($&)=~y/aeiou//!ge得到它下降到27字节(26个字符+1了-p
hmatt1

是啊谢谢。我再也不能指望我忘记了多少次了y///。:(
manatwork

3

Ruby,38个字节

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

用法:

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。在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

Rebol-70

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

3

PowerShell,35个字节

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

有点讨厌,但实际上竞争一次?(默认情况下,PowerShell不区分大小写,woo)


仅供参考,您需要这样称呼echo <word> | code,其中<word>是您的单词或短语
Pureferret 2015年

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
manatwork

我同意,但是规则说“您可以编写一个完整的程序,或者是一个从标准输入中获取输入并输出结果的函数。” 因此,我决定制作完整程序。我将编辑解决方案以保存两个字节))谢谢!
xuesheng 2015年

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

Mathematica,95个字节

不会赢得任何比赛,但是...

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

您知道我可以在此测试的任何在线编译器吗?
Spikatrix

没有,但是您可以在这里免费试用。
LegionMammal978 2015年

@CoolGuy如果您在此处获得免费帐户,则可以在线运行Mathematica(Wolfram语言)代码。(InputString虽然不确定Web界面中是否存在,但这是Mathematica中的对话框。)

@Calle在Mathematica脚本中,InputString接受下一行输入。
LegionMammal978

好的我明白了。仍然不确定它是否可以在云笔记本中使用,但至少现在我知道为什么将其用于标准输入。

2

golflua,55个字节

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

强制小写后的元音基本模式匹配。(未解禁的)Lua等效为

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

顺便说一句,对于Lua版本,使用起来实际上要短2个字符,gsub('[aeiouAEIOU]','')并跳过lower()
凯尔·卡诺斯

2

R,139字节

读/写stdout()很糟糕

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还不错。;)您可以使用cat()而不是write(..., stdout())
Alex A.

2

Python 3,72个字节

@randomra回答启发。这是相同的长度 稍长,但使用正则表达式,而不是名单理解的。它的可读性也较差。

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

节省7个字节:import re;print(*map(len,re.sub("[^aeiou ]","",input()).split()))。(;如果需要,请使用换行符。)
mbomb007

@ 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

Matlab,73个字节

您的挑战不是很清楚(但是很有趣)。我假设

  • 通过“元音”你的意思是aeiou
  • 字符串不包含前导或尾随空格

码:

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

KDB(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解决方案:(达恩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]

如果输出必须以空格分隔,则K在末尾附加a


0

SAS,72

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

这种限制I / O格式确实伤害了这种格式,因为它占用这里的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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.