Сортировка чисел

21

В углублениях символов Unicode существует блок Unicode, состоящий из (в настоящее время) 63 символов с именем «Числовые формы», который состоит из символов, которые имеют числовые значения, такие как римская цифра Ⅻ, вульгарные дроби, такие как ⅑ или ↉, или странные, такие как ↊ (10) или ↈ (100000).

Ваша задача - написать программу или функцию, которая при задании списка назначенных символов Unicode в этом блоке сортирует список по числовым значениям каждого символа.

(Сортируемый) список символов и значений можно найти на странице Википедии .

Чтобы быть самодостаточным, вот список кодовых точек и их значений:

Hex     Char   Value
0x00BC: ¼   = 1/4 or 0.25
0x00BD: ½   = 1/2 or 0.5
0x00BE: ¾   = 3/4 or 0.75
0x2150: ⅐   = 1/7 or 0.142857
0x2151: ⅑   = 1/9 or 0.111111
0x2152: ⅒   = 1/10 or 0.1
0x2153: ⅓   = 1/3 or 0.333333
0x2154: ⅔   = 2/3 or 0.666667
0x2155: ⅕   = 1/5 or 0.2
0x2156: ⅖   = 2/5 or 0.4
0x2157: ⅗   = 3/5 or 0.6
0x2158: ⅘   = 4/5 or 0.8
0x2159: ⅙   = 1/6 or 0.166667
0x215A: ⅚   = 5/6 or 0.833333
0x215B: ⅛   = 1/8 or 0.125
0x215C: ⅜   = 3/8 or 0.375
0x215D: ⅝   = 5/8 or 0.625
0x215E: ⅞   = 7/8 or 0.875
0x215F: ⅟   = 1
0x2160: Ⅰ   = 1
0x2161: Ⅱ   = 2
0x2162: Ⅲ   = 3
0x2163: Ⅳ   = 4
0x2164: Ⅴ   = 5
0x2165: Ⅵ   = 6
0x2166: Ⅶ   = 7
0x2167: Ⅷ   = 8
0x2168: Ⅸ   = 9
0x2169: Ⅹ   = 10
0x216A: Ⅺ   = 11
0x216B: Ⅻ   = 12
0x216C: Ⅼ   = 50
0x216D: Ⅽ   = 100
0x216E: Ⅾ   = 500
0x216F: Ⅿ   = 1000
0x2170: ⅰ   = 1
0x2171: ⅱ   = 2
0x2172: ⅲ   = 3
0x2173: ⅳ   = 4
0x2174: ⅴ   = 5
0x2175: ⅵ   = 6
0x2176: ⅶ   = 7
0x2177: ⅷ   = 8
0x2178: ⅸ   = 9
0x2179: ⅹ   = 10
0x217A: ⅺ   = 11
0x217B: ⅻ   = 12
0x217C: ⅼ   = 50
0x217D: ⅽ   = 100
0x217E: ⅾ   = 500
0x217F: ⅿ   = 1000
0x2180: ↀ   = 1000
0x2181: ↁ   = 5000
0x2182: ↂ   = 10000
0x2183: Ↄ   = 100
0x2184: ↄ   = 100
0x2185: ↅ   = 6
0x2186: ↆ   = 50
0x2187: ↇ   = 50000
0x2188: ↈ   = 100000
0x2189: ↉   = 0
0x218A: ↊   = 10
0x218B: ↋   = 11

Тестовые случаи:

['½','ↆ','ↂ','⅒','Ⅽ','⅑','ⅷ'] -> ['⅒','⅑','½','ⅷ','ↆ','Ⅽ','ↂ']

['¼','↋','↉','ↅ','⅐','⅟','Ⅻ','ⅺ'] -> ['↉','⅐','¼','⅟','ↅ','↋','ⅺ','Ⅻ']

['¼','½','¾','⅐','⅑','⅒','⅓','⅔','⅕','⅖','⅗','⅘','⅙','⅚','⅛','⅜','⅝','⅞','⅟'] -> ['⅒','⅑','⅛','⅐','⅙','⅕','¼','⅓','⅜','⅖','½','⅗','⅝','⅔','¾','⅘','⅚','⅞','⅟']

'⅞ⅾ↊ↄⅨⅮⅺↁⅸⅰⅩⅱⅶ¾ⅧↅↃ↋ↆ⅔ⅼⅲ⅘⅒ⅽⅦ⅕ⅤⅭⅳↂⅪⅬⅯↇⅠⅷ⅛Ⅵ½ⅵ¼ⅻ⅐Ⅱ⅜⅗⅝⅚Ⅳ⅓ⅴ↉ⅿⅫⅹↀↈ⅙⅑Ⅲ⅖⅟' -> '↉⅒⅑⅛⅐⅙⅕¼⅓⅜⅖½⅗⅝⅔¾⅘⅚⅞⅟ⅠⅰⅡⅱⅢⅲⅣⅳⅤⅴⅥⅵↅⅦⅶⅧⅷⅨⅸⅩⅹ↊Ⅺⅺ↋ⅫⅻⅬⅼↆⅭⅽↄↃⅮⅾⅯⅿↀↁↂↇↈ'

['Ↄ','ↄ','↊','↋'] -> ['↊','↋','ↄ','Ↄ']

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

Правила:

  • Если в будущем этому блоку будет назначено больше символов, вам не нужно будет обновлять свой код для их поддержки.
  • Порядок символов с одинаковыми значениями не имеет значения.
  • IO гибкий .
    • Вывод должен быть в виде символов, а не числовых значений
  • Стандартные лазейки запрещены.
  • Я не запрещаю встроенные модули, которые могут получить числовое значение символа, но я рекомендую также добавить не встроенный ответ, если это возможно.
  • Это , поэтому выигрывает самый короткий ответ в байтах для каждого языка! Удачи!
Джо Кинг
источник
9
RIP monospacing :(
Джо Кинг,

Ответы:

6

Python 3 , 216 213 байт

-3 байта благодаря TFeld

lambda l:sorted(l,key='⅒⅑⅐⅙⅕¼⅓⅖½⅗⅔¾⅘⅚⅟ⅠⅰⅡⅱⅢⅲⅣⅳⅤⅴⅥⅵↅⅦⅶⅧⅷⅨⅸⅩⅹ↊Ⅺⅺ↋ⅫⅻⅬⅼↆⅭⅽↃↄ⅛⅜Ⅾⅾ⅝⅞Ⅿⅿↀↁↂↇↈ'.find)

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

Со встроенным, который выбирает числовое значение, 111 байтов

lambda l:sorted(l,key=lambda c:[10,11,100,100,0]['↊↋Ↄↄ'.find(c)]or numeric(c))
from unicodedata import*

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

прут
источник
4
Вы можете сохранить 3 байта, удалив из строки (найдите результаты, -1которые наименьшие)
TFeld
4

Perl 6 , 57 байт

*.sort: {%(<Ↄ 100 ↄ 100 ↊ 10 ↋ 11>){$_}//.unival}

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

Просто просматривает четыре исключительных символа в хэше или возвращается к встроенному univalметоду.

Шон
источник
Вам не нужно место после двоеточия. Кроме того, ваша ссылка все еще находится в блоке кода, а не в лямбде-чем-либо
Джо Кинг
4

05AB1E (legacy) , 192 74 63 61 байт

Σ•Bšā¿ÑáζΔÕæ₅"®GÙ₂®°ƶío"§óÏ4¸bćÔ!₃ùZFúÐìŸ
,λ₂ϦP(Ì•65в₂+sÇт%k

-118 байт, используя только символы кодовой страницы 05AB1E, поэтому нам не нужно использовать кодировку UTF-8.
-11 байт благодаря @Adnan .
-2 байта благодаря @Grimy .

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

Объяснение:

Σ            # Sort the input by:
 Bšā¿ÑáζΔÕæ₅"®GÙ₂®°ƶío"§óÏ4¸bćÔ!₃ùZFúÐìŸ
 ,λ₂ϦP(Ì•65в₂+
             #  List of ASCII values modulo-100 of the characters we want to sort
 sÇ          #  Get the ASCII value of the current input-character
   т%        #  Take modulo 100 of this ASCII value
 k           #  And get the index in the list of ASCII values, as sorting order

Так что же •Bšā¿ÑáζΔÕæ₅"®GÙ₂®°ƶío"§óÏ4¸bćÔ!₃ùZFúÐìŸ\n,λ₂ϦP(Ì•65в₂+?

На основании порядка символов по модулю 100 мы получаем следующий список:

[85,30,29,39,28,37,33,88,31,40,34,89,35,41,32,90,36,38,42,43,44,60,45,61,46,62,47,63,48,64,49,65,81,50,66,51,67,52,68,53,69,86,54,70,87,55,71,56,72,82,57,73,79,80,58,74,59,75,76,77,78,83,84]

Они генерируются следующей программой:

"↉⅒⅑⅛⅐⅙⅕¼⅓⅜⅖½⅗⅝⅔¾⅘⅚⅞⅟ⅠⅰⅡⅱⅢⅲⅣⅳⅤⅴⅥⅵↅⅦⅶⅧⅷⅨⅸⅩⅹ↊Ⅺⅺ↋ⅫⅻⅬⅼↆⅭⅽↃↄⅮⅾⅯⅿↀↁↂↇↈ"Çт%

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

•Bšā¿ÑáζΔÕæ₅"®GÙ₂®°ƶío"§óÏ4¸bćÔ!₃ùZFúÐìŸ\n,λ₂ϦP(Ì•65в₂+это более короткий вариант этого списка: взять сжатое число 1485725021600091112740267145165274006958935956446028449609419704394607952161907963838640094709317691369972842282463 , затем преобразовать его в Base-65, а затем добавить 26 к каждому.

Попробуйте онлайн и убедитесь, что списки совпадают .

Кевин Круйссен
источник
1
Да, не все эти символы находятся в кодировке 05AB1E, так что это будет 192 байта.
Okx
2
Да, невозможно представить этот код в виде 68-байтового файла, что вынуждает нас вернуться к UTF-8, который действительно составляет 192 байта .
Аднан
1
@JoKing Итак, теперь я использую только символы из кодовой страницы 05AB1E. ;) Все еще скучный подход, но посмотрим, смогу ли я найти какой-то арифметический шаблон.
Кевин Круйссен
1
Я думаю, что вы можете заменить "]&%/$-)`'0*a+1(b,.234D5E6F7G8H9IY:J;K<L=M^>N_?O@PZAQWXBRCSTUV[\"Ç8-на•4Œ”dóŒfÝŸĀTUÕáOyÖOÀÁàu¼6¹₆Žr‡_›y³eß₂©ǝ²ƶ"SAÎAñ'¡û†Ø(•91в
Аднан
1
Хм, похоже, это ошибка синтаксического анализа, не регистрирующая закрывающую скобку. Я посмотрю на это.
Аднан
3

Сетчатка , 1 93 байта (UTF-8)

2{O`.
T`¼-¾⅐-↋\LI ^]Q@TU\\[ZYWSPNK\HFDB?=;975X\VR\OMJG\ECA><:86432\-)#1%0,*&.(!"$/+'`Ro

Попробуйте онлайн! Объяснение: Сортирует символы в порядке кодов, затем сопоставляет числовые символы и символы ASCII, чтобы числовые символы с наименьшим значением отображали символы ASCII с наименьшей кодовой точкой, и наоборот. Затем повторяет упражнение, так что теперь символы сортируются в порядке отображения ASCII, который соответствует желаемому порядку чисел, прежде чем они будут преобразованы обратно. Редактировать: Сохранено 100 (!) Байтов, указав порядок символов ASCII, а не числовых символов.

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

Желе , 55 байт

O%70‘“$Żz*ṀḢD⁹VṢaʠƝ lẹkƝʋ9⁽ƭXmż4#⁺3ç%|ọṢLxƈ⁽}ÞƇ2’Œ?¤iµÞ

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

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

Как?

Намного проще, чем кажется, поскольку “$Żz*ṀḢD⁹VṢaʠƝ lẹkƝʋ9⁽ƭXmż4#⁺3ç%|ọṢLxƈ⁽}ÞƇ2’в базе 250 просто большое число, использующее кодовую страницу Jelly в качестве цифр, я буду использовать “...’вместо нее.

O%70‘“...’Œ?¤iµÞ - Link: list of characters
               Þ - sort by:
              µ  -   the monadic function (i.e. f(character)):
O                -     get the ordinal value of the character
 %70             -     modulo by 70 (get the remainder after dividing by 70)
                 -       - giving integers in [0,69] excluding [52,58]
    ‘            -     increment (below code pattern can't have anything but '↉' map to 0)
            ¤    -     nilad followed by link(s) as a nilad:
     “...’       -       literal 7826363328008670802853323905140295872014816612737076282224746687856347808481112431487214423845098801
          Œ?     -       get the permutation of natural numbers [1,N] with minimal N such
                 -         that this permutation would reside at the given index in a
                 -         sorted list of all permutations of those same numbers
                 -         -> [46,52,53,54,55,56,57,58,61,60,70,59,68,64,49,62,1,65,50,66,2,63,51,67,69,3,4,5,21,6,22,7,23,8,24,9,25,10,26,42,11,27,12,28,13,29,14,30,47,15,31,48,16,32,17,33,43,18,34,40,41,19,35,20,36,37,38,39,44,45]
             i   -     first index of (the ordinal mod 70 plus 1) in that list

В сторону

По иронии судьбы, ближайший к «использовать встроенный подход», который я мог собрать, был 85 байтов , здесь используется сжатая строка:

from unicodedata import*; copy_to( atoms['
'], numeric( atoms['
'].call()))

которая разбивается на новые строки и соединяется с s, чтобы получить код Python:

from unicodedata import*; copy_to( atoms['⁸'], numeric( atoms['⁸'].call()))

который может быть выполнен в интерпретаторе Jelly - он поместит числовое значение символа Unicode в левый аргумент nilad для дальнейшего использования.

Джонатан Аллан
источник
3

Japt , 72 байта

ñ@`'%!x("y#) z$&*+,<-=.>/?0@1aq2b3c4d5ev6fw7g8hr9iop:j;klmn¡`u bXcuL

Попробуйте или запустите все тесты


объяснение

ñ@                 :Sort by passing each X through a function
  `...`            :  A compressed string, which itself contains a bunch of unprintables (See below for codepoints of original string)
       u           :  Uppercase
         b         :  Index of
          Xc       :   Charcode of X
            uL     :   Mod 100 and get character at that codepoint

кодовых

30,29,39,28,37,33,120,31,40,34,121,35,41,32,122,36,38,42,43,44,60,45,61,46,62,47,63,48,64,49,97,113,50,98,51,99,52,100,53,101,118,54,102,119,55,103,56,104,114,57,105,111,112,58,106,59,107,108,109,110,115,116

Исходное решение, 90 89 88 байт

ñ!b`(&" )#$*!%'+,-=.>/?0@1a2br3c4d5e6fw7gx8h9:jpq;k<lmÍ/`®iv u nLõd)dÃi6'¼ iA'½ iE'¾

Попробуйте или запустите все тесты


объяснение

   `...`                                :A compressed string, which itself contains a bunch of unprintables (See below for codepoints of original string)
        ®                               :Map
         iv                             :  Prepend "v"
            u                           :  Convert to uppercase
               Lõ                       :  Range [1,100]
                 d                      :  Characters at those codepoints
              n   )                     :  Convert from that base to base-10
                   d                    :  Get the character at that codepoint
                    Ã                   :End map
                     i6'¼               :Insert "¼" at (0-based) index 6
                          iA'½          :Insert "½" at index 10
                               iE'¾     :Insert "¾" at index 14
ñ                                       :Sort the input array
 !b                                     :  By finding the index of the current element in the string above

кодовых

31,30,40,29,38,34,32,41,35,36,42,33,37,39,43,44,45,61,46,62,47,63,48,64,49,97,50,98,114,51,99,52,100,53,101,54,102,119,55,103,120,56,104,57,105,115,58,106,112,113,59,107,60,108,109,110,111,116,117
мохнатый
источник
3

05AB1E, 56 53 51 50 49 48 байтов

ΣÇ©1ö•Ω‘~Èr–Õî5®Î¼ÓÂ∍_OûR•42в•мjāl†£•₂°*S>ÅΓ®Íè+

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

В основе этого решения лежит сжатый список, отображающий код Unicode, указывающий на ключ сортировки. Символы, которые соответствуют одному и тому же номеру, отображаются на одну и ту же клавишу, поэтому нам нужно только 40 разных клавиш.

70 - это наименьшее число, с помощью которого мы можем модулировать все входные кодовые точки и получать четкие результаты. Поскольку индексирование в 05AB1E оборачивается, нам не нужно явно указывать 70%, просто убедитесь, что список имеет длину 70.

Обратите внимание, что есть длинные участки последовательных кодовых точек с последовательными ключами. Таким образом, кодирование (ключ - кодовая точка), а не просто (ключ), дает длинные отрезки идентичных чисел, которые можно кодировать по длине прогона. Однако диапазон кодовых точек очень велик (черт побери, те 0xBC .. 0xBE), что может быть проблемой. Поэтому вместо (key - codepoint) мы кодируем (key - sum_of_digits (codepoint)), что, к сожалению, ограничивает длину растяжения до 10, но весьма неплохо при сокращении диапазона кодированных значений. (Конечно, возможны и другие функции, такие как кодовая точка% постоянная, но сумма цифр дает наилучшие результаты).

Кроме того, оказывается, что поворот списка на 2 хорошо сочетается с кодированием по длине прогона, поэтому перед индексацией мы вычитаем 2 из кодовой точки.

•Ω‘~Èr–Õî5®Î¼ÓÂ∍_OûR•42в    # compressed list [25, 34, 27, 36, 30, 38, 29, 35, 41, 0, 28, 16, 19, 31, 7, 4, 11, 17, 22, 13, 16, 17, 20, 8, 19, 4, 18, 21]
•мjāl†£•                    # compressed integer 79980000101007
        ₂°*                 # times 10**26
           S                # split to a list of digits
            >               # add 1 to each
             ÅΓ             # run-length decode, using the first list as elements and the second list as lengths

Σ                           # sort by
 Ç©1ö                       # sum of digits of the codepoint
           +                # plus
     ...  è                 # the element of the run-length decoded list
        ®Í                  # with index (codepoint - 2) % 70
Grimmy
источник
1

T-SQL, 207 байт

SELECT*FROM t ORDER BY
CHARINDEX(c,N'⅒⅑⅛⅐⅙⅕¼⅓⅜⅖½⅗⅝⅔¾⅘⅚⅞⅟ⅠⅰⅡⅱⅢⅲⅣⅳⅤⅴⅥ
              ⅵↅⅦⅶⅧⅷⅨⅸⅩⅹ↊Ⅺⅺ↋ⅫⅻⅬⅼↆⅭⅽↃↄⅮⅾⅯⅿↀↁↂↇↈ'COLLATE Thai_BIN)

Возврат в середине строки предназначен только для удобства чтения. Я думаю, что я правильно подсчитал число байтов (3 из числовых символов - 1 байт, остальные - 2 байта), количество символов - 148.

Я предварительно отсортировал строку в порядке возрастания, опуская (который возвращает 0), как подсказывают другие ответы.

Я использую любое двоичное сопоставление, Thai_BINтак как оно имеет самое короткое имя. (Сортировка в SQL предписывает, как выполняется сортировка / сравнение символов, мне нужен двоичный файл, чтобы каждый символ соответствовал самому себе.)

В соответствии с нашими стандартами ввода / вывода ввод осуществляется через существующую таблицу t с NCHAR(1)полем c .

Если вы сами определяете входную таблицу, используя двоичное сопоставление, вы можете оставить это, чтобы сохранить 16 байтов:

CREATE TABLE t(c NCHAR(1) COLLATE Thai_BIN)
BradC
источник
Какие символы будут соответствовать друг другу, если вы не используете двоичное сопоставление?
Нил
1
@Neil Ну, на самом деле , зависит от того, какой другой порядок сортировки вы используете! :). Самым очевидным, что я заметил (используя мой сервер по умолчанию SQL_Latin1_General_SP1_CI_AS), было то, что прописные и строчные римские цифры соответствуют друг другу. Который .... хм ... может на самом деле работать на меня здесь, так как они разрешают до того же числа. Но если название сопоставления намного длиннее, это противодействует экономии. БРБ, нужно еще немного проверить ...
BradC
1
@ Нил Нет, ничего хорошего. При использовании недвоичных сопоставлений 10 из менее распространенных символов ( ⅐⅑⅒Ↄↄↅↆↇↈ↉↊↋если вам интересно) все совпадают друг с другом.
BradC
Ах, это позор, но спасибо, что сообщили мне знать!
Нил
1

Рубин , 77 байт

Изменяет все символы на буквы, представляющие числовые значения и сортировки по ним.

->a{a.sort_by{|e|e.tr'¼-¾⅐-↋','HLPECBIOGKMQFRDJNSaa-pa-ppqrnnfmstAjk'}}

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

Значение чернил
источник
1

Perl 6 , 13 52 байта

*.sort:{%(<Ↄ 99  99  10  11>){$_}//.EVAL}

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

bb94
источник
2
Использование eval не обманывает, но это просто не решает проблему. 52, что на самом деле работает:*.sort:{%(<Ↄ 99 ↄ 99 ↊ 10 ↋ 11>){$_}//.EVAL}
Grimmy