Книга Рэндалла Манро «xkcd, том 0» использует довольно странную систему счисления для номеров страниц. Первые несколько номеров страниц
1, 2, 10, 11, 12, 20, 100, 101, 102, 110, 111, 112, 120, 200, 1000, 1001, ...
Это выглядит как троичный, но обратите внимание, что он прыгает с 20
прямой к 100
, от 120
к 200
и от 200
к 1000
. Один из способов определения этой последовательности состоит в том, чтобы сказать, что она перечисляет все троичные числа, которые содержат не более одного 2
и не 1
после этого 2
. Вы можете найти это на OEIS в записи A169683 . Эта система счисления называется асимметричной двоичной системой .
Ваша задача - найти представление заданного натурального числа N
в этой системе счисления.
Вы можете написать программу или функцию, принимая ввод через STDIN (или ближайшую альтернативу), аргумент командной строки или аргумент функции и выводя результат через STDOUT (или ближайшую альтернативу), возвращаемое значение функции или параметр функции (out).
Выходные данные могут быть строкой, числом с десятичным представлением, равным асимметричному двоичному представлению, или списком цифр (в виде целых чисел или символов / строк). Вы не должны возвращать ведущие нули.
Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.
Интересный факт: в этой системе счисления есть некоторые достоинства. Увеличивая число, вы всегда будете менять не более двух соседних цифр - вам никогда не придется переносить изменение по всему номеру. С правильным представлением, которое позволяет увеличивать в O (1).
Тестовые случаи
1 => 1
2 => 2
3 => 10
6 => 20
7 => 100
50 => 11011
100 => 110020
200 => 1100110
1000 => 111110120
10000 => 1001110001012
100000 => 1100001101010020
1000000 => 1111010000100100100
1048576 => 10000000000000000001
1000000000000000000 => 11011110000010110110101100111010011101100100000000000001102
Я дам вознаграждение за самый короткий ответ, который может решить последний контрольный пример (и любой другой ввод аналогичной величины, поэтому не думайте о его жестком кодировании) менее чем за секунду.
Leaderboards
Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.
Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:
# Language Name, N bytes
где N
размер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:
# Ruby, <s>104</s> <s>101</s> 96 bytes
<script>site = 'meta.codegolf'; postID = 5314; isAnswer = true; QUESTION_ID = 51517</script><script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)</code></pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>
источник
59->60
и109->110
с дополнительными 0.Ответы:
Pyth, 17 байт
Это несколько смехотворно медленно
O(output^log_2(3))
. Это экспоненциально по длине ввода, но не по экспоненте вдвойне, как некоторые ответы на странице. Некоторые идеи взяты из ответа @ Dennis, здесь .Демонстрация.
Он использует
.f
функцию Pyth «цикл, пока не найдено n совпадений».источник
CJam,
2423222119 байтовЭто подход O (log n) , где n - вход, который мгновенно завершает последний тест. Он преобразует n непосредственно в двоичный файл с перекосом, используя модульное деление на значения цифры 1 .
Этот код заканчивается ошибкой, которая переходит к STDERR с интерпретатором Java, что разрешено в соответствии с консенсусом по Meta .
Если вы попробуете этот код в интерпретаторе CJam , просто проигнорируйте все, кроме последней строки вывода.
Ошибка может быть устранена за счет 2 байтов, добавив
2>
кW%
.Спасибо @ MartinBüttner за отыгрывание одного байта.
Фон
Косое двоичное представление a k ... a 0 соответствует целому числу n = (2 k + 1 -1) a k + ... + (2 1 -1) a 0 .
Поскольку оба (2 k -1) + ... + (2 1 -1) = 2 k + 1 - (k + 2) и (2 k -1) + ... + 2 (2 j -1) = 2 к + 1 - (2 J + 1 - 2 J + к + 1) меньше , чем 2 к + 1 -1 , значения в к к в 0 могут быть восстановлены путем последовательного модульного деления на 2 K + 1 -1 , 2 к -1 и др.
Для начала нам нужно сначала найти значение 2 k + 1 -1 . Поскольку n не больше 2 (2 k + 1 -1) , целое число n + 1 должно быть строго меньше, чем 2 k + 2 .
Таким образом, если взять целую часть двоичного логарифма n + 1, то получится k + 1 .
Наконец, мы видим, что целое число n + 1 имеет ⌊log 2 (n + 1) ⌋ цифр в базе 2.
Как это устроено
В двух последних итерациях мы выполняем модульное деление на 1 и 0 . Первый помещает нежелательный 0 в стек. Последняя попытка выполнения
0 0 md
, которая извлекает из стека оба нежелательных 0 с, немедленно завершается, вместо того, чтобы что-либо выдвигать, и сбрасывает стек в STDOUT.источник
Python 2, 67 байт
Кажется, работает для данных тестов. Если я правильно понял, это должно быть примерно
O(place values set in output)
так, так что он легко делает последний случай.Звоните как
f(100)
. Возвращает десятичное представление, равное косому двоичному файлу.Python 3, 65 байт
Чуть менее эффективный, но все же логарифмический, поэтому последний случай почти мгновенный.
Звоните как
g(100)
. Возвращает список цифр.источник
2and
скомпилировать в 3? Я в 2 и2and2
выдает синтаксическую ошибку2and2
не будет работать, потому что он будет проанализирован как2 and2
- try2and 2
, который должен работать, если ваша версия Python достаточно новая (протестирована в Python 2.7.10)CJam,
222120 байтЭто подход O (e n n) , где n - вход. Он перечисляет первые ⌊e n ⌋ неотрицательные целые числа в базе 3, удаляет те, которые имеют 2 с или 1 с после первых 2 (если есть), и выбирает n + 1- е число .
Попробуйте онлайн в интерпретаторе CJam .
Как это устроено
источник
Pyth, 20 байт
Запускается в O (log (input ())), что значительно меньше секунды для окончательного теста. Основано на прогоне до ошибки цикла. Нет завершающего перевода строки.
Демонстрация.
Объяснение:
J инициализируется значением самой маленькой двоичной позиции двоичного разряда, которая больше, чем вход. Затем каждый раз в цикле мы делаем следующее:
J
изQ
с=%QJ
. Например, еслиQ=10
иJ=7
,Q
становится3
, что соответствует перекосу двоичного файла, изменяющемуся от110
на10
. Это не влияет на первую итерацию.J
к следующему меньшему косому двоичному базовому значению с помощью=/J2
. Это сражен деление на 2, изменениеJ=7
кJ=3
, например. Поскольку это происходит до того, как выводится первая цифра,J
инициализируется на одну цифру выше необходимой./QJ
(эффективно).p
вместо печати по умолчанию в Pyth, чтобы избежать запятой новой строки.Этот цикл будет повторяться до тех пор, пока не
J
станет равным нулю, после чего будет сгенерирована ошибка деления на ноль, и цикл закончится.источник
ES6, 105 байт
Использование:
f(1048576)
=> `" 10000000000000000001 "Проверьте последний аргумент на свой страх и риск. Я сдался через 5 секунд.
И красивая печать с комментариями!
источник
f=
.f=n=>{for(o=0;~n--;o+=c?Math.pow(3,s.length+c):1)s=o.toString(3),c=~s.search(2);return s}
Math.pow(3,s.length+c)
на3**(s.length+c)
.Сетчатка, 55 байт
Принимает участие в одинарных.
Каждая строка должна идти в свой собственный файл, но вы можете запустить код как один файл с
-s
флагом. Например:Метод: Выполнение приращения для строки, введенной число раз, начиная со строки
0
.Мы используем следующие правила приращения:
2
:^2 -> ^12
;02 -> 12
;12 -> 20
2
:0$ -> 1$
;1$ -> 2$
(Там может быть более одной
2
в строке,^
и$
отмечает начало и конец строки в правилах) .Больше информации о Retina.
источник
Ява,
154148Этот ответ принимает форму одной анонимной функции, которая принимает целочисленный аргумент и возвращает ответ в виде строки. Ниже приведен полный класс для тестирования этого решения.
источник
Баш + кореутилс, 52
Это грубое насилие, поэтому оно довольно медленно для больших чисел.
Выход:
источник
Java
337335253246244 байтаМетод, который принимает индекс как a
long
и возвращает результат в виде строкиИспользует
long
для индекса , так может теоретически обработать последний тестовый случай, но я действительно не хотел бы предложить это.источник
if(j == 0)
утверждении (четыре байта). Вам не нужно заявлятьk
; Вы можете просто использоватьj
снова (еще четыре). Вы можете использовать вывод обобщенного типа (в Java 7) в своем объявлении List (new ArrayList<>();
) (еще 4)Хаскелл,
7372Спасибо @nimi за 1 байт!
Это решение не выиграет ни одной награды, последние пару тестов занимают слишком много времени, но, думаю, я играл в нее неплохо.
Это решение - довольно наивный подход, который вычисляет асимметричное двоичное число
n
, увеличивая его в 0n
раз.источник
CJam, 24 байта
Это подход O (n log n) , где n - вход. Он начинается с асимметричного двоичного представления, равного 0, и увеличивает соответствующее целое число n раз.
Попробуйте онлайн в интерпретаторе CJam .
Фон
Увеличение числа в асимметричном двоичном коде можно выполнить, выполнив два простых шага:
Заменить возможное 2 на 0 .
Если 2 был заменен, увеличьте число слева.
В противном случае увеличьте последнюю цифру.
Как это устроено
источник
VBA,
209147142 байтаМоя математика неэффективна, и мой гольф может использовать работу. Но это моя первая попытка в PoG, и я решил попробовать. Что-то вроде грубой силы.
Он просто считает на 1, если последняя цифра не равна 2, затем отступает на 2 и прыгает вперед на 10. Плюс тянущиеся 0.
Это перестает работать на 65534, потому что VBA настаивает на выдаче вывода в научной нотации, но логика должна работать нормально для еще больших чисел
С нетерпением жду предложений по игре в гольф, VBA не очень дружелюбен к гольфу, но он не так часто представлен, и я думаю, что он может превзойти Java по длине.
Edit1: спасибо Ману за помощь сбрить 62 байта
Edit2: поменялся местами
debug.print
вmsgbox
качестве вывода. Сохранено 5 байтисточник
Debug.Print (q)
. Кроме того, вы можете удалить большую часть пробелов (редактор вернет их обратно, но они не нужны). Вам не нужно заявлятьk as Long
, просто написатьk
. Это будет переменная типа Variant, и код все равно будет работать. С этими советами вы должны получить ~ 165 байтов.InStr
, они не являются обязательными.Trim()
не нужно, так как у вас нет пробелов. При правильном применении я получаю 147 байтов .debug.print q
будет стандартный вывод?msgbox q
короче, но опять-таки кажется, что это не совсем стандартный вывод.Sheet1.cells(1,1)
похоже на типичный вывод, но предполагает его работу в Excel. Я просто не совсем уверен в том, насколько строгий код-гольф в подобных вещах.MsgBox
, если кто-то жалуется, вы все равно можете изменить его обратно.Javascript ES6,
9986787672 символовКонтрольная работа:
Спасибо за факт - это основа моего решения :)
источник
Октава,
107101 байтДолжно быть O (log n), если я это правильно понимаю ...
Довольно-печати:
Я был несколько озадачен решением последней задачи, поскольку Octave по умолчанию рассматривает все как числа с плавающей запятой, и у меня не было необходимой точности для вычисления последней. Я справился с этим, потратив драгоценные байты, чтобы все было беззнаковым целым числом. Результат последнего был слишком большим, чтобы его можно было рассматривать как число, поэтому результатом является строка.
Вывод (я хочу
1e18 - 1
показать, что могу сделать это точно, а последний набор выводов показывает, сколько времени потребуется для вычисления этого значения):источник
T-SQL,
221189177 байтРЕДАКТИРОВАТЬ: Исходные версии этого кода будет производить неправильный вывод для некоторых чисел, это было исправлено.
При каждом запросе здесь просто добавьте число для вычисления перед первой запятой.
Все знают, что T-SQL - лучший язык для игры в гольф. Вот версия, которая будет рассчитывать даже последний контрольный пример. На машине, на которой я ее тестировал, она работала менее чем за секунду, мне было бы интересно посмотреть, как она работает для всех остальных.
И вот оно снова, но читабельно:
Если я использую только целые числа, это может быть немного короче: 157 байтов:
И еще раз, более читабельным:
источник
@
, это действительный идентификатор в SQL, и вы, скорее всего, можете сойти с него,Char(8000)
который по-прежнему дешевле, чем nvarchar (max). Вы также можете преобразоватьchar
вместоvarchar
или использоватьstr
функцию.@
, глупая я.CHAR(8000)
Совет довольно хорошо, я попробую это. Кажется, я всегда забываю оSTR()
благодарности за помощь.select @t=concat(@t,@/i)
которая должна быть меньше. Требуется sql2012, хотя.CONCAT
Я нахожусь на 2008. Поэтому я не могу проверить это без использования скрипта SQL прямо сейчас. Хороший звонок, хотя.Код машины Тьюринга,
333293 байтаЯ использую кодировку, как здесь .
Эта машина использует 9 состояний и 11 цветов.
Если двоичный ввод допустим, он может быть уменьшен до 4 цветов, что позволяет сэкономить несколько десятков байтов.
Если приведенная выше ссылка не работает (иногда она работает для меня, в других случаях страница не загружается), вы также можете проверить это с помощью этой реализации Java.
источник
Perl, 66 байт
Номер должен быть введен через STDIN.
источник
(.?)
в$2
так(.*)
в$1
должен быть жадным и получить этот символ первой. Но если он будет удален, код больше не даст правильных результатов! Кстати, тебе не нужен финал;
.$c=<>;s/(.*)2(.*)/$1+1 .$2.0/e||$_++while($c--);print
. Я был прав,(.?)
никогда ничего не захватывал.$_=1;$c=<>;s/(.?)2/1+$1.0/e||$_++while(--$c);print
50 байтов..*
в начале или в конце можно оптимизировать, если вы просто замените его исходным текстом. Также нет смысла добавлять 0 в конце, так как в оригинале всегда есть только нули$3
.Pyth, 19 байт
Логарифмическая сложность. Легко заканчивается в необходимое количество времени. Вывод в виде списка цифр.
Демонстрация .
источник
Perl,
847067 байтНе очень гольф, становитсялучше, но работает очень быстро!Предложение Денниса снижает его до 51 (50 байт + ключ -p)
Он должен вызываться так, как
perl -p skew_binary.pl num_list.txt
если бы онnum_list.txt
содержал одну строку с номером для кодирования на нем.источник
Математика, 65
Должно быть достаточно быстро, хотя я должен признать, что заглянул в другие материалы, прежде чем сделать это.
Использование:
Выход:
Начинает выдавать сообщения об ошибках MaxExtraPrecision где-то после 10 ^ 228 (для которых он вычисляет результат в 0,03 секунды на моем компьютере)
После снятия ограничения MaxExtraPrecision он будет обрабатывать числа примерно до 10 ^ 8000 в секунду.
Входные данные:
Выход:
источник
C, 95 байтов
Это принимает целое число и буфер для возврата цифр. Результаты сохраняются в
b
конце и заканчиваются значением3
(которое не может появиться в выходных данных). Нам не нужно обрабатывать ввод0
(поскольку в вопросе указаны только положительные целые числа), поэтому нет специального регистра, чтобы избежать пустого вывода.Расширенный код
Мы работаем путем последовательного вычитания, начиная с самой значимой цифры. Единственная сложность заключается в том, что мы используем переменную,
m
чтобы избежать печати начальных нулей. Приunsigned long long
желании может быть сделано естественное расширение стоимостью 10 байтов.Тестовая программа
Передайте числа для преобразования в качестве аргументов команды. Он преобразует
int
буфер массива в печатную строку цифр. Время выполнения составляет менее одной миллисекунды для ввода1000000000000000000
.Результаты теста
источник
auto a=~0ull
для небольшого преимущества ...JavaScript (Node.js) , 40 байт
Попробуйте онлайн!
Это решение не работает в последнем тестовом примере. Это просто вызывает переполнение стека на нем.
источник
CoffeeScript,
9269 байтОсновываясь на ответе и обновлениях Qwertiy :
источник
Japt , 31 байт
Попробуйте онлайн!
Почти прямой порт этого решения JS . Не знаю, есть ли лучший способ.
Распаковано и как это работает
источник
Stax , 16 байт
Запустите и отладьте его
Я точно не знаю, что такое формальный класс сложности, но он достаточно быстрый, чтобы выполнить все тестовые примеры за одну десятую секунды на этом компьютере.
Распакованный, размазанный и прокомментированный, это выглядит так. В этой программе регистр x изначально содержит входные данные.
Запустите этот
источник