Большинство компьютеров хранят целые числа в двоичном формате, но выводят их в десятичном виде. Однако десятичная дробь - это всего лишь одно представление, нам просто кажется, что это удобно.
Эта задача состоит в том, чтобы написать некоторый код для вывода целочисленного значения в коротком десятичном формате .
Что это?
http://en.wikipedia.org/wiki/Shortlex_order
Shortlex принимает длину последовательности цифр в качестве основного значения значения. Последовательность, начинающаяся с пустой строки, представляющей ноль, является ...
ε,0,1,...,8,9,00,01,...98,99,000,001,...,998,999,0000,...
(Подумайте о столбцах Excel, но используйте только десятичные цифры.)
Напишите программу или функцию, которая принимает целое число и возвращает строку, соответствующую кратко-десятичному представлению этого целого числа, как описано выше.
Тестовые значения:
0 → «» (пустая строка)
1 → «0»
10 → «9»
11 → «00»
42 → «31»
100 → «89»
800 → «689»
1060 → «949»
10270 → «9159»
100501 → "89390"
19, 20, 21, 22
в десятичном08, 09, 10, 11
формате отображается в коротком. Вот почему я так запутался100 -> 89
!Ответы:
JavaScript (ES6) 42
74Тест в консоли FireFox
Выход
Как я об этом подумал?
При фиксированном количестве цифр выходная последовательность просто возрастает, поэтому между входом и выходом существует фиксированная дельта. Взглянуть:
Но ведущими 0 трудно управлять, поэтому у меня есть стандартная хитрость, добавить первую цифру и работать по модулю (то есть вырезать первую цифру в выводе). Затем -1-> +9, -11 -> +89, -111 -> +889 и так далее.
Последний шаг: мне все равно, какая первая цифра, поэтому нет необходимости проверять, является ли число iinput <или> чем 111 ... (честно, я нашел это методом проб и ошибок)
Тестовое задание
источник
n-~(n+'')
а не простоn-~n
?(n+'').replace(...)
, заменить работает на строки, а не числа.Marbelous
177173170Он работает только для значений до 256, поскольку Marbelous - это 8-битный язык.
Как это устроено
Marbelous - это двумерный язык со значениями, представленными 8-битными шариками, которые падают на одну ячейку на каждом тике, если какое-либо устройство не предотвращает их падение. Эта Marbelous программа состоит из 3 досок; давайте начнем с самого простого:
:O
является названием доски (если быть точным, O является именем и: сообщает интерпретируемому, что эта строка является именем. Давая доскам имя, другие доски могут вызывать их}0
как устройство ввода, это можно рассматривать как аргумент этой функции. Эта ячейка будет заменена входным мрамором (значением) при вызове функции.+Z
добавляет 35 к любому мрамору, который проходит над ним и позволяет ему проваливаться.+C
делает то же самое, но только добавляет 12.{0
является выходной ячейкой Когда шарик достигнет этой ячейки, функция выйдет и вернет значение в этом устройстве вывода.Итак, все вместе, эта доска принимает одно значение, а затем добавляет 47 к нему. Для нас это означает, что он превращает любое однозначное число в ascii-код цифры -1 (это, конечно, также будет работать для 10).
Эта доска выглядит немного сложнее. Вы должны быть в состоянии идентифицировать
:I
как название платы и заметили некоторые устройства ввода и вывода. Вы заметите, что у нас есть два разных устройства ввода,}0
и}1
. Это означает, что эта функция принимает 2 входа. Вы также заметите, что есть два экземпляра}1
устройства. При вызове функции обе эти ячейки будут содержать одно и то же значение. Устройство}0
ввода находится прямо над\/
устройством, оно действует как мусорная корзина и удаляет любой мрамор, который падает на него немедленно.Давайте посмотрим, что происходит с одним из шариков, вставленных в плату
}1
устройствами ввода:Он упадет на первый тик и ударит
=9
устройство. Это сравнивает значение мрамора с 9 и позволяет мрамору провалиться, если утверждение выполнено=9
до конца. Мрамор толкается вправо, если нет.&0
и&1
синхронизаторы. Они держатся за шарики, которые падают на них, пока все другие&n
синхронизаторы также не будут заполнены. Как вы можете ожидать, это условно вызовет другое поведение на некоторой другой части доски.Если я скажу вам, что
++
это инкрементор, вы уже должны быть в состоянии сказать, чем будут заполнены различные синхронизаторы. Слева&1
будет входное значение}1
+ 1,&0
рядом с ним будет 0 (00
это языковой литерал, представленный в шестнадцатеричном формате). Второй&1
будет содержать значение 1, а правое&0
заполнено значениемF7
, которое вычитает 9 из значения, поскольку сложение в Marbelous равно по модулю 256.//
является дефлектором, который толкает любой мрамор влево, а не дает ему упасть.Соединение всего этого дает вам следующее: если мрамор
}1
равен 9,&0
синхронизаторы заполняются. Это приведет к тому, что значение 0 попадет на{0
выход иF7
(или -9) на{1
выход. Если}1
не 9,{0
будет заполнено}1
+ 1 и{0
будет содержать 1. Существует также{>
устройство, это специальный вывод, который выводит мрамор рядом с доской вместо нее. Это будет заполнено,}1
если оно будет равно 9.Хорошо, теперь для большого. Эта доска не имеет явного имени, так как это основная доска файла. Его неявное имя
Mb
. Вы должны быть в состоянии распознать некоторые клетки. Есть устройство ввода, некоторые языковые литералы (00
аFF
). Есть несколько синхронизаторов и есть дефлектор. давайте пройдемся по этой части за частью.Таким образом, входное значение (вход командной строки, поскольку это основная плата) начинается со второй ячейки сверху, где
}0
находится. Он упадет и достигнет>0
устройства, которое является другим устройством сравнения. любой мрамор больше 0 проваливается, любой другой мрамор сдвигается вправо. (поскольку переменные Marbelous не имеют знака, только ровно 0 будут сдвинуты вправо). Этот мрамор нулевого значения затем попадет в@6
устройство. Это портал, который переносит мрамор на другой соответствующий портал, в данном случае прямо над ним. Затем шарик 0 достигнет&0
синхронизатора и вызовет некоторые вещи в другом месте.Если мрамор не равен 0, он падает, отклоняется вправо от
\\
ударов,--
которые уменьшают его на единицу, а затем падает на/\
клонера. Это устройство берет мрамор и выводит одну его копию справа и одну слева. Левый@0
переместится вверх к другому, где мрамор снова пройдет ту же последовательность. Левый будет взят в другом месте. Это дает нам цикл, который уменьшает ввод командной строки один раз за цикл и запускает некоторое поведение в каждом цикле, пока не достигнет 0. Затем запускается другое поведение.Давайте посмотрим, что происходит с мрамором, вставленным в
@4
каждую петлю.Здесь есть 3 языковых литерала (
FF
), которые сразу попадут в порталы. Эти порталы перенесут их на триII
устройства.II
относится к доске, которую:I
мы определили ниже по файлу. Так как:I
имеет 2 разных устройства ввода, его представление на другой плате должно иметь ширину 2 ячейки. Поскольку у нас есть 6 ячеекII
, мы можем сказать, что у нас есть 3 экземпляра этой функции на доске.Мраморы
FF
(или 256, или -1, если хотите) будут находиться во входных ячейках:I
функции в ожидании, пока не будет достаточно входного мрамора для запуска функции (еще одного). Вот где@4
вступает портал. Копия уменьшенного ввода командной строки падает там в каждом цикле. Это активирует крайнюю левую:I
доску. Изначально со значениями 256 (или -1) и любым другим значением ввода командной строки было -1. Левый мрамор будет помещен в}0
устройства:I
доски, а правый - в}1
. Если вы вспомните, что сделала эта доска, вы сможете сказать, к чему это привело. Он выведет увеличенную версию правого входа на левом выходе (и он превратит 9 в 0, а не 10) и выведет 1 или -9 справа.Увеличенное значение будет перенесено порталом обратно в правую входную ячейку, а значение справа попадет в синхронизатор. Если синхронизатор уже держит мрамор, два мрамора столкнутся. Столкнувшиеся шарики складываются по модулю 256. Таким образом, значения в синхронизаторах сделают следующее: они начинаются пустыми, а затем превращаются в 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, а затем в 1 снова (так как 247 добавляется по модулю 256).
Вы также можете помнить, что шарик выводится вправо, когда входное значение возвращается к 0. Так как
:I
доски находятся рядом друг с другом, эта команда сработает однажды вправо. Это заполнит три синхронизатора значениями, которые на одно больше, чем они должны быть, чтобы быть кратким представлением ввода командной строки, к тому времени, когда это зацикливается до 0.Вы также можете помнить, что
:O
функция превращает значение в значение ascii цифры, которая представляет значение -1. Выход этихOO
ячеек будет падать с платы, которая печатает их соответствующие символы ascii в STDOUT.Так что же происходит, когда мрамор ввода командной строки достигает 0 и заполняет эти
&0
синхронизаторы? ну, несколько шариков со значением 0 падают и запускают три синхронизатора, которые содержат цифры (+ 1) номера короткого номера в нижней части платы.&3
сначала срабатывает, так как содержит самую значимую цифру, затем&2
следует&1
. Этот мрамор затем телепортируется на другое@5
устройство, прежде чем в конечном итоге попасть в!!
ячейку, которая завершает доску.источник
CJam,
1411 байтовПопробуйте онлайн.
Как это устроено
Этот подход в значительной степени основан на ответе edc65 (с его явного разрешения ):
Пример запуска
источник
Питон 2 (38)
(43)Нет замены символов, только арифметика.
Ungolfed:
У меня нет веской причины, почему рекурсия работает, я просто подгоняю этот шаблон к списку значений. Если вы измените каждый
n-1
наn
, вы получите обычное представление цифр.Для игры в гольф я использую
~-n
вычисленияn-1
с более высоким приоритетом, чем/10
или%10
, экономя на паренсе. Этоn*'_'
просто для создания пустой строки, когдаn=0
и любая другая строка в противном случае. Для'_'
этой цели может быть любая строка.источник
Рубин,
7068666457 байтОпределяет функцию для вызова как
f[42]
. Вот грубая разбивка алгоритма:0
отдельно.Кредиты на идею использования форматной строки идут в Falko!
В качестве альтернативы, используя подход edc65:
Это 45 байтов, и я только включаю его, потому что я не бью его этим. ;)
источник
Haskell, 67 байт
это решение в основном добавляет 1 заданное количество раз в кратком обозначении.
использование:
источник
CJam, 16 байтов
Попробуйте онлайн. Требуется не менее O (n) времени и памяти, поэтому оставьте 100501 офлайновому переводчику ...
Как это устроено
Основная идея, лежащая в основе этого подхода, состоит в том, чтобы вычислить по меньшей мере N коротких десятичных знаков в их естественном порядке и отбросить все, кроме N-го. Не очень эффективно, но коротко.
Пример запуска
источник
Bash + coreutils, 27 байт
Порт умного ответа @ edc65 , с улучшениями @ Денниса :
Выход:
Предыдущий ответ:
Bash + coreutils,
7154 байтаВот немного другой способ сделать это:
jot
выводит растущие шестнадцатеричные числаtr
преобразует это в (0,1, ..., 8,9, b, ... f, 0a, 00,01, ..., 99,9b, ..., ff, 0aa, ..., 000 , ...)grep
просто фильтрует все строки, содержащие цифры, чтобы дать (0,1, ..., 8,9,00, ..., 99,000 ....)sed
удаляет все кроме n-й строкиsed
подсчитывает номера строк, начинающиеся с 1, поэтому ошибки, если передается 0)grep
, нам нужно сгенерировать больше целых чисел с основанием 11 сseq
/,dc
чем входное число. Повторение цифр n более чем достаточно.Обратите внимание, что после того, как номер короткого номера напечатан, он
seq
продолжает генерировать числа до$1$1
, что замедляется, особенно для больших входных чисел - O (n²), я думаю. Мы можем ускорить процесс, выполнив выходseq
сразу же после печати, по цене 7 байт:В этом вопросе нет требования к скорости, поэтому в качестве основного ответа я выберу более короткую версию.
источник
s='jot -w%x $1$1|tr 0-9a a0-9|grep -P ^\\d+$|sed $1!d 2>-'; echo ${#s}
. Я подозреваю, что вы можете использовать python для измерения длины строки, которая обрабатывает «\\» как один символ.$a
кажется ненужной;cut -b2-<<<$[$1-~${1//?/8}]
должно работать просто отлично.Питон 2 -
84, 7066Альтернативный подход (такой же длины):
источник
Python 3, 107 символов
Это не закончилось победой, но я подумал, что это было умно:
Я определяю генератор для всей последовательности в 64 символов. К сожалению, я должен пройти через некоторые искажения, чтобы получить n-й элемент генератора ... если бы я только мог это сделать
S=lambda n:G()[n]
.источник
Пиф , 12
Еще один порт ответа @ edc65, который является явным победителем (IMO):
Тестовый пакет (благодаря @DigitalTrauama):
Объяснение:
источник
[8, 8, 9] -> 889
). Как ты это делаешь?jk
превратит ваш список в строку, иv
превратит это в int. Такvjk[8 8 9]
что дадим номер 889.[2 -1] -> 19
и[1 11] -> 21
.Java 8, 60 байт
Порт из @ edc65 удивительный ответ JavaScript (ES6) , так как я сомневаюсь, что это может быть сделано короче арифметическим способом в Java.
Попробуй это здесь.
источник
Haskell , 57 байт
Попробуйте онлайн!
Создает бесконечный список коротких номеров и индексов в нем для ответа.
g n
создает n-е «поколение» чисел, добавляя следующую цифру перед каждым из чисел в предыдущем поколении.источник
05AB1E , 7 байтов
Использует замену edc65 на 8 трюков
Попробуйте онлайн!
объяснение
источник
Excel, 37 байт
Используя подход @ edc65:
источник
Желе , 5 байт
Попробуйте онлайн!
Я очень новичок в желе, поэтому, если вы можете улучшить это, пожалуйста, прокомментируйте!
Объяснение:
(Согласно комментарию res выше, проблема эквивалентна преобразованию числа в биективное основание 10)
источник