Das erstaunliche Sortiersystem des verrückten Bibliothekars

21

Es ist wieder Schulzeit! Für einen Teilzeitjob helfen Sie also in der Bibliothek der Schule. Das Problem ist, dass der Hauptbibliothekar noch nie die Worte "Dewey Decimal" gehört hat, geschweige denn dieses System implementiert hat. Stattdessen ist das verwendete Sortiersystem mit der Erweiterung der Bibliothek "organisch" gewachsen ...

In dem Bestreben, Ihre geistige Gesundheit zu wahren, haben Sie sich dazu entschlossen, ein Programm zu schreiben, mit dem Sie Bücher sortieren können, wenn sie zurückgegeben werden. (Der Bibliothekar ist sehr streng.)

Input-Output

  • Die Eingabe ist eine Liste von (hypothetischen) Buchtiteln, eine pro Zeile, von STDIN / Sprachäquivalent.
  • Sie können davon ausgehen, dass nicht mehr als 100 Bücher gleichzeitig eingegeben wurden (Sie können nur so viele Bücher gleichzeitig in der Bibliothek herumtragen).
  • Bücher können mehrere Wörter in ihren Titeln enthalten und diese Wörter können durch Leerzeichen oder andere Satzzeichen (z. B. einen Doppelpunkt :, einen Bindestrich -usw.) getrennt sein.
  • Nehmen Sie zur Vereinfachung der Berechnung an, dass alle Titel UTF-8 sind.

Es werden die gleichen Titel ausgegeben, sortiert nach den folgenden Regeln, wiederum einer pro Zeile nach STDOUT / Sprachäquivalent.

Die Sortierregeln

Bücher werden numerisch sortiert, basierend auf ihrem durchschnittlichen Zeichenwert (dh dem kumulierten Zeichenwert geteilt durch die Anzahl der Zeichen im Buchtitel), wobei die folgenden Regeln gelten:

  • Alle Zeichen bestimmen die Anzahl der Zeichen in einem Titel.
  • Kleinbuchstaben werden nach ihrer Position im Alphabet gezählt. (a = 1, b = 2, ... z = 26)
  • Wenn der Titel Großbuchstaben enthält, zählen diese für 1,5 ihren Kleinbuchstabenwert (A = 1,5, B = 3, ... Z = 39). ("Großbuchstaben sind wichtig!", Sagt der Bibliothekar.)
  • Jedes Interpunktionszeichen / Symbol in dieser Liste !@#$%^&*()-=_+[]\{}|;':",./<>?~zählt -1 vom kumulierten Wert vor der Mittelwertbildung. ("Grandiose Titel sind nicht!")
  • Wenn der Titel eine arabisch geschriebene Zahl enthält , wird diese Zahl vor dem Sortieren vom Durchschnittswert abgezogen. Mehrere aufeinanderfolgende Ziffern werden als eine Zahl behandelt (z. B. 4242 subtrahieren, 4 nicht subtrahieren und dann 2 subtrahieren). Einzelne Ziffern zählen nicht für den kumulativen Wert (dh jede Ziffer trägt 0 bei), sondern für die Anzahl der Zeichen. Beachten Sie, dass dies zu einem negativen Wert führen kann und entsprechend behandelt werden sollte. (Gerüchten zufolge ist der Bibliothekar seit einigen Jahren in einen Mathematiklehrer verknallt.)
  • Wenn der Titel zwei separate Wörter enthält, die mit einem beginnen R, erhält das Buch die Note "unendlich" und wird auf einen Stapel in der Ecke gelegt (dh zufällig am Ende der Liste angeordnet). (Der Bibliothekar wurde einmal von einer Person mit diesen Initialen entlassen, oder wie Sie gehört haben.)
  • Leerzeichen zählen nicht für den kumulativen Zeichenwert (dh sie tragen 0 bei), tragen jedoch zur Anzahl der Zeichen in einem Titel bei.
  • Zeichen, die nicht den obigen Regeln entsprechen (z. B. a ÿ), zählen nicht für den kumulativen Zeichenwert (dh sie tragen 0 bei), tragen jedoch zur Anzahl der Zeichen in einem Titel bei.
  • Zum Beispiel hätte ein hypothetisches Buch ÿÿÿÿÿeine "Punktzahl" von (0+0+0+0+0) / 5 = 0, aber ein hypothetisches Buch ÿÿyÿÿhätte eine "Punktzahl" von (0+0+25+0+0) / 5 = 5.
  • Zwei Bücher, die zufällig gleich "punkten", können in der von Ihnen gewählten Reihenfolge ausgegeben werden. (Sie sind auf jeden Fall im selben Regal)

Beispiel Eingabe 1

War and Peace
Reading Rainbow: The Best Unicorn Ever
Maus
Home for a Bunny

Beispiel Ausgabe 1 (mit "Punkten" in Klammern, um die Argumentation anzuzeigen - Sie müssen sie nicht ausdrucken)

War and Peace (8.5)
Home for a Bunny (10.125)
Maus (15.125)
Reading Rainbow: The Best Unicorn Ever (infinity)

Beispiel Eingabe 2

Matthew
Mark
Luke
John
Revelations

Beispielausgabe 2 (mit "Punkten" in Klammern als Begründung - Sie müssen sie nicht ausdrucken)

Mark (12.375)
John (13)
Revelations (13.545454...)
Luke (13.75)
Matthew (~13.786)

Beispiel Eingabe 3

42
9 Kings
1:8
7th

Beispielausgabe 3 (mit "Punkten" in Klammern als Begründung - Sie müssen sie nicht ausdrucken)

42 (-42)
1:8 (-9.3333...)
9 Kings (~0.36)
7th (2.3333...)

Andere Einschränkungen

  • Das ist Code-Golf, weil Sie das Programm vor den Augen des Bibliothekars geheim halten müssen. Je kleiner das Programm, desto einfacher ist es, es zu verbergen.
  • Es gelten die üblichen Lückenbeschränkungen
  • Lassen Sie sich nicht vom Bibliothekar davon abhalten, Ihre Zeit mit PPCG zu verbringen.
AdmBorkBork
quelle
Was ist, wenn zwei Bücher genau das gleiche Ergebnis erzielen? dh ich habe Regenbogen und Ruby Rails
lesen
@KishanKumar In diesem speziellen Fall "zufällig am Ende der Liste angeordnet", da sie beide Doppel-R sind. Mit anderen Worten, treffen Sie Ihre Wahl. Im Allgemeinen können zwei Wörter, die die gleiche Punktzahl haben, in beliebiger Reihenfolge zueinander angezeigt werden. Ich werde eine Kugel hinzufügen, um das zu klären.
AdmBorkBork
7
Sie benötigen ein A-Wort, damit Ihr System einen Akronymnamen hat. Ich empfehle Crazy Librarian's Amazing Sorting System: D
Geobits
3
@Geobits Hast du KLASSE?
AdmBorkBork
Zahlen sind nur Dezimalzahlen? Was ist, wenn es mehrere gibt, werden alle separat abgezogen?
Paŭlo Ebermann,

Antworten:

5

APL (132)

{⎕ML←3⋄⍵[⍋{2='R'+.=↑¨⍵⊂⍨⍵≠' ':!99⋄↑(+/⍎¨'0',⍵⊂⍨⍵∊⎕D)-⍨((+/∊1.5 1×(⍳×∊⍨)∘⍵¨G)-+/⍵∊(⎕UCS 32+⍳94)~'`',⎕D,∊G←(⊂⎕A),⊂⎕UCS 96+⍳26)÷⍴⍵}¨⍵]}

Da alle anderen dasselbe tun, ist dies auch eine Funktion, die eine Reihe von Titeln übernimmt und sortiert zurückgibt, z.

      titles
┌─────────────┬──────────────────────────────────────┬────┬────────────────┬───────┬────┬────┬────┬───────────┬──┬───────┬───┬───┐
│War and Peace│Reading Rainbow: The Best Unicorn Ever│Maus│Home for a Bunny│Matthew│Mark│Luke│John│Revelations│42│9 Kings│1:8│7th│
└─────────────┴──────────────────────────────────────┴────┴────────────────┴───────┴────┴────┴────┴───────────┴──┴───────┴───┴───┘

      {⎕ML←3⋄⍵[⍋{2='R'+.=↑¨⍵⊂⍨⍵≠' ':!99⋄↑(+/⍎¨'0',⍵⊂⍨⍵∊⎕D)-⍨((+/∊1.5 1×(⍳×∊⍨)∘⍵¨G)-+/⍵∊(⎕UCS 32+⍳94)~'`',⎕D,∊G←(⊂⎕A),⊂⎕UCS 96+⍳26)÷⍴⍵}¨⍵]}titles
┌──┬───┬───────┬───┬─────────────┬────────────────┬────┬────┬───────────┬────┬───────┬────┬──────────────────────────────────────┐
│42│1:8│9 Kings│7th│War and Peace│Home for a Bunny│Mark│John│Revelations│Luke│Matthew│Maus│Reading Rainbow: The Best Unicorn Ever│
└──┴───┴───────┴───┴─────────────┴────────────────┴────┴────┴───────────┴────┴───────┴────┴──────────────────────────────────────┘

Erläuterung:

  • ⎕ML←3: ⎕MLauf 3(für ) setzen
  • ⍵[⍋{... }¨⍵]: Sortiert die Eingabe nach den von der inneren Funktion zurückgegebenen Werten
    • ↑¨⍵⊂⍨⍵≠' ': Ermittelt das erste Zeichen jedes Wortes
    • 2='R'+.=: Sehen Sie, ob zwei davon sind 'R'.
    • :!99: wenn ja, 99 zurück! (9,3 × 10 155 ). Das ist nicht unendlich, aber es reicht aus: Ein Titel kann niemals eine Punktzahl haben, die größer als das 38-fache seiner Länge ist (ZZZZ ...), solange kein einzelner Titel größer als etwa 2 × 10 130 ist Yottabyte ist ist garantiert, dass diese am Ende sein werden.
    • : Andernfalls:
    • (... )÷⍴⍵: Teilen Sie die Punktzahl durch die Länge von, nachdem Sie sie berechnet haben:
      • G←(⊂⎕A),(⎕UCS 96+⍳26): In GGroß- und Kleinbuchstaben speichern
      • (⎕UCS 32+⍳94)~'`',⎕D,∊G: die druckbaren ASCII-Zeichen mit Ausnahme von Buchstaben, Ziffern, Leerzeichen und '`', bei denen ein Punkt abgezogen wird. (Dies ist kürzer als das Ausschreiben, da Ges später verwendet wird.)
      • +/⍵∊: Zähle die Anzahl dieser Zeichen in
      • -: subtrahiere dies von:
      • +/∊1.5 1×(⍳×∊⍨)∘⍵¨G: die Summe von 1,5 × der Punktzahl für die Großbuchstaben und 1 × der Punktzahl für die Kleinbuchstaben.
    • -⍨: subtrahiere danach die Summe der Zahlen in :
      • ⍵⊂⍨⍵∊⎕D: Finde die Zifferngruppen in
      • '0',: add '0', um zu verhindern, dass die Liste leer ist
      • ⍎¨: bewerte jeden String
      • +/: finde die Summe
Marinus
quelle
Stattdessen !99könnten Sie⌊/⍬
Adám
1
Ich liebe es, langen Code in APL zu betrachten. Ich habe das Gefühl, die Welt sei so groß wie ich. Und ich mag Symbole.
Conor O'Brien
2

Lua 5.3, 366 364 Bytes

r={}for i,s in ipairs(arg)do n=0 s:gsub("%l",function(a)n=n+(a:byte()-96)end):gsub("%u",function(a)n=n+(a:byte()-64)*1.5 end):gsub("%p",function(a)n=n-1 end):gsub("^R?.- R.- ?R?",function()n=math.huge end)m=n/utf8.len(s)s:gsub("%d+",function(a)m=m-a end)table.insert(r,{s=s,n=m})end table.sort(r,function(a,b)return a.n<b.n end)for i,v in ipairs(r)do print(v.s)end

Dieser Code funktioniert nur in Lua 5.3, da er Unicode-Zeichen verarbeiten muss. Wenn Sie sich nicht für Unicode interessieren, ersetzen Sie "utf8" durch "string" und es funktioniert einwandfrei mit Lua 5.2 oder 5.1.

Die Eingaben stammen von Befehlszeilenargumenten. Führen Sie sie daher entweder über die Befehlszeile aus oder setzen Sie den folgenden Code über meine Antwort:

arg = {"Title 1", "Title 2", "Title 3"}
Trebuchette
quelle
Ich habe Lua 5.3 nicht auf meinem Rechner, aber ich bin Ihrem Vorschlag gefolgt, utf8mit Ideonestring zu tauschen, und habe keine Ausgabe erhalten.
AdmBorkBork
@ TimyD siehe meine Bearbeitung
Trebuchette
Gut. Soße. Und (arg)sitzt da und starrt mir ins Gesicht. Diese Frage hat anscheinend mein Gehirn gebraten. Habe eine +1.
AdmBorkBork
Bei MoonScript sind dies 266 Bytes: pastebin.com/wr4qVs5h .
kirbyfan64sos
2

Mathematica, 253 216 Bytes (214 Zeichen)

r=RegularExpression;c=ToCharacterCode;f=SortBy[Tr@Flatten@Reap[StringCases[#,
{r@"(\\bR.*)+"->∞,r@"\\d+":>0Sow@-FromDigits@"$0",r@"[a-z]":>c@"$0"-96,
r@"[A-Z]":>1.5c@"$0"-96,r@"[!-/:-@[-_{-~]"->-1}]/StringLength@#]&]

Rufen Sie die Funktion wie f[{"42", "9 Kings", "1:8", "7th"}]folgt auf: Es wird eine sortierte Liste der Eingaben zurückgegeben.

Gerade noch geschafft! Mathematicas Mustervergleich ist nicht so präzise, ​​wenn es um Zeichenfolgen geht, und ich werde einfach von diesen langen Namen umgebracht. Die zusätzlichen zwei Bytes sind für das InfinityUnicode-Zeichen.

(Lassen Sie mich wissen, wenn ich Standardlücken verpasst habe.)

Aktualisieren

Bei näherer Betrachtung der Antwort von edc65 sieht es so aus, als würde das OP eine Funktion akzeptieren, die eine Liste von Zeichenfolgen sortiert. In diesem Sinne können wir die Curry-Form von SortBy(die Mathematica als "Operatorform" bezeichnet) verwenden. Mit einem Argument (die Funktion, die auf die Listenelemente angewendet wird, um deren Reihenfolge zu bestimmen) verhält es sich wie eine Funktion, die ein Argument verwendet und die sortierte Form der Eingabe zurückgibt. das heißt, SortBy[list, f]ist äquivalent zu (SortBy[f])[list].

Ungolfed

Function[{titles},
  SortBy[titles, Function[{str}, (* sort by function value *)
    Total[Flatten[Reap[ (* total up all the parts *)
      StringCases[str, {
        RegularExpression["(\\bR.*){2}"] -> Infinity
          (* matches R at the start of a word twice, adds infinity to the total *),
        RegularExpression["\\d+"] :> 0 * Sow[-FromDigits["$0"]]
          (* matches a number, Sows it for Reap to collect, then multiplies by zero
                                                          to not affect the average *),
        RegularExpression["[a-z]"] :> ToCharacterCode["$0"] - 96
          (* matches a lowercase letter and returns its value *),
        RegularExpression["[A-Z]"] :> 1.5 ToCharacterCode["$0"] - 96
          (* matches an uppercase letter and returns 1.5 its value *),
        RegularExpression["[!-/:-@[-_{-~]"] -> -1
          (* matches a 'grandiose' symbol and returns -1 *)
      }] / StringLength[#] (* averages character values *)
    ]]]
  ]]
]
2012rcampion
quelle
1
Gute Antwort, und Sie erhalten ein Internet-Cookie, das "unendlich" buchstäblich in Ihren Berechnungen verwendet ;-).
AdmBorkBork
@TimmyD Die Schönheit der symbolischen mathematischen Verarbeitung =)
2012rcampion
Wahrscheinlich meinst du 214 Zeichen, 216 Bytes. Gut gemacht, ich habe versucht, aber auf keinen Fall zu konkurrieren
edc65
2

JavaScript (ES6), 210 218 251

Als Funktion mit einem Array-Argument wird sortiert zurückgegeben.

f=L=>(S=s=>([...s].map(c=>t-=(a=s.charCodeAt(l++))>32&a<48|a>57&a<65|a>90&a<96|a>122&a<127?1:a>64&a<123?96-(a<96?a*1.5:a):0,l=t=0),s.split(/\D/).map(n=>t-=n,t/=l),t/!s.split(/\bR/)[2]),L.sort((a,b)=>S(a)-S(b)))

//TEST

test1=['War and Peace','Reading Rainbow: The Best Unicorn Ever','Maus','Home for a Bunny']
test2=['Matthew','Mark','Luke','John','Revelations']
test3=['42','9 Kings','1:8','7th']

;O.innerHTML=f(test1)+'\n\n'+f(test2)+'\n\n'+f(test3);

// The comparing function used to sort, more readable

Sort=s=>(
  t = 0, // running total
  l = 0, // to calc the string length avoiding the '.length' property
  [...s].map(c=>{
    a=s.charCodeAt(l++);
    t-=a>32&a<48|a>57&a<65|a>90&a<96|a>122&a<127
      ? 1 // symbols (ASCII char except space, alphanumeric and backtick)
      : a>64&a<123 
        ? 96-(a<96?a*1.5:a) // alphabetic both upcase and lowcase, and backtick
        // lowcase: 96-a, upcase (64-a)*1.5=>96-a*1.5, backtick is 96 and 96-96 == 0
        : 0 // else space, non ASCII, and numeric : 0
  }),
  t = t/l, // average
  s.split(/\D/).map(n=>t-=n), // sub number values
  f = s.split(/\bR/)[2], // split at words starting with R, if less then 2 f is undefined
  t/!f // dividing by not f I can get the infinity I need
)
<pre id=O></pre>

edc65
quelle
Schön gemacht. Für Bezug auf jemand anderen diese Antwort zu lesen, hatte ich zu ändern , O.innerHTMLum this.InnerHTMLdie Konsole in Firefox.
AdmBorkBork
1

C #, 352 349 Bytes

Aufgrund der Magie von Linq:

class A{static void Main(string[]a){foreach(var x in a.OrderBy(b=>{var s="0";int j=0;return Regex.Split(b,@"[^\w]+").Count(l=>l[0]=='R')==2?(1/0d):b.Aggregate(0d,(d,e)=>{if(e>47&e<58){s+=e;return d;}d+=(e>64&e<91)?(e-64)*1.5:(e>96&e<123)?e-96:e>32&e<127&e!=96?-1:0;j+=int.Parse(s);s="0";return d;})/b.Length-j-int.Parse(s);}))Console.WriteLine(x);}}

Hätte weitere 6 Bytes sparen können, wenn Backtick in die Interpunktionsliste aufgenommen worden wäre!

class A
{
    static void Main(string[] a)
    {
        foreach (var x in a.OrderBy(b =>
            {
                var s = "0";
                int j = 0;
                return Regex.Split(b, @"[^\w]+").Count(l => l[0] == 'R') == 2
                    ? (1 / 0d)
                        : b.Aggregate(0d, (d, e) =>
                        {
                            if (e > 47 & e < 58) { s += e; return d; }
                            d += (e > 64 & e < 91) ? (e - 64) * 1.5 : (e > 96 & e < 123) ? e - 96 : e > 32 & e < 127 & e != 96 ? -1 : 0;
                            j += int.Parse(s);
                            s = "0";
                            return d;
                        }) / b.Length - j - int.Parse(s);
            }))
            Console.WriteLine(x);
    }

}
Yitz
quelle
1

Los, 755 Bytes

package main
import("os"
"fmt"
"math"
"bufio"
"regexp"
"sort"
"strconv")
type F float64
type T []F
func(t T)Swap(i,j int){t[i],t[j],S[i],S[j]=t[j],t[i],S[j],S[i]}
func(t T)Len()int{return len(t)}
func(t T)Less(i,j int)bool{return t[i]<t[j]}
var S []string
func main(){var t T
for{b:=bufio.NewReader(os.Stdin)
w,_,_:=b.ReadLine()
if len(w)==0{break}
u:=string(w)
var v F
for _,c:=range u{if 96<c&&c<123{v+=F(c)-F(96)}else
if 64<c&&c<91{v+=(F(c)-64)*1.5}else
if (48>c&&c>32)||(c>57&&c<127){v-=1}}
a:=v/F(len(w))
r,_:=regexp.Compile("[0-9]+")
n:=r.FindAllString(string(w),-1)
for _,x:=range n{y,_:=strconv.Atoi(x);a-=F(y)}
if m,_:=regexp.Match("((^| )R.*){2}",w);m{a=F(math.Inf(1))}
S=append(S,u)
t=append(t,a)}
sort.Sort(t)
for _,o:=range S{fmt.Println(o)}}

Die formatierte Version:

package main

import (
    "bufio"
    "fmt"
    "math"
    "os"
    "regexp"
    "sort"
    "strconv"
)

type F float64
type T []F

func (t T) Swap(i, j int)      { t[i], t[j], S[i], S[j] = t[j], t[i], S[j], S[i] }
func (t T) Len() int           { return len(t) }
func (t T) Less(i, j int) bool { return t[i] < t[j] }

var S []string

func main() {
    var t T
    for {
        b := bufio.NewReader(os.Stdin)
        w, _, _ := b.ReadLine()
        if len(w) == 0 {
            break
        }
        u := string(w)
        var v F
        for _, c := range u {
            if 96 < c && c < 123 {
                v += F(c) - F(96)
            } else if 64 < c && c < 91 {
                v += (F(c) - 64) * 1.5
            } else if (48 > c && c > 32) || (c > 57 && c < 127) {
                v -= 1
            }
        }
        a := v / F(len(w))
        r, _ := regexp.Compile("[0-9]+")
        n := r.FindAllString(string(w), -1)
        for _, x := range n {
            y, _ := strconv.Atoi(x)
            a -= F(y)
        }
        if m, _ := regexp.Match("((^| )R.*){2}", w); m {
            a = F(math.Inf(1))
        }
        S = append(S, u)
        t = append(t, a)
    }
    sort.Sort(t)
    for _, o := range S {
        fmt.Println(o)
    }
}

Durch die Implementierung einer benutzerdefinierten Sortierschnittstelle wurde der Zeitraum länger als erwartet. Das Programm liest von STDIN, bis das Ende der Eingabe oder eine leere Zeile eingegeben wird.

Fabian Schmengler
quelle
1

PHP, 362 367 Bytes

<?for(;$w=fgets(STDIN);$S[]=$w){for($l=$i=mb_strlen($w);$i--;){$c=array_sum(unpack("C*",mb_substr($w,$i,1)));96<$c&&$c<123 and $v+=$c-96 or 64<$c&&$c<91 and $v+=1.5*$c-96 or 48<$c&&$c>32||$c>57&&$c<127 and $v-=1;}$v/=$l;preg_match_all("/\d+/",$w,$m);$v-=array_sum($m[0]);preg_match("/((^| )R.*){2}/",$w)&&$v=INF;$t[]=$v;}array_multisort($t,$S);echo join("
",$S);

Formatierte Version:

<?php
for (; $w = fgets(STDIN); $S[] = $w) {
    for ($l = $i = mb_strlen($w); $i--;) {
        $c = array_sum(unpack("C*", mb_substr($w, $i, 1)));
        96 < $c && $c < 123 and $v += $c - 96
        or 64 < $c && $c < 91 and $v += 1.5 * $c - 96
        or 48 < $c && $c > 32 || $c > 57 && $c < 127 and $v -= 1;
    }
    $v /= $l;
    preg_match_all("/\d+/", $w, $m);
    $v -= array_sum($m[0]);
    preg_match("/((^| )R.*){2}/", $w) && $v = INF;
    $t[] = $v;
}
array_multisort($t, $S);
echo join("
", $S); 

Interessante Zeilen:

$c = array_sum(unpack("C*", mb_substr($w, $i, 1)));

Konvertiert ein einzelnes UTF-8-Zeichen in seine Bytewerte und summiert diese, sodass wir den tatsächlichen Wert für ASCII-Zeichen und einen Wert über 127 für Multibyte-Zeichen erhalten.

96 < $c && $c < 123 and $v += $c - 96
or 64 < $c && $c < 91 and $v += 1.5 * $c - 96
or 48 < $c && $c > 32 || $c > 57 && $c < 127 and $v -= 1;

Verwendet die niedrige Operatorpriorität von andund or, um den Zeichenwert in einer einzelnen Anweisung ohne zuzuweisen if.

Fabian Schmengler
quelle
1

Perl 5 , 190 Bytes

sub p{$_=pop;chomp;$c=-y/A-Za-z0-9 \\`//c;map$c+=(32&ord$_?1:1.5)*(31&ord),/[a-z]/gi;$c/=length;map$c-=$_,/\d+/g;$c}say(sort{$y=$b=~/\bR.*\bR/;($x=$a=~/\bR.*\bR/)||$y?$x-$y:(p($a)<=>p$b)}<>)

Probieren Sie es online!

Xcali
quelle