Rosetta Stone Challenge: Run-Length Encoding v2.0

8

Das Ziel einer Rosetta Stone Challenge ist es, Lösungen in möglichst vielen Sprachen zu schreiben. Zeigen Sie Ihre Programmier-Mehrsprachigkeit!

Die Herausforderung

Wir haben Lauflängencodierung durchgeführt wird Vordergrund , sondern nur läuft von einem einzelnen Zeichen betrachtet. Natürlich können wir manchmal sogar noch größere Einsparungen erzielen, wenn wir Läufe mit mehreren Zeichen berücksichtigen.

Nehmen Sie aaaxyzxyzxyzddddzum Beispiel. Dies kann komprimiert werden 3a3{xyz}4d. Ihre Aufgabe ist es, ein Funktionsprogramm zu schreiben, das bei einer Groß- und Kleinschreibung von Buchstaben und Leerzeichen mithilfe der Lauflängencodierung für Läufe mit mehreren Zeichen optimal komprimiert wird .

Sie können Eingaben über das Funktionsargument STDIN oder ARGV vornehmen und das Ergebnis zurückgeben oder an STDOUT drucken.

Läufe dürfen nicht verschachtelt sein, aaabbbaaabbbmüssen es 3a3b3a3bauch nicht sein 2{3a3b} . Dh die Zeichenfolge sollte in einem einzigen Durchgang codiert (oder decodiert) werden.

Folgen der optimalen Komprimierung

Einige Beispiele, bei denen eine naive Anwendung der Lauflängencodierung zu suboptimalen Ergebnissen führen kann:

  • abab darf nicht "komprimiert" werden 2{ab}
  • aaaabcdeabcdedarf nicht auf 4abcdeabcdesondern komprimiert 3a2{abcde}werden.

Wenn es zwei optimale Versionen gibt (z. B. aaund 2aoder abcabcund 2{abc}), ist jedes Ergebnis in Ordnung.

Beispiele

Input              Output

aa                 aa -or- 2a
aaaaaAAAAA         5a5A
ababa              ababa
abababa            a3{ba} -or- 3{ab}a
foo foo bar        2{foo }bar
aaaabcdeabcde      3a2{abcde}
xYzxYz             xYzxYz -or- 2{xYz}
abcabcdefcdef      abcab2{cdef}
pppqqqpppqqq       3p3q3p3q
pppqqqpppqqqpppqqq 3{pppqqq}

Wertung

Jede Sprache ist ein separater Wettbewerb darüber, wer den kürzesten Beitrag schreiben kann. Der Gesamtsieger wäre jedoch die Person, die die meisten dieser Teilwettbewerbe gewinnt. Dies bedeutet, dass eine Person, die in vielen ungewöhnlichen Sprachen antwortet, einen Vorteil erzielen kann. Code Golf ist meistens ein Tiebreaker, wenn es mehr als eine Lösung in einer Sprache gibt: Die Person mit dem kürzesten Programm erhält eine Gutschrift für diese Sprache.

Wenn es ein Unentschieden gibt, ist der Gewinner die Person mit den meisten Einsendungen auf dem zweiten Platz (und so weiter).

Regeln, Einschränkungen und Hinweise

Bitte bewahren Sie alle Ihre unterschiedlichen Beiträge in einer einzigen Antwort auf.

Auch keine Shenanigans mit grundsätzlich gleicher Antwort in leicht unterschiedlichen Sprachdialekten. Ich werde beurteilen, welche Beiträge unterschiedlich genug sind.

Aktuelle Rangliste

Dieser Abschnitt wird regelmäßig aktualisiert, um die Anzahl der Sprachen und die jeweils führenden Personen anzuzeigen.

  • C # (265) - edc65
  • JavaScript (206) - edc65
  • Python (214) - Will
  • VB.NET (346) - edc65

Aktuelle Benutzerrankings

  1. edc65 (3)
  2. Will (1)
Martin Ender
quelle

Antworten:

1

JavaScript (E6) 206

Fast sicher, dass es optimal ist. Ich versuche, die längste Zeichenfolge mit der maximalen Verstärkung zu codieren, und codiere rekursiv, was links und rechts verbleibt. Nach jedem Versuch behalte ich das kürzeste Ergebnis.

Golfnoten (JS-spezifisch)

  • Pseudoargumente anstelle von Einheimischen (zur Rekursion)
  • Vergleichen Sie die Längen mit einem Index außerhalb der Grenzen, der "undefiniert" ergibt.
R=(s,n=s,d=s.length>>1,w,i,j,c)=>{
  for(;d;--d){
    for(i=-1;s[d+d+i++];){
      w=s.slice(i,j=i+d);
      for(r=1;w==s.substr(j,d);j+=d)++r;
      c=d>1?r+'{'+w+'}':r+w,
      // c[d*r-1]|| /* uncomment this line (+10 bytes) to have faster response
      n[(c=R(s.slice(0,i))+c+R(s.slice(j))).length]&&(n=c)
    }
  }
  return n
}

Test In FireFox / Firebug - Konsole

;['aa','aaaaaAAAAA','ababa','abababa','foo foo bar', 'aaaabcdeabcde',
  'xYzxYz', 'abcabcdefcdef', 'pppqqqpppqqq','pppqqqpppqqqpppqqq']
.forEach(x=>console.log(x+' -> '+R(x)))

Ausgabe

aa -> aa
aaaaaAAAAA -> 5a5A
ababa -> ababa
abababa -> 3{ab}a
foo foo bar -> 2{foo }bar
aaaabcdeabcde -> 3a2{abcde}
xYzxYz -> xYzxYz
abcabcdefcdef -> abcab2{cdef}
pppqqqpppqqq -> 3p3q3p3q
pppqqqpppqqqpppqqq -> 3{pppqqq}

C # (.NET 4.0) 265

Genau der gleiche Algorithmus

string R(string s)
{
  string n=s,c,w;
  int l=s.Length,d=l/2,i,j,r;
  for(;d>0;--d)
  {
    for(i=0;d+d+i<=l;i++)
    {
      w=s.Substring(i,d);
      for(j=i+d,r=1;j+d<=l&&w==s.Substring(j,d);j+=d)++r;
      c=d>1?r+"{"+w+"}":r+w;
      // if(c.Length<d*r){ // uncomment this line for faster execution
        c=R(s.Substring(0,i))+c+R(s.Substring(j));
        n=c.Length<n.Length?c:n;
      //} // and this one of course
    }
  }
  return n;
}

Testen Sie in LinqPad im Modus 'C # -Programm' und fügen Sie nach der R-Funktion eine Hauptleitung hinzu

void Main()
{
  string[] test = {"aa","aaaaaAAAAA","ababa","abababa","foo foo bar","aaaabcdeabcde",
  "xYzxYz","abcabcdefcdef","pppqqqpppqqq","pppqqqpppqqqpppqqq"};
  test.Select(x => new { x, r=R(x) }).Dump("Result");
}

Gleiche Ausgabe

VB.Net (.NET 4) 346 (wahrscheinlich)

Gleicher Algorithmus und gleiche Bibliothek, aber die Sprache ist unterschiedlich genug

Ich kann mir über die Anzahl der Bytes nicht sicher sein, da Visual Studio den Code immer wieder neu formatiert und Leerzeichen hinzufügt.

Golfnoten: Verwenden Sie besser etwas anderes

function R(s as string)

  dim n=s,c,w
  dim l=s.Length,i,j,d
  for d=l\2 to 1 step-1
    for i=0 to l-d-d
      w=s.Substring(i,d)
      j=i+d
      r=1
      do while (j+d<=l andalso w=s.Substring(j,d))
        r=r+1
        j=j+d
      loop
      c=if(d>1,r & "{" & w & "}",r & w)
      if(c.Length<d*r) then
        c=R(s.Substring(0,i))+c+R(s.Substring(j))
        if c.Length<n.Length then n=c
      end if
    next
  next
  return n

end function
edc65
quelle
Sie können das Hinzufügen von Leerzeichen rückgängig machen. Wenn Sie ein Zeichen eingeben, das eine Neuformatierung ermöglicht, drücken Sie Strg-Z, um die Formatierung rückgängig zu machen. Es bedeutet ab und zu zwei Zeichen anstelle von einem, aber es ist besser, als danach alle Leerzeichen und Zeilenvorschübe zu entfernen.
Jerry Jeremiah
3

Python 214

def t(s):
 b=s;l=len;r=range(1,l(s))
 for i in r:
  p=s[:i];b=min(b,p+t(s[i:]),key=l);x=1
  for j in r:k=i*j+i;x*=p==s[i*j:k];b=min(b,(b,''.join((`j+1`,"{"[i<2:],p,"}"[i<2:],t(s[k:]))))[x],key=l)           
 return b

(Einzug der zweiten Ebene ist Tabulator)

Da dies , ist dies der naive rekursive Ansatz ohne vorzeitigen Ausstieg, daher ist er wirklich sehr, sehr langsam.

Wille
quelle