Ordenar nombres de bandas


22

Descripción del desafío

Tienes una biblioteca de música con muchas pistas grabadas por muchas bandas, cada una de las cuales tiene un nombre, como Queen,Aerosmith , Sunny Day Real Estate, The Strokes. Cuando un reproductor de audio muestra su biblioteca alfabéticamente por nombre de banda, generalmente omite la Theparte, ya que muchos nombres de bandas comienzan The, lo que facilita la navegación a través de su colección de medios. En este desafío, dada una lista (matriz) de cadenas, debe ordenarla de esa manera (es decir, omitir la Thepalabra al comienzo del nombre). Puede escribir un método o un programa de trabajo completo.

Muestra de entradas / salidas

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

Notas / casos de borde

  • Ordenar lexicográficamente no distingue entre mayúsculas y minúsculas, por lo tanto The Police,The police y the policetodos son equivalentes,

  • Su algoritmo solo debe omitir la primera thepalabra, por lo que las bandas nombradas The Theo The The Bandordenadas normalmente por la segunda the,

  • Una banda llamada The(una palabra de tres letras) se ordena normalmente (sin saltos),

  • El orden de dos bandas con el mismo nombre, una de las cuales comienza con the(like The Policey Police) no está definido,

  • Puede suponer que si el nombre de una banda consta de más de una palabra, están separados por un solo carácter de espacio. No necesita manejar espacios en blanco iniciales o finales,

  • Todas las cadenas de entrada coinciden [A-Za-z0-9 ]*, es decir, consistirán solo en letras mayúsculas y minúsculas del alfabeto inglés, dígitos y caracteres de espacio,

  • Recuerda que este es un desafío de , ¡así que haz tu código lo más corto posible!


¿Los nombres solo con números aparecen antes o después del orden alfabético?
AdmBorkBork

Las cadenas de solo
números

1
¿Cuál es el orden de clasificación de They The The? (La mayoría de las respuestas probablemente tendrían que cambiar si es algo que no sea indefinido)
Brad Gilbert b2gills

¿Qué hay de Los Lobos?
njzk2

3
The The es una banda real por cierto. (junto con The Who, The What, The Where, The When, The Why y The How)
DanTheMan

Respuestas:


7

Python, 56 62 64 bytes

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

Intentalo

Gracias a @Chris H por señalar que lstrip()no se manejaba The Thecorrectamente, ya que la tira estaba explotando todos los caracteres coincidentes y clasificándola como una cadena en blanco, y @manatwork por encontrar la falla en el uso replace(). La nueva versión debería funcionar.

Versión antigua:

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

1
No estoy convencido. Agregar "Los animales" a la última lista da ['The The', 'The', 'The Animals', 'Thermodynamics', 'The They']. El segundo caso sugiere que el asiento debería ser ['Los animales', 'El The', 'The', 'Termodinámica', 'The They'] (o intercambie los artículos segundo y tercero). Un poco de violín sugiere que el espacio interior strip('the ')está siendo ignorado - intentefor x in ['The The', 'The They', 'Thermodynamics', 'The', 'The Animals']: print (x.lower().strip('the '))
Chris H

Eso replace()no es mucho mejor: 'what the snake'.replace('the ','',1)resultados 'what snake'.
manatwork el

5

V , 32 28 bytes

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

Pruébalo en línea!

Nota para uno mismo: ¡Haga una abreviatura para :sortque no necesite 6 bytes completos para un solo comando!

Explicación:

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

No estoy familiarizado con V, pero parece que este funciona bien sin los asteriscos. ¿Es esta coincidencia con la entrada, o realmente innecesaria?
kirkpatt

1
@kirkpatt ¡Buena idea! Eso casi funciona, pero no del todo. Por ejemplo, con esta entrada , coloca incorrectamente "Radiohead" después de "The Ramones" y "The Roots". Sin embargo, eso me da una idea ...
DJMcMayhem

¿Qué pasa si theestá en minúsculas, como the pAper chAse?
AdmBorkBork

4

Retina , 34 bytes

El avance de línea final es significativo.

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

O`
.+;

I / O es una banda por línea.

Pruébalo en línea!

Explicación

%`^
$';

Duplicar cada línea, utilizando ;como separador.

T`L`l`.+;

Convierta todo delante de ;a en minúsculas.

m`^the 

Elimine cualquier thes que aparezca al comienzo de una línea.

O`

Ordenar las líneas.

.+;

Elimina los comienzos de las líneas que usamos para ordenar.


¿No podrías agrupar los primeros 3 pasos en un solo paso? Como en PCRE: s / (?i:the )?(.*)/ \L$1\E;$0/
Falco

@Falco .NET no admite cambios de mayúsculas y minúsculas en las cadenas de sustitución y tampoco los he agregado al sustituto personalizado de Retina.
Martin Ender

4

Pyke, 16 bytes

.#l1D"the ".^4*>

Pruébalo aquí!

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

3

Perl, 52 bytes

-13 bytes gracias a @manatwork
-1 byte gracias a @ msh210

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

Una banda por línea como entrada, y también lo es la salida.

La implementación es bastante sencilla: el programa imprime la lista de bandas, ordenadas con la ayuda de una función personalizada ( f) que devuelve el nombre de la banda en minúsculas sin el guión final the.


Es más corto con la sustitución en lugar de corresponder: sub f{lc$_[0]=~s/^the //ir}.
manatwork

1 byte más corto de hecho, gracias.
Dada

En realidad, conté 2 o 3 bytes más cortos: no es necesario tanto el lcparámetro entre paréntesis como el iindicador en sustitución. ¿O has conocido un caso de prueba donde eso no funciona?
manatwork el

Pensando de nuevo, la cantidad de opciones de línea de comandos también podría reducirse si se toma el nombre de cada banda en línea independiente: 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 el

1
Guarde tres bytes: en lc poplugar de lc$_[0]y en saylugar de print. (Esto último requiere -M5.01, que es gratis.) Probado en Strawberry 5.20.2 con solo el primer caso de prueba de la pregunta.
msh210

2

Python, 66 72 69 bytes

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

Utiliza el sortedmétodo de Python con el keyargumento de la palabra clave para ordenar por el nombre menos "The". Esta es una lambda; para llamarlo, ponle un nombre poniéndolo f=al frente.

¡Ahora con insensibilidad a mayúsculas y minúsculas!


2
Sin embargo, no cumple con el requisito de insensibilidad de mayúsculas y minúsculas ... Un nombre de banda puede comenzar the , en cuyo caso este método no funcionará correctamente.
shooqie

@shooqie Oh, no vi ese requisito. Lo arreglaré.
Cobre


2

Perl 6 , 26 bytes

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

Explicación:

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

Prueba:

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 bytes

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

Guardado 3 bytes gracias a @MathiasRJessen

La entrada es a través de argumentos de línea de comandos. Ordena los nombres originales en función de los resultados del bloque de secuencia de comandos {...}que realiza una expresión regular -replacepara eliminar el inicio (sin distinción entre mayúsculas y minúsculas)"the " .

Ejemplos

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

-replaceno distingue entre mayúsculas y minúsculas por defecto, '^the 'será suficiente para el patrón
Mathias R. Jessen

@ MathiasR.Jessen Sí, gracias por el recordatorio.
AdmBorkBork

@ValueInk Vea el comentario de Mathias sobre la insensibilidad a mayúsculas y minúsculas y el ejemplo final que agregué.
AdmBorkBork

2

JavaScript / ECMAScript 6 93 70 bytes

70 Gracias a Neil y Downgoat por sus consejos.

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

Versión legible para la variante de 70 bytes

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

Versión legible para la variante de 93 bytes

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

¿No debería esa expresión regular tener algo ^dentro? Además, localeCompare no distingue entre mayúsculas y minúsculas en mi sistema, por lo que no necesitaba el toLowerCase, solo una /ibandera en la expresión regular. Finalmente, puede jugar golf de la siguiente manera: B=>B.sort((a,b)=>...,R=s=>...)- sortignora el parámetro adicional que establece R.
Neil

¿En qué parte de la expresión regular iría? Eso sería una negación y se supone que la expresión coincide y borra "the". Intentaré usar la configuración regional sin la conversión de minúsculas.
Pandacoder

@Pandacoder the ^shuold ir al comienzo de la expresión regular
Downgoat

@Downgoat Al probar todos los casos dados, y en algunos casos, pensé específicamente en romper el RegEx, con o sin ^ No obtengo ningún cambio en el comportamiento, solo un personaje adicional que no logra nada.
Pandacoder

@Pandacoder que no lo hace válido. ^ es un ancla que requiere que "the" esté al principio según las especificaciones
Downgoat

1

Java 8, 178 bytes

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

Versión sin golf:

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

Llamar como tal:

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

Sé que respondiste esto hace casi un año, pero puedes jugar al golf algunas cosas. Como usted afirma que usa Java 8, puede cambiar void q(String[]s){...}a s->{...}. Y puedes cambiar ambos (x.toLowerCase().startsWith("the ")?x.substring(4):x)con x.replaceFirst("(?i)the ",""). Entonces el total se convierte en: s->{java.util.Arrays.sort(s,(a,b)->a.replaceFirst("(?i)the ","").compareToIgnoreCase(b.replaceFirst("(?i)the ","")));}- 118 bytes
Kevin Cruijssen

Buen truco con el replaceFirst. Cuando respondí esto, me habían dicho varias veces sobre otras respuestas que s->{ ... }no estaban permitidas y tenía que tener una firma de método completa con tipos y demás. No sé si eso ha cambiado desde entonces.
Justin

No estoy seguro acerca de entonces, pero en estos días está permitido y utilizado por casi todos los jugadores de golf en Java o C # .NET.
Kevin Cruijssen

0

Nim , 96 bytes

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

Aquellos import toman tantos bytes:|

Una traducción de mi respuesta de Python .

Este es un procedimiento anónimo; para usarlo, debe pasar a un procedimiento de prueba. Aquí hay un programa completo que puede usar para realizar pruebas:

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 bytes

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

Llamar con

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

Caso de prueba:

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 bytes

tk'^the '[]YX2$S

El formato de entrada es (cada línea corresponde a un caso de prueba)

{'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'}

Pruébalo en línea!

Explicación

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 bytes

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

¡Prueba en línea!

Sin contar los usos, la respuesta sería de 102 bytes.


Creo que puede ignorar el final ToLower()debido al requisito de mayúsculas y minúsculas
TheLethalCoder

También puede convertirlo en una función anónima que debería guardar algunos bytes:
TheLethalCoder

l=>l.OrderBy(b=>(b.ToLower().StartsWith("the ")?b.Substring(4):b));Para 67 bytes y luego debe agregar el using System.Linq;también
TheLethalCoder

@TheLethalCoder: Necesito el segundo ToLowerdebido al requisito de mayúsculas y minúsculas. De lo contrario, la orden distingue entre mayúsculas y minúsculas.
raznagul

Está bien el punto sobre la conversión a una función anónima sigue en pie, aunque
TheLethalCoder

0

BASH, 64 Bytes

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

Entrada: stdin, una banda por línea. Salida: stdout

Nota: Los segundos reemplazos (s / ^ The / / y s / ^ / The /) usan el carácter de tabulación, por lo que no siempre copian / pegan correctamente.


0

Bash + coreutils, 44 bytes

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

Explicación: el formato de entrada y salida es una banda por línea

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

Prueba de funcionamiento (utilizando un documento aquí con EOF como marcador final):

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

Salida:

Aerosmith
Queen
The Strokes
Sunny Day Real Estate

0

Vim, 18 bytes

Bueno, ahora que me di cuenta de que esto es posible, estoy un poco avergonzado por mi respuesta de 26 bytes V, especialmente porque se supone que V es más corto que vim. Pero esto es más o menos una construcción.

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

Explicación (directamente de vim help):

                            *: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 bytes

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

Bueno, finalmente pude terminar esto C. Los consejos de golf son muy apreciados.

En este envío, Mes la función de comparación que se debe suministrar qsort. Por lo tanto, para invocar esto, debe usar qsorten el formato qsort(argv++,argc--,8,M)donde argvcontiene los argumentos de la línea de comandos yargc es el número de argumentos proporcionados.

¡Pruébelo en línea!


0

05AB1E , 27 bytes (no competitivos)

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

Pruébalo en línea!

Explicación

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 bytes

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

41% mi respuesta es .toLowerCase(), mátame ahora.


Salida

Cuando corres ...

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

El resultado es...

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

Sin salida de depuración o error.


0

q / kdb +, 36 33 bytes

Solución:

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

Ejemplo:

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"

Explicación:

Elimine cualquier "[Tt] he" de cada cadena de entrada, ordene esta lista, luego ordene la lista original según la indexación de la lista ordenada.

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

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

Función principal

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

); }

Función de clasificación de 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);}

Gracias a @raznagul por guardar 18 bytes


No funciona si un nombre comienza con the . El tipo debe ser insensible a mayúsculas y minúsculas.
shooqie

Esto no funcionará en absoluto ... Las cadenas son inmutables. Lo que quieres hacer es que 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); }The and The debería funcionar, y encadena un inmutable
Socratic Phoenix

Arreglado eso, pero encuéntrame una banda que comience con una pequeña "the"
Roman Gräf

2
Arrays.sortdevuelve tipo vacío
user902383

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.