Écrire un programme qui trouve la lettre appariée la plus courante dans une chaîne

20

Le programme doit sortir la lettre qui est le plus jumelée. Par exemple, si votre programme a reçu la chaîne suivante:

"Sally's friend Bobby searched for seashells."

il doit sortir Lcar il "ll"se produit deux fois, ce qui est plus fréquent que l'autre paire "bb".

Règles:

  • Si plus d'une lettre a la 1ère place pour les occurrences, alors sortez-les toutes par ordre alphabétique (par exemple, vous "Sally's friends Jimmy and Bobby rummaged for seashells."devriez sortir les deux LET M[ou "LM"si vous voulez] car elles se produisent toutes les deux plus fréquemment que les autres paires.)
  • Les lettres triplées, quadruplées, etc. comptent pour une paire (par exemple, "lll"dans "willless"est compté pour une seule paire L.)
  • Les paires de lettres doivent être composées d'un seul mot (par exemple, elles "Sally's sociable friends Sammy and Bobby searched for fabulous seashells."doivent sortir Let non pas Sparce qu'elles ont "ss"plus d'occurrences "ll"qu'elles sont séparées par des espaces).
  • Ne compter que les lettres de l'alphabet anglais
  • La casse n'a pas d'importance (par exemple, "Ss"c'est la même chose que "SS"ou "ss", et tous sont comptés comme une paire de S.)

Vous pouvez lire vos commentaires où bon vous semble. Le code le plus court gagne.

ayane
la source
2
Pouvons-nous supposer que seules les lettres apparaîtront par paires ou l'entrée pourrait-elle contenir des espaces doubles ou doubles, 'etc.?
Martin Ender
1
Peut-on supposer qu'au moins une lettre apparaît deux fois?
Martin Ender
@ MartinBüttner Oui, vous pouvez supposer qu'au moins une paire de lettres se produit. Cependant, d'autres personnages peuvent également apparaître par paires. Ne comptez que les lettres.
ayane
Même s'il n'y a qu'une seule paire, puis-je l'imprimer dans une liste comme ['l']?
Maltysen
@Maltysen Oui, vous pouvez le faire.
ayane

Réponses:

6

Pyth, 26 25 24 16 15 octets

.M/sfthTrrz08ZG

Essayez-le en ligne: Démonstration

Explication:

.M/sfthTrrz08ZG   implicit: z = input string
         rz0      convert z to lower-char
        r   8     run-length-encoding (into tuples [count, char])
    f             filter for tuples T, which satisfy:
     thT            T[0]-1 != 0 (count > 1)
   s              join to a string
.M            G   find the elements Z of "abcd...z", which produce the highest value:
  /...........Z       count of Z in ...
Jakube
la source
1
eC-> senregistre un octet.
isaacg
Connaissez-vous de bonnes ressources que je pourrais utiliser pour apprendre Pyth?
Beta Decay
@BetaDecay Vous pouvez trouver un tutoriel sur Pyth sur pyth.readthedocs.org Il ne couvre pas toutes les fonctionnalités et astuces, mais c'est un bon début. Et si vous avez des questions, posez-les simplement dans le chat .
Jakube
7

Bash + GNU coreutils, 133

grep -Eo '([A-Z])\1+'<<<"${1^^}"|cut -c1|sort|uniq -c|sort -rn|while read n l
do((a-n&&a-0))&&exit||echo $l&&a=$n
done|sort|tr -d \\n

Testcases:

$ for t in "Sally's friend Bobby searched for seashells." \
> "Sally's friends Jimmy and Bobby rummaged for seashells." \
> "willless" \
> "Sally's sociable friends Sammy and Bobby searched for fabulous seashells." \
> "11ss11aa"
> do
> ./mostpaired.sh "$t"
> echo
> done
L
LM
LS
L
AS
$ 
Traumatisme numérique
la source
Ne compte-t-il que les lettres? (testcase: 11ss11aa-> SA)
edc65
@ edc65 Là je l'ai corrigé ;-). En fait, 11ss11aa-> AS :)
Digital Trauma
Je pense que vous devez l' sort -rêtre sort -rnsi vous avez 10 lettres paires ou plus.
Toby Speight
@TobySpeight. Oui. Fixé.
Digital Trauma
peut le raccourcir avec AWK au lieu de while: awk '! n {n = $ 1}; n == $ 1' | grep -o. $
Nik O'Lai
5

CJam, 29 27 octets

leue`{2a>},s_el-$e`$z~\)-,>

Merci à @Optimizer d'avoir joué au golf sur 2 octets!

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça fonctionne

leu    e# Read a line from STDIN and covert to uppercase.
e`     e# Perform run-length encoding.
       e# Example: "AABBBC!!" -> [[2 'A] [3 'B] [1 'C] [2 '!]]
{2a>}, e# Filter out all pairs that are less of equal to [2].
s      e# Stringify.
       e# Example: [[2 'A] [3 'B] [2 '!]] -> "2A3B2!"
_el    e# Push a copy of the string and convert to lowercase.
       e# Example: "2A3B2!" -> "2a3b2!"
-      e# Remove all character from the second string from the first.
       e# Example: "2A3B2!" "2a3b2!" - -> "AB"
$e`$   e# Sort, perform run-length encoding and sort again.
       e# Example: "ABACABDBC" -> "AAABBBCCD"
       e#                      -> [[3 'A] [3 'B] [2 'C] [1 'D]]
                               -> [[1 'D] [2 'C] [3 'A] [3 'B]]
z~     e# Zip and dump.
       e# Example: [[1 'D] [2 'C] [3 'A] [3 'B]] -> [1 2 3 3] ['D 'C 'A 'B]
\)     e# Pop out the last element from the first array.
       e# Example: [1 2 3 3] -> [1 2 3] 3
-      e# Remove all occurrences of the popped element from the array.
       e# Example: [1 2 3] 3 -> [1 2]
,      e# Compute the length of the remainder.
>      e# Skip that many elements from the character array.
Dennis
la source
z~\)-,>devrait fonctionner aussi loin que je peux voir.
Optimizer
@Optimizer: plus court et beaucoup plus intuitif. Merci!
Dennis
4

Pyth - 23 22 21 20 octets

Utilise la substitution regexp pour remplacer tous les deux ou plus de l'alphabet par une valeur temporaire, et utilise .Maximal pour obtenir toutes les occurrences les plus élevées. Merci à @Jakube d'avoir souligné la redondance du tri et de la sauvegarde d'un octet.

.M/:rz0+Z"{2,}"KC0KG

Prend les entrées de stdin et les sorties comme ['l', 'm']stdout.

.M        G         Values which yield maximal amount over lowercase alphabet
 /                  Count
  :                 Regexp substitution
   rz0              Lowercased input
   +Z               String concatenate current loop var         
    "{2,}"          Regexp 2 or more of previous group
   KCZ              Inline assign null byte to K and use value
  K                 Count K which is null byte

Essayez-le en ligne ici .

Maltysen
la source
4

C, 155

Quelque chose de différent, pas de regexps.

m=1,i=1,n[91];
main(c,a)char**a;
{
  char*t=a[1];
  for(;c=*t++;)(c&=95)>64&&c<91&&(c-(*t&95)?i=1:(c=(n[c]+=i),i=0,m=m<c?c:m));
  for(c=0;++c<91;)n[c]-m||putchar(c);
}
edc65
la source
3

Python 2, 132 143 octets

def f(x):import re;x=re.findall(r'(.)\1+',x.upper());s={l:x.count(l)for l in x};print "".join(sorted([l for l in s if s[l]==max(s.values())]))

Exemple d'exécution:

f("Sally's friends Jimmy and Bobby rummaged for seashells.")
LM
heo
la source
1
Il ne remplit probablement pas "les lettres triplées, quadruplées, etc. comptent pour une paire"
Ginden
Tu as raison! j'ai essayé de le réparer. merci de l'avoir signalé :)
heo
2

CJam, 37 octets

leue`{~_el-\(e&},1f=$e`$_W=0=f-{,1=},

Essayez-le en ligne

Sans prise en charge des expressions régulières, je crains qu'il soit difficile de rivaliser avec Pyth. C'est le meilleur que j'ai trouvé lors d'un premier passage.

Explication:

l     Get input.
eu    Convert it to upper case, since case does not matter.
e`    Run length encoding, to split into groups of same characters.
{     Start of block for filtering.
  ~     Unpack the length/letter pair.
  _     Copy the letter.
  el    Change copy to lower case.
  -     Subtract to compare. If result is non-zero, this is a letter.
  \     Swap count to top.
  (     Decrement to get truthy value for count > 1.
  e&    Logical and: It's a letter, and count is > 1.
},    End of filter.
1f=   Don't need the counts anymore, filter out the letters only from the RLE pairs.
$     Sort them, so that multiples of the same letter are sequential.
e`    RLE again, to count how many multiples of each letter we had.
$     And sort again, to get the count/letter pairs in order of incrementing count.
_     Copy list.
W=0=  Pick out count of last element, which is the highest count.
f-    Remove count from pairs that have the highest count. This leaves them
      as one member lists with letter only, while others still have count/letter.
{     Start block for filter.
  ,1=   Check for list length one.
},    End filter.
Reto Koradi
la source
2

Q (66)

Relativement lisible pour démarrer:

{where g=max g:.Q.A#count each group y where not differ y:upper x}
skeevey
la source
2

R, 105 octets

cat(substr(names(b<-table(regmatches(s<-toupper(readline()),gregexpr("([A-Z])\\1+",s))))[b==max(b)],1,1))

Cela lit une ligne de texte de STDIN et imprime une liste délimitée par des espaces des lettres appariées les plus courantes à STDOUT.

Non golfé + explication:

# Read a string from STDIN, convert to uppercase
s <- toupper(readline())

# Get each match of the regex /([A-Z])\1+/
matches <- regmatches(s, gregexpr("([A-Z])\\1+", s))

# Compute the frequency of each match
freq <- table(matches)

# Get the matches with the highest frequency
highest <- names(freq)[freq == max(freq)]

# Each element of highest is the literal pair, so take the first character
first <- substr(highest, 1, 1)

# Print to STDOUT
cat(first)

Exemples:

> (code)
Sally's friends Jimmy and Bobby rummaged for seashells.
L M

> (code)
Sally's friend Bobby searched for seashells.
L

> (code)
Sally's sociable friends Sammy and Bobby searched for fabulous seashells.
L

> (code)
11ss11nn
N S

Vous pouvez l' essayer en ligne !

Alex A.
la source
Vous pouvez probablement vous débarrasser du touppersi vous ignorez la casse et utilisez perl dans votre gregexpr. par exemplecat(substr(names(b<-table(regmatches(s<-readline(),gregexpr("(\\w)\\1+",s,T,T))))[b==max(b)],1,1))
MickyT
@MickyT: J'y avais pensé, mais il semble que l'OP souhaite que la sortie soit en majuscules, il devrait donc l'utiliser toupperpour s'assurer de toute façon.
Alex A.
C'est dommage, je l'ai raté quand j'ai lu la question.
MickyT
J'ai essayé le violon, mais il semble fonctionner indéfiniment sans outpuy dans Firefox. Testcase: 11ss11nn?
edc65
@ edc65 C'est un problème avec R-Fiddle; rien ne fonctionne du tout. J'ai contacté leur administrateur pour signaler le problème. Correction de mon expression régulière et maintenant votre test fonctionne comme prévu, mais cela m'a coûté 2 octets. Merci d'avoir signalé ce truc, je l'apprécie!
Alex A.
2

Rubis, 60

f=->s{(?a..?z).group_by{|l|s.scan(/#{l*2}+/i).size}.max[1]}

p f["Sally's friends Jimmy and Bobby rummaged for seashells."]

group_bycrée une structure de hachage (dictionnaire) où les clés sont la sortie du bloc et les valeurs sont des listes de lettres qui aboutissent à chaque clé. Dans ce cas, les clés correspondent à plus de 2 exécutions d'une lettre, sans tenir compte de la casse. maxcompare chaque [key,value]tuple lexicographiquement, donc il trouve juste la clé maximale. [1]Retourne ensuite la partie liste de valeurs du tuple.

histocrate
la source
2

Python 2, 185 159 153

i=input().lower()
d=sorted({l:len(i.split(l+l))for l in map(chr,range(97,123))}.items(),None,lambda x:x[1],1)
print sorted(c for c,k in d if k==d[0][1])

Prend l'entrée comme une chaîne entre guillemets.

Daniel Wakefield
la source
2

C # 160 octets

sest l'entrée:

char? d(string s){s=s.ToUpper();return s.Select((x,i)=>new{y=x,z=i==0?(char?)null:s[i-1]}).Where(x=>x.y==x.z).GroupBy(x=>x.z).OrderBy(x=>x.Count()).Last().Key;}
DLeh
la source
1

rs, 146 octets

[^A-Za-z]/
*(.)\1+/\1\1
*(.)(?!\1)/
$/#
+*(.)#(?!.*?\1)/#\1
+*(.)(.*)#(.*)\1/\2#\3\1\1
#/
*(.)(\1*)/\1(_)^^((^^\1\2))
([^_])(_+)(?!_)(?=.*\2_)/
_/

Essayez! S'il vous plaît! Il m'a fallu une éternité pour faire les boutons même avec la boîte de sortie sur cette page ...

Eh bien, c'était assez ... fou. La logique ici est un peu bizarre; Je ne posterai une explication que si quelqu'un le demande. (Bien sûr, j'ai aussi dit que pour une réponse INTERCAL dont l'explication était demandée ... que je n'ai jamais expliqué ...;)

kirbyfan64sos
la source
J'aime l'interpréteur, mais vous voudrez peut-être mettre la case de débogage sur la même ligne que les boutons ou quelque chose. Ça a l'air bizarre tout le long de leur. Toujours cool! +1
Maltysen
Je l'
ai
@Maltysen Je vais considérer cela. Merci!
kirbyfan64sos
@ edc65 Merde ... quel était le message d'erreur complet? On dirait que cela pourrait être un bogue PyPy.js. Ou tout simplement le fait que je n'ai jamais testé cela sur Firefox ...
kirbyfan64sos
1

JavaScript 156 153

var x=prompt(),f={},a=0,o
x.toUpperCase().replace(/([A-Z])\1+/g,function(m,s){m=f[s]=-~f[s]
if(a==m)o.push(s)
if(a<m)a=m,o=[s]})
alert(o.sort().join(""))

marteau-de-loup
la source
f[s]?f[s]+1:1->-~f[s]
edc65
Il échoue avec les non-lettres:Count only letters from the English alphabet
edc65
Merci @ edc65. J'ai ajouté le raccourci et la vérification AZ.
Wolfhammer le
1
Votre code exact, rationalisé et ES6: f=x=>{x.toUpperCase(f={},a=0,o).replace(/([A-Z])\1+/g,(m,s)=>a<(m=f[s]=-~f[s])?(a=m,o=[s]):a>m?0:o.push(s));alert(o.sort().join'')}(les 2 derniers '' sont vraiment des backticks, & # 96
edc65
1

Bash + textutils (grep, sed), 111 caractères

fold -1<<<$s|uniq -iD|sort -f|uniq -ic|sort -rn|grep -i [A-Z]|sed -n '1h;G;s/\(\s*\S\+\s\)\(.\)\n\1./\2/p'|sort

Bash + awk (au lieu de sed), 97 caractères

fold -1<<<$s|uniq -iD|sort -f|uniq -ic|sort -rn|grep -i [A-Z]|awk '!n{n=$1};n==$1{print $2}'|sort

pour le tester, attribuez d'abord s

s="Sally's friends Jimmy ää and Bobby rummaged ää for seashells."
Nik O'Lai
la source
0

R, 98 octets

Très similaire à la solution d'Alex, mais utilise une substitution plutôt qu'une correspondance pour déterminer les lettres consécutives. Le scan est utilisé pour obtenir l'entrée et également pour diviser le résultat de la substitution sur les espaces.

cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])

Quelques tests

> cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])
1: 11 was a race horse, 22 was one too. 11 won one race and 22 one won too.
19: 
Read 18 items
Read 2 items
O
> cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])
1: Sally's friends Jimmy and Bobby rummaged for seashells.
9: 
Read 8 items
Read 5 items
L M
> cat(names(a<-table(scan(,'',t=gsub('([A-z]?)(\\1?)[^A-z]*','\\U\\2 ',scan(,''),T,T))))[a==max(a)])
1: 11ss11nn
2: 
Read 1 item
Read 2 items
N S
> 
MickyT
la source