Сортування назв групи


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

Першими виходять лише рядки
shooqie

1
Який порядок сортування Theта The The? (Більшість відповідей, ймовірно, потрібно буде змінити, якщо це щось інше, ніж невизначене)
Бред Гілберт b2gills

як щодо Лос-Лобоса?
njzk2

3
До речі, The - справжня група. (разом із "Хто, що, куди, коли, чому і чому")
DanTheMan

Відповіді:


7

Пітон, 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", "Термодинаміка", "Вони"] (або поміняти місцями 2-й і 3-й пункти). Невелика хитрість говорить про те, що простір всередині strip('the ')ігнорується - спробуйтеfor x in ['The The', 'The They', 'Thermodynamics', 'The', 'The Animals']: print (x.lower().strip('the '))
Chris H

Це 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, але, здається, цей відмінно працює без зірочок. Це збіг із входом чи насправді непотрібний?
kirkpatt

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}.
манатура

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'.
манатура

1
Збережіть три байти: lc popзамість lc$_[0]і sayзамість print. (Останнє вимагає -M5.01, що є безкоштовним.) Перевірено в Полуниці 5.20.2, лише перший тестовий випадок із питання.
msh210

2

Пітон, 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)
};

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

Куди в реггесі ^ піде? Це було б запереченням, і вираз повинен відповідати та стирати "the". Я спробую використати порівняння локалів без малої конверсії.
Pandacoder

@Pandacoder shuold ^йде на початку
виразки

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

@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

Хаскелл, 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через невідчутну до регістру вимогу. Інакше замовлення залежить від регістру.
raznagul

Гаразд, питання про перетворення його на анонімну функцію все ще залишається
TheLethalCoder

0

БАШ, 64 байт

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

Вхід: stdin, одна смуга на рядок. Вихід: stdout

Примітка. Другі заміни (s / ^ / / і 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

Вім, 18 байт

Ну а тепер, коли я зрозумів, що це можливо, мене ніби збентежує моя відповідь V-байтом 26, тим більше, що 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 повинен працювати, і струни незмінні
Socrat Phoenix

Виправлено це, але знайдіть мені одну групу, яка починається з невеликого "the"
Романа Гряфа

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

1
@ RomanGräfthe pAper chAse
AdmBorkBork
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.