Сортировать имена групп


22

Описание задачи

У вас есть музыкальная библиотека с большим количеством треков , записанных многими группами, каждая из которых имеет имя, как Queen, Aerosmith, Sunny Day Real Estate, The Strokes. Когда аудиопроигрыватель отображает вашу библиотеку в алфавитном порядке по имени группы, он обычно пропускает Theчасть, поскольку многие названия групп начинаются с Theнее, упрощая навигацию по вашей медиаколлекции. В этой задаче, учитывая список (массив) строк, вам нужно отсортировать его таким образом (то есть пропустить Theслово в начале имени). Вы можете написать метод или полную рабочую программу.

Образцы входов / выходов

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

Примечания / Крайние случаи

  • Сортировка лексический нечувствительна к регистру, поэтому The Police, The policeи the policeвсе эквивалентны,

  • Ваш алгоритм должен опускать только первое theслово, поэтому группы с именами The Theили The The Bandотсортированы по второму the,

  • Группа с именем The(трехбуквенное слово) сортируется нормально (без пропусков),

  • Порядок двух групп с одинаковым названием, одна из которых начинается с the(например, The Policeи Police), не определена,

  • Вы можете предположить, что если имя группы состоит из более чем одного слова, они разделяются одним пробелом. Вам не нужно обрабатывать начальные или конечные пробелы,

  • Все входные строки совпадают [A-Za-z0-9 ]*, то есть они будут состоять только из строчных и прописных букв английского алфавита, цифр и пробелов,

  • Помните, что это задача , поэтому сделайте ваш код как можно короче!


Имена только для цифр идут до или после алфавита?
AdmBorkBork

Сначала идут
числовые

1
Каков порядок сортировки Theи The The? (Большинство ответов, вероятно, нужно будет изменить, если это что-то отличное от неопределенного)
Брэд Гилберт b2gills

как насчет Лос Лобос?
njzk2

3
Кстати, The The Настоящая группа. (вместе с тем, кто, что, где, когда, почему и как)
DanTheMan

Ответы:


7

Python, 56 62 64 байта

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

Попытайся

Спасибо @Chris H за то, что он указал, что lstrip()это не обрабатывалось The Theправильно, так как полоса уничтожала все подходящие символы и сортировал ее как пустую строку, и @manatwork за нахождение недостатка в использовании replace(). Новая версия должна работать.

Старая версия:

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

1
Я не убежден. Добавление «животных» в последний список дает ['The The', 'The', 'The Animals', 'Thermodynamics', 'The They']. 2-й крайний вариант предполагает, что сит должен быть [«Животные», «The», «The», «Thermodynamics», «The Они»] (или поменяйте местами 2-й и 3-й пункты). Немного возни с предположением, что пространство внутри strip('the ')игнорируется - попробуйтеfor x in ['The The', 'The They', 'Thermodynamics', 'The', 'The Animals']: print (x.lower().strip('the '))
Крис Х

Это replace()не намного лучше: 'what the snake'.replace('the ','',1)результаты 'what snake'.
Манатворк

5

V , 32 28 байт

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

Попробуйте онлайн!

Примечание для себя: сделайте аббревиатуру для :sortтого, чтобы мне не понадобилось 6 целых байтов для одной команды!

Объяснение:

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

Не знаком с V, но, кажется, этот работает нормально без звездочек. Это совпадение с входом или на самом деле не нужно?
Киркпатт

1
@kirkpatt Хорошая идея! Это почти работает, но не совсем. Например, при этом вводе неправильно ставится «Radiohead» после «The Ramones» и «The Roots». Тем не менее, это дает мне идею ...
DJMcMayhem

Что произойдет, если theвсе в нижнем регистре, как the pAper chAse?
AdmBorkBork

4

Сетчатка , 34 байта

Конечный перевод строки является значительным.

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

O`
.+;

I / O - одна полоса на линию.

Попробуйте онлайн!

объяснение

%`^
$';

Дублируйте каждую строку, используя ;в качестве разделителя.

T`L`l`.+;

Переверните все перед ;строчными буквами.

m`^the 

Удалите все thes, которые появляются в начале строки.

O`

Сортировка строк.

.+;

Удалите начала строк, которые мы использовали для сортировки.


Не могли бы вы упаковать первые 3 шага в один шаг? Как в PCRE: s / (?i:the )?(.*)/ \L$1\E;$0/
Falco

@Falco .NET не поддерживает изменения регистра в строках замещения, и я еще не добавил их в пользовательский заменитель Retina.
Мартин Эндер


3

Perl, 52 байта

-13 байт благодаря @manatwork
-1 байт благодаря @ msh210

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

Одна полоса на строку в качестве входных данных, и поэтому является выходной.

Реализация довольно проста: программа печатает список диапазонов, отсортированный с помощью пользовательской функции ( f), которая возвращает имя диапазона в нижнем регистре без возможного начала the.


Короче с замещением вместо соответствия: sub f{lc$_[0]=~s/^the //ir}.
manatwork

На 1 байт действительно, спасибо.
Дада

На самом деле я посчитал на 2 или 3 байта короче: не нужно ни круглых скобок вокруг lcпараметра, ни iфлага в подстановке. Или вы встречали тестовый случай, где это не работает?
Манатворк

Снова Думая, количество опций командной строки также может быть уменьшено , если вы каждый название группы на отдельной строке: 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
Сохраните три байта: lc popвместо lc$_[0]и sayвместо print. (Последнее требует -M5.01, что бесплатно.) Протестировано в Strawberry 5.20.2 только с первым контрольным примером из вопроса.
msh210

2

Python, 66 72 69 байт

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

Использует sortedметод Python с keyключевым словом аргумент для сортировки по имени минус «The». Это лямбда; чтобы назвать это, дать ему имя, поставив f=перед.

Теперь с дополнительной нечувствительностью к регистру!


2
Это не соответствует требованию нечувствительности к регистру, хотя ... Название группы может начинаться с the , в этом случае этот метод не будет работать должным образом.
Shooqie

@shooqie О, я не видел это требование. Я исправлю это.
Медь


2

Perl 6 , 26 байт

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

Объяснение:

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

Тест:

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 байт

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

Сохранено 3 байта благодаря @MathiasRJessen

Ввод осуществляется через аргументы командной строки. Сортирует исходные имена на основе результатов блока скрипта, {...}который выполняет регулярное выражение -replaceдля удаления ведущих (без учета регистра) "the ".

Примеры

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

-replaceпо умолчанию нечувствителен к регистру, '^the 'будет достаточно для шаблона
Матиас Р. Джессен

@ MathiasR.Jessen Да, спасибо за напоминание.
AdmBorkBork

@ValueInk См. Комментарий Матиаса о нечувствительности к регистру и последний пример, который я добавил.
AdmBorkBork

2

JavaScript / ECMAScript 6 93 70 байт

70 Спасибо Нейлу и Даунгоату за совет

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

Читаемая версия для 70-байтового варианта

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

Читаемая версия для 93-байтового варианта

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

Не должно ли это регулярное выражение быть ^в нем? Кроме того, localeCompare нечувствителен к регистру в моей системе, поэтому мне не нужен был toLowerCaseтолько /iфлаг в регулярном выражении. Наконец, вы можете изменить это следующим образом: B=>B.sort((a,b)=>...,R=s=>...)- sortигнорирует дополнительный параметр, который устанавливается R.
Нейл

Куда в регулярном выражении ^ пойдет? Это было бы отрицанием, и выражение должно совпадать и стирать «the». Я попробую использовать сравнение локали без преобразования в нижний регистр.
Пандакодер

@Pandacoder the ^shuold идет в начале регулярного выражения
Downgoat

@Downgoat После тестирования всех заданных случаев и нескольких случаев, которые я придумал, специально намереваясь сломать RegEx, с или без ^ я не получаю никаких изменений в поведении, только дополнительный символ, который ничего не выполняет.
Пандакодер

@Pandacoder, который не делает его действительным. ^ - это якорь, который требует, чтобы "the" было в начале согласно спецификации
Downgoat

1

Java 8, 178 байт

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

Безголовая версия:

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

Звоните как таковой:

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

Я знаю, что вы ответили на это почти год назад, но вы можете сыграть в гольф несколько вещей. Поскольку вы заявляете, что используете Java 8, вы можете перейти void q(String[]s){...}на s->{...}. И вы можете изменить как (x.toLowerCase().startsWith("the ")?x.substring(4):x)с x.replaceFirst("(?i)the ",""). Итого получается: s->{java.util.Arrays.sort(s,(a,b)->a.replaceFirst("(?i)the ","").compareToIgnoreCase(b.replaceFirst("(?i)the ","")));}- 118 байтов
Кевин Круйссен,

Аккуратный трюк с заменой первого. Когда я ответил на это, мне несколько раз говорили о других s->{ ... }недопустимых ответах, и мне нужно было иметь полную сигнатуру метода с типами и еще много чего. Я не знаю, изменилось ли это с тех пор.
Джастин

Не уверен насчет того времени, но в наши дни это разрешено и используется почти всеми, кто играет в гольф на Java или C # .NET.
Кевин Круйссен

0

Ним , 96 байт

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

Те importзанимают так много байтов:|

Перевод моего Python ответа .

Это анонимная процедура; чтобы использовать это, это должно быть передано в процедуру тестирования. Вот полная программа, которую вы можете использовать для тестирования:

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 байта

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

Позвонить с

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

Прецедент:

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 байт

tk'^the '[]YX2$S

Формат ввода (каждая строка соответствует тесту)

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

Попробуйте онлайн!

объяснение

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 байт

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

Попробуйте онлайн!

Без учета использования ответ будет 102 байта.


Я считаю, что вы можете проигнорировать финал ToLower()из-за нечувствительного к регистру требования
TheLethalCoder

Также вы можете сделать это анонимной функцией, которая должна сохранять несколько байтов:
TheLethalCoder

l=>l.OrderBy(b=>(b.ToLower().StartsWith("the ")?b.Substring(4):b));Для 67 байт , а затем вам нужно добавить на using System.Linq;слишком
TheLethalCoder

@TheLethalCoder: мне нужно второе ToLowerиз-за нечувствительного к регистру требования. В противном случае порядок будет чувствительным к регистру.
Разнагул

Хорошо, вопрос о том, чтобы преобразовать его в анонимную функцию, остается в
силе

0

BASH, 64 байта

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

Ввод: стандартный ввод, одна полоса на строку. Выход: стандартный вывод

Примечание. Во вторых заменах (s / ^ The / / и s / ^ / The /) используется символ табуляции, поэтому они не всегда правильно копируют / вставляют.


0

Bash + coreutils, 44 байта

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

Пояснение: формат ввода и вывода - одна полоса на строку

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

Тестовый прогон (используя здесь документ с EOF в качестве маркера конца):

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

Выход:

Aerosmith
Queen
The Strokes
Sunny Day Real Estate

0

Vim, 18 байт

Теперь, когда я понял, что это возможно, меня немного смущает мой 26-байтовый V-ответ, тем более что V должен быть короче, чем vim. Но это в значительной степени встроенный.

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

Пояснение (прямо из справки 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 байт

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

Ну, я наконец-то нашел время закончить это C. Советы по гольфу очень ценятся.

В этом представлении Mбудет представлена ​​функция сравнения qsort. Поэтому, чтобы вызвать это, вы должны использовать qsortв формате, qsort(argv++,argc--,8,M)где argvсодержатся аргументы командной строки и argcколичество предоставленных аргументов.

Попробуйте онлайн!


0

05AB1E , 27 байт (не конкурирует)

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

Попробуйте онлайн!

объяснение

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 байта

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

41% мой ответ: .toLowerCase()убей меня сейчас.


Выход

Когда работает ...

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

Результат ...

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

Без отладки или вывода ошибок.


0

q / kdb +, 36 33 байта

Решение:

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

Пример:

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"

Объяснение:

Удалите все «[Tt] he» из каждой входной строки, отсортируйте этот список, затем отсортируйте исходный список на основе индексации отсортированного списка.

{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 байт

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

Основная функция

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

); }

Функция сортировки по гольфу:

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

Спасибо @raznagul за сохранение 18 байт


Не работает, если имя начинается с the . Сортировка должна быть без учета регистра.
Shooqie

Это не сработает вообще ... Строки неизменны. Вы хотите сделать 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 должен работать, и строки неизменны
Сократов Феникс

Исправил это, но найди мне одну группу, которая начинается с небольшого "the"
Roman Gräf

2
Arrays.sortвозвращает тип void
user902383

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.