Erkennung serieller Abstimmungen

51

Stack Exchange erkennt automatisch serielle Abstimmungen (wenn ein Benutzer viele Beiträge eines anderen Benutzers positiv oder negativ bewertet) und kehrt diese um. In dieser Herausforderung implementieren Sie einen sehr, sehr einfachen "Serienwahl" -Detektor.

Eingang

Die Eingabe ist eine Zeichenfolge, die eine Liste von Stimmen darstellt. Jede Gruppe von zwei Zeichen stellt eine Abstimmung dar - die erste ist der Wähler und die zweite ist der Benutzer, über den abgestimmt wird. Zum Beispiel die folgende Eingabe

ababbccd

Kann analysiert werden als ab ab bc cdund repräsentiert adie bzweifache, bdie ceinmalige und cdie deinmalige Abstimmung .

Die Eingabe besteht nur aus Kleinbuchstaben und hat immer eine gerade Länge> 0. Sie können auch nicht über sich selbst abstimmen (also nein aaoder hh).

Ausgabe

Für die Zwecke dieser Herausforderung wird die Serienabstimmung als ein beliebiger Benutzer definiert, der dreimal oder öfter über einen anderen Benutzer abstimmt.

Die Ausgabe ist, wie viele Stimmen für jeden Benutzer umgekehrt werden sollen (das heißt, wie viele Stimmen für jeden Benutzer wurden umgekehrt, nicht wie viele Stimmen, die sie abgegeben haben, wurden umgekehrt), und zwar im Format [user][votes][user2][votes2].... Zum Beispiel kann ein Eingang abababab( aAbstimmung über bsollten viermal) -Ausgang b4(vier Stimmen wurden von umgekehrt azu b).

Die Ausgabe kann in einer beliebigen Reihenfolge erfolgen, aber sowohl die Eingabe als auch die Ausgabe müssen einzelne Zeichenfolgen sein, wie oben beschrieben.

Testfälle

In                            Out
---------------------------------------------------------------------------
abababcbcbcbcbbababa          b7a3
edfdgdhdfgfgfgih              g3
jkkjjkkjjkkjljljljmlmlnmnmnm  j6k3m3
opqrstuv                      <none>
vwvwwvwv                      <none>
xyxyxyxyxyxyxyzyzyzyxzxzxz    y10z3
nanananananananabatman        a8
banana                        <none>
Türknauf
quelle
16
+1 für nanananananananabatmanTestfall.
neun

Antworten:

6

Pyth, 22 Bytes

pM_srSsfttTtMM.gkcz2 8

Probieren Sie es online aus: Demo oder Test Suite

Erläuterung:

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

Beispiel:

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
quelle
34

Unleserlich , 1830 1796 1791 1771 1762 1745 1736 1727 1626 1606 1577 Bytes

Die Ausgabe erfolgt in umgekehrter alphabetischer Reihenfolge ( zbis a), jedoch nach Ihren Regeln, die als zulässig erscheinen.

"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "

Erläuterung

Um einen Eindruck davon zu bekommen, was Unreadable kann, ist hier die grundlegende Operation:

  • Sie haben ein unendliches Band mit Ganzzahlzellen beliebiger Größe
  • Sie haben keinen Speicherzeiger wie in Brainfuck. Stattdessen dereferenzieren Sie Zellen nach ihrer Position auf dem Band. Dies bedeutet, dass Sie den Wert 4 oder den Wert 4 lesen können (doppelte Dereferenzierung).
  • Sie können nur Speicherzellen lesen oder schreiben (nicht wie in Brainfuck direkt inkrementieren / dekrementieren).
  • Sie können Werte innerhalb eines Ausdrucks erhöhen / verringern. So eine Speicherzelle Sie müssen erhöhen lesen , Schritt , Schreib , oder anders ausgedrückt: write(x, inc(read(x))).
  • Es gibt while-Schleifen und ternäre Bedingungen, die nur auf Null im Vergleich zu Nicht-Null prüfen können.

Dieses Programm verwendet das Band wie folgt. Die Variablennamen werden später im Pseudocode verwendet. Auch dies dokumentiert die erste Version (die 1830 Bytes war); In den Änderungen am unteren Rand sehen Sie, was sich seitdem geändert hat.

  • Zelle 0: variabelq
  • Zelle 1: Variablen a, p,ch
  • Zelle 2: Variablen hash,v
  • Zelle 3: Variablen b,r
  • Zelle 4: Variablen aa,l
  • Zelle 5: Bleibt 0, um das „Ende“ der Dezimalstellenfolge zu markieren
  • Zellen 6–95: Speichern Sie die Zeichenfolge der Dezimalstellen rückwärts
  • Zellen 96–121: Speichern Sie die Anzahl der Stimmen, die von den Benutzern a(96) bis z(121) abgezogen werden sollen ( der ASCII-Code des Buchstabens minus eins).
  • Zellen 4657–7380: Denken Sie daran, welche Wähler / Wähler-Kombinationen wie oft aufgetreten sind. Diese Zellen haben nur 4 mögliche Werte: 0= noch nicht gesehen, -1= einmal gesehen, -2= zweimal gesehen, -3= beliebig oft mehr als 2 gesehen.

Der Algorithmus geht im Wesentlichen wie folgt vor:

  • Lesen Sie weiter Zeichenpaare aund b. Berechnen Sie den Hash-Wert (a-2)*(a-1)+b-1, der für jede Buchstabenkombination von a – z eindeutig ist.
  • Überprüfen Sie die Speicherzelle mit diesem Hash-Wert ( *hash). Wenn dies -3der Fall ist, ist der Benutzer bereits zum Entfernen von Stimmen berechtigt *(b-1). Ansonsten dekrementieren *hash. Wenn dies jetzt -3 der Fall ist, kann der Benutzer nach drei Vorkommnissen nur noch Stimmen entfernen, also inkrementieren Sie *(b-1)um 3.
  • Gehen Sie danach die Zeichen in umgekehrter Reihenfolge durch ( zbis a) und geben Sie die Zeichen aus, für die Stimmen abgezogen werden müssen. Dies erfordert eine manuelle Ganzzahldivision durch 10, um die Zahl in Dezimalstellen zu übersetzen.

Nach alledem sieht das Programm wie folgt aus:

// 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: Es wurde erkannt, dass ich den Rückgabewert einer while-Schleife an einer Stelle wiederverwenden kann.

Edit 2, 1796 → 1791: Es stellt sich heraus, dass das Programm etwas kleiner ist, wenn ich anstelle der Zellen 6–95 die Dezimalstellen in den negativ nummerierten Zellen speichere (ab –1). Als zusätzlichen Bonus ist das Programm nicht mehr auf 10⁹⁰ Stimmen beschränkt!

Bearbeiten 3, 1791 → 1771: Statt das Ergebnis der Zuordnung *(ch = l + 95)zu v, ich jetzt weisen Sie ihn qund dann die Zuordnung bewegen v = qin die während Zustand, wobei der Code auf 1777 Bytes. Tauschen Sie dann die Position von qund vauf dem Band aus, da sie qjetzt 1 häufiger ist als v.

Edit 4, 1771 → 1762: Duh. Die Initialisierung hashauf 1 anstelle von 0 ist 9 Byte kürzer. Der Hash-Code ist jetzt 1 mehr, was keine Rolle spielt.

Edit 5, 1762 → 1745: Wenn ich initialisiere qund rauf 1 anstatt auf 0, muss ich ein paar -1s streuen , um es richtig zu machen, und alles scheint sich abzubrechen - mit der Ausnahme, dass die while v { --v; [...] }Schleife jetzt eine Iteration weniger ausführen muss. was ich sagen kann while --v { [...] }, was 26 Zeichen kürzer ist.

Edit 6, 1745 → 1736: Anstelle von { r = 1; ++q }können wir schreiben q = *((r = 1)+1)+1. Dies qhängt von der Tatsache ab, dass sich die Variable in Steckplatz 2 befindet. Wenn es auf Position 1 wäre, wäre dies noch kürzer, aber dann wäre das gesamte Programm insgesamt länger.

Edit 7, 1745 → 1727: Edit 6 wurde rückgängig gemacht und stattdessen wurde das Speichern erreicht, indem die innerste while-Schleife in den Ausdruck eingefügt wurde, der den stelligen ASCII-Code berechnet, der ebenfalls bei 1736 Byte endet ... aber dann eine Dekrementierungsanweisung (9 Byte) gespeichert hat ) durch Ändern ((++r) - 11) ? r :auf (r - 10) ? ++r :.

Edit 8, 1727 → 1626: Die Hash-Berechnung wurde überarbeitet. Es wird jetzt eine while-Schleife weniger verwendet. Die Zellenpositionen haben jetzt ihre tatsächlichen ASCII-Codes (nicht mehr um 1 deaktiviert). Variablen an verschiedenen Stellen auf dem Band neu gemischt, da sie jetzt mit unterschiedlicher Häufigkeit auftreten.

Edit 9, 1626 → 1606: Verrückteres Inlining. Der Body der ersten while-Schleife sieht jetzt ungefähr so ​​aus:

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

und die variablenzuordnung hat sich nun fast vollständig geändert.

Bearbeiten 10, 1606 → 1577: Ich beobachtete , dass aund a2beide erniedrige auf 0 in While - Schleifen, also wenn ich paaren könnte pentweder mit denjenigen, aber nicht mit ch, ich zu initialisieren würde nicht brauchen , pum 0(die 29 Byte Kosten). Es stellte sich heraus, dass ich das durch Tauschen pund Tauschen tun kann r. Die neuesten Variablenzuweisungen (und ihre Häufigkeit im Code) lauten jetzt:

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
quelle
1
Angesichts der Tatsache, dass eine Novemvigintillion Stimmen eine Folge von 2 × 10 ^ 90 Bytes erfordern würde und das derzeit kleinstmögliche Volumen von 10 ^ 24 Bytes ungefähr 1/3 der Größe der Großen Pyramide von Gizeh entspricht , glaube ich nicht, dass Sie dies tun irgendetwas, worüber man sich Sorgen machen muss. ;)
ETHproductions
1
@ETHproductions: Trotzdem habe ich diese Einschränkung beim Golfen
behoben
22

CJam, 23 Bytes

Run-Length Party!

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

oder

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

Führen Sie alle Testfälle aus

Erläuterung

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.

Die andere Version beginnt durch die Paare Umkehren, die an anderer Stelle zwei Bytes speichert: a) in jeder Kette das erste Zeichen der Auswahl ist nur :cstatt , Wf=um die zweite Auswahl. b) Wir müssen vor der zweiten RLE nicht erneut sortieren, da die Paare bereits primär nach dem verbleibenden Zeichen sortiert wurden.

Martin Ender
quelle
FWIW die Qin Ihrer zweiten Antwort sollte qfür Nicht-Test-Wrapper-Zwecke sein.
Peter Taylor
@ Peter Taylor Ich mache das die ganze Zeit -.-
Martin Ender
Ich weiß, es ist ein kleines Detail, aber das Umwandeln 3in eine Liste für den Vergleich ist ein netter Trick. Ich habe es nur zu meiner eigenen Unterhaltung gelöst und dort ein Byte verloren, weil ich es benutzt habe 0=2>. Ansonsten hatte ich fast die gleiche Lösung wie bei Ihrer ersten Lösung, nur dass ich sie für den letzten Schritt ::\ anstelle von verwendet habe Wf%.
Reto Koradi
10

Bash, 95 94 85 81 Bytes

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

Eine elegante, aber lange erste Lösung für den Anfang ...

Dank User112638726 für ein Byte mit dem Speichern sed, DigitalTrauma zum Speichern 9 mit fold, und Rainer P. zum Speichern von 4 mehr mit awk‚s substr!

Um zu sehen, wie es funktioniert, nehmen wir die Eingabe abababcbcbcbcbbababa.

  • Nach fold -2(Zeilenumbruch auf eine Breite von 2) haben wir

    ab
    ab
    cb
    cb
    cb
    cb
    ba
    ba
    ba
    
  • Nach sort | uniq -c( -cgibt ein sehr geschicktes Flag aus, uniqdas angibt, wie oft jede Zeile in der Eingabe erscheint), erhalten wir

          3 ab
          3 ba
          4 cb
    
  • Untersuchen wir nun den letzten awkBefehl:

    • $1>2: Nur Material ausgeben, wenn Datensatz 1 (auch bekannt als die Anzahl identischer Stimmen) größer als 2 ist (d. H. ≥ 3). Mit anderen Worten, ignorieren Sie alle Zeilen, die mit einer Zahl ≤ 2 beginnen.

    • {c[substr($2,2)]+=$1}: Wenn die Zahl größer als 2 ist, fügen Sie diese Zahl der cHash-Tabelle hinzu, wobei Sie das zweite Zeichen von Datensatz 2 (auch bekannt als Voting-ee) als Schlüssel verwenden. (Wir müssen nicht alles auf Null initialisieren; awktut das für uns.)

    • END{...}: Dies bedeutet nur, dass nach der Verarbeitung der gesamten Datei Folgendes zu tun ist.

    • for(x in c)printf x c[x]: Ziemlich selbsterklärend. Drucken Sie jeden Schlüssel und seinen entsprechenden Wert.

Türknauf
quelle
&entspricht \0in sed
User112638726 15.12.15
@ User112638726 Wusste nicht, danke
Türklinke
Reduziert ein bisschensed -r 's/.(.)/\1\n/g'|awk '{a[$1]++}END{for(i in a)printf (a[i]>2)?i a[i]:y}
User112638726
@ User112638726 Das schlägt beispielsweise für die Eingabe fehl bacada.
Türklinke
Oh ja mein Schlechtes!
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]');

Testfälle:

Auf einer hohen Ebene füllt dieser Code ein Objekt mit Schlüssel-Wert-Paaren, die die Stimmenempfänger der Anzahl der Stimmen zuordnen { b:7, a:3 }und sie dann zu einer Zeichenfolge in einer forSchleife zusammenfügen. Der Code ist in einem evalAusdruck der Verwendung zu ermöglichen , forinnerhalb eines Pfeils Funktion , ohne Ausgaben Bytes auf { }und ;return r.

( Wenden Sie sich an user81655, um drei Bytes zu sparen!)

Erklärung des evalCodes:

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
quelle
6

Haskell, 103 Bytes

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)

Anwendungsbeispiel: f "jkkjjkkjjkkjljljljmlmlnmnmnm"->"k3j6m3"

Wie es funktioniert:

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
quelle
6

JavaScript (ES6), 195 174 169 167 158 Byte

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

Prüfung

Gavin.Paolucci.Kleinow
quelle
1
Willkommen bei PPCG :) Wir haben hier und hier einige Tipps zum Golfen in JS . Ich kenne JS selbst nicht gut genug, um wirklich zu helfen, aber
viel Spaß
1
Zum einen können Sie das vars entfernen . Wer kümmert sich darum, den globalen Anwendungsbereich des Codegolfs zu verschmutzen? ;)
Türklinke
Auch /(\w{2})/gkann einfach sein /../g- wir bereits wissen , dass die Eingabe nur Buchstaben sind, und Wiederholen einer (oder zwei) Zeichen kürzer als {2}. Wenn Sie interessiert sind, können Sie sich meine JavaScript-Antwort auf diese Herausforderung ansehen (und Fragen dazu kommentieren). Willkommen bei PGCC!
Apsillers
4

Mathematica, 110 100 99 Bytes

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

Perl, 86 84 83 Bytes

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

Das sind 82 Bytes plus 1 für das -pKommandozeilenargument:

$ echo xyxyxyxyxyxyxyxyzyzyzyxzxzxz | perl -p 86.pl
y11z3


Etwas ungolfed:

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 Sparen Sie 2 Bytes, indem Sie das grep einfügen
  • Update 83 Sparen Sie 1 Byte, indem Sie globale temporäre Variablen ${$'}anstelle von verwenden $g{$'}. Funktioniert leider $$'nicht.
Kenney
quelle
3

Pure Bash, 151

Länger als ich gehofft hatte, aber hier ist es.

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

Verwendet die assoziative Array-Indizierung, um die erforderliche Zählung durchzuführen. Benötigt Bash-Version 4.0 oder höher.

Digitales Trauma
quelle
1

PHP 247 Zeichen

(Autsch)

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

Erklärt

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

Habe dies getan, ohne auf andere Antworten zu schauen. Dies ist das schwierigste Codegolf, das ich bisher angegangen bin. Ich begrüße alle Optimierungen.

Gans
quelle
0

R, 221 Bytes

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="")}

ungolfed

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="")
  }
}

Hier gibt es viel Raum für Verbesserungen.

Mutador
quelle