Đếm số nguyên âm trong mỗi từ của chuỗi


13

Đây là một thử thách khá dễ dàng.

Thử thách

Đầu vào sẽ chứa một chuỗi (không nullhoặc trống) có độ dài tối đa 100. Xuất số nguyên âm trong mỗi từ của chuỗi, cách nhau bằng khoảng trắng.

Quy tắc

  • Chuỗi sẽ không dài hơn 100 ký tự.
  • Chuỗi sẽ chỉ chứa bảng chữ cái A-Z, a-zvà cũng có thể chứa khoảng trắng.
  • Đầu vào phải được tiêu thụ từ các stdinđối số hoặc dòng lệnh.
  • Đầu ra phải được xuất ra trong stdout.
  • Bạn có thể viết một chương trình đầy đủ hoặc một hàm lấy đầu vào từ stdinvà xuất kết quả.
  • Nguyên âm mà chương trình / chức năng của bạn cần đếm là aeiouAEIOU.

Các trường hợp thử nghiệm

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

Chấm điểm

Đây là , vì vậy bài nộp ngắn nhất (tính bằng byte) sẽ thắng.


6
Có một lý do tại sao bạn nhấn mạnh vào một định dạng I / O khá hạn chế? Không phải mọi ngôn ngữ đều có thể (thuận tiện) tương tác với STDIN và STDOUT. Chúng tôi có mặc định cho điều này (tất nhiên bạn có thể ghi đè nếu bạn muốn), điều này cũng cho phép đối số dòng lệnh, đối số hàm, giá trị trả về, v.v. (Chúng cũng có thể được tìm thấy trong wiki thẻ .)
Martin Ender

@ MartinBüttner, " Có lý do tại sao bạn khăng khăng một định dạng I / O khá hạn chế không? " - Không. Tôi chỉ thích stdinvới stdout. Tôi không muốn "nhận đầu vào" thông qua các đối số chức năng. đối số dòng lệnh có vẻ ok. Tôi đã thêm nó vào bài viết.
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.Ý của bạn về nguyên âm là gì?
edc65

Là một không gian dấu duy nhất được không?
Alex A.

3
Sử dụng Sandbox cho các thách thức được đề xuất.
mbomb007

Câu trả lời:


8

Bình thường, 17 byte

jdml@"aeiou"dcrzZ

Giải pháp đơn giản. Dùng thử trực tuyến: Trình diễn hoặc thử nghiệm khai thác

Giải trình:

               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

Nó luôn làm tôi thích thú khi mọi người viết một giải pháp Pyth và gọi nó là "Đơn giản" (Mặc dù điều này được thừa nhận là dễ nắm bắt hơn hầu hết) +1
Christopher Wirt

10

C, 113 108 103 96 byte

Cảm ơn @ andrea-biondo vì đã tiết kiệm 5 byte đặc biệt tốt đẹp.

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

Điều này vẫn cảm thấy hơi khó chịu vì vậy hy vọng tôi có thể lấy nó xuống khá nhiều byte vào tối nay.

Phần thú vị có lẽ là

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

sẽ là 1nếu clà một nguyên âm ASCII (chữ hoa hoặc chữ thường) và 0cho các ký tự khác a-zA-Z. Các subexpression c-65&31bản đồ 'a''A'đến 0, 'b''B'để 2, vv Khi chúng ta thêm 33các nguyên âm tương ứng với số 33, 37, 41, 47, 53tương ứng, tất cả trong số đó là (thuận tiện) thủ. Trong phạm vi của chúng tôi, chỉ những số như vậy sẽ phân chia 124701951 = 33*37*41*47*53, tức là chỉ đối với nguyên âm thì phần còn lại 124701951%(...)bằng không.

EDIT: Theo cách này, người ta có thể xem xét biểu thức !(n%((c-65&31)+s))trong đó (n,s) = (124701951, 33)xác định xem nhân vật ccó phải là nguyên âm hay không. Trong các bình luận @ andrea-biondo đã chỉ ra rằng cặp này (n,s) = (2016,28)cũng có thể được sử dụng trong biểu thức này để xác định nguyên âm. Tôi sẽ để lại lời giải thích hiện tại về các số nguyên tố ở trên, nhưng lý do việc ghép đôi ngắn này hoạt động trở lại là do trong phạm vi 28--53, các số duy nhất có các thừa số nguyên tố hoàn toàn trong tập hợp các thừa số nguyên tố của năm 2016 là 28, 32, 36, 42, 48, tương ứng chính xác với các nguyên âm.

EDIT2: 5 byte khác được lưu kể từ khi (c-65&31)+28có thể rút ngắn thành c%32+27.

EDIT3: Được chuyển đổi thành một vòng lặp do-while để cuối cùng có được nó dưới 100 byte.

Các trường hợp thử nghiệm:

$ ./vowelc "Đây là trường hợp thử nghiệm đầu tiên"
1 1 1 1 1 2 
$ ./vowelc "một cộng hai bằng ba"
2 1 1 3 2 
$ ./vowelc "aeiou AEIOU"
5 5 
$ ./vowelc "psst"                     
0

CHÚA ƠI! Điều này thật tuyệt vời! Bạn có thể tiết kiệm nhiều byte hơn bằng cách sử dụng a;bên ngoài main. Bằng cách này, bạn giảm số byte là bạn không cần phải khai báo atrong main(...)và cũng không cần phải khởi tạo atừ các vòng lặp.
Spikatrix

1
@CoolGuy: ađược khởi tạo lại ở mỗi vòng lặp, vì vậy bạn không thể khởi tạo nó một lần bằng 0 bằng cách khai báo toàn cục. Tôi đã viết một bruteforcer nhỏ để tìm (n, s)cặp nhỏ nhất n%((c-65&31)+s)bằng 0 cho nguyên âm và khác không cho phụ âm (az, AZ). Tôi tìm thấy (2016, 28)và nó dường như hoạt động tốt: !(2016%((c-65&31)+28))ngắn hơn 5 ký tự. Dù sao, giải pháp rất hay :)
Andrea Biondo

7

CJam, 21 19 byte

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

Cách thức hoạt động :

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

Dùng thử trực tuyến tại đây


6

R, 44 43 byte

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

Ungolfed + giải thích:

# 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

30nhân vật +1cho -n.

Giống như rất nhiều mã Perl, điều này hoạt động từ phải sang trái. splitsẽ phân chia dòng nhập vào khoảng trắng. mapsẽ chạy mã giữa {}trên mỗi từ được phân chia. lclàm cho chữ thường =~y/aeiou//sẽ cho chúng ta số nguyên âm. .$"sẽ nối một khoảng trắng vào từ. saysau đó in tất cả các từ!

Chạy với:

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()])

Rất đơn giản, khá dễ đọc. wviết tắt của từ, cviết tắt của ký tự.


4

Perl: 30 ký tự

(Loại lực lượng quy tắc: các số trong đầu ra được phân tách bằng nhiều khoảng trắng như các từ đầu vào.)

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

Chạy mẫu:

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 ký tự

(Chỉ để cho thấy sẽ ngắn đến mức nào nếu tôi không quên y///giá trị trả về. Một lần nữa. Bây giờ hãy đi và trả lời câu trả lời của chilemagic đã nhắc nhở tôi về giá trị trả về. Một lần nữa.)y///

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

Dang này đập câu trả lời của tôi. Điều này s!\w+!lc($&)=~y/aeiou//!gegiúp nó giảm xuống còn 27byte (26 ký tự +1 cho -p.
hmatt1

Vâng cảm ơn. Tôi không thể đếm trên đầu ngón tay của mình bao nhiêu lần tôi đã quên y///. :(
manatwork

3

Ruby, 38 byte

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

Sử dụng:

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 qua cửa sổ bật lên. Chạy đoạn trích trong Firefox để kiểm tra.

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

Nổi loạn - 70

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

3

PowerShell, 35 byte

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

Kinda nhàm chán, nhưng thực sự cạnh tranh cho một lần? (PowerShell không phân biệt chữ hoa chữ thường theo mặc định, woo)


FYI, bạn cần gọi như thế này echo <word> | code, trong đó <word> là từ hoặc cụm từ của bạn
Pureferret

3

Bash - 85

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

Giải trình

  • read l đọc một dòng từ đầu vào
  • for w in l chia dòng thành các từ bằng cách sử dụng dấu tách khoảng trắng
  • x=${w//[^aouieAOUIE]/} xóa tất cả ngoại trừ nguyên âm khỏi từ
  • ${#x} là độ dài của chuỗi kết quả === số nguyên âm

Cảm thấy quá mức. Yêu cầu cho biết đầu vào sẽ chỉ chứa các chữ cái và dấu cách. Vậy tại sao bạn chuẩn bị nó để xử lý nhiều dòng đầu vào? Nếu không có while.. do.. donesẽ ngắn hơn. Cũng không cần cuối cùng /trong sự thay thế mô hình. Và một không gian theo nghĩa đen là thoát ngắn hơn so với trích dẫn. read l;for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo
manatwork

Tôi đồng ý nhưng quy tắc nói 'Bạn có thể viết một chương trình đầy đủ hoặc một hàm lấy đầu vào từ stdin và đưa ra kết quả.' Vì vậy, tôi đã quyết định thực hiện chương trình đầy đủ. Tôi sẽ chỉnh sửa giải pháp để tiết kiệm hai byte)) Cảm ơn!
xuesheng

3

Julia, 76 72 69 65 byte

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

Ungolfed + giải thích:

# 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

Điều này sẽ bao gồm một không gian duy nhất, mà tôi nói là hợp pháp.


2

Toán học, 95 byte

Sẽ không chiến thắng bất kỳ cuộc thi nào, nhưng ...

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

Bạn có biết bất kỳ trình biên dịch trực tuyến nào mà tôi có thể kiểm tra điều này không?
Spikatrix

Không có gì, nhưng bạn có thể dùng thử miễn phí tại đây .
LegionMammal978

@CoolGuy Bạn có thể chạy mã Mathicala (Ngôn ngữ Wolfram) trực tuyến nếu bạn có tài khoản miễn phí tại đây . ( InputStringTuy nhiên, không chắc chắn tồn tại trong giao diện web, đó là một hộp thoại trong

@Calle Trong các tập lệnh Mathicala, InputStringlấy dòng đầu vào tiếp theo.
LegionMammal978

ok, tôi hiểu rồi Chà vẫn không chắc nó có hoạt động trong máy tính xách tay trên đám mây hay không nhưng ít nhất bây giờ tôi biết tại sao nó được sử dụng cho stdin.

2

golflua, 55 byte

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

Kết hợp mẫu cơ bản của nguyên âm sau khi viết thường. Một Lua tương đương

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

Bên cạnh đó, đối với phiên bản Lua, nó thực sự ngắn hơn 2 ký tự để sử dụng gsub('[aeiouAEIOU]','')và bỏ qua lower().
Kyle Kanos

2

R , 139 byte

Đọc / ghi stdout () là khủng khiếp

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 không tệ lắm . ;) Bạn có thể sử dụng cat()chứ không phải write(..., stdout()).
Alex A.

2

Python 3, 72 byte

Lấy cảm hứng từ @randomra 's câu trả lời . Nó có cùng độ dài dài hơn một chút, nhưng sử dụng regex thay vì hiểu danh sách. Nó cũng ít đọc hơn.

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

Lưu 7 byte : import re;print(*map(len,re.sub("[^aeiou ]","",input()).split())). (Sử dụng dòng mới thay vì ;nếu bạn muốn.)
mbomb007

@ mbomb007 Nó cần phải không phân biệt chữ hoa chữ thường ( 2là cờ không phân biệt chữ hoa chữ thường) và được phân chia " "để có thể có 0 phần dài

Ah, các bài kiểm tra của tôi không đủ rộng để nhận thấy điều đó.
mbomb007

2

PHP - 94

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

Phiên bản ung dung

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

2

Mục tiêu-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);}}

Không phải là ngôn ngữ nhỏ gọn nhất, nhưng nó hoạt động.

Phiên bản không nén:

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

Thử thách của bạn không rõ ràng lắm (nhưng nó rất thú vị). Tôi đang giả sử

  • "Nguyên âm" có nghĩa là bạn a , e, i, o,u .
  • Chuỗi không chứa khoảng trắng ở đầu hoặc cuối

Mã số:

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

2

rs , 50 byte

Điều này không hoàn toàn được tính; rs đã được tải lên khoảng 2 tuần sau khi điều này được đăng. Tuy nhiên, rõ ràng điều này sẽ không giành được bất cứ điều gì, vì vậy nó vẫn rất tuyệt.

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

Bản thử trực tiếp.

Việc thực hiện khá đơn giản:

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

Cảm ơn kirbyfan64sos đã tiết kiệm cho tôi 15 byte - điều đó thực sự hữu ích!
Lưu ý có thêm một khoảng trống ở cuối đầu ra.


Bạn có thể xóa cuộc gọi đến splitbằng cách cài đặt thêm $/=" ";và bạn có thể rút ngắn tiền tố vòng lặp thành while(<>). Với hai thay đổi đó, mã trở thành $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "}, tiết kiệm 14 byte!
kirbyfan64sos

2

Haskell, 76 68 byte

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

Thực hiện đơn giản, không chắc chắn nếu có bất cứ điều gì để chơi golf ở đây.


1

KDB (Q), 30 byte

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

Giải trình

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

Kiểm tra

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

1

Smalltalk - 66 72

Đây là trong Smalltalk / X; tên của stdin và stdout có thể khác nhau trong squeak / pharo.

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

Trong Smalltalk / X (và nhiều phương ngữ khác), các ký hiệu hiểu #value:, vì vậy nó có thể được viết tắt thành 66 ký tự:

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

Nếu được mã hóa dưới dạng hàm lấy chuỗi làm đối số "s":

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

Tất nhiên, trong mã thực, người ta sẽ sử dụng hàm tiện ích "f", trả về một vectơ của số đếm và in ra. Tuy nhiên, định dạng đầu ra sau đó không chính xác là những gì thách thức yêu cầu:

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

1

Python 2, 76 byte

Tôi đã thực hiện điều này trước khi tôi thấy bất kỳ giải pháp nào khác, sau đó kiểm tra để tìm hai giải pháp P3 ngắn hơn :( giới hạn 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' '

kiểm tra bằng cách sử dụng mẫu bên dưới sau khi lưu dưới dạng vowels.ps1

"the quick brown fox" | vowels.ps1

Theo cách này, nó là một tập lệnh thực tế và không chỉ là một đoạn mã do đó thỏa mãn ràng buộc:

"Đầu vào phải được sử dụng từ stdin hoặc đối số dòng lệnh."


1

Thạch , 7 byte

Ḳf€ØcL€

Hãy thử trực tuyến!

Tìm thấy với sự giúp đỡ từ ông Xcoder trong trò chuyện

Giải trình

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

Nếu đầu ra phải được phân tách bằng dấu cách, sau đó nối a Kvào cuối


0

SÀI GÒN, 72

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

Định dạng I / O hạn chế cho cái này thực sự làm tổn thương cái này vì nó chịu trách nhiệm cho 25 byte ở đây.


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

Điều này không thành công cho trường hợp thử nghiệm thứ ba. Chương trình của bạn dường như không được tính AEIOU.
Spikatrix
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.