Trier les noms de bande


22

Description du défi

Vous avez une bibliothèque musicale avec de nombreuses pistes enregistrées par de nombreux groupes, dont chacun a un nom, comme Queen, Aerosmith, Sunny Day Real Estate, The Strokes. Lorsqu'un lecteur audio affiche votre bibliothèque par ordre alphabétique par nom de groupe, il ignore généralement la Thepartie, car de nombreux noms de groupe commencent par The, ce qui facilite la navigation dans votre collection multimédia. Dans ce défi, étant donné une liste (tableau) de chaînes, vous devez le trier de cette façon (c'est-à-dire en omettant le Themot au début du nom). Vous pouvez soit écrire une méthode ou un programme de travail complet.

Exemples d'entrées / sorties

[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]

Notes / étuis Edge

  • Le tri lexicographique est insensible à la casse, donc The Police, The policeet the policesont tous équivalents,

  • Votre algorithme ne doit omettre que le premier themot, donc les bandes nommées The Theou The The Bandsont triées normalement par le second the,

  • Une bande nommée The(un mot de trois lettres) est triée normalement (pas de saut),

  • Ordre de deux bandes portant le même nom, dont l'une commence par the(comme The Policeet Police) n'est pas définie,

  • Vous pouvez supposer que si le nom d'un groupe se compose de plusieurs mots, ils sont séparés par un seul espace. Vous n'avez pas besoin de gérer les espaces blancs de début ou de fin,

  • Toutes les chaînes d'entrée correspondent [A-Za-z0-9 ]*, c'est-à-dire qu'elles ne seront composées que de lettres minuscules et majuscules de l'alphabet anglais, de chiffres et de caractères d'espacement,

  • N'oubliez pas qu'il s'agit d'un défi de , alors faites votre code aussi court que possible!


Les noms uniquement numériques viennent-ils avant ou après l'ordre alphabétique?
AdmBorkBork

Les chaînes uniquement
numériques

1
Quel est l'ordre de tri de Theet The The? (La plupart des réponses devraient probablement changer si ce n'est pas défini)
Brad Gilbert b2gills

que diriez-vous de Los Lobos?
njzk2

3
Le The est un vrai groupe au fait. (avec le qui, le quoi, le où, le quand, le pourquoi et le comment)
DanTheMan

Réponses:


7

Python, 56 62 64 octets

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

Essayez-le

Merci à @Chris H d'avoir souligné que cela lstrip()ne se passait pas The Thecorrectement, car la bande dynamitait tous les caractères correspondants et la triait comme une chaîne vide, et @manatwork pour trouver la faille dans l'utilisation replace(). La nouvelle version devrait fonctionner.

Ancienne version:

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

1
Je ne suis pas convaincu. L'ajout de "Les animaux" à la dernière liste donne ['The The', 'The', 'The Animals', 'Thermodynamics', 'The They']. Le cas du 2e bord suggère que la position assise devrait être [«Les animaux», «Le», «Le», «Thermodynamique», «Le Ils»] (ou permutez les 2e et 3e éléments). Un petit tripot suggère que l'espace à l'intérieur strip('the ')est ignoré - essayezfor x in ['The The', 'The They', 'Thermodynamics', 'The', 'The Animals']: print (x.lower().strip('the '))
Chris H

Ce replace()n'est pas beaucoup mieux: les 'what the snake'.replace('the ','',1)résultats 'what snake'.
manatwork du

5

V , 32 28 octets

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

Essayez-le en ligne!

Note à soi-même: faites une abréviation pour :sortque je n'aie pas besoin de 6 octets entiers pour une seule commande!

Explication:

ç^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 '

Pas familier avec V, mais il semble que celui-ci fonctionne bien sans les astérisques. Est-ce une coïncidence avec l'entrée, ou est-elle réellement inutile?
kirkpatt

1
@kirkpatt Bonne idée! Cela fonctionne presque , mais pas tout à fait. Par exemple, avec cette entrée, il place incorrectement "Radiohead" après "The Ramones" et "The Roots". Cependant, cela me donne une idée ...
DJMcMayhem

Que se passe-t-il si theest en minuscules, comme the pAper chAse?
AdmBorkBork

4

Rétine , 34 octets

Le saut de ligne arrière est important.

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

O`
.+;

Les E / S sont une bande par ligne.

Essayez-le en ligne!

Explication

%`^
$';

Dupliquez chaque ligne en utilisant ;comme séparateur.

T`L`l`.+;

Tournez tout devant un ;boîtier inférieur.

m`^the 

Supprimez tous les thes qui apparaissent au début d'une ligne.

O`

Triez les lignes.

.+;

Supprimez les débuts des lignes que nous avons utilisées pour le tri.


Ne pourriez-vous pas regrouper les 3 premières étapes en une seule étape? Comme dans PCRE: s / (?i:the )?(.*)/ \L$1\E;$0/
Falco

@Falco .NET ne prend pas en charge les modifications de casse dans les chaînes de substitution et je ne les ai pas encore ajoutées au remplaçant personnalisé de Retina.
Martin Ender

4

Pyke, 16 octets

.#l1D"the ".^4*>

Essayez-le ici!

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

3

Perl, 52 octets

-13 octets grâce à @manatwork
-1 octets grâce à @ msh210

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

Une bande par ligne en entrée, tout comme la sortie.

L'implémentation est assez simple: le programme imprime la liste des bandes, triées à l'aide d'une fonction personnalisée ( f) qui renvoie le nom de la bande en minuscules sans le début éventuel the.


Est plus courte avec substitution au lieu de chercher : sub f{lc$_[0]=~s/^the //ir}.
manatwork

1 octet plus court en effet, merci.
Dada

En fait, j'ai compté 2 ou 3 octets plus court: pas besoin à la fois de la parenthèse autour lcdu paramètre et du idrapeau de substitution. Ou avez-vous rencontré un cas de test où cela ne fonctionne pas?
manatwork

Penser à nouveau, la quantité d'options de ligne de commande pourrait également être réduite si vous prenez chaque nom de bande sur une ligne séparée: perl -e 'sub f{lc$_[0]=~s/^the //ri}print sort{f($a)cmp f$b}<>' <<< $'Queen\nAerosmith\nSunny Day Real Estate\nThe Strokes'.
manatwork

1
Enregistrez trois octets: lc popau lieu de lc$_[0]et sayau lieu de print. (Ce dernier nécessite -M5.01, qui est gratuit.) Testé dans Strawberry 5.20.2 avec seulement le premier cas de test de la question.
msh210

2

Python, 66 72 69 octets

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

Utilise la sortedméthode Python avec l' keyargument mot - clé pour trier par le nom moins "The". Ceci est un lambda; pour l'appeler, donnez-lui un nom en le mettant f=en avant.

Maintenant avec une insensibilité à la casse supplémentaire!


2
Il ne répond pas à l'exigence d'insensibilité à la casse, cependant ... Un nom de bande peut commencer par the , auquel cas cette méthode ne fonctionnera pas correctement.
shooqie

@shooqie Oh, je n'ai pas vu cette exigence. Je le réparerai.
Copper


2

Perl 6 , 26 octets

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

Explication:

# 「*」 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
      //
  }
)

Tester:

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 octets

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

Enregistré 3 octets grâce à @MathiasRJessen

L'entrée se fait via des arguments de ligne de commande. Trie les noms d'origine en fonction des résultats du bloc de script {...}qui effectue une expression régulière -replacepour supprimer le début (sans respecter la casse) "the ".

Exemples

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

-replaceest insensible à la casse par défaut, '^the 'suffira pour le motif
Mathias R. Jessen

@ MathiasR.Jessen Oui, merci pour le rappel.
AdmBorkBork

@ValueInk Voir le commentaire de Mathias sur l'insensibilité à la casse et le dernier exemple que j'ai ajouté.
AdmBorkBork

2

JavaScript / ECMAScript 6 93 70 octets

70 Merci à Neil et Downgoat pour leurs conseils

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

Version lisible pour la variante 70 octets

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

Version lisible pour la variante 93 octets

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

Cette expression rationnelle ne devrait-elle pas en contenir ^? En outre, localeCompare est insensible à la casse sur mon système, donc je n'avais pas besoin de toLowerCase, juste un /iindicateur sur l'expression régulière. Enfin, vous pouvez jouer au golf comme suit: B=>B.sort((a,b)=>...,R=s=>...)- sortignore le paramètre supplémentaire qui définit R.
Neil

Où irait le regex? Ce serait une négation et l'expression est censée correspondre et effacer "le". J'essaierai d'utiliser la comparaison locale sans la conversion en minuscules.
Pandacoder

@Pandacoder the ^shuold go au début de l'expression
régulière

@Downgoat En testant tous les cas donnés, et quelques cas, j'ai trouvé spécifiquement l'intention de casser le RegEx, avec ou sans le ^ Je n'obtiens aucun changement de comportement, seulement un caractère supplémentaire qui n'accomplit rien.
Pandacoder

@Pandacoder qui ne le rend pas valide. le ^ est une ancre qui nécessite que le "le" soit au début selon la spécification
Downgoat

1

Java 8, 178 octets

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

Version non golfée:

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

Appelez comme tel:

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

Je sais que vous avez répondu à cette question il y a presque un an, mais vous pouvez jouer au golf à plusieurs choses. Puisque vous déclarez que vous utilisez Java 8, vous pouvez passer void q(String[]s){...}à s->{...}. Et vous pouvez changer les deux (x.toLowerCase().startsWith("the ")?x.substring(4):x)avec x.replaceFirst("(?i)the ",""). Le total devient donc: s->{java.util.Arrays.sort(s,(a,b)->a.replaceFirst("(?i)the ","").compareToIgnoreCase(b.replaceFirst("(?i)the ","")));}- 118 octets
Kevin Cruijssen

Astuce avec le replaceFirst. Quand j'ai répondu à cela, on m'avait dit à plusieurs reprises sur d'autres réponses qui s->{ ... }n'étaient pas autorisées et je devais avoir une signature de méthode complète avec les types et ainsi de suite. Je ne sais pas si cela a changé depuis.
Justin

Je ne sais pas à l'époque, mais ces jours-ci, il est autorisé et utilisé par presque tout le monde qui joue au golf en Java ou en C # .NET.
Kevin Cruijssen

0

Nim , 96 octets

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

Ceux import s prennent tellement d'octets:|

Une traduction de mon réponse Python .

Il s'agit d'une procédure anonyme; pour l'utiliser, il doit être passé dans une procédure de test. Voici un programme complet que vous pouvez utiliser pour les tests:

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 octets

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

Appeler avec

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

Cas de test:

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 octets

tk'^the '[]YX2$S

Le format d'entrée est (chaque ligne correspond à un cas de 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'}

Essayez-le en ligne!

Explication

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 octets

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

Essayez en ligne!

Sans compter les utilisations, la réponse serait de 102 octets.


Je crois que vous pouvez ignorer la finale en ToLower()raison de l'exigence insensible à la casse
TheLethalCoder

Vous pouvez également en faire une fonction anonyme qui devrait économiser quelques octets:
TheLethalCoder

l=>l.OrderBy(b=>(b.ToLower().StartsWith("the ")?b.Substring(4):b));Pour 67 octets, puis vous devez ajouter using System.Linq;aussi
TheLethalCoder

@TheLethalCoder: J'ai besoin du second en ToLowerraison de l'exigence insensible à la casse. Sinon, la commande serait sensible à la casse.
raznagul

D'accord, le point de le convertir en fonction anonyme est toujours
valable

0

BASH, 64 octets

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

Entrée: stdin, une bande par ligne. Sortie: stdout

Remarque: Les seconds remplacements (s / ^ Le / / et s / ^ / Le /) utilisent le caractère de tabulation, donc ils ne copient / collent pas toujours correctement.


0

Bash + coreutils, 44 octets

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

Explication: le format d'entrée et de sortie est une bande par ligne

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

Test (en utilisant un document ici avec EOF comme marqueur de fin):

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

Sortie:

Aerosmith
Queen
The Strokes
Sunny Day Real Estate

0

Vim, 18 octets

Eh bien maintenant que j'ai réalisé que c'était possible, je suis un peu gêné par ma réponse V de 26 octets, d'autant plus que V est censé être plus court que vim. Mais c'est à peu près une fonction intégrée.

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

Explication (directement de l'aide de 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 octets

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

Eh bien, j'ai finalement réussi à terminer cela C. Les conseils de golf sont très appréciés.

Dans cette soumission, Mest la fonction de comparaison à fournir qsort. Par conséquent, pour invoquer cela, vous devez utiliser qsortau format qsort(argv++,argc--,8,M)argv contient les arguments de ligne de commande et argcest le nombre d'arguments fournis.

Essayez-le en ligne!


0

05AB1E , 27 octets (non concurrent)

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

Essayez-le en ligne!

Explication

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 octets

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

41% ma réponse est .toLowerCase(), tuez-moi maintenant.


Sortie

Lors de l'exécution ...

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

Le résultat est...

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

Sans sortie de débogage ou d'erreur.


0

q / kdb +, 36 33 octets

Solution:

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

Exemple:

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"

Explication:

Supprimez tout "[Tt] he" de chaque chaîne d'entrée, triez cette liste, puis triez la liste d'origine en fonction de l'indexation de la liste triée.

{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 octets

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

Fonction 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]))

); }

Fonction de tri golf:

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

Merci à @raznagul pour avoir économisé 18 octets


Ne fonctionne pas si un nom commence par the . Le tri doit être insensible à la casse.
shooqie

Cela ne fonctionnera pas du tout ... Les cordes sont immuables. Vous voulez faire 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); }puisque le et le devraient fonctionner, et les cordes sont immuables
Socratic Phoenix

Correction de cela, mais trouvez-moi un groupe qui commence par un petit "the"
Roman Gräf

2
Arrays.sortrenvoie type void
user902383

1
@ RomanGräfthe pAper chAse
AdmBorkBork
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.