Détection de vote en série

51

Stack Exchange détecte automatiquement le vote en série (lorsqu'un utilisateur augmente ou diminue le nombre de messages d'un autre utilisateur) et l'inverse. Dans ce défi, vous allez implémenter un détecteur de «vote en série» très, très simple.

Contribution

L'entrée est une chaîne représentant une liste de votes. Chaque groupe de deux personnages représente un vote - le premier est l'électeur et le second l'utilisateur sur lequel un vote est demandé. Par exemple, l'entrée suivante

ababbccd

peut être analysé comme ab ab bc cd, et représente représenter avoter bdeux fois, bvoter cune fois et cvoter dune fois.

L'entrée ne comprend que des lettres minuscules et sera toujours égale à 0. Vous ne pouvez pas non plus voter sur vous-même (donc non aaou hh).

Sortie

Aux fins de ce défi, le vote en série est défini comme tout utilisateur donné votant sur un autre utilisateur trois fois ou plus.

La sortie indique combien de votes doivent être inversés pour chaque utilisateur (c'est-à-dire combien de votes sur chaque utilisateur ont été inversés et non pas combien de votes ont été inversés), dans le format [user][votes][user2][votes2].... Par exemple, une entrée de abababab( avote sur bquatre fois) doit être sortie b4(quatre votes ont été inversés de aà b).

La sortie peut être dans l’ordre que vous souhaitez, mais l’entrée et la sortie doivent être des chaînes uniques, comme décrit ci-dessus.

Cas de test

In                            Out
---------------------------------------------------------------------------
abababcbcbcbcbbababa          b7a3
edfdgdhdfgfgfgih              g3
jkkjjkkjjkkjljljljmlmlnmnmnm  j6k3m3
opqrstuv                      <none>
vwvwwvwv                      <none>
xyxyxyxyxyxyxyzyzyzyxzxzxz    y10z3
nanananananananabatman        a8
banana                        <none>
Poignée de porte
la source
16
+1 pour nanananananananabatmanle cas de test.
9

Réponses:

6

Pyth, 22 octets

pM_srSsfttTtMM.gkcz2 8

Essayez-le en ligne: démonstration ou suite de tests

Explication:

pM_srSsfttTtMM.gkcz2 8
                 cz2     chop the input into pairs
              .gk        group these pairs by their value
           tMM           discard the first char in each pair in each group
       fttT              discard all groups, that contain less than three pairs
      s                  concatenate all groups to get a list of chars
     S                   sort all chars
    r                8   run-length-encoding
   s                     concatenate all (count,char) pairs 
  _                      reverse the order
pM                       print each element without separator

Exemple:

input:   ededgdhdfgfgfgihed
chop:    ['ed', 'ed', 'gd', 'hd', 'fg', 'fg', 'fg', 'ih', 'ed']
group:   [['ed', 'ed', 'ed'], ['fg', 'fg', 'fg'], ['gd'], ['hd'], ['ih']]
discard: [['d', 'd', 'd'], ['g', 'g', 'g'], ['d'], ['d'], ['h']]
discard: [['d', 'd', 'd'], ['g', 'g', 'g']]
concat.: ['d', 'd', 'd', 'g', 'g', 'g']
sort:    ['d', 'd', 'd', 'g', 'g', 'g']
rle:     [[3, 'd'], [3, 'g']]
concat.: [3, 'd', 3, 'g']
reverse: ['g', 3, 'd', 3]
print:   g3d3
Jakube
la source
34

Illisible , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 octets

La sortie est dans l'ordre alphabétique inverse ( zà a) mais selon vos règles, cela semble être autorisé.

« " « » « « « » « » « » » » « « « » » » « » » « » « « » « » « » « » « » » « » « » « »" « » « » » « « " » » « » « « » « » « » » « » « « « » « » « » « » « » » » « »" " « » « » « « « » « » « » » » « « " » » « « « » « « « » « » « » » » « « « » » » « » » » « » « » « » « " « » « » « » » " « »« « » » « » « " « » « » « « « » « » « » » » « « « » » » »" « » « « « » « » « » « » » » « » « » « » "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " « » « « » » « » « « » « » « »" » « » « » « » « " « » » " « » « » « » « » « « « » » »" « « » »« » « » « » « « » « » « » « « « » « « « » « » « » « » » » « » « » « » » » « » « » « » » « » "" « » « » « » « « « » « » « » « « « » » » « » » » « « « » » » « " « » « » « » »" « » « » « » « « « » » » « » « « » » « » « » « » « « « » « » « » « « « » » » « » » » « » « » « « « » » » « « « » » » »« « " » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » »" » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « " « » « » « « « » « » « » » » »" « » « « » » « » « « « » « » « » « » » » « » « » « » « « » » « » « « » » « » « « « » « » » » « » " »« » « » « » « » « « « » « » « » « » » » « » « » « « « » » » « » « « » » « » « » « » "" « » « » « » « « » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » »" « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « »"" « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » " » « « " » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » »" » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ". Que" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" br suffisamment l'en qu' plusieurs plusieurs plusieurs plusieurs-plusieurs-plusieurs plusieurs-plusieurs plusieurs plusieurs-plusieurs plusieurs plusieurs prog plusieurs plusieurs quí plusieurs Réc plusieurs plusieurs plusieurs plusieurs plusieurs qu dél l'en plusieurs bien dél l'en plusieurs bien déluré 'dél bien' '' '' '' '' "" '"" "" "" "" "" "." "" "." "" "." "" "" "" "" "". «'". «". Diverses différentes différentes plusieurs plusieurs différentes que plusieurs plusieurs ''. '' '' Mais pas que plusieurs plusieurs-plusieurs-plusieurs-plusieurs-plusieurs “'' '' '"' "" "" "mais pas trop non fourni mais pas encore '' ''". '"Mais pas"' "" "" "" mais pas “'". « » « « » » « » « « »" » « " « » « » « » » « « »" » « » « " « » « » « « « » « » « » « » » » « » » « » « « » « » « » « » » « » « « « » « » « » « « « » » » « » » » « » « « « » « » « » » » « » " « »« » « » « « » » « » « " « » « « « » « » « » » » « » « » « « « » » » »" « » « « « » « » « » « » » » « » « » « » « « » » « » " « » « « « » » » « « « » » » « « « » » » « « « » » » « « « » » »" « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « »"" « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » « « » » « » " » « « " » » « " « » « » « « « » « » « » » » « » « » « » » " « » « « « » « » « » « » » » « » « » « » "" "" "" "" "" "" "" "" "" "" "" "" "" ""« » « « » « » « » « » » « » « » « » « » « « » « » « » « » » « » « » « » « » « « » « » « » « » » « » « » « » « » « « » « » « » « » » « » « » « » « « « » « « « » « » « » » » « » » » « " « » « » « » »" « » « « « » « » » » « » « » « « « » » » « » « « » » « » « » « » « « « » » » « » " « » « » « »« « »" » « » « " « » « » » « « » « » « » « « « » » »" » « » « " » « « » « » « »" » « » « » « »" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "."" "". "" "" "" "" "" "" "" "" "" "" "" "" "" "."" "". "" "" "" "" "" "" "" "" "" "" "" "" "" ".

Explication

Tout d'abord, pour avoir une idée de ce que peut illisible, voici son fonctionnement de base:

  • Vous avez une bande infinie de cellules entières de taille arbitraire
  • Vous n'avez pas de pointeur de mémoire comme dans Brainfuck; au lieu de cela, vous déréférencez les cellules en fonction de leur emplacement sur la bande. Cela signifie que vous pouvez «lire la valeur n ° 4» ou «lire la valeur n ° (lire la valeur n ° 4)» (double déréférence).
  • Vous pouvez uniquement lire ou écrire des cellules de mémoire (pas directement incrémenter / décrémenter comme dans Brainfuck).
  • Vous pouvez incrémenter / décrémenter des valeurs dans une expression. Ainsi, pour incrémenter une cellule de mémoire que vous avez à lire , incrément , écriture , ou en d' autres termes: write(x, inc(read(x))).
  • Il existe des boucles while et des conditions ternaires qui peuvent uniquement vérifier si elles sont nulles ou non.

Ce programme utilise la bande comme suit. Les noms de variables seront utilisés dans le pseudocode plus tard. En outre, cela documente la première version (qui était de 1830 octets); voir les modifications au bas de ce qui a changé depuis.

  • Cellule 0: variableq
  • Cellule 1: les variables a, p,ch
  • Cellule 2: variables hash,v
  • Cellule 3: variables b,r
  • Cellule 4: variables aa,l
  • Cellule 5: reste 0 pour marquer la "fin" de la chaîne de chiffres décimaux
  • Cellules 6 à 95: stocke la chaîne de chiffres décimaux à l'envers
  • Cellules 96-121: stocke le nombre de votes à déduire des utilisateurs a(96) à z(121) (le code ASCII de la lettre moins un).
  • Cellules 4657–7380: rappelez-vous combien de combinaisons électeur / votant ont été rencontrées combien de fois. Ces cellules n'ont que 4 valeurs possibles: 0= pas encore vu, -1= vu une fois, -2= vu deux fois, -3= vu un nombre quelconque de fois supérieur à 2.

L'algorithme procède essentiellement comme suit:

  • Continuez à lire les paires de caractères aet b. Calculez la valeur de hachage (a-2)*(a-1)+b-1, qui est unique pour chaque combinaison de lettres a – z.
  • Vérifiez la cellule de mémoire à cette valeur de hachage ( *hash). Si c'est le cas -3, l'utilisateur est déjà éligible pour le retrait du vote, donc incrémenté *(b-1). Sinon, décrémentez *hash. S'il est maintenant -3 , l'utilisateur vient se droit à la suppression de vote après trois occurrences, si incrément *(b-1)par 3.
  • Après cela, parcourez les caractères dans l’ordre inverse ( zen a) et indiquez ceux pour lesquels des votes doivent être déduits. Cela nécessite une division manuelle en nombre entier par 10 pour traduire le nombre en chiffres décimaux.

Avec tout cela clarifié, voici à quoi ressemble le programme en tant que pseudocode:

// Read pairs of characters
while (a = read) + 1 {
    b = read

    // Calculate hash = (a-1)*(a-2)/2 + b-1
    // This also sets a = b-1
    hash = 0
    while --a {
        aa = a
        while --aa {
            ++hash
        }
    }
    while --b {
        ++a
        ++hash
    }

    // If this combination has just been seen for the third time,
    // increment *a by 3; if more than third time, increment *a by 1
    *a = (*hash + 3) ? ((--*hash) + 3 ? *a : (*a+3)) : (*a+1)
}

// Loop through the characters z to a
l = 27
while --l {                     // l loops from 26 to 1 (not 0)
    (v = *(ch = l + 95)) ? {    // 'a' is ASCII 97, but cell 96
        print (ch+1)            // print the votee

        // Now we need to turn the number v into decimal.
        // p points to where we are storing decimal digits.
        p = 5

        while v {
            // Integer division by 10 (q=quotient, r=remainder)
            r = (q = 0)
            while v {
                --v
                (++r - 10) ? 1 : {
                    r = 0
                    ++q
                }
            }
            // Store digit ASCII character
            *(++p) = r + 48     // 48 = '0'
            v = q
        }

        // Now output all the digit ASCII characters in reverse order
        while *p {
            print *(--p + 1)
        }

    } : 1
}

Edit 1, 1830 → 1796: Je me suis rendu compte que je pouvais réutiliser la valeur de retour d'une boucle while à un endroit.

Éditer 2, 1796 → 1791: il s'avère que le programme est légèrement plus petit si, au lieu d'utiliser les cellules 6 à 95, je stocke les chiffres décimaux dans les cellules numérotées négatives (à partir de –1). En prime, le programme n'est plus limité à 10⁹⁰ voix!

Edit 3, 1791 → 1771: Au lieu d’affecter le résultat de *(ch = l + 95)to v, je l’assigne qpuis je déplace l’affectation v = qdans la condition while, en portant le code à 1777 octets. Puis permutez l'emplacement de qet vsur la bande car il qest maintenant 1 plus commun que v.

Éditer 4, 1771 → 1762: Duh. Initialiser hashà 1 au lieu de 0 est 9 octets plus court. Le code de hachage est maintenant 1 plus, ce qui n'a pas d'importance.

Edit 5, 1762 → 1745: Si j’initialise qet rà 1 au lieu de 0, je dois saupoudrer un peu -1de place pour que tout soit correct, et tout semble s’annuler - sauf que la while v { --v; [...] }boucle doit maintenant exécuter une itération de moins, ce que je peux faire en disant while --v { [...] }, qui est 26 caractères plus court.

Edit 6, 1745 → 1736: Au lieu de { r = 1; ++q }, nous pouvons écrire q = *((r = 1)+1)+1. Cela repose sur le fait qu’il se qtrouve à la variable emplacement n ° 2. Si c'était dans l'emplacement 1, ce serait encore plus court, mais le programme tout entier serait plus long dans l'ensemble.

Edit 7, 1745 → 1727: Revered Edit 6 et à la place, a réalisé la sauvegarde en insérant la boucle la plus interne en boucle dans l’expression qui calcule le code de code ASCII, qui se termine également à 1736 octets ... mais a ensuite enregistré une instruction de décrémentation (9 octets). ) en changeant ((++r) - 11) ? r :pour (r - 10) ? ++r :.

Édition 8, 1727 → 1626: Retouche du calcul du hachage. Il utilise maintenant une boucle while de moins. Les emplacements des cellules sont maintenant à leurs codes ASCII réels (pas plus de 1). Remaniement des variables à différents emplacements sur la bande car elles se produisent maintenant à une fréquence différente.

Edit 9, 1626 → 1606: Inlining plus fou. Le corps de la première boucle while ressemble maintenant à ceci:

// b = next char
*(b = (hash = read)) = {

    // hash = b + (a-1)*(a-2)/2
    while (a2 = --a) {
        while --a2 {
            ++hash
        }
    }

    // If this combination has just been seen for the third time,
    // increment *b by 3; if more than third time, increment *b by 1
    (*hash + 3) ? ((--*hash) + 3 ? *b : (*b+3)) : (*b+1)
}

et l'assignation de variable a maintenant presque complètement changé.

Modifier 10, 1606 → 1577: Je remarquai que aet a2sont tous les deux décrémenté à 0 pendant que les boucles, donc si je pouvais paire pavec l'un de ceux -ci , mais pas avec ch, je ne aurais pas besoin d'initialiser pà 0(qui coûte 29 octets). Il se trouve que je peux le faire en échangeant pet r. Les affectations de variable les plus récentes (et leur fréquence d'apparition dans le code) sont maintenant:

0 = v (3)                    (total  3)
1 = hash (6), r (5), ch (2)  (total 13)
2 = b (4), q (5)             (total  9)
3 = a (3), p (5)             (total  8)
4 = a2 (3), l (4)            (total  7)
Timwi
la source
1
Étant donné qu’un novemvigintillion aurait besoin d’une chaîne de 2 * 10 ^ 90 octets et que le plus petit volume actuel de 10 ^ 24 octets est environ 1/3 de la taille de la grande pyramide de Gizeh , je ne pense pas que vous ayez de quoi s'inquiéter. ;)
ETHproductions
1
@ETHproductions: Néanmoins, en jouant au programme, il m'est arrivé de corriger cette limitation :)
Timwi
22

CJam, 23 octets

Fête de longueur!

q2/$e`{3a>},e~Wf=$e`Wf%

ou

qW%2/$e`{3a>},e~:ce`Wf%

Exécuter tous les cas de test

Explication

q2/   e# Read input and split into pairs.
$e`   e# Sort and run-length encode - this tallies the pairs.
{     e# Filter the tallies...
  3a> e#   Keep only those which start with a 3 or greater.
},    e# Now we need to group the remaining pairs.
e~    e# Run-length decode the remaining pairs.
Wf=   e# Select the second character from each pair (the one being voted on).
$e`   e# Tally the characters by sorting and RLE'ing again.
Wf%   e# Reverse each pair, because CJam's RLE has the number first and the character last.

L'autre version commence par inverser les paires, ce qui économise deux octets ailleurs: a) la sélection du premier caractère de chaque chaîne :cremplace uniquement celle Wf=du second. b) Il n'est pas nécessaire de trier à nouveau avant le deuxième RLE, car les paires étaient déjà triées principalement par le personnage restant.

Martin Ender
la source
FWIW la Qdans votre deuxième réponse devrait être à des qfins non-test-wrapper.
Peter Taylor
@PeterTaylor Je le fais tout le temps -.-
Martin Ender
Je sais que c'est un détail mineur, mais convertir le 3en liste pour la comparaison est une astuce intéressante. Je l'ai résolu uniquement pour mon propre divertissement et j'ai perdu un octet parce que je l'utilisais 0=2>. Sinon, je me suis retrouvé avec presque la même chose que votre première solution, sauf que vous utilisiez la ::\ place de Wf%la dernière étape.
Reto Koradi
10

Bash, 95 94 85 81 octets

fold -2|sort|uniq -c|awk '$1>2{c[substr($2,2)]+=$1}END{for(x in c)printf x c[x]}'

Une première solution élégante, mais longue

Merci à User112638726 pour l' enregistrement d' un octet avec sed, DigitalTrauma pour sauver 9 avec fold, et Rainer P. pour sauver 4 plus avec awk« s substr!

Pour voir comment cela fonctionne, prenons l’entrée abababcbcbcbcbbababa.

  • Après fold -2(enroulez la ligne à une largeur de 2), nous avons

    ab
    ab
    cb
    cb
    cb
    cb
    ba
    ba
    ba
    
  • Après sort | uniq -c( -cest un indicateur très astucieux uniqqui indique le nombre de fois où chaque ligne apparaît en entrée), nous obtenons

          3 ab
          3 ba
          4 cb
    
  • Examinons maintenant la dernière awkcommande:

    • $1>2: N'affiche que les choses si l'enregistrement 1 (c'est-à-dire le nombre de votes identiques) est supérieur à 2 (c'est-à-dire ≥ 3). En d'autres termes, ignorez les lignes commençant par un nombre ≤ 2.

    • {c[substr($2,2)]+=$1}: Si le nombre est supérieur à 2, ajoutez ce nombre à la ctable de hachage, en utilisant le deuxième caractère de l’enregistrement 2 (alias le vote-ee) comme clé. (Nous n'avons pas à tout initialiser à zéro; awkc'est ce que nous faisons .)

    • END{...}: Cela signifie simplement "après avoir traité l’ensemble du fichier, voici ce qu’il faut faire ensuite".

    • for(x in c)printf x c[x]: Assez explicite. Imprimer chaque clé et sa valeur correspondante.

Poignée de porte
la source
&est équivalent à \0in sed
User112638726
@ User112638726 Je ne savais pas ça, merci
Bouton de porte
Réduit un peused -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
User112638726
@ User112638726 Cela échoue pour l'entrée bacada, par exemple.
Poignée de porte
Oh oui mon mal!
User112638726
8

JavaScript, 114 113 110

f=s=>eval('o={},s.replace(/../g,m=>s.search(`^((..)*${m}){3}`)?0:o[c=m[1]]=~~o[c]+1);r="";for(v in o)r+=v+o[v]');

Cas de test:

À un niveau élevé, ce code renseigne un objet avec des paires clé-valeur qui mappent les destinataires d'un vote sur le nombre de votes, { b:7, a:3 }puis les relie à une chaîne en forboucle. Le code est dans une evalexpression pour permettre l'utilisation de fordans une fonction de flèche sans avoir besoin de dépenser des octets sur { }et ;return r.

(Accessoires à user81655 pour économiser trois octets!)

Explication du evalcode:

o={},                             // object to hold name/vote mapping
s.replace(/../g,                  // for each pair of chars in input
  m=>s.search(`^((..)*${m}){3}`)  // see if pair appears 3 times
                                  //   (0 if true, -1 if not)
     ?0                           // if not, do nothing
     :o[c=m[1]]=~~o[c]+1          // if yes, increment the property named after
                                  //   the second character in the pair
);
r="";                       // return string
for(v in o)r+=v+o[v]        // populate string with characters and vote totals
apsillers
la source
6

Haskell, 103 octets

import Data.Lists
f s|c<-chunksOf 2 s,b<-[e!!1|e<-c,countElem e c>2]=nub b>>= \q->q:show(countElem q b)

Exemple d'utilisation: f "jkkjjkkjjkkjljljljmlmlnmnmnm"->"k3j6m3"

Comment ça fonctionne:

c<-chunksOf 2 s                      -- split the input into lists of 2 elements
b<-[e!!1|e<-c,countElem e c>2]       -- for every element e of that list take the 2nd
                                     -- char if there are more than 2 copies of e
nub b>>= \q->q:show(countElem q b)   -- take every uniq element thereof and append
                                     -- the number how often it appears 
nimi
la source
6

JavaScript (ES6), 195 174 169 167 158 octets

s=v=>eval("a={},b={},e='';(v.match(/../g)).forEach(c=>{a[c]=(a[c]||0)+1});for(var k in a){d=k[1];a[k]>2&&(b[d]=(b[d]||0)+a[k])};for(var k in b){e+=k+b[k]};e")

Tester

Gavin.Paolucci.Kleinow
la source
1
Bienvenue chez PPCG :) Nous avons quelques conseils pour jouer au golf dans JS ici et ici . Je ne connais pas JS moi-même assez bien pour vraiment aider, mais bon golf :)
FryAmTheEggman
1
D'une part, vous pouvez supprimer le vars. Qui se soucie de polluer la portée mondiale du code golf? ;)
Poignée de porte
De plus, nous /(\w{2})/gpouvons simplement savoir /../g- nous savons déjà que l’entrée n’est que des lettres et que la répétition d’un (ou deux) caractères est plus courte que {2}. Si cela vous intéresse, vous pouvez consulter (et commenter des questions) ma réponse JavaScript à ce défi. Bienvenue chez PGCC!
apsillers
4

Mathematica, 110 100 99 octets

g=Cases[Tr@#,#2,All]&;""<>g[g[BlockMap[$,Characters@#,2],i_*_/;i>2]/.$->Last,i_*x_:>x<>ToString@i]&
Alephalpha
la source
3

Perl, 86 84 83 octets

s/../$h{$&}++/eg;@l=%l=map{/./;$h{$_}>2?($',${$'}+=$h{$_}):()}keys%h;$"="";$_="@l"

C'est 82 octets plus 1 pour l' -pargument en ligne de commande:

$ echo xyxyxyxyxyxyxyxyzyzyzyxzxzxz | perl -p 86.pl
y11z3


Un peu non-golfé:

s/../$h{$&}++/eg;     # construct hash %h with pair counts

@l = %l = map         # assign to array via hash to filter dupes
{                     
  /./;                # match the first character

  $h{$_}>2?           # filter on 3 or more identical votes
  (                   # return a 2 element list (k/v pair for %l):
    $',               # $POSTMATCH: the 2nd character (votee)
    ${$'} += $h{$_}   # increment votee total votes, value is new total
  )
  :()
}
keys %h;              # iterate the unique pairs

$" = "";              # set $LIST_SEPARATOR to empty string
$_ = "@l"             # implicit join using $";  $_ gets printed with -p
  • update 84 Économisez 2 octets en insérant le grep
  • update 83 Save 1 octet en utilisant des variables temporaires globales ${$'}au lieu de $g{$'}. Malheureusement,$$' ça ne marche pas.
Kenney
la source
3

Pure Bash, 151

Plus longtemps que je l'espérais, mais le voici.

declare -A a n
for((;v<${#1};v+=2));{((a[${1:v:2}]++));}
for u in ${!a[@]};{((a[$u]>2))&&((n[${u:1}]+=a[$u]));}
for u in ${!n[@]};{ printf $u${n[$u]};}

Utilise l'indexation par tableaux associatifs pour effectuer le comptage nécessaire. Nécessite bash version 4.0 ou supérieure.

Trauma numérique
la source
1

Caractères PHP 247

(Aie)

$f='';for($i=0;$i<strlen($s);$i=$i+2){$a[]=$s[$i].$s[$i+1];}$r=[];for($i=0;$i<count($a);$i++){$t=array_count_values($a);$c=$t[$a[$i]];if($c>=3){$r[$a[$i][1]][$a[$i][0]]=$c;}}for($i=0;$i<count($r);$i++){$f.=key($r).array_sum(current($r));next($r);}

A expliqué

// Test Case
$s = 'nanananananananabatman';

// Final result here
$f = '';

// Seperate strings into array in 2 character chunks
for ($i = 0; $i < strlen($s); $i = $i + 2)
{
    $a[] = $s[$i] . $s[$i + 1];
}

// Make an array of data
// The first level of array has voted on user as key
// Inside of that array is a dictionary with the voter user as the key, and the number of votes as the value
$r = [];
for ($i = 0; $i < count($a); $i++)
{
    $t = array_count_values($a);
    $c = $t[$a[$i]];
    if ($c >= 3)
    {
        $r[$a[$i][1]][$a[$i][0]] = $c;
    }
}

// Combine votes from different users to the same user into the final result string
for ($i = 0; $i < count($r); $i++)
{
    $f .= key($r) . array_sum(current($r));
    next($r);
}

echo $f;

Est-ce que cela sans regarder d'autres réponses. C'est le code de golf le plus difficile que j'ai jamais abordé. Je me félicite de toutes les optimisations.

OIE
la source
0

R, 221 octets

code

f=function(s){t=strsplit(gsub("(.{2})","\\1 ", s)," ")[[1]];z=table(t)[table(t)>2];n=substr(names(z),2,2);x=data.frame(y=z,t=n);a=aggregate(x$y,by=list(x$t),sum);for(i in nrow(a):1)cat(as.character(a[i,1]),a[i,2],sep="")}

non-golfé

f <- function(s){
  l <- gsub("(.{2})", "\\1 ", s)
  t <- strsplit(l," ")[[1]]
  z <- table(t)[table(t)>2]
  n <- substr(names(z),2,2)
  x <- data.frame(y=z,t=n)
  a <- aggregate(x$y, by=list(x$t),sum)
  for(i in nrow(a):1){
    cat(as.character(a[i,1]),a[i,2],sep="")
  }
}

Il y a beaucoup de place à l'amélioration ici.

Mutador
la source