PronunciationSort ™

24

Все мы знаем о различных причудливых алгоритмах сортировки, но ни один из них не дает нам чисел таким образом, который легко произносить. Чтобы исправить это, я предлагаю использовать PronuationSort ™, наиболее естественный способ сортировки списков чисел.

Произношение

Официальные правила произнесения чисел (в этом вызове) таковы, что цифры произносятся одна за другой, а полученная строка сортируется в лексикографическом порядке. В качестве примера это означает, что число 845произносится "eight four five"и должно быть соответственно отсортировано.

Отрицательные числа

Отрицательные числа произносятся путем добавления слова "minus". Таким образом, -23произносится как "minus two three". Обратите внимание, что это приводит к тому, что отрицательные числа оказываются в середине вывода, прямо между числами, начинающимися с 4(четыре) и 9(девять).

В качестве руководства официальный порядок слов для произношенияSort ™:

  • восемь
  • 5
  • четыре
  • минус
  • 9
  • один
  • Семь
  • шесть
  • три
  • два
  • нуль

То есть,

8, 5, 4, -, 9, 1, 7, 6, 3, 2, 0

вход

Список целых чисел в диапазоне , содержащий не более 100 элементов. Ввод в виде списка строк не допускается. Если ваш язык не поддерживает ввод в виде списка, допустимо указывать ввод в виде отдельных целых чисел.[999,999]

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

Выход

Те же самые целые числа, в порядке произношенияSort ™. Обратите внимание, что числа должны быть преобразованы только в их произношение, чтобы получить сортировку, выходные данные не должны содержать строк.

Примеры

В примерах средний шаг (заключенный в скобки) служит только руководством и не является частью вывода.

[1, 2, 3] -> (['one', 'two', 'three']) -> [1, 3, 2]
[-1, 0, 1, 2] -> (['minus one', 'zero', 'one', 'two']) -> [-1, 1, 2, 0]
[-100, 45, 96] -> (['minus one zero zero', 'four five', 'nine six']) -> [45, -100, 96]
[11, 12, 13, 134, 135] -> (['one one', 'one two', 'one three', 'one three four', 'one three five']) -> [11, 13, 135, 134, 12]

Есть также скрипт для проверки ваших результатов .

maxb
источник
5
Почему «один» (произносится как «выиграл») не приходит после двух и до нуля?
Бен Миллер - Восстановить Монику
3
@BenMiller Я не могу вспомнить, если это ты комментировал в песочнице, но этот комментарий дал мне дежавю. Чтобы ответить на это здесь, я обдумал это, но я пошел с орфографией, чтобы избежать обсуждений орфографии (например, «два» против «слишком», «выиграл» или «wan»)
maxb
17
Так что это на самом деле более «сортировка по буквам», чем «сортировка по произношению» :-)
Paŭlo Ebermann
3
облом. Я надеялся, что они будут отсортированы по тому, как трудно их произносить ...
Н.Х.
2
Эта задача действительно должна быть переименована, поскольку сортировка здесь практически не имеет отношения к произношению. Было бы намного сложнее, если бы он основывался на произношении (например, четыре могут предшествовать пяти, если вы сортируете однотонник ⟨ɔː⟩ перед дифтонгом ⟨aɪ⟩, но пять перед четырьмя, если вы сортируете производный ⟨a⟩ до o - получено ⟨ɔ⟩ - насколько мне известно, не существует установленного порядка сортировки произношения ни в IPA, ни в какой-либо другой схеме).
Янус Бакс Жак

Ответы:

8

05AB1E (наследие) , 15 байтов

Σε•Koéa₃•'-3ǝsk

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

объяснение

Σ                 # sort by
 ε                # apply to each
             sk   # index of the element in
  •Koéa₃•         # "85409176320"
         '-3ǝ     # with "-" inserted at index 3
Emigna
источник
Кажется, есть ошибка в сжатом целом числе •ĆU‘•. Он добавляет новую строку во время отображения / сортировки по любой причине. Σ•ĆU‘•"54-ÿ"sSkмог бы быть 15-байтовой альтернативой, над которой я работал, если бы не эта странная ошибка ... Если я •ĆU‘•9176320
перехожу
1
@KevinCruijssen: Это странно. Тебе было бы 14 с …54-ìчетным
Эминья
@KevinCruijssen: Вы могли бы сделать Σ•RT‹•Á…54-ìsSkдля 15
Эмигна
•t∍ýJ•'-ìÁÁтакже будет работать
Emigna
8

Haskell , 57 байт

import Data.List
sortOn$map(`elemIndex`"54-9176320").show

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

Винсент
источник
1
Это так чисто и понятно! Определенно победитель с точки зрения простоты понимания.
Стивен Белден
8

Желе ,  15  13 байт

ṾV€ị“Þ⁽3Z6»µÞ

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

Монадическая ссылка, принимающая список целых чисел, которая выдает список целых чисел.

Как?

Сортирует по порядковым значениям цифр целых чисел (где -это «цифра» -1), преобразованных в строки с использованием символов с их модульным индексом на основе 1 в магической строке «murgeon lix».

Сортировка является буквенной, где пробел считается меньше любой буквы.

Волшебная строка «murgeon lix» была найдена при проверке словарей желе, используемых для сжатия. Нет слов из 11 букв, которые удовлетворяют требованиям (и ни одного из них больше, чем при дедупликации). так как пробел сортируется перед буквами, следующим наиболее очевидным выбором является слово длиной семь, за которым следует пробел, за которым следует слово длины три. «murgeon» и «lix» - единственная удовлетворяющая комбинация, хотя без пробела возможны и другие (например “£Py:ƥ», «murgeonalix», который работает с тем же количеством байтов)

ṾV€ị“Þ⁽3Z6»µÞ - Link: list of integers
            Þ - sort by:
           µ  -   the monadic link: -- i.e. do this for each integer, then sort by that
Ṿ             -     unevaluate  (e.g. -803 -> ['-','8','0','3'])
 V€           -     evaluate each as Jelly code  (e.g. ['-','8','0','3'] -> [-1,8,0,3])
    “Þ⁽3Z6»   -     "murgeon lix" (compression of words in Jelly's dictionary plus a space)
   ị          -     index into (1-indexed & modular) (e.g. [-1,8,0,3] -> "i xr")

Предыдущие @ 15 байтов :

ṾV€ị“¡Zo⁶’Œ?¤µÞ

Здесь “¡Zo⁶’Œ?¤находится первая перестановка натуральных чисел, которая будет находиться в индексе 21 340 635, когда все перестановки чисел отсортированы лексикографически - что есть [6,10,9,3,2,8,7,1,5,4,11]. ( “¡Zo⁶’является базовым представлением 250 для 21340635, в то время как Œ?выполняется вычисление и ¤группирует эти инструкции вместе)

Джонатан Аллан
источник
Даже с объяснениями я не чувствую себя очень умным. Отличное решение!
максимум
Более короткая версия, вероятно, также легче понять!
Джонатан Аллан
7

Perl 6 , 30 байт

*.sort:{TR/0..9-/a5982176043/}

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

Порт GB решение Ruby.

Оригинальная 35-байтовая версия

*.sort: (~*).uninames».&{S/\w*.//}

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

Преобразуйте каждое число в строку, получите имя Unicode для каждого символа, удалите первое слово («DIGIT» или «HYPHEN»), а затем сортируйте.

nwellnhof
источник
6

JavaScript (SpiderMonkey) , 69 байт

a=>a.sort((a,b)=>(g=n=>[...n+''].map(c=>':598217604'[c]||3))(a)>g(b))

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

Arnauld
источник
Похоже, вы можете удалить +'', видя, как вы принимаете ввод в виде массива строк.
Лохматый
@ Shaggy Я больше не беру струны, потому что я не уверен, разрешено ли это здесь.
Арно
Ах ... Ты прав. Это добавит пару байтов к моему решению.
Лохматый
6

K (нгн / к) , 21 20 байт

{x@<"54-9176320"?$x}

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

{ } функция с аргументом x

$ форматировать как строки

""?-263"8"

< вычислить сортировку по возрастанию перестановки

x@ аргумент в этих показателях

СПП
источник
6

Python 3, 68 байт 67 байт 64 байта

lambda x:sorted(x,key=lambda y:[*map('54-9176320'.find,str(y))])

Использует встроенную sortedфункцию с анонимной лямбдой для ключа. Жестко запрограммируйте порядок сортировки и сравните каждую цифру в каждом значении в списке ввода с ее позицией в списке порядка сортировки.

Редактировать: 1 байт был сохранен путем удаления 8из списка сортировки, чтобы воспользоваться возможностью str.findвозврата, -1когда параметр не найден. Благодаря MaxB.

Edit2: сохранены 3 байта, используя помеченный синтаксис в listлитерале вместо listконструктора

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

mypetlion
источник
1
Не могли бы вы удалить первые 8 в строке? Поскольку Python возвращает -1, если подстрока не найдена.
максимум
@maxb Хороший улов. Ред.
mypetlion
2
Порту Python 2 58:lambda x:sorted(x,key=lambda y:map('54-9176320'.find,`y`))
Джонатан Аллан
5

Pyth, 17 16 байт

oxL"54-9176320"`

Попробуйте онлайн здесь или проверьте все тестовые примеры сразу здесь .

oxL"54-9176320"`NQ   Implicit: Q=eval(input())
                     Trailing N, Q inferred
o                Q   Order the elements of Q, as N, using...
               `N      Convert N to string
 xL                    Get the index of each character of that string...
   "54-9176320"        ... in the lookup ordering
                       (if character missing, returns -1, so 8 is still sorted before 5)

Сохранено 1 байт благодаря @ngn и их K-ответу , пропуская 8 в начале строки словаря

Sok
источник
4

Japt, 19 байт

ñ_s ®n"54-9176320

Попытайся

мохнатый
источник
Отличное решение! Ввод в виде списка строк, к сожалению, не разрешен.
максимум
Вы можете сохранить некоторые, злоупотребив S.n(s): ñ_s ®n"54-9176320(по-видимому S.n(s), точно так же, как и s.b(S)для Sдлины 1, за исключением того, что она возвращается 0вместо -1)
ETHproductions
Хороший трюк, @ETHproductions, спасибо :) Я запомню этот на будущее.
Лохматый
3

Сетчатка 0.8.2 , 36 байт

T`-d`3:598217604
O`
T`3:598217604`-d

Попробуйте онлайн! Ссылка включает тестовый набор. Объяснение:

T`-d`3:598217604

Переведите знак минус и цифры в их положение в порядке произношения, используя :для 10-й позиции.

O`

Сортировка в порядке произношения.

T`3:598217604`-d

Переведите заказ обратно в исходный знак минус и цифры.

Нил
источник
3

R , 58 байт

function(x)x[order(mapply(chartr,"-0-9","dkfjicbhgae",x))]

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

Ввод представляет собой список чисел, который неявно преобразуется в виде строки с использованием chartr. orderзатем использует лексикографический порядок, чтобы получить порядок сортировки исходного списка.

Jayce
источник
3

Java (JDK 10) , 123 байта

l->l.sort(java.util.Comparator.comparing(n->{var r="";for(var c:(""+n).split(""))r+=11+"54-9176320".indexOf(c);return r;}))

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

Это наивная реализация Java. Должно быть много в гольф.

кредиты

Оливье Грегуар
источник
1
Изменение .chars-IntStream и .reduceна регулярной петле экономит 2 байта: n->{var r="";for(var c:(""+n).split(""))r+=10+"854-9176320".indexOf(c);return r;}. Кроме того, можно сохранить еще один байт, изменив его 10+"85на 20+"5, поскольку в этом случае .indexOfцифра for 8будет равна -1. Попробуй онлайн 123 байта
Кевин Круйссен,
2

JavaScript (SpiderMonkey) , 87 73 байта

a=>a.sort((p,q,F=b=>[...""+b].map(x=>"54-9176320".search(x)))=>F(p)>F(q))

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

Спасибо @Arnauld за сообщение о том, что сортировка в SpiderMonkey стабильна, так что ||-(F(q)>F(p))часть может быть окончательно отброшена.

Сиеру Асакото
источник
2

Красный , 114 байт

func[n][g: func[a][collect[foreach c form a[keep index? find"854-9176320"c]]]sort/compare n func[x y][(g x)< g y]]

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

Более читабельно:

f: func [ n ] [
    g: func [ a ] [
        collect [ 
            foreach c form a [ 
                keep index? find "854-9176320" c
            ]
        ]
    ]
    sort/compare n func [ x y ] [ (g x) < g y ]
]
Гален Иванов
источник
2

C ++, 353 байта

Это своего рода комедийная запись, но я напрасно тратил время и писал ее, поэтому я не могу не публиковать ее ... Наслаждайтесь смешком и дайте мне знать, есть ли какие-нибудь космические заставки, которые я пропустил!

#include<algorithm>
#include<iostream>
#include<iterator>
#include<numeric>
#include<string>
using namespace std;auto f(int i){auto s=to_string(i);for(auto&c:s)c='A'+"854-9176320"s.find(c);return s;}int main(){int a[100];auto b=begin(a);auto e=end(a);iota(b,e,-50);sort(b,e,[](int l,int r){return f(l)<f(r);});copy(b,e,ostream_iterator<int>(cout," "));}

Выход:

8 5 4 48 45 44 49 41 47 46 43 42 40 -8 -5 -50 -4 -48 -45 -44 -49 -41 -47 -46 -43 -42 -40 -9 -1 -18 -15 - 14 -19 -11 -17 -16 -13 -12 -10 -7 -6 -3 -38 -35 -34 -39 -31 -31 -36 -36 -33 -32 -30 -2 -28 -25 -24 - 29 -21 -27 -26 -23 -22 -20 9 1 18 15 14 19 11 17 16 13 12 10 7 6 3 38 35 34 39 31 37 36 33 32 30 2 28 25 24 29 21 27 26 23 22 20 0

underscore_d
источник
Я вижу, что вы также живете под девизом "если я не
нажму
1
Эй, я не могу позволить себе легкомысленные пробелы в этом языке! Забавно делать это, потому что в остальное время мало что делает меня таким же злым, как открытие чужого кода, который, очевидно, думает, что написание ужасающей монолитной стены заставит их казаться умнее и / или активно оплачивать за каждый перевод новой строки.
underscore_d
1
Здравствуйте! Сожми свое решение до 195 символов
Макс Ехлаков
@MaxYekhlakov Круто, спасибо, что задумался! Я понял после прочтения немного больше; кажется, что мне не обязательно предоставлять полностью скомпилируемую программу, а вместо этого только функции, которые будут обрабатывать указанный ввод и вывод. D'о!
underscore_d
2

Mathematica, 68 байт

SortBy[If[# < 0,"m ",""]<>StringRiffle@IntegerName@IntegerDigits@#&]

Функция. Принимает список целых чисел в качестве входных данных и возвращает отсортированный список в качестве выходных данных. Просто разделяет цифры каждого числа с помощью IntegerDigits, преобразует каждую цифру в "zero", "one"и т. Д., С помощью IntegerName, преобразует список в строку, разделенную пробелами, с StringRiffleдобавлением, "m "если число является отрицательным, и сортирует на основе этой строки. Действительно, это был самый короткий подход, который я могу найти, поскольку Mathematica использует лексикографическую сортировку только для списков одинаковой длины; таким образом, подход, основанный на том, 854-9176320что занимает больше байтов, так как строковые функции очень дороги.

LegionMammal978
источник
Всегда доверяйте Mathematica иметь комбинацию встроенных. Умное решение!
максимум
1

05AB1E , 15 14 байтов

Σ•ĆU‘•…54-ìsSk

-1 байт благодаря @Emigna .

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

Σ                 # Sort by:
 •ĆU‘•            #  Push the compressed integer 9176320
      54-        #  Push the string "54-"
          ì       #  Prepend this string before the integer: "54-9176320"
           s      #  Swap so the current number to sort is at the top of the stack
            S     #  Convert it to a list of characters
             k    #  Check for each its index in the string (resulting in -1 for '8')

Посмотрите эту подсказку 05AB1E (раздел Как сжать большие целые числа ), чтобы понять, почему •ĆU‘•это так 9176320.

Кевин Круйссен
источник