Ordina i nomi delle bande


22

Descrizione della sfida

Si dispone di una libreria musicale con molte tracce registrate da molte band, ognuno dei quali ha un nome, come Queen, Aerosmith, Sunny Day Real Estate, The Strokes. Quando un lettore audio visualizza la libreria in ordine alfabetico in base al nome della band, di solito salta la Theparte, poiché molti nomi di band iniziano con The, facilitando la navigazione nella raccolta multimediale. In questa sfida, dato un elenco (array) di stringhe, è necessario ordinarlo in questo modo (ovvero omettere la Theparola all'inizio del nome). Puoi scrivere un metodo o un programma di lavoro completo.

Ingressi / uscite di esempio

[Queen, Aerosmith, Sunny Day Real Estate, The Strokes] -> [Aerosmith, Queen, The Strokes, Sunny Day Real Estate]
[The Ramones, The Cure, The Pixies, The Roots, The Animals, Enrique Iglesias] -> [The Animals, The Cure, Enrique Iglesias, The Pixies, The Ramones, The Roots]
[The The, The They, Thermodynamics] -> [The The, Thermodynamics, The They]

Casi Note / Edge

  • L'ordinamento lessicografico non fa distinzione tra maiuscole e minuscole, quindi The Police, The policee the policesono tutti equivalenti,

  • Il tuo algoritmo dovrebbe omettere solo la prima theparola, quindi le bande nominate The Theo The The Bandordinate normalmente dalla seconda the,

  • Una banda denominata The(una parola di tre lettere) viene ordinata normalmente (senza saltare),

  • L'ordine di due bande con lo stesso nome, uno dei quali inizia con the(like The Policee Police) non è definito,

  • Puoi presumere che se il nome di una band è composto da più di una parola, sono separati da un singolo carattere spaziale. Non è necessario gestire spazi bianchi iniziali o finali,

  • Tutte le stringhe di input corrispondono [A-Za-z0-9 ]*, ovvero consisteranno solo di lettere minuscole e maiuscole dell'alfabeto inglese, cifre e caratteri spaziali,

  • Ricorda che si tratta di una sfida con il , quindi rendi il tuo codice il più breve possibile!


I nomi solo numerici vengono prima o dopo alfabetico?
AdmBorkBork,

Le stringhe solo
numerali

1
Qual è l'ordinamento di Thee The The? (Probabilmente la maggior parte delle risposte avrebbe bisogno di cambiare se fosse qualcosa di diverso da undefined)
Brad Gilbert b2gills

che ne dici di Los Lobos?
njzk2,

3
A proposito, The è una vera band. (insieme a The Who, The What, The Where, The When, The Why e The How)
DanTheMan

Risposte:


7

Python, 56 62 64 byte

lambda b:sorted(b,key=lambda x:(x,x[4:])[x.lower()[:4]=='the '])

Provalo

Grazie a @Chris H per aver sottolineato che lstrip()non si stava gestendo The Thecorrettamente, poiché la striscia faceva saltare tutti i caratteri corrispondenti e li ordinava come una stringa vuota, e @manatwork per trovare il difetto nell'uso replace(). La nuova versione dovrebbe funzionare.

Vecchia versione:

lambda b:sorted(b,key=lambda x:x.lower().lstrip('the '))

1
Non sono convinto. Aggiungendo "Gli animali" all'ultimo elenco si ottiene ['The The', 'The', 'The Animals', 'Thermodynamics', 'The They']. Il caso del secondo margine suggerisce che sit dovrebbe essere ['The Animals', 'The The', 'The', 'Thermodynamics', 'The They'] (o scambiare il 2 ° e il 3 ° oggetto). Un po 'di confusione suggerisce che lo spazio all'interno strip('the ')venga ignorato - provafor x in ['The The', 'The They', 'Thermodynamics', 'The', 'The Animals']: print (x.lower().strip('the '))
Chris H

Non replace()è molto meglio: i 'what the snake'.replace('the ','',1)risultati 'what snake'.
arte

5

V , 32 28 byte

ç^The /dwA_
:sort
ç_/$xIThe 

Provalo online!

Nota per sé: crea un'abbreviazione per :sortnon avere bisogno di 6 byte interi per un singolo comando!

Spiegazione:

ç^The /     "On every line starting with 'The ',
       dw   "Delete a word
         A_ "And (A)ppend an underscore '_'

:sort       "Sort all lines alphabetically

ç_/         "On every line containing an underscore,
   $x       "Delete the last character
     IThe   "And prepened 'The '

Non ho familiarità con V, ma sembra che funzioni bene senza gli asterischi. Questa coincidenza con l'input o effettivamente non necessaria?
Kirkpatt,

1
@kirkpatt Buona idea! Che quasi funziona, ma non del tutto. Ad esempio, con questo input inserisce erroneamente "Radiohead" dopo "The Ramones" e "The Roots". Tuttavia, questo mi dà un'idea ...
DJMcMayhem

Cosa succede se theè tutto in minuscolo, come the pAper chAse?
AdmBorkBork,

4

Retina , 34 byte

L'alimentazione di linea finale è significativa.

%`^
$';
T`L`l`.+;
m`^the 

O`
.+;

L'I / O è una banda per riga.

Provalo online!

Spiegazione

%`^
$';

Duplica ogni riga, usando ;come separatore.

T`L`l`.+;

Trasforma tutto davanti a ;a in minuscolo.

m`^the 

Rimuovi qualsiasi thes che appare all'inizio di una riga.

O`

Ordina le linee.

.+;

Rimuovi gli inizi delle righe che abbiamo usato per l'ordinamento.


Non potresti mettere insieme i primi 3 Passaggi in un unico passaggio? Come in PCRE: s / (?i:the )?(.*)/ \L$1\E;$0/
Falco,

@Falco .NET non supporta le modifiche ai casi nelle stringhe di sostituzione e non le ho ancora aggiunte al sostituto personalizzato di Retina.
Martin Ender,

4

Pyke, 16 byte

.#l1D"the ".^4*>

Provalo qui!

.#                - sort_by(V, input)
  l1              -  i = i.lower()
      "the ".^    -   i.startswith("the ")
              I   -  if ^:
               4> -   i[4:]

3

Perl, 52 byte

-13 byte grazie a @manatwork
-1 byte grazie a @ msh210

sub f{lc pop=~s/^the //ri}print sort{f($a)cmp f$b}<>

Una banda per riga come input, così come l'output.

L'implementazione è abbastanza semplice: il programma stampa l'elenco delle bande, ordinato con l'aiuto di una funzione personalizzata ( f) che restituisce il nome della banda in minuscolo senza l'eventuale lead the.


È più breve con la sostituzione al posto di corrispondenza: sub f{lc$_[0]=~s/^the //ir}.
arte

In effetti 1 byte più corto, grazie.
Dada,

In realtà ho contato 2 o 3 byte in meno: non sono necessarie sia la parentesi attorno lcal parametro sia il iflag in sostituzione. O hai incontrato un caso di prova in cui non funziona?
arte

Pensare ancora una volta, la quantità di opzioni della riga di comando potrebbe anche essere ridotto se si prende ogni nome band riga separata: perl -e 'sub f{lc$_[0]=~s/^the //ri}print sort{f($a)cmp f$b}<>' <<< $'Queen\nAerosmith\nSunny Day Real Estate\nThe Strokes'.
arte

1
Salva tre byte: lc popanziché lc$_[0]e sayinvece di print. (Quest'ultimo richiede -M5.01, che è gratuito.) Testato in Strawberry 5.20.2 con solo il primo test case dalla domanda.
msh210,

2

Python, 66 72 69 byte

lambda x:sorted(x,key=lambda a:a[4*(a.lower()[:4]=='the '):].lower())

Utilizza il sortedmetodo Python con l' keyargomento della parola chiave per ordinare in base al nome meno "The". Questo è un lambda; per chiamarlo, dagli un nome mettendolo f=di fronte.

Ora con insensibilità al case extra!


2
Non soddisfa il requisito di insensibilità al caso, tuttavia ... Un nome di banda può iniziare con the , nel qual caso questo metodo non funzionerà correttamente.
shooqie,

@shooqie Oh, non ho visto questo requisito. Lo aggiusterò.
Rame


2

Perl 6 , 26 byte

*.sort({fc S:i/^'the '//})

Spiegazione:

# 「*」 is the input to this Whatever lambda
*.sort(

  # sort based on the return value of this Block lambda
  {
    fc # foldcase the following

    # string replace but not in-place
    S
      :ignorecase
      /
        # at the start of the string
        ^

        # match 「the 」
        'the '

      # replace with nothing
      //
  }
)

Test:

use v6.c;
use Test;

my @tests = (
  « Queen Aerosmith 'Sunny Day Real Estate' 'The Strokes' »
    => « Aerosmith Queen 'The Strokes' 'Sunny Day Real Estate' »,
  « 'The Ramones' 'The Cure' 'The Pixies' 'The Roots' 'The Animals' 'Enrique Iglesias' »
    => « 'The Animals' 'The Cure' 'Enrique Iglesias' 'The Pixies' 'The Ramones' 'The Roots' »,
  « 'The The' 'The They' Thermodynamics »
    => « 'The The' Thermodynamics 'The They' »,
);

# give it a lexical name for clarity
my &band-sort = *.sort({fc S:i/^'the '//});

plan +@tests;

for @tests -> ( :key(@input), :value(@expected) ) {
  is-deeply band-sort(@input), @expected, @expected.perl;
}
1..3
ok 1 - ("Aerosmith", "Queen", "The Strokes", "Sunny Day Real Estate")
ok 2 - ("The Animals", "The Cure", "Enrique Iglesias", "The Pixies", "The Ramones", "The Roots")
ok 3 - ("The The", "Thermodynamics", "The They")

2

PowerShell v2 +, 33 32 29 byte

$args|sort{$_-replace'^the '}

Salvato 3 byte grazie a @MathiasRJessen

L'input avviene tramite argomenti della riga di comando. Ordina i nomi originali in base ai risultati del blocco di script {...}che esegue una regex -replaceper eliminare il carattere iniziale (senza distinzione tra maiuscole e minuscole) "the ".

Esempi

PS C:\Tools\Scripts\golfing> .\sort-band-names.ps1 'the Ramones' 'The cure' 'The Pixies' 'The Roots' 'the Animals' 'Enrique Iglesias'
the Animals
The cure
Enrique Iglesias
The Pixies
the Ramones
The Roots

PS C:\Tools\Scripts\golfing> .\sort-band-names.ps1 'The The' 'The They' 'Thermodynamics'
The The
Thermodynamics
The They

PS C:\Tools\Scripts\golfing> .\sort-band-names.ps1 'THE STOOGES' 'The Strokes' 'The The' 'the they' 'the band' 'STP'
the band
THE STOOGES
STP
The Strokes
The The
the they

-replacenon fa distinzione tra maiuscole e minuscole per impostazione predefinita, '^the 'sarà sufficiente per il modello
Mathias R. Jessen,

@ MathiasR.Jessen Sì, grazie per il promemoria.
AdmBorkBork,

@ValueInk Vedi il commento di Mathias sull'insensibilità ai casi e sull'esempio finale che ho aggiunto.
AdmBorkBork,

2

JavaScript / ECMAScript 6 93 70 byte

70 Grazie a Neil e Downgoat per un consiglio

B=>B.sort((a,b)=>R(a).localeCompare(R(b)),R=s=>s.replace(/^the /i,''))

Versione leggibile per la variante a 70 byte

let sortBandNames = (bandNames) => {
    let stripThe = (name) => name.replace(/^the /i, '');
    let compareFunc = (a, b) => stripThe(a).localeCompare(stripThe(b));
    return bandNames.sort(compareFunc)
};

93

f=B=>{R=s=>s.toLowerCase().replace(/the /,'');return B.sort((a,b)=>R(a).localeCompare(R(b)))}

Versione leggibile per la variante a 93 byte

let sortBandNames = (bandNames) => {
    let stripThe = (name) => name.toLowerCase().replace(/the /, '');
    let compareFunc = (a, b) => stripThe(a).localeCompare(stripThe(b));
    return bandNames.sort(compareFunc)
};

Quel regexp non dovrebbe esserci ^qualcosa dentro? Inoltre, localeCompare non fa distinzione tra maiuscole e minuscole sul mio sistema, quindi non avevo bisogno di toLowerCase, solo un /iflag sul regexp. Finalmente puoi giocare a golf come segue: B=>B.sort((a,b)=>...,R=s=>...)- sortignora il parametro extra che imposta R.
Neil,

Dove sarebbe nella regex ^ andare? Sarebbe una negazione e l'espressione dovrebbe corrispondere e cancellare "il". Proverò a utilizzare il confronto locale senza la conversione minuscola.
Pandacoder

@Pandacoder the ^shuold go all'inizio del regex
Downgoat

@Downgoat Dal test di tutti i casi indicati, e alcuni casi mi sono venuti in mente con l'intenzione specifica di rompere il RegEx, con o senza il ^ non ottengo alcun cambiamento nel comportamento, solo un personaggio in più che non compie nulla.
Pandacoder,

@Pandacoder che non lo rende valido. il ^ è un'ancora che richiede che il "the" sia all'inizio per specifica
Downgoat

1

Java 8, 178 byte

void q(String[]s){java.util.Arrays.sort(s,(a,b)->(a.toLowerCase().startsWith("the ")?a.substring(4):a).compareToIgnoreCase(b.toLowerCase().startsWith("the ")?b.substring(4):b));}

Versione non golfata:

void sort(String[] bands) {
    java.util.Arrays.sort(bands, (a, b) -> 
        (a.toLowerCase().startsWith("the ") ? a.substring(4) : a).compareToIgnoreCase(
            b.toLowerCase().startsWith("the ") ? b.substring(4) : b
        )
    );
}

Chiama come tale:

public static void main(String[] args) {
    String[] bands = {"The Strokes", "Queen", "AC/DC", "The Band", "Cage the Elephant", "cage the elephant"};
    sort(bands); // or q(bands) in the golfed version
    System.out.println(java.util.Arrays.toString(bands));
}

So che hai risposto a questa domanda quasi un anno fa, ma puoi giocare a golf alcune cose. Dato che dichiari di usare Java 8, puoi passare void q(String[]s){...}a s->{...}. E puoi cambiare entrambi (x.toLowerCase().startsWith("the ")?x.substring(4):x)con x.replaceFirst("(?i)the ",""). Quindi il totale diventa: s->{java.util.Arrays.sort(s,(a,b)->a.replaceFirst("(?i)the ","").compareToIgnoreCase(b.replaceFirst("(?i)the ","")));}- 118 byte
Kevin Cruijssen,

Trucco pulito con il primo sostituto. Quando ho risposto a questa domanda mi era stato detto alcune volte su altre risposte che s->{ ... }non erano consentite e dovevo avere una firma del metodo completa con tipi e quant'altro. Non so se sia cambiato da allora.
Giustino,

Non sono sicuro di allora, ma in questi giorni è consentito e utilizzato da quasi tutti i giocatori di golf in Java o C # .NET.
Kevin Cruijssen,

0

Nim , 96 byte

import algorithm,strutils,future
x=>x.sortedByIt toLower it[4*int(it.toLower[0..3]=="the ")..^0]

Questi importoccupano così tanti byte:|

Una traduzione della mia risposta Python .

Questa è una procedura anonima; per usarlo, deve essere passato in una procedura di test. Ecco un programma completo che puoi utilizzare per i test:

import algorithm,strutils,future
proc test(x: seq[string] -> seq[string]) =
 echo x(@["The The", "The They", "Thermodynamics"]) # Substitute your input here
test(x=>x.sortedByIt toLower it[4*int(it.toLower[0..3]=="the ")..^0])

0

Haskell, 84 byte

import Data.List
p(t:'h':'e':' ':s)|elem t"Tt"=s
p s=s
sortBy(\a b->p a`compare`p b)

Chiama con

sortBy(\a b->p a`compare`p b)["The The", "The They", "Thermodynamics"]

TestCase:

let s = sortBy(\a b->p a`compare`p b)
and[s["Queen", "Aerosmith", "Sunny Day Real Estate", "The Strokes"]==["Aerosmith", "Queen", "The Strokes", "Sunny Day Real Estate"],s["The Ramones", "The Cure", "The Pixies", "The Roots", "The Animals", "Enrique Iglesias"]==["The Animals", "The Cure", "Enrique Iglesias", "The Pixies", "The Ramones", "The Roots"],s["The The", "The They", "Thermodynamics"]==["The The", "Thermodynamics", "The They"]]

0

MATL , 16 byte

tk'^the '[]YX2$S

Il formato di input è (ogni riga corrisponde a un caso di test)

{'Queen', 'Aerosmith', 'Sunny Day Real Estate', 'The Strokes'} 
{'The Ramones', 'The Cure', 'The Pixies', 'The Roots', 'The Animals', 'Enrique Iglesias'}
{'The The', 'The They', 'Thermodynamics'}

Provalo online!

Spiegazione

t        % Implicitly input cell array of strings. Push another copy
k        % Convert to lowercase
'^the '  % String to be used as regex pattern: matches initial 'the '
[]       % Empty array
YX       % Regex replacement: replace initial 'the ' in each string by empty array
2$S      % Sort input according to the modified cell array. Implicitly display

0

C #, 139 byte

using System.Linq;System.Collections.IEnumerable S(string[] l)=> l.OrderBy(b=>(b.ToLower().StartsWith("the ")?b.Substring(4):b).ToLower());

Prova online!

Senza contare gli utilizzi la risposta sarebbe di 102 byte.


Credo che tu possa ignorare il finale a ToLower()causa del requisito insensibile alle maiuscole / minuscole
TheLethalCoder

Inoltre puoi renderlo una funzione anonima che dovrebbe salvare alcuni byte:
TheLethalCoder

l=>l.OrderBy(b=>(b.ToLower().StartsWith("the ")?b.Substring(4):b));Per 67 byte e quindi è necessario aggiungere using System.Linq;anche quello
TheLethalCoder

@TheLethalCoder: ho bisogno del secondo a ToLowercausa del requisito insensibile al maiuscolo / minuscolo. Altrimenti l'ordine sarebbe sensibile al maiuscolo / minuscolo.
raznagul,

Va bene il punto sulla conversione in una funzione anonima è ancora
valida

0

BASH, 64 byte

sed 's/^the / /;s/^The /    /'|sort -fb|sed 's/^ /the /;s/^ /The /'

Input: stdin, una banda per riga. Uscita: stdout

Nota: i secondi sostituti (s / ^ The / / e s / ^ / The /) usano il carattere tab, quindi non sempre copiano / incollano correttamente.


0

Bash + coreutils, 44 byte

sed '/^the /I!s,^,@ ,'|sort -dk2|sed s,@\ ,,

Spiegazione: il formato di input e output è una banda per riga

sed '/^the /I!s,^,@ ,'   # prepend '@ ' to each line not starting with 'the ', case
                         #insensitive. This adds a temporary field needed by sort.
sort -dk2                # sort in ascending dictionary order by 2nd field onward
sed s,@\ ,,              # remove the temporary field

Esecuzione del test (utilizzando un documento qui con EOF come marker finale):

./sort_bands.sh << EOF
> Queen
> Aerosmith
> Sunny Day Real Estate
> The Strokes
> EOF

Produzione:

Aerosmith
Queen
The Strokes
Sunny Day Real Estate

0

Vim, 18 byte

Bene, ora che ho capito che questo è possibile, sono un po 'imbarazzato dalla mia risposta a V di 26 byte, specialmente perché V dovrebbe essere più corto di VIM. Ma questo è praticamente un builtin.

:sor i/\(The \)*/<CR>

Spiegazione (direttamente dalla guida di Vim):

                            *:sor* *:sort*
:[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/]
            Sort lines in [range].  When no range is given all
            lines are sorted.

            With [i] case is ignored.

            When /{pattern}/ is specified and there is no [r] flag
            the text matched with {pattern} is skipped, so that
            you sort on what comes after the match.
            Instead of the slash any non-letter can be used.

0

C, 216 212 135 + 5 ( qsort) = 221 217 140 byte

M(void*a,void*b){char*A,*B;A=*(char**)a;B=*(char**)b;A=strcasestr(A,"The ")?A+4:A;B=strcasestr(B,"The ")?B+4:B;return strcasecmp(A,B);}

Bene, finalmente sono riuscito a finire questo C. I consigli sul golf sono molto apprezzati.

In questa presentazione, Mè la funzione di confronto a cui fornire qsort. Pertanto, per invocare questo, è necessario utilizzare qsortnel formato qsort(argv++,argc--,8,M)dove argvcontiene gli argomenti della riga di comando eargc è il numero di argomenti forniti.

Provalo online!


0

05AB1E , 27 byte (non concorrenti)

vyð¡RD¤…TheQsgα£Rðý})‚øí{ø¤

Provalo online!

Spiegazione

vyð¡RD¤…TheQsgα£Rðý})‚øí{ø¤   Argument l
v                 }           For each y in l, do:
 yð¡                            Split y on space
    RD                          Reverse and duplicate
      ¤…TheQ                    Last element equals "The" (true = 1, false = 0)
            sgα                 Absolute difference with length of array
               £                Get elements from index 0 to calculated difference
                R               Reverse
                 ðý             Join on space
                    )‚øí      Pair each element with original
                        {ø¤   Sort and get the original band name

0

Groovy, 34 byte

{it.sort{it.toLowerCase()-'the '}}

41% la mia risposta è .toLowerCase(), uccidimi ora.


Produzione

Durante l'esecuzione ...

({it.sort{it.toLowerCase()-'the '}})(['The ramones','The Cure','The Pixies','The Roots','The Animals','Enrique Iglesias'])

Il risultato è ...

[The Animals, The Cure, Enrique Iglesias, The Pixies, The ramones, The Roots]

Senza debug o output di errori.


0

q / kdb +, 36 33 byte

Soluzione:

{x(<)@[x;(&)x like"[Tt]he *";4_]}

Esempio:

q){x(<)@[x;(&)x like"[Tt]he *";4_]}("Queen";"Aerosmith";"Sunny Day Real Estate";"The Strokes";"the Eagles")
"Aerosmith"
"the Eagles"
"Queen"
"The Strokes"
"Sunny Day Real Estate"

Spiegazione:

Rimuovere qualsiasi "[Tt] he" da ciascuna stringa di input, ordinare questo elenco, quindi ordinare l'elenco originale in base all'indicizzazione dell'elenco ordinato.

{x iasc @[x;where x like "[Tt]he *";4_]} / ungolfed solution
{                                      } / lambda function
        @[x;                       ;  ]  / apply function to x at indices
                                    4_   / 4 drop, remove first 4 items
            where x like "[Tt]he *"      / where the input matches 'The ...' or 'the ...'
   iasc                                  / returns sorted indices
 x                                       / index into original list at these indices


-2

Java 176 158 byte

public String[]sort(String[]names){
  for(int i=-1;++i<names.length;)
    if(names[i].startsWith("(The |the )"))
      names[i]=names[i].substring(4);
  return Arrays.sort(names,String.CASE_INSENSITIVE_ORDER);
  }

Funzione principale

public static void main(String[]args){
  Scanner s = new Scanner(System.in);
  List<String> list= new ArrayList<>();
  while(!(String h = s.nextLine).equalsIgnoreCase("~")){
    list.add(h);
  }
System.out.println(sort(list.toArray(newString[0]))

); }

Funzione golf ordinata:

String[]s(String[]n){for(int i=-1;++i<n.length;)if(n[i].startsWith("(The |the )"))n[i]=n[i].substring(4);return Arrays.sort(n,String.CASE_INSENSITIVE_ORDER);}

Grazie a @raznagul per aver salvato 18 byte


Non funziona se un nome inizia con the . L'ordinamento dovrebbe fare distinzione tra maiuscole e minuscole.
shooqie,

Questo non funzionerà affatto ... Le stringhe sono immutabili. Volete fare public String[]sort(String[]names){ for(int i=-1;++i<names.length;) names[i]=names[i].replaceFirst("(the|The)", ""); return Arrays.sort(names,String.CASE_INSENSITIVE_ORDER); }dal momento che il e The dovrebbero funzionare, e stringe un immutabile
Socratic Phoenix

Risolto il problema, ma trovami una band che inizia con un piccolo "the"
Roman Gräf

2
Arrays.sortrestituisce il tipo void
user902383

1
@ RomanGräfthe pAper chAse
AdmBorkBork
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.