Алфавитное целое

19

Алфавитное целое

Для данного набора чисел поместите их в алфавитном порядке, когда они прописаны (то есть 1: один, 2: два, 90: девяносто, 19: девятнадцать). Ваш код должен работать для диапазона [-999999, 999999]. Вывод должен иметь разделитель между числами. Будет работать пробел, а также пробел и запятая, как показано в примерах ниже. Входные данные могут быть массивом целых чисел, строкой чисел с разделителями или любым другим способом. Все целые числа предполагаются уникальными.

Числа не ставятся через дефис для целей этой задачи, а пробелы располагаются в алфавитном порядке перед любыми другими символами. Предполагается, что отрицательные числа выражаются с помощью слова minus. Например, fourбудет предшествовать four thousandи номер -40будет отсортирован с использованием строки minus forty. Предположим, что все числа будут состоять только из числовых слов и без союзов (например, использовать two thousand forty twoвместо two thousand and forty two).


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

Однозначные целые числа:

Входные данные:

1, 2, 3, 4, 5

Выход:

5, 4, 1, 3, 2

Многозначные целые числа:

Входные данные:

-1002, 5, 435012, 4, 23, 81, 82

Выход:

81, 82, 5, 4, 435012, -1002, 23

Пробелы между словами, без дефисов, запятых или «и»:

Входные данные:

6, 16, 60, 64, 600, 6000, 60000, 60004, 60008, 60204, 60804

Выход:

6, 600, 6000, 16, 60, 64, 60000, 60008, 60804, 60004, 60204

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

wubs
источник
Вот ссылка на соответствующий пост песочницы.
wubs
Будет ли вход когда-либо содержать более одного целого числа?
ETHproductions
@ETHproductions Нет, не будет. Я уточню это в вопросе.
wubs
8
Добро пожаловать в PPCG. Хороший аватар. : D Хороший первый вопрос.
AdmBorkBork
@TimmyD Спасибо! Я с нетерпением жду PowerShell - все, что я могу здесь.
wubs

Ответы:

5

JavaScript (ES6), 189 179 186 байт

let f =

a=>a.sort((x,y)=>!x-!y||(X=q(x),Y=q(y),X>Y)-(X<Y),q=n=>n<0?"L"+q(-n):n>999?q(n/1e3)+"Z"+q(n%1e3):n>99?q(n/100)+"K"+q(n%100):n>19?"  cYHFVSCO"[n/10|0]+q(n%10):"0PdaIGTQAMWDbXJEURBN"[n|0])

let g = a => console.log(`[${f(a)}]`)

g([1,2,3,4,5])
g([-1002,5,435012,4,23,81,82])
g([0,1000,1100])
<input id=I value="1 2 3 4 5"><button onclick="g(I.value.match(/\d+/g)||[])">Run</button>

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

Это создает очень краткий способ отображения каждого числа в его лексографически правильное положение. Вот что делает рекурсивная qфункция:

q(-X)        => "L" + q(X)
q(XYYY)      => q(X) + "Z" + q(YYY)
q(XYY)       => q(X) + "K" + q(YY)
q(XY >= 20)` => "  cYHFVSCO"[X] + q(Y)
q(X)         => "0PdaIGTQAMWDbXJEURBN"[X]

В 0начале строки необходимо убедиться, что, например, 100 ( one hundredпреобразовано в PK0) отсортировано до 101( one hundred oneпреобразовано в PKP). Это создает странный сценарий, в котором 0 ( zero) сортируется в начало массива, поэтому, чтобы обойти это, в функции сортировки мы сначала сортируем любые нули справа !x-!y||(....

ETHproductions
источник
Похоже, это не работает для [1100, 1000]. Я ожидал бы, что выходные данные будут 1000 (one thousand), 1100 (one thousand one hundred), но выходные данные будут в том же порядке, что и входные.
молоко
@milk Хм ... Я не уверен, почему это происходит, но я посмотрю на это.
ETHproductions
@milk Ах, 1000анализируется как one thousand zero; Я исправлю это на мгновение. Должны ли мы поддерживать 0самостоятельно, хотя? Это уникальный случай, который добавит примерно 15 байтов в мой код.
ETHproductions
11

Информ 7, 214 201 118 байт

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

Отступ должен использовать вкладку (\t символы ), но HTML не нравится. И наоборот, Inform не любит пробелы для отступов, поэтому вам придется заменить пробелы на вкладки, если вы скопируете и вставите код отсюда, чтобы протестировать его. Или просто скопируйте и вставьте из источника Markdown.

Golfed:

К Х:
    повторите через таблицу 1:
        теперь Q запись - «[R запись в словах]»;
    сортировать таблицу 1 в порядке Q;
    сказать «[R в таблице 1]».

Входные данные должны быть таблицей Inform, например, ( \tмежду столбцами):

Таблица 1
R (число) Q (текст)
-1002
5
435012
4
23
81
82

Выход:

81, 82, 5, 4, 435012, -1002, 23

Эта функция запускает таблицу один раз, добавляя текстовое представление каждого числа в новом столбце. Затем он сортирует строки таблицы по текстовому столбцу; в Inform строки сортируются лексикографически. Наконец, он печатает исходный столбец в новом порядке. Удобно, что формат Inform 7 «сырой, но иногда полезный» для распечатки столбцов таблицы оказывается разделенным запятыми, именно так, как требуется.

Ungolfed, с шаблоном, показывающим, как вызвать функцию:

Чтобы напечатать числа в алфавитном порядке:
    повторите через таблицу сортируемых чисел:
        теперь имя записи «[индексная запись в словах]»;
    сортировать таблицу сортируемых чисел в порядке имен;
    скажем "[столбец индекса в таблице сортируемых чисел]".

Таблица сортируемых чисел
индекс (число) имя (текст)
-1002
5
435012
4
23
81
82

Есть комната.
Когда начинается игра: напечатайте номера в алфавитном порядке.
Draconis
источник
1
Я немного смущен этим. Есть wordsли ссылка на прописанные версии чисел, встроенные в Inform 7?
Павел
1
@Pavel Действительно! «(число) в словах» возвращает строку с текстовым представлением числа. Он удобно использует «минус» для отрицательных чисел, и хотя он ставит дефисы между словами, он делает это последовательно и алфавитно расставляет дефисы перед всеми буквами (поэтому конечный результат один и тот же).
Драконис
2
+1 за выбор языка. Я должен был бы проверить, но я подозреваю, что есть некоторые возможности игры в гольф; например, действительно ли парсер требует всех этих "the" статей? И вам нужно было бы спросить OP, но я не вижу никакой очевидной причины, почему «и» не будет действительным разделителем. Даже если нет, один пробел явно разрешен, так что просто say "[R entry] "должно хватить.
Ильмари Каронен
Я бы сказал «и» в конце все в порядке. Я не говорил, что разделители должны быть единообразными, так что это вполне приемлемый ответ. Если бы я мог дать очки за самый интересный ответ, я бы дал его вам. Мне очень нравится читаемость этого языка, даже в гольф. Хорошая работа!
wubs
Наконец-то у меня появилась возможность немного поиграть с Inform7, и мне удалось перенаправить ваш вход до 118 байтов. Так как размещение кода Inform в комментариях работает не очень хорошо, я пошел дальше и отредактировал его в своем ответе напрямую. Я надеюсь, что вы не возражаете, не стесняйтесь отменить и / или настроить мои изменения так, как вам нравится.
Илмари Каронен
4

Mathematica, 67 байт

SortBy[#,#~IntegerName~"Words"~StringReplace~{","->"","-"->""}&]&

Безымянная функция, принимающая список целых чисел в качестве аргумента и возвращающая список целых чисел в качестве значения. #~IntegerName~"Words"является встроенным, который меняет целое число на его имя на английском языке. IntegerNameиногда на выходе выводятся запятые и дефисы, поэтому StringReplaceвызов избавляется от них. (К сожалению, дефис на самом деле является 3-байтовым символом, 8208, в UTF-8.) Затем SortByсортирует исходный список по алфавиту в соответствии со значением измененного целочисленного имени.

Хорошее совпадение: IntegerNameиспользует negativeвместо того, чтобы minusв своем выводе - но никакое слово, появляющееся в именах любого из разрешенных чисел, не находится в алфавитном порядке между этими двумя словами, поэтому замена не требуется!

(Шляпа для ngenisis за напоминание Sortby.)

Грег Мартин
источник
Престижность! Я был очень близок к тому, чтобы получить это решение, но эта черта доставляла мне головную боль!
ngenisis
Ваш ответ здесь действительно использует правильный дефис? Если я скопирую то, что у вас здесь есть, в Mathematica, это не заменит дефисы из IntegerName. В документации Wolfram говорится, что это юникод-символ 2010 года .
ngenisis
Тогда, вероятно, нет - я попытался получить правильный дефис в этом ответе, но, похоже, мне это не удалось.
Грег Мартин
Я разрезал ваш ответ пополам;)
Х. Антонио Перес
А потом некоторые ... вы делаете ненужные изменения в строке.
Х. Антонио Перес
4

Bash + GNU utils + bsdgames, 52

  • 4 байта сохранены благодаря @izabera.
sed 's/.*/echo `echo &|number`:&/e'|sort|sed s/.*://

I / O - строки с разделителями новой строки.

  • Первое выражение sed заменяет каждое числовое число командой оболочки, которая выводит словеснуюnumber форму числа (заданного утилитой bsdgames ), после :чего следует числовая форма числа.
  • Это тогда sortред.
  • Затем второй sedобрезает ведущие символы до и включая :, оставляя числовую форму отсортированной по мере необходимости.

numberправильно обрабатывает «минус», и его вывод достаточно близок к указанному формату, который sortработает как требуется. Он выдает «сорок четыре» вместо «сорок четыре», но это не должно иметь значения с точки зрения сортировки.

Для пакета bsdgames может потребоваться установка:

sudo apt-get install bsdgames

sedИ sortутилиты почти наверняка уже в вашем дистрибутиве.

Цифровая травма
источник
-t:бесполезно, и вы можете использоватьnumber<<<&
izabera
@izabera Да - спасибо - я удалил -t:. Тем не менее, eфункция val в sed выполняет команды с использованием sh, поэтому такие функции bash, как, например <<<, не будут работать.
Цифровая травма
он отлично работает, пока ваш sh bash: P
izabera
@izabera Нет, если bash запущен так, как shон пытается максимально эмулировать Posix sh, это означает, что такие bashisms <<<отключены. GNU sed«s eВэл функция запускает команды с /bin/sh -c ...и /bin/bash -c .... Вы пробовали это?
Цифровая травма
bash никогда не отключается <<<, даже в режиме
posix
1

Python + inflect, 97 91 89 байт

from inflect import*
a={x:engine().number_to_words(x)for x in words}
sorted(a,key=a.get)

Использовал inflectбиблиотеку для преобразования wordsмассива целых чисел в их фонетическое / строковое представление. Хранится в словаре пар k / v, где ключи были числовым представлением, а значения были строковым представлением. Возвращает список ключей, отсортированных по значениям.

РЕДАКТИРОВАТЬ: Сохранено 5 и 3 байта, благодаря ETHproductions и Alex.S!

9814072356
источник
Добро пожаловать в PPCG! Вы можете сыграть в гольф, убрав пробелы ; например, вторая строка может быть a={x:inflect.engine().number_to_words(x)for x in words}.
ETHproductions
Вы можете сохранить два байта, используя from inflect import*и выбрасывая inflect.во второй строке.
Alex.S
Увы, похоже, что это также не в состоянии правильно сортировать список 40, 44, 40000, 40804, 40004, 40204 (который должен оставаться в таком порядке).
Ильмари Каронен
0

Mathematica, 30 байт

Ответ ниже выводит чистую функцию, которая будет принимать список целых чисел в качестве входных данных и сортировать их по алфавитному имени. Только то, что доктор прописал ;)

SortBy[#~IntegerName~"Words"&]

Вот негольфированная версия:

SortBy[IntegerName[#, "Words"]&]

А вот пример использования:

SortBy[#~IntegerName~"Words"&][{0,1,2,3,4,5,6,7,8,9,10}]

Который также может быть записан как

SortBy[#~IntegerName~"Words"&]@{0,1,2,3,4,5,6,7,8,9,10}

Они производят идентичные результаты - в f[x]Mathematica , эквивалентно f@x.

Outputs: {8, 5, 4, 9, 1, 7, 6, 10, 3, 2}

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

MyF = SortBy[#~IntegerName~"Words"&];
TheirF = SortBy[#, #~IntegerName~"Words"~ StringReplace~{"," -> "", "-" -> ""} &] &;
MyF[Range[-999999, 999999]] == TheirF[Range[-999999, 999999]]
(*Outputs True*)
Х. Антонио Перес
источник
Отличное расследование! К сожалению, на самом деле они не дают одинаковый приказ. TheirFправильно сортирует 888 до 880 000, а MyFне. Вероятно, проблема связана с копированием-вставкой странного дефиса: ваша версия, TheirFвероятно, заменяет нормальные дефисы (которых нет), в то время как фактическая версия заменяет странный 3-байтовый дефис Unicode. (Было бы еще интересно посмотреть, нужно ли удалять запятые.)
Грег Мартин
Я проверил это на Range [999999]. Похоже, удаление запятых не нужно, но замена «[Дефис]» на «» определенно необходима.
ngenisis
0

Common Lisp, 113 байт

Внешние библиотеки не нужны.

(print(mapcar #'cdr(sort(loop for i in x collect(cons(format()"~r"i)i))(lambda(y z)(string-lessp(car y)(car z))))))

Выведите, если xесть '(1 2 3 4 5):

(5 4 1 3 2)
Гарри
источник