Двоично-десятичный преобразователь
Насколько я вижу, у нас нет простой задачи преобразования двоичного числа в десятичное.
Напишите программу или функцию, которая принимает положительное двоичное целое число и выводит его десятичное значение.
Вам не разрешено использовать какие-либо встроенные базовые функции преобразования. Целочисленные-десятичные функции (например, функция, которая превращается 101010
в [1, 0, 1, 0, 1, 0]
или "101010"
) освобождены от этого правила и, таким образом, разрешены.
Правила:
- Код должен поддерживать двоичные числа вплоть до наибольшего числового значения, поддерживаемого вашим языком (по умолчанию)
- Вы можете выбрать ведущие нули в двоичном представлении
- Десятичный вывод может не иметь начальных нулей.
- Форматы ввода и вывода являются необязательными, но между цифрами не должно быть разделителей.
(1,0,1,0,1,0,1,0)
не является допустимым форматом ввода, но оба10101010
и(["10101010"])
являются.- Вы должны принять вход в «нормальном» направлении.
1110
это14
не7
.
- Вы должны принять вход в «нормальном» направлении.
Тестовые случаи:
1
1
10
2
101010
42
1101111111010101100101110111001110001000110100110011100000111
2016120520371234567
Эта проблема связана с несколькими другими проблемами, например, это , это и это .
code-golf
base-conversion
binary
Стьюи Гриффин
источник
источник
-1
(32 1's
и64 1's
)round(x)==x
вы в порядке :)2.000
принимается выход для10
.Ответы:
Желе , 5 байт
Попробуйте онлайн!
объяснение
В ролях
D
является монадой (функция с одним аргументом): цифры, превращающиеся1234
в[1, 2, 3, 4]
.Ḥ
это монада, которая удваивает свой единственный аргумент.+
это диада (функция с двумя аргументами), которая добавляет свои левый и правый аргументы.Оттуда становится немного сложно.
Вот что происходит во время разбора
D
,Ḥ
И+
читают. Цепочка выглядит так[D, Ḥ, +]
.Следующие два символа - это quicks , которые действуют как постфиксные операторы времени анализа в ссылках (функциях), которые мы до сих пор читали.
Когда
¥
читается, последние две ссылки выталкиваются и заменяются ссылкой, которая действует как диада, образованная их составлением. Так что теперь цепочка выглядит так[D, dyad(Ḥ+)]
.Когда
/
читается, последняя ссылка (которая должна быть диадой) выталкивается и заменяется монадой, которая сворачивается с помощью этой диады (интуитивно:f/
берет список, заменяет запятые в немf
и оценивает результат.)Конечная цепочка выглядит как
[D, fold(dyad(Ḥ+))]
две монады.Вот что происходит во время выполнения
Ввод (число) неявно считывается в рабочее значение (скажем,
101010
).D
выполняется, заменяя рабочее значение его цифрами ([1,0,1,0,1,0]
).fold(dyad(Ḥ+))
выполняется, заменяя рабочее значение на1∗0∗1∗0∗1∗0
, где∗
диадаḤ+
.Так что же
x∗y
оценивать?В диадическом определении рабочим значением изначально является левый аргумент
x
.Ḥ
, То двойная монада, удваивает это значение. Рабочая ценность сейчас2x
.+
у плюсовой диады отсутствует правильный аргумент, так что это ловушка : особый синтаксический паттерн, в который вводится правильный аргумент этой диады+
. Это дает2x + y
как окончательное рабочее значение, которое возвращается.Таким образом, все выражение оценивается как:
источник
Python 2,
49373130 байтТеперь это займет двоичное число в десятичном представлении, поскольку Python может обрабатывать произвольно большие целые числа.
спасибо xnor за сохранение байта :)
Самый простой способ увидеть, как это работает, это увидеть базовую формулу для преобразования двоичного в десятичное:
Это «стандартный» способ конвертации. Вы можете расширить третью строку следующим образом:
И это по сути то, что делает рекурсивный метод, который я сделал.
Альтернативные решения у меня были:
источник
n%5
илиn%2
вместоn%10
.05AB1E , 6 байтов
Код:
Для объяснения возьмем пример 101010 . Начнем с цифры 1 (которая представлена первой цифрой). После этого у нас есть два случая:
Таким образом, для случая 101010 рассчитывается следующее:
Объяснение кода:
Использует кодировку CP-1252 . Попробуйте онлайн!
источник
Haskell,
16111 + 57 = 168 байт+57 байт для флагов компиляции
-XOverloadedStrings
,-XOverlappingInstances
и-XFlexibleInstances
.Задача имеет некоторый громоздкий формат ввода-вывода , потому что он сильно зависит от того, как типы данных выражены в исходном коде. Моя первая версия (16 байт), а именно
принимает список целых чисел, например,
[1,0,1,0,1,0]
и был объявлен недействительным, потому что литеральные списки на Haskell, как оказалось, находятся,
между элементами. Списки как таковые не запрещены. В моей новой версии я использую ту же самую функцию, которая теперь называетсяf
, но я перегружаю «Цитировать вложенные последовательности символов». Функция по-прежнему принимает список целых чисел, как вы можете видеть в аннотации типа[Int] -> Int
, но списки с однозначными целыми числами теперь можно записать"1234"
, например, например,который оценивает
42
. Не повезло Haskell, потому что собственный формат списка не соответствует правилам вызова. Кстати,f [1,0,1,0,1,0]
все еще работает.источник
(1,0,1,0,1,0,1,0)
не является допустимым форматом ввода, но и то10101010
и другое(["10101010"])
". Более того, комментарий предполагает, что массив символов является приемлемым, если так интерпретируется ввод строки.10101010
,"10101010"
или нечто подобное , и сделать его работу , то представление является действительным. Вы можете назвать это строкой, списком, целым числом или как угодно. Ввод[1][0][1][0]
или[1,0,1,0]
не в порядке. В принципе, должно быть возможно просто ударить несколько единиц и нулей подряд где-нибудь. Это понятно?Сетчатка, 15 байт
Преобразует из двоичного в унарный, затем унарный в десятичный.
Попробуйте онлайн
источник
PHP, 44 байта
Я мог бы поклясться, что видел этот вопрос раньше. Но хорошо.
Читает число слева направо, сдвигает влево и добавляет текущий бит.
источник
JavaScript (ES6),
3331 байтРедактировать: короче, но менее красиво: 2 байта сохранены благодаря @ETHproductions.
источник
.map
короче:s=>[...s].map(c=>+c+r+r,r=0)|r
s=>[...s].map(c=>r+=+c+r,r=0)|r
Лабиринт ,
1715 байтПопробуйте онлайн!
Лабиринт - это двумерный язык, основанный на стеке. В лабиринте выполнение кода следует по пути кода, как лабиринт с пробелами, выступающими в качестве стен и начинающимися с самого верхнего левого непробельного символа. Поток кода определяется знаком вершины стека. Поскольку в нижней части стека есть неявные нули, первые четыре инструкции (
-+:+
) не имеют никакого эффекта.Цикл, начиная с
,
,
Выдвиньте значение кода ascii следующего входного символа до конца стека или нажмите -1, если EOF._48
толкает 48 к вершине стека-
Поп у, поп х, толчокx-y
. Предыдущие инструкции имеют эффект вычитания 48 из входного значения, получая 0 для «0» и 1 для «1».+
Поп у, поп х, толчокx+y
.:
Дублируйте вершину стека+
Эта и предыдущая инструкция умножают текущее значение на 2Таким образом, круговая часть кода, по сути, умножает текущее число на 2 и добавляет 1 или 0 в зависимости от того, был ли введен символ 1 или 0.
Хвост
Если вершина стека отрицательна (это означает, что EOF был найден), код будет повернут налево на стыке (в направлении точки с запятой).
)
Icrement вершина стека, чтобы получить 2/
Pop y, pop x, push x / y (целочисленное деление). Это приводит к отмене последнего*2
из цикла.!
Выведите целочисленное представление вершины стека. В этот момент программа поворачивается, потому что она зашла в тупик, а затем завершается с ошибкой, потому что она пытается разделить на ноль.Спасибо @Martin Ender за то, что он сэкономил мне 2 байта (и научил меня, как лучше думать в Лабиринте).
источник
_48-
вы можете просто сделать,#%
но, к сожалению, я не понимаю, как это может помочь с подсчетом байтов.`)
вместо,;_2
хотя.#%
. Можете ли вы объяснить, как это работает в качестве замены для_48-
преобразования из ASCII в INT. Спасибо за)
совет. Я сделаю это изменение.#
это просто сокращение_2
. Хотя_2%
это не общий метод преобразования ASCII в целое число, он работает здесь, потому что вас интересуют только первые две цифры в качестве возможного ввода. Альтернативой может быть_1&
(так как по модулю 2 просто извлекается младший значащий бит).#%
), чтобы сократить код в целом.Brain-Flak ,
46, 28 байтПопробуйте онлайн!
Много-много байтов сохранено благодаря @Riley!
Поскольку мозг-зенитчик не может принимать двоичный ввод, input представляет собой список «0» и «1».
Объяснение:
источник
([]){({}[()]<({}<>({}){})><>)}<>
([]){{}({}<>({}){})<>([])}<>
Java,
84794648 байтИзменено на
long
/ 48 байтов:Занимался гольфом / 46 байтов:
Спасибо @Geobits! / 79 байт:
84 байта:
источник
s
должно бытьchar[]
. Я надеюсь, что это позволено ...Befunge-98, 12 байт
Попробуйте онлайн!
Читает по одному символу за раз из ввода, преобразует его в 0 или 1, принимая его значение по модулю 2 (0 - это char (48), 1 - это char (49)), затем использует обычный алгоритм удвоения текущего значения и добавления новая цифра каждый раз.
Бонус: это работает с любой строкой ввода, я некоторое время пытался найти какую-нибудь забавную комбинацию ввода-вывода, но я не смог ничего произвести (к сожалению, «answer» = 46). Ты можешь?
источник
Javascript (ES7)
414036 байтпринимает строку в качестве входных данных
Побрил байт благодаря ETHproductions
источник
**
- странная, но хорошая работа, используя ее здесь.1<<b.length
будет делать то же самое, но это потребует, чтобы скобки не анализировались как(c*1)<<(b.length+...)
. Я думаю , что вы можете сохранить байты, заменяяb[0]
сb+b
( смотрите здесь ).C # 6,
853736 байтисточник
05AB1E , 7 байтов
Попробуйте онлайн!
объяснение
источник
С, 53
Так же, как мой ответ JavaScript
Тест Ideone
источник
v
и вc
качестве глобальных переменных (хотя вам нужно изменить имяv
, поскольку это уже имя функции), например:w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
w,c;
но я не хочу использовать глобальные переменные, когда ответ - функция (даже в коде-гольфе)=0
.Perl, 25 байт
-3 байта благодаря @Dom Hastings.
24 байта кода + 1 байт для
-p
флага.Чтобы запустить это:
Пояснения:
источник
Напористый , 10 байт
Принимает входной сигнал в виде списка 0/1 в командной строке:
$ pushy binary.pshy 1,0,1,0,1,0
.Алгоритм действительно показывает красоту наличия второго стека:
Этот метод работает, потому что стек будет удвоен
stack length - n
до достижения числаn
, которое затем будет сброшено во второй стек для дальнейшего использования. Вот как процесс выглядит для ввода101010
:источник
Matlab, 30 байт
В последнем тесте есть ошибки округления (из-за
double
), поэтому, если вам нужна полная точность:с 47 байтами.
источник
@(x)sum(2.^(find(flip(x)-48)-1))
что даст правильный результат для всех случаев для 32 байтов.flip
работает какfliplr
будтоx
является одномерным.f=@(x)..; f('1111001010')
.Сетчатка , 12 байт
Число байтов предполагает кодировку ISO 8859-1.
Попробуйте онлайн!
Альтернативное решение:
объяснение
Это, вероятно, будет легче объяснить, основываясь на моей старой версии, в которой меньше возможностей для игры в гольф, а затем покажу, как я ее сократил. Я использовал для преобразования двоичного в десятичное, как это:
Единственный разумный способ построить десятичное число в Retina - это подсчитать вещи (потому что Retina имеет несколько функций, которые позволяют печатать десятичное число, представляющее сумму). Так что на самом деле единственный возможный подход - преобразовать двоичный код в унарный, а затем посчитать количество унарных цифр. Последняя строка выполняет подсчет, поэтому первые четыре преобразуют двоичный код в унарный.
Как мы это делаем? В общем, чтобы преобразовать список битов в целое число, мы инициализируем результат
0
и затем перебираем биты от старшего к младшему, удваиваем значение, которое у нас уже есть, и добавляем текущий бит. Например, если двоичное число есть1011
, мы действительно вычислим:Где я отметил отдельные биты для ясности.
Хитрость сделать это в унарном виде состоит в том, что а) что удвоение означает просто повторение числа и б), так как мы считаем
1
s в конце, нам даже не нужно различать0
s и1
s в процессе. Это станет яснее через секунду.Что программа делает, так это то, что она сначала добавляет запятую в начало в качестве маркера того, сколько входных данных мы уже обработали:
Слева от маркера у нас будет значение, которое мы накапливаем (которое правильно инициализируется равным унарному представлению нуля), а справа от значения будет следующий бит для обработки. Теперь мы применяем следующую замену в цикле:
Просто глядя на
,(.)
и$1,
, это каждый раз перемещает маркер на один бит вправо. Но мы также вставляем$`
, то есть все перед маркером, то есть текущее значение, которое мы удваиваем. Вот отдельные шаги при обработке ввода1011
, где я пометил результат вставки$`
над каждой строкой (он пуст для первого шага):Вы увидите, что мы сохранили и удвоили ноль вместе со всем остальным, но так как мы игнорируем их в конце, не имеет значения, как часто мы удваивали их, пока число
1
s правильный. Если вы посчитаете их,11
их будет просто то, что нам нужно.Таким образом, остается вопрос о том, как сделать это до 12 байтов. Самая дорогая часть 18-байтовой версии - использование маркера. Цель состоит в том, чтобы избавиться от этого. Мы действительно хотим удвоить префикс каждого бита, поэтому первая идея может быть такой:
Проблема в том, что эти замены происходят одновременно, поэтому первый бит не удваивается для каждого бита, а просто копируется один раз каждый раз. Для ввода
1011
мы получим (пометив вставленный$`
):Нам по-прежнему необходимо рекурсивно обрабатывать ввод, чтобы удвоенный первый префикс снова удваивался со второго и так далее. Одна идея состоит в том, чтобы вставлять маркеры везде и многократно заменять их префиксом:
После замены каждого маркера префиксом в первый раз, нам нужно запомнить, где было начало ввода, поэтому мы также вставляем перевод строки и используем
%
опцию, чтобы убедиться, что следующий$`
выбирает только ближайший перевод строки.Это работает, но это все еще слишком долго (16 байт при подсчете
1
s в конце). Как насчет того, чтобы все перевернуть? Места, в которые мы хотим вставить маркеры, обозначены\B
(позиция между двумя цифрами). Почему бы нам просто не вставить префиксы в эти позиции? Это почти работает, но разница в том, что в предыдущем решении мы фактически удалили один маркер в каждой замене, и это важно, чтобы процесс завершился. Тем не менее,\B
это не персонаж, а просто позиции, поэтому ничего не удаляется. Однако мы можем остановить\B
от сопоставления, вместо этого вставив нецифровый символ в это место. Это превращает несловесную границу в границу слова, что эквивалентно удалению символа маркера ранее. И вот что делает 12-байтовое решение:Просто для полноты, вот отдельные этапы обработки
1011
, с пустой строкой после каждого шага:Опять же, вы обнаружите, что последний результат содержит ровно 11
1
с.В качестве упражнения для читателя, вы можете увидеть, как это довольно просто обобщается на другие базы (для нескольких дополнительных байтов на инкремент в базе)?
источник
T-SQL, 202 байта
источник
PHP, 64 байта
Мы инвертируем наше двоичное число, разбиваем его на составляющие его цифры и суммируем их в зависимости от положения.
источник
Утилиты Bash + GNU, 29 байт
Ввод / вывод через стандартный ввод / вывод.
sed
Выражение разбивает двоичные вверх в каждую цифру и строит выражение RPN дляdc
оценки.источник
PowerShell v2 +, 55 байт
Чувствует себя слишком долго ...Кажется, я не могу играть в гольф - советы приветствуются.объяснение
источник
JavaScript (ES6), 32 байта
Рекурсия снова спасает день! Хотя параметризация кажется немного длинной ...
источник
[...n]
нужно ли заключать в скобки?Mathematica,
271311 байтПринимает
List
битов в качестве входных данных (например{1, 0, 1, 1, 0}
- Mathematica «s двоичное представление числа22
)источник
Characters
функцию.IntegerDigits
в первую очередь.D
, что делает то же самое, что иIntegerDigits
Clojure,
1141056341 байтV4: 41 байт
-22 байта благодаря @cliffroot. Поскольку
digit
это символ, его можно преобразовать в его код черезint
, а затем вычесть из него 48, чтобы получить действительное число. Карта была также разложена. Я не знаю, почему это казалось необходимым.V3: 63 байта
-42 байта (!), Заглядывая в другие ответы. Мое "застегивание" было очевидно очень наивным. Вместо того, чтобы увеличивать 2 до мощности текущего места, затем умножать ее на текущую цифру и добавлять результат к аккумулятору, он просто умножает аккумулятор на 2, добавляет текущую цифру, а затем добавляет ее к аккумулятору. Также преобразовал функцию сокращения в макрос, чтобы немного сбрить.
Спасибо @nimi и @Adnan!
Ungolfed:
V2: 105 байт
-9 байт путем перестановки строки, поэтому мне не нужно создавать неловкий нисходящий диапазон.
V1: 114 байт
Ну я конечно не побеждаю! В мою защиту это первая написанная мной программа, которая конвертирует базы, поэтому мне пришлось научиться делать это. Также не помогает то, что
Math/pow
возвращает значение типа double, которое требует преобразования, иInteger/parseInt
не принимает символ, поэтому перед передачей цифру необходимо обернуть.Zips строка с нисходящим индексом, представляющим номер места. Сокращает полученный список.
Ungolfed:
источник
#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %)
улучшенная версия. Переместилmap
часть кода прямо вreduce
, изменил целочисленный метод разбора, создаю внешнюю функцию с сокращенным лямбда-синтаксисом.int
можно использовать для разбора !? Это сбивает как 10 байтов в каждом вызове, который я сделал здесь, лол.Perl,
211916 + 4 = 20 байт-4 байта благодаря @Dada
Запустите с
-F -p
(включая дополнительное место послеF
). Передать значения в функцию с помощьюecho -n
Беги как
echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'
Я чувствую, что это достаточно отличается от ответа @ Dada, что он заслуживает своей собственной записи.
Объяснение:
Это использует мой личный алгоритм выбора для преобразования двоичных в десятичные. Учитывая двоичное число, начните свой аккумулятор с 0, и пройдитесь по его битам один за другим. Удвойте аккумулятор каждый бит, затем добавьте сам бит в свой аккумулятор, и вы получите десятичное значение. Это работает, потому что каждый бит удваивается соответствующее количество раз для его позиции на основе того, сколько еще битов осталось в исходном двоичном числе.
источник
perl -F -pE '$\+=$_+$\for@F}{'
R (32 бита), 64 байта
Ввод для функции должен быть дан как символ. Базовые функции R поддерживают 32-битные целые числа.
Входные данные:
Выход:
R (64 бит), 74 байта
Ввод для функции должен быть дан как символ. Пакет
bit64
должен использоваться для 64-битных целых чисел.Входные данные:
Выход:
источник
el(strsplit(x,""))
вместо того,strsplit(x,split="")[[1]]
чтобы сохранить пару байтов.el
функции - я не знал об этом.Дьялог АПЛ , 12 байт
⍞
получить строку ввода⍎¨
преобразовать каждый символ в число⌽
обратный(
...)/
вставить следующую функцию между числами++⊢
сумма аргументов плюс правильный аргументнгн побрил 2 байта.
источник
к, 8 байт
Тот же метод, что и в ответе на Haskell.
Пример:
источник