Rechercher les occurrences d'un caractère dans une chaîne d'entrée

18

Défi

Écrivez un programme qui, étant donné une chaîne de x10 caractères et un caractère y, renvoie le nombre de fois où le caractère yapparaît dans la chaîne x.

Le programme le plus court en octets pour ce faire gagne.

Exemple

Input: tttggloyoi, t
Output: 3

Input: onomatopoe, o
Output: 4
Rosslyn Taghoy
la source
11
Cela semble presque trop facile d'un défi. Aussi pourquoi limiter l'entrée à 10, au lieu de pas de limite du tout?
Fatalize
7
A besoin d'une condition gagnante.
isaacg
2
N'hésitez pas à annuler ma modification si elle n'est pas d'accord avec vous
Beta Decay
8
Quelle est la flexibilité du format d'entrée? Pouvons-nous choisir un délimiteur différent, comme un espace ou une nouvelle ligne? La chaîne peut-elle être entre guillemets? Pouvons-nous prendre la lettre en premier et la chaîne en second? Les caractères seront-ils toujours des minuscules? Sinon, quels autres personnages peuvent apparaître?
Martin Ender
5
Cela ressemble étrangement à une question d'entrevue C ...
Quentin

Réponses:

18

Pyth, 3 octets

/ww

Exemple d'exécution:

$ pyth -c '/ww'
sdhkfhjkkj
k
3

Bien sûr, l'utilisateur peut entrer plus ou moins de 10 lettres sur la première entrée, mais nous n'avons pas à nous soucier de ce qui se passe lorsque l'utilisateur viole la spécification.

isaacg
la source
semble que ce n'est plus du pyth valide?
Ven
explication s'il vous plait?
MilkyWay90 du
@ MilkyWay90 Voici comment vous pourriez l'utiliser: Essayez-le en ligne! . /compte simplement le nombre d'occurrences dans la première chaîne d'entrée de la deuxième chaîne d'entrée. wprend une ligne d'entrée.
isaacg
@isaacg oh, je vois. Je vous remercie!
MilkyWay90
11

Pyth - 3 octets

Une réponse Pyth différente, moins évidente, de la même taille. Il se replie en comptant sur l'entrée.

/FQ

Suite de tests .

Maltysen
la source
7

JavaScript, 32

(p=prompt)().split(p()).length-1
edc65
la source
6

Bash, 24 caractères

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

Exemple d'exécution:

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

bash-4.3$ bash letter-count.sh onomatopoe o
4
homme au travail
la source
6

Rétine , 12 octets

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

Simplement une expression régulière qui correspond à un caractère qui est égal au dernier caractère de l'entrée (sauf lui-même). Lorsqu'une seule expression régulière est donnée, Retina renvoie simplement le nombre de correspondances.

Martin Ender
la source
Wow, je suis ici essayant de faire toutes sortes de trucs fantaisistes avec rs , et tu me bats avec des lookaheads. +1
kirbyfan64sos
4

Labyrinthe , 32 29 27 24 octets

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

Cela lit d'abord le caractère unique, suivi de la chaîne dans laquelle compter, et suppose qu'il n'y a pas d'octets nuls dans la chaîne.

Explication

Le code commence par ),}, qui définit le bas de la pile sur 1, lit le premier caractère et le déplace vers la pile auxiliaire pour une utilisation future. Le 1sera notre compteur (le décalage de 1 sera annulé plus tard et est nécessaire pour que l'IP prenne les tours nécessaires).

L'IP va maintenant descendre pour lire le premier caractère de la chaîne de recherche avec ,. La valeur est annulée avec `, encore une fois pour obtenir le comportement de braquage correct. Pendant que nous lisons des caractères de STDIN, l'IP suivra maintenant cette boucle:

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

{:}crée une copie du code de caractère stocké et l' +ajoute à la valeur actuelle. Si le résultat est 0(c'est-à-dire que le caractère actuel est celui que nous recherchons), l'IP se déplace tout droit: -se débarrasse simplement du 0, )incrémente le compteur,{} est un no-op.

Cependant, si le résultat après +est différent de zéro, nous ne voulons pas compter le caractère actuel. L'IP prend donc un virage à droite à la place. C'est une impasse, de sorte que le code y est exécuté deux fois, une fois en avant et une en arrière. Autrement dit, le code réel dans ce cas devient );___;)+-){}. );se débarrasse simplement de cette différence non nulle, ___pousse 3 zéros, mais ;supprime l'un d'eux. )incrémente l'un des deux zéros restants, les +ajoute en un seul 1, le -soustrait du compteur et) incrémente le compteur. En d'autres termes, nous avons créé un no-op très élaboré.

Lorsque nous frappons EOF, ,pousse -1, qui `se transforme en 1et l'IP prend un virage à droite. -soustrait le 1du compteur (annulation du décalage initial). !imprime le compteur et @termine le programme.

Martin Ender
la source
4

Python 3, 29 octets

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

Meh, c'était facile. Suppose que l'entrée est une chaîne de dix lettres.

Beta Decay
la source
4
Tu m'as copié! : D
isaacg
1
@isaacg Les grands esprits pensent de même? ; D
Beta Decay
Si vous n'avez pas besoin de lire l'entrée, ne serait-il pas f=lambda x,y:x.count(y)plus court? (Désolé si cela ne fonctionne pas, je suis sur mobile et je ne peux pas vérifier)
Cole
@ mbomb007 Mon erreur, merci pour la clarification.
cole
1
La suppression des crochets autour de l'impression vous permet d'économiser un caractère print input().count(input())ou a,b=input();print a.count(b)avec le même montant
Willem
4

Snowman 1.0.2 , 16 caractères

~vgvgaSaLNdEtSsP

Étonnamment court. Explication:

~      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
Poignée de porte
la source
Bon travail! Je n'aurais pas pensé qu'une solution aussi courte serait possible dans Snowman.
Alex A.
4

C ++ Template-Métaprogrammation, 160 154 116 octets

Juste pour les rires.

Merci à ex-bart de l'avoir joué au golf!

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;

Utilisation: Le premier caractère de l'instanciation du modèle est le caractère à rechercher.

Compléter avec clang -std = c ++ 11 -c -> le résultat est au début du message d'erreur.

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

Complétez avec gcc -std = c ++ 11 -c -> le résultat est au bas du message d'erreur.

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)

Recherchez A < 3 , 't', '\ 000'> et A < 3 , 't', '\ x00'>

Version 154 octets

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;

Version 160 octets:

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;
Otomo
la source
Vous pouvez raccourcir ((x==y)?1:0)juste (x==y)pour économiser environ 6 octets (je pense).
kirbyfan64sos
Merci - je voulais être sûr qu'il s'agit d'un comportement défini, car je n'étais pas sûr de ce que la norme disait à propos boolde la intconversion.
Otomo
C'est un comportement défini.
kirbyfan64sos
Oui, maintenant je le sais aussi. :) Merci beaucoup. (Je pensais que cela dépendrait de l'implémentation.)
Otomo
1
128 octets: utilisez anonyme enumau lieu de static const. Utilisez 0au lieu de '\0'pour terminer. Utilisez intau lieu de char. Utilisez une déclaration légèrement différente pour instancier. Supprimez la nouvelle ligne de superflouos. 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;. Vérifié avec g ++ et clang.
ex-bart
3

Bash + grep, 26 octets

grep -o "$1"<<<"$2"|wc -l
Tarod
la source
3

Javascript (ES6), 26 octets

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

Cette solution quick'n'easy définit une fonction anonyme. Pour l'utiliser, ajoutez une déclaration de variable au début. Essaye le:

EDIT: Oh, je vois qu'il y a déjà une solution très similaire. J'espère que ça va.

ETHproductions
la source
3

Haskell, 21 octets

a!b=sum[1|x<-a,x==b]
Otomo
la source
3

C ++, 78 octets

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

Appelez comme ceci:

$ g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out tttggloyoi t; echo $?
3
ex-bart
la source
3

Élément , 23 octets

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

La nouvelle ligne fait partie du programme. Je l'utilise en fait comme nom de variable .

Ce programme fonctionne essentiellement en stockant le caractère cible dans une variable, en gardant la chaîne actuelle en haut de la pile, puis en bouclant le processus "hacher, comparer et déplacer le résultat en dessous", en additionnant les résultats à la fin.

La nouvelle ligne en tant que nom de variable provient de l'utilisation de la nouvelle ligne à la fin de l'entrée en la coupant et en la stockant. La nouvelle ligne du code est l'endroit où je l'ai lu.

L'entrée est comme ceci:

qqqqwwweee
q

La sortie est comme ça

4
PhiNotPi
la source
3

Julia, 26 25 octets

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

le findin fonction renvoie les indices du premier argument auxquels le deuxième argument est trouvé comme vecteur. La longueur du vecteur est le nombre d'occurrences.

Un octet enregistré grâce à Glen O.

Alex A.
la source
endofvous fera économiser un octet à la place de length.
Glen O
3

APL, 7 3 octets

+/⍷

Cela crée un train de fonctions. Il fonctionne en créant un vecteur de zéros et de uns correspondant aux indices auxquels le caractère apparaît dans la chaîne ( ). Le vecteur est ensuite additionné (+/ ).

4 octets enregistrés grâce à kirbyfan64sos et NBZ!

Alex A.
la source
L'APL est-elle curry comme K? Je pense que vous pourriez simplement faire quelque chose comme ça +/⍷(je ne connais pas APL, donc je peux me tromper).
kirbyfan64sos
@ kirbyfan64sos Le seul curry que je connaisse est la nourriture, donc je ne suis pas sûr. Mais je vais m'en occuper. Merci pour la suggestion!
Alex A.
@ kirbyfan64sos Oui, cela s'appelle un train de fonctions , donc + / ⍷ fonctionnerait bien, mais comme nous recherchons un seul caractère, on pourrait tout aussi bien utiliser = au lieu de ⍷.
2015 à
3

Perl, 21 16 caractères

(Code de 13 caractères + option de ligne de commande à 3 caractères.)

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

Exemple d'exécution:

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
homme au travail
la source
Truc sympa avec <>!
ThisSuitIsBlackNot
Vous pouvez enregistrer un octet en supprimant -let en vous assurant que votre entrée n'a pas de nouvelle ligne de fin:echo -en 'onomatopoe\no' | perl -pe '$_=eval"y/".<>."//"'
ThisSuitIsBlackNot
1
Et vous pouvez faire tomber votre total à 16 avecperl -pe '$_+=s/${\<>}//g'
ThisSuitIsBlackNot
Cette astuce de référencement est incroyable. Merci, @ThisSuitIsBlackNot.
manatwork
Pourquoi est-ce +=nécessaire? =semble fonctionner aussi bien (et devrait toujours fonctionner lorsque l'entrée commence par quelques chiffres).
ex-bart
3

PHP, 36 35 octets

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


Utilisation:
appelez le script avec deux arguments.
php script.php qwertzqwertz q

PHP, 23 octets

Si vous enregistrez des variables globales (uniquement possible en PHP 5.3 et inférieur), vous pouvez économiser 12 octets (grâce à Martijn )

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


Usage:
appeler le script et déclarer des variables globalesphp script.php?a=qwertzqwertz&b=q

jrenk
la source
1
Vous pouvez supprimer un espace après la virgule pour obtenir un octet de moins
Voitcus
1
Si vous avez des registres mondiaux, vous pouvez faire script.php?a=qwertzqwertz&b=q, et faire <?=substr_count($a,$b);, 23 caractères
Martijn
@Martijn bonne idée merci!
jrenk
3

Dyalog APL , 3 octets

      +/=

C'est-à-dire "La somme des octets égaux". Par exemple:

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

ou juste

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

K ne bat pas APL cette fois.

Essayez-le en ligne.

Adam
la source
Veuillez ne pas modifier des dizaines de messages à la fois. Vous inondez complètement la première page. S'il y a beaucoup de publications qui nécessitent une modification (ce qui arrive parfois, par exemple parce qu'une nouvelle balise est ajoutée), il est généralement agréable de n'en faire que 3 à la fois, puis d'attendre au moins 12 heures pour qu'elles puissent tomber devant page.
Martin Ender
@ MartinBüttner Ouais, je ne m'en rendais pas compte à l'époque. :-( Les ​​utilisateurs réguliers n'ont pas l'option "
Édition
Malheureusement, il n'existe aucune option de ce type, même pas pour les modérateurs.
Martin Ender
3

T-SQL, 99 40 octets

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

Fait simplement une différence entre la chaîne d'entrée et la chaîne avec le caractère supprimé. Prend l'entrée du tableau t

Modifier a été modifié pour supprimer un problème de comptage des espaces et pour prendre en compte les entrées acceptables actuelles pour SQL. Merci @BradC pour tous les changements et économies

MickyT
la source
Vous ne devriez pas avoir besoin de tout l'échafaudage, faites-le SELECT LEN(s)-LEN(REPLACE(s,c,''))FROM t, où t est une table d'entrée pré-remplie avec les champs set c.
BradC
Sur une autre note, ce code donne la mauvaise réponse pour des chaînes comme A B C D celle-ci se terminant par des espaces (si vous êtes invité à compter les espaces), car LENignore les espaces de fin.
BradC
@BradC Je pense qu'à l'époque, les règles sur ce qui était acceptable, en particulier sur SQL, étaient restrictives et peu claires. Je vais space
essayer de
Habituellement, je remplis simplement la fin et je soustrais une; dans ce cas, l'entrée est garantie à exactement 10 caractères, vous pouvez simplement la coder en dur commeSELECT 11-LEN(REPLACE(s,c,'')+'x')FROM t
BradC
@BradC ouais, en regardant à nouveau, je ne sais pas pourquoi j'ai autorisé la longueur variable. Faire des changements.
MickyT
2

Octave / Matlab, 33 octets

sum(input('','s')==input('','s'))
Luis Mendo
la source
2

J, 5 octets

+/@:=

Je pense que J aurait un intégré pour cela, mais je n'ai pas pu en trouver un - peut-être qu'un des utilisateurs actifs de J peut m'éclairer. Au lieu de cela, cela s'applique d'abord =aux entrées, transformant chaque caractère en 1s'il est égal à celui demandé ou 0autrement. +/Calcule ensuite la somme de cette liste.

Martin Ender
la source
2

Fichier de commandes, 121 octets

Parce que je suis masochiste ...

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%

Avertissement: suppose que _cela ne se produit pas dans la chaîne d'entrée. Si c'est le cas, la variable edoit être ajustée de manière appropriée.

Ceci configure notre variable de compteur c, et notre démarcation de fin de chaîne comme _, avant d'ajouter cela à notre chaîne d'entrée %1et de définir la chaîne concaténée sur t. Ensuite, nous entrons dans la boucle :l, nous définissons une variable de caractère temporaire apour être le premier caractère de t, vérifions si elle correspond à notre deuxième chaîne d'entrée %2et incrémentons csi vrai, puis coupons le premier caractère de t. Notre condition de fin de boucle vérifie tnotre démarcation de fin de chaîne et reboucle sinon. Nous sortons ensuite echola valeur de notre compteur.

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.

AdmBorkBork
la source
2

CJam, 5 bytes

ll/,(

Explanation

l      e# read x
 l     e# read y
  /    e# split x by y
   ,   e# count
    (  e# subtract one
Ypnypn
la source
2

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

AdmBorkBork
la source
2

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").

Glen O
la source
2

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

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.

Cristian Lupascu
la source
You can remove $><< and reduce 4 bytes.
Vasu Adari
@VasuAdari but I need to print the result somehow...
Cristian Lupascu
can you not do this? -> p gets.count(gets)-1
Vasu Adari
@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!
Cristian Lupascu
2

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'
Vasu Adari
la source