18
\$\begingroup\$

Challenge

Write a program that, given a string x which is 10 characters long and a character y, outputs the number of times character y occurs in string x.

The shortest program in bytes to do so wins.

Example

Input: tttggloyoi, t
Output: 3

Input: onomatopoe, o
Output: 4
\$\endgroup\$
  • 11
    \$\begingroup\$ This seems almost too easy of a challenge. Also why limit the input to 10, instead of no limit at all? \$\endgroup\$ – Fatalize Sep 2 '15 at 9:37
  • 6
    \$\begingroup\$ Needs a winning condition. \$\endgroup\$ – isaacg Sep 2 '15 at 9:41
  • 2
    \$\begingroup\$ Feel free to rollback my edit if it doesn't agree with you \$\endgroup\$ – Beta Decay Sep 2 '15 at 10:13
  • 7
    \$\begingroup\$ How flexible is the input format? Can we choose a different delimiter, like a space or newline? Can the string be in quotes? Can we take the letter first and the string second? Will the characters always be lower case letters? If not, which other characters can occur? \$\endgroup\$ – Martin Ender Sep 2 '15 at 10:50
  • 5
    \$\begingroup\$ This looks suspiciously like a C interview question... \$\endgroup\$ – Quentin Sep 2 '15 at 20:33

45 Answers 45

18
\$\begingroup\$

Pyth, 3 bytes

/ww

Example run:

$ pyth -c '/ww'
sdhkfhjkkj
k
3

Of course, the user could input more or less than 10 letters on the first input, but we don't need to worry about what happens when the user violates the spec.

\$\endgroup\$
  • \$\begingroup\$ seems like that's not valid pyth anymore? \$\endgroup\$ – Ven Feb 9 '16 at 15:34
  • \$\begingroup\$ explanation please? \$\endgroup\$ – MilkyWay90 2 days ago
11
\$\begingroup\$

Pyth - 3 bytes

A different, less obvious, Pyth answer of the same size. It folds counting over the input.

/FQ

Test Suite.

\$\endgroup\$
7
\$\begingroup\$

JavaScript, 32

(p=prompt)().split(p()).length-1
\$\endgroup\$
6
\$\begingroup\$

Bash, 24 characters

x=${1//[^$2]}
echo ${#x}

Sample run:

bash-4.3$ bash letter-count.sh tttggloyoi t
3

bash-4.3$ bash letter-count.sh onomatopoe o
4
\$\endgroup\$
6
\$\begingroup\$

Retina, 12 bytes

(.)(?=.*\1$)

Simply a regex which matches a character which is equal to the last character in the input (except itself). When given a single regex, Retina simply returns the number of matches.

\$\endgroup\$
4
\$\begingroup\$

Labyrinth, 32 29 27 24 bytes

),}{)-
@ ,  +);__
!-`{:}

This reads the single character first, followed by the string in which to count, and assumes that there are no null-bytes in the string.

Explanation

The code starts with ),}, which sets the bottom of the stack to 1, reads the first character and moves it to the auxiliary stack for future use. The 1 will be our counter (the offset of 1 will be cancelled later and is necessary for the IP to take the required turns).

The IP will now move down to read the first character of the search string with ,. The value is negated with `, again to get the correct turning behaviour. While we're reading characters from STDIN, the IP will now follow this loop:

  }{)-
  ,  +);__
  `{:}

{:} makes a copy of the stored character code and + adds it to the current value. If the result is 0 (i.e. the current character is the one we're looking for), the IP moves straight ahead: - simply gets rid of the 0, ) increments the counter, {} is a no-op.

However, if the result after + is non-zero, we don't want to count the current character. So the IP takes a right-turn instead. That's a dead-end, so that code there is executed twice, once forwards and once backwards. That is, the actual code in this case becomes );___;)+-){}. ); just gets rid of that non-zero difference, ___ pushes 3 zeroes, but ; discards one of them. ) increments one of the two remaining two zeroes, + adds them into a single 1, - subtracts it from the counter and ) increments the counter. In other words, we've created a very elaborate no-op.

When we hit EOF, , pushes -1, which ` turns into 1 and the IP takes a right-turn. - subtracts the 1 from the counter (cancelling the initial offset). ! prints the counter and @ terminates the program.

\$\endgroup\$
4
\$\begingroup\$

Python 3, 29 bytes

print(input().count(input()))

Meh, this was easy. Assumes that input is a ten letter string.

\$\endgroup\$
  • 4
    \$\begingroup\$ You copied me! :D \$\endgroup\$ – isaacg Sep 2 '15 at 9:54
  • 1
    \$\begingroup\$ @isaacg Great minds think alike? ;D \$\endgroup\$ – Beta Decay Sep 2 '15 at 9:55
  • \$\begingroup\$ If you don't need to read input, wouldn't f=lambda x,y:x.count(y) be shorter? (Sorry if this doesn't work, I'm on mobile and can't check) \$\endgroup\$ – cole Sep 2 '15 at 19:46
  • \$\begingroup\$ @mbomb007 My mistake, thanks for clarifying. \$\endgroup\$ – cole Sep 2 '15 at 19:57
  • 1
    \$\begingroup\$ Removing the brackets around print saves you a character print input().count(input()) or a,b=input();print a.count(b) with the same amount \$\endgroup\$ – Willem Sep 2 '15 at 19:58
4
\$\begingroup\$

Snowman 1.0.2, 16 characters

~vgvgaSaLNdEtSsP

Surprisingly short. Explanation:

~      make all vars active (even though we only need two, we don't really care)
vgvg   get two lines of input
aS     split first line on second line
aL     length of the new array
NdE    decrement (because ex. "axbxc""x"aS -> ["a" "b" "c"] which is length 3)
tSsP   to-string and print
\$\endgroup\$
  • \$\begingroup\$ Nice work! I wouldn't have thought that a solution that short would be possible in Snowman. \$\endgroup\$ – Alex A. Sep 3 '15 at 1:40
4
\$\begingroup\$

C++ Template-Metaprogramming, 160 154 116 bytes

Just for the giggles.

Thanks to ex-bart for golfing it down!

template<int w,int x,int y,int...s>class A:A<w+(x==y),x,s...>{};A<0,'t','t','t','t','g','g','l','o','y','o','i',0>a;

Usage: The first char in the template instanciation is the character to search.

Complile with clang -std=c++11 -c -> the result is at the beginning of the error message.

Occurences.cpp:1:66: error: too few template arguments for class template 'A'
template<int w,char x,char y,char...s>class A{static const int a=A<w+((x==y)?1:0),x,s...>::a;};
                                                             ^
Occurences.cpp:1:66: note: in instantiation of template class 'A<3, 't', '\x00'>' requested here
template<int w,char x,char y,char...s>class A{static const int a=A<w+((x==y)?1:0),x,s...>::a;};

Complile with gcc -std=c++11 -c -> the result is at the bottom of the error message.

Occurences.cpp: In instantiation of ‘const int A<3, 't', '\000'>::a’:
Occurences.cpp:1:64:   recursively required from ‘const int A<1, 't', 't', 't', 'g', 'g', 'l', 'o', 'y', 'o', 'i', '\000'>::a’
Occurences.cpp:1:64:   required from ‘const int A<0, 't', 't', 't', 't', 'g', 'g', 'l', 'o', 'y', 'o', 'i', '\000'>::a’
Occurences.cpp:2:62:   required from here
Occurences.cpp:1:64: error: wrong number of template arguments (2, should be at least 3)

Search for the A<3, 't', '\000'> and A<3, 't', '\x00'>

154 byte version

template<int w,char x,char y,char...s>class A{static const int a=A<w+(x==y),x,s...>::a;};                          
int a=A<0,'t','t','t','t','g','g','l','o','y','o','i','\0'>::a;

160 byte version:

template<int w,char x,char y,char...s>class A{static const int a=A<w+((x==y)?1:0),x,s...>::a;};                          
int a=A<0,'t','t','t','t','g','g','l','o','y','o','i','\0'>::a;
\$\endgroup\$
  • \$\begingroup\$ You can shorten ((x==y)?1:0) to just (x==y) to save about 6 bytes (I think). \$\endgroup\$ – kirbyfan64sos Sep 2 '15 at 21:11
  • \$\begingroup\$ Thanks--wanted to be sure that it is defined behaviour, because I wasn't sure what the standard said about bool to int conversion. \$\endgroup\$ – Otomo Sep 2 '15 at 21:34
  • \$\begingroup\$ It's defined behavior. \$\endgroup\$ – kirbyfan64sos Sep 2 '15 at 21:34
  • \$\begingroup\$ Yep, now I know that, too. :) Thank you very much. (I thought maybe it would be implementation dependent.) \$\endgroup\$ – Otomo Sep 2 '15 at 21:37
  • 1
    \$\begingroup\$ 128 bytes: Use anonymous enum instead of static const. Use 0 instead of '\0' to terminate. Use int instead of char. Use a slightly different declaration to instanciate. Remove superflouos newline. template<int w,int x,int y,int...s>class A{enum{a=A<w+(x==y),x,s...>::a};};A<0,'t','t','t','t','g','g','l','o','y','o','i',0>a;. Checked with g++ and clang. \$\endgroup\$ – ex-bart Sep 3 '15 at 0:17
3
\$\begingroup\$

Bash + grep, 26 bytes

grep -o "$1"<<<"$2"|wc -l
\$\endgroup\$
3
\$\begingroup\$

Javascript (ES6), 26 bytes

(a,b)=>a.split(b).length-1

This quick'n'easy solution defines an anonymous function. To use it, add a variable declaration to the beginning. Try it out:

z=(a,b)=>(a.split(b)||[0]).length-1;

input1=document.getElementById("input1");
input2=document.getElementById("input2");
p=document.getElementById("a");
q=function(){
  setTimeout(function(){
    p.innerHTML=z(input1.value,input2.value)||0;
  },10);
};
input1.addEventListener("keydown",q);
input2.addEventListener("keydown",q);
<form>Text to search: <input type="text" id="input1" value="hello world!"/><br>Char to find: <input type="text" id="input2" value="l"/></form>

<h3>Output:</h3>
<p id="a">3</p>

EDIT: Oh, I see there's a very similar solution already. I hope that's OK.

\$\endgroup\$
3
\$\begingroup\$

Haskell, 21 bytes

a!b=sum[1|x<-a,x==b]
\$\endgroup\$
3
\$\begingroup\$

C++, 78 bytes

int main(int,char**v){int c=0,i=0;while(i<10)v[1][i++]==*v[2]&&++c;return c;}

Call like this:

$ g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out tttggloyoi t; echo $?
3
\$\endgroup\$
3
\$\begingroup\$

Element, 23 bytes

__);11'[)\
~="0 1@][+]`

The newline is part of the program. I am actually using it as a variable name.

This program basically works by storing the target character in a variable, keeping the current string on the top of the stack, and then looping the "chop, compare, and move result underneath" process, adding up the results in the end.

The newline as a variable name comes from using the newline at the end of input by chopping it off and storing into it. The newline in the code is where I read from it.

Input is like this:

qqqqwwweee
q

Output is like this

4
\$\endgroup\$
3
\$\begingroup\$

Julia, 26 25 bytes

f(s,c)=endof(findin(s,c))

The findin function returns the indices in the first argument at which the second argument is found as a vector. The length of the vector is the number of occurrences.

Saved one byte thanks to Glen O.

\$\endgroup\$
  • \$\begingroup\$ endof will save you a byte in place of length. \$\endgroup\$ – Glen O Sep 3 '15 at 3:46
3
\$\begingroup\$

APL, 7 3 bytes

+/⍷

This creates a function train. It works by creating a vector of zeros and ones corresponding to the indices at which the character appears in the string (). The vector is then summed (+/).

Saved 4 bytes thanks to kirbyfan64sos and NBZ!

\$\endgroup\$
  • \$\begingroup\$ Is APL curried like K? I would think you could just do something like +/⍷ then (I don't know APL, so I might be wrong). \$\endgroup\$ – kirbyfan64sos Sep 2 '15 at 21:10
  • \$\begingroup\$ @kirbyfan64sos The only curry I know is food so I'm not sure. But I'll look into it. Thanks for the suggestion! \$\endgroup\$ – Alex A. Sep 3 '15 at 0:12
  • \$\begingroup\$ @kirbyfan64sos Yes, it is called a function train, so +/⍷ would indeed work, but since we are looking for a single char, one might as well use = instead of ⍷. \$\endgroup\$ – Adám Sep 3 '15 at 7:29
3
\$\begingroup\$

Perl, 21 16 characters

(13 characters code + 3 character command line option.)

$_=0+s/$^I//g

Sample run:

bash-4.3$ perl -it -pe '$_=0+s/$^I//g' <<< tttggloyoi
3

bash-4.3$ perl -io -pe '$_=0+s/$^I//g' <<< onomatopoe
4

bash-4.3$ perl -i5 -pe '$_=0+s/$^I//g' <<< 1234
0
\$\endgroup\$
  • \$\begingroup\$ Neat trick with <>! \$\endgroup\$ – ThisSuitIsBlackNot Sep 2 '15 at 16:28
  • \$\begingroup\$ You could save a byte by dropping -l and ensuring that your input has no trailing newline: echo -en 'onomatopoe\no' | perl -pe '$_=eval"y/".<>."//"' \$\endgroup\$ – ThisSuitIsBlackNot Sep 2 '15 at 16:30
  • 1
    \$\begingroup\$ And you can knock your total down to 16 with perl -pe '$_+=s/${\<>}//g' \$\endgroup\$ – ThisSuitIsBlackNot Sep 2 '15 at 17:03
  • \$\begingroup\$ That referencing trick is incredible. Thank you, @ThisSuitIsBlackNot. \$\endgroup\$ – manatwork Sep 2 '15 at 18:42
  • \$\begingroup\$ Why is the += needed? = seems to work just as well (and should still work when the input happens to start with some digits). \$\endgroup\$ – ex-bart Sep 3 '15 at 15:39
3
\$\begingroup\$

PHP, 36 35 bytes

<?=substr_count($argv[1],$argv[2]);


Usage:
Call the script with two arguments.
php script.php qwertzqwertz q

PHP, 23 bytes

If you register global Variables (only possible in PHP 5.3 and below) you can save 12 bytes (thanks to Martijn)

<?=substr_count($a,$b);


Usage:
Call the script and declare global variables php script.php?a=qwertzqwertz&b=q

\$\endgroup\$
  • 1
    \$\begingroup\$ You can remove a space after the comma to get one byte less \$\endgroup\$ – Voitcus Sep 2 '15 at 11:38
  • 1
    \$\begingroup\$ If you have register globals you can do script.php?a=qwertzqwertz&b=q, and do <?=substr_count($a,$b);, 23 chars \$\endgroup\$ – Martijn Sep 2 '15 at 14:04
  • \$\begingroup\$ @Martijn good idea thank you! \$\endgroup\$ – jrenk Sep 2 '15 at 14:16
3
\$\begingroup\$

Dyalog APL, 3 bytes

      +/=

I.e. "The sum of the equal bytes". E.g.:

      f ← +/=
      'onomatopoe' f 'o'
4

or just

      'onomatopoe'(+/=)'o'
4

K doesn't beat APL this time.

Try it online.

\$\endgroup\$
  • \$\begingroup\$ Please don't edit dozens of posts at once. You're completely flooding the front page. If there are many posts that need editing (which occasionally does happen, e.g. because a new tag is added), then it's generally nice to only do 3 of them at a time and then wait at least 12 hours so they can drop off the front page. \$\endgroup\$ – Martin Ender May 26 '16 at 13:46
  • \$\begingroup\$ @MartinBüttner Yeah, I didn't realize at the time. :-( Regular users do not have the "Minor edit" option... I do realize why it cannot be available for everyone. \$\endgroup\$ – Adám May 26 '16 at 14:13
  • \$\begingroup\$ Unfortunately, there is no such option at all, not even for moderators. \$\endgroup\$ – Martin Ender May 26 '16 at 14:19
3
\$\begingroup\$

T-SQL, 99 40 Bytes

SELECT 11-LEN(REPLACE(s,c,'')+'x')FROM t

Simply does a difference between the input string and the string with the character removed. Takes input from table t

Edit changed to remove an issue with counting spaces and to take into account current acceptable inputs for SQL. Thanks @BradC for all the changes and savings

\$\endgroup\$
  • \$\begingroup\$ You shouldn't need all the scaffolding, just do SELECT LEN(s)-LEN(REPLACE(s,c,''))FROM t, where t is a pre-populated input table with fields s and c. \$\endgroup\$ – BradC Oct 10 at 18:54
  • \$\begingroup\$ On another note, this code gives the wrong answer for strings like A B C D that end in spaces (if you're asked to count spaces), since LEN ignores trailing spaces. \$\endgroup\$ – BradC Oct 10 at 18:59
  • \$\begingroup\$ @BradC I think way back then, the rules around what was acceptable, especially around SQL was restrictive and unclear. I'll have a look at fixing the space issue when I have a little time \$\endgroup\$ – MickyT Oct 10 at 21:17
  • \$\begingroup\$ I usually just pad the end and subtract one; in this case input is guaranteed to be exactly 10 characters, you could just hard code it as SELECT 11-LEN(REPLACE(s,c,'')+'x')FROM t \$\endgroup\$ – BradC Oct 10 at 21:30
  • \$\begingroup\$ @BradC yeah, looking at this again, not sure why I allowed for variable length. Making changes. \$\endgroup\$ – MickyT Oct 10 at 21:37
2
\$\begingroup\$

Octave / Matlab, 33 bytes

sum(input('','s')==input('','s'))
\$\endgroup\$
2
\$\begingroup\$

J, 5 bytes

+/@:=

I feel like J would have a built-in for this, but I haven't been able to find one - maybe one of the active J users can enlighten me. So instead this first applies = to the inputs, turning each character into 1 if it's equal to the requested one or 0 otherwise. Then +/ computes the sum of that list.

\$\endgroup\$
2
\$\begingroup\$

Batch File, 121 Bytes

Because I'm a masochist ...

SET c=0
SET e=_
SET t=%1%%e%
:l
SET a=%t:~0,1%
IF "%a%"=="%2" SET /A c+=1
SET t=%t:~1%
IF NOT "%t%"=="%e%" GOTO l
ECHO %c%

Warning: Assumes that _ doesn't occur in the input string. If it does, then the variable e needs to be adjusted appropriately.

This sets up our counter variable, c, and our end-of-string demarcation as _, before appending that to our input string %1 and setting the concatenated string to t. Then, we're entering loop :l, we set a temporary character variable a to be the first character of t, check if it matches our second input string %2 and increment c if true, then trim the first character off of t. Our end-of-loop condition checks t against our end-of-string demarcation, and loops back if not. We then echo out the value of our counter.

It would probably be possible to use a FOR loop instead, but that would necessitate enabling DelayedExpansion, which I think will actually be longer byte-wise than this. Verification of that is left as an exercise to the reader.

\$\endgroup\$
2
\$\begingroup\$

CJam, 5 bytes

ll/,(

Explanation

l      e# read x
 l     e# read y
  /    e# split x by y
   ,   e# count
    (  e# subtract one
\$\endgroup\$
2
\$\begingroup\$

PowerShell, 32 Bytes

A four-for-one! And they're all the same length! :)

($args[0]-split$args[1]).Count-1

or

param($a,$b)($a-split$b).Count-1

Alternatively,

$args[0].Split($args[1]).Count-1

or

param($a,$b)$a.Split($b).Count-1

The first two styles use the inline operator -split, while the second two implicitly casts the first argument as a String and uses the .Split() string-based operator. In all instances an array is returned, where we must decrement Count by one, since we're getting back one more array item than occurrences of the second argument.

This one was kinda fun...

\$\endgroup\$
2
\$\begingroup\$

Julia, 21 bytes

f(s,c)=sum(i->c==i,s)

Note that it requires that c be a char, not a single-character string. So you use it as f("test me",'e') (which returns 2) and not f("test me","e") (which returns 0, because 'e'!="e").

\$\endgroup\$
2
\$\begingroup\$

><> (Fish), 30 bytes

0&v
=?\ilb
=?\:@=&+&l1
n&/;

Takes the string, then character to count. Input isn't separated (at least in the online interpreter). Try it on the online interpreter: http://fishlanguage.com I counted the bytes by hand, so let me know if I'm wrong.

Explanation

First off, ><> is 2 dimensional and and loops through a line or column until it hits a ; or error. This means that if it's proceeding left to right (like it does at the beginning of a program), it will wrap around the line if it reaches the end and is not moved or told to stop the program. Some characters per line will be repeated because they have different functions depending on the direction of the pointer, and the fourth line will have characters in reverse order because the pointer moves right to left.

A summary of the program is provided below. Look at the instructions listed for ><> on esolangs to see what each individual character does.

Line 1: 0&v

0&v -put 0 into the register and change direction to down-up

Line 2: =?\ilb

(starting where line 1 moves the pointer to, i.e. the third character)

\ -reflect the pointer and make it move left-right
i -read input
lb=?\ -reflect downwards if there are 11 values in the stack

line 3: =?\:@=&+&l1

(starting at the third character)

:@ -duplicate y and shift the stack e.g. ['x','y','y'] -> ['y','x','y']
=&+& -increment the register if the character popped from x = y
l1=?\ -reflect downwards if there is 1 value in the stack

Line 4: n&/;

(starting at the third character)

/ -reflect right-left
&n; -print value of the register
\$\endgroup\$
2
\$\begingroup\$

Ruby, 22 20 bytes

p gets.count(gets)-1

Demo: http://ideone.com/MEeTd2

The -1 is due to the fact that gets retrieves the input, plus a newline character. Ruby's String#count counts the number of times any character from the argument occurs in the string.

For example, for the input [test\n, t\n], the t occurs twice and the \n occurs once, and needs to be subtracted.

\$\endgroup\$
  • \$\begingroup\$ You can remove $><< and reduce 4 bytes. \$\endgroup\$ – Vasu Adari Sep 2 '15 at 14:33
  • \$\begingroup\$ @VasuAdari but I need to print the result somehow... \$\endgroup\$ – Cristian Lupascu Sep 2 '15 at 15:13
  • \$\begingroup\$ can you not do this? -> p gets.count(gets)-1 \$\endgroup\$ – Vasu Adari Sep 3 '15 at 4:34
  • \$\begingroup\$ @VasuAdari You're right; for the moment I thought that would put qutoes around the output, but it's numeric so it's OK. Thanks! \$\endgroup\$ – Cristian Lupascu Sep 3 '15 at 6:14
2
\$\begingroup\$

Ruby, 18 bytes

->s,c{p s.count c}

Usage:

->s,c{p s.count c}.call 'tttggloyoi', 't'

->s,c{p s.count c}.call 'onomatopoe', 'o'
\$\endgroup\$
1
\$\begingroup\$

rs, 33 bytes

+(.)(.* (?!\1).)/\2
(.*)../(^^\1)

Live demo and test cases.

This is pretty simple. The first line removes all characters except the ones we're counting. The next line counts the number of characters that are left, excluding the one we're searching for.

Takes input separated by spaces, e.g.:

onomatopoe o
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.