Упростить двоичный файл

20

Вызов

Задав двоичное число в качестве ввода любым способом, «упростите» число, используя полную программу или функцию.

вход

[binary]
  • binary число в двоичном коде, которое больше 0.

Выход

Возьмите входные данные, преобразуйте их в основание 10 без использования встроенной функции, затем, если это число содержит только 1 и 0, преобразуйте его в число 10, как если бы это было другое двоичное число. Повторяйте процесс, пока число не может быть прочитано в двоичном виде, и выведите это число.

Дополнительная информация

  • Если вход равен 1, просто выведите 1. Ваша программа не должна бесконечно упрощаться 1.

  • Это кодовый гольф, поэтому самый короткий ответ в байтах к вторнику (17 ноября) выигрывает.

  • Если что-то сбивает с толку, оставьте комментарий с указанием того, что мне нужно прояснить, и я внесу соответствующие изменения.

  • Встроенные средства для преобразования базы не допускаются.

Примеры

     Input | Output

         1 | 1
      1010 | 2
      1011 | 3
   1100100 | 4
   1100101 | 5
1111110011 | 3
The_Basset_Hound
источник
4
Могли бы использовать пару тестовых случаев.
Исаак
Является ли входная строка ASCII, или фактически 1 и 0?
Том Карпентер
@TomCarpenter 1 с и 0 с.
The_Basset_Hound
@isaacg Добавлены способы получить 1-5 в качестве вывода.
The_Basset_Hound
Разрешены ли функции, которые преобразуют строку в заданную базу?
Исаак

Ответы:

14

Pyth, 20 16 байтов

u?-GTG`u+yNsTG0z

4 байта благодаря Якубе

Половина кода ( u+yNsTG0) - это просто базовый код преобразования.

Тестирование

u?-GTG`u+yNsTG0z
                    z = input() (The string of 1s and 0s)
                    T = 10
u              z    Apply until the value stops changing, starting with z
                    G is the current value, a string of 0s and 1s.
 ?-GT               If G - T, e.g., G with the digits 1 and 0 removed is not empty,
     G              Return G, to end the iteration.
       u     G0     Else, reduce over G with initial value 0.
         yN         Double the running total
        +  sT       and add the next digit, cast to an int.
      `             Convert to string.

Входные данные 1обрабатываются тем фактом, что uзначение перестает меняться.

isaacg
источник
4
Поздравляю, ты превзошел Денниса! На данный момент ...
Конор О'Брайен
9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Секрет в Пифте.
Исаак
8

CJam, 24 23 байта

q{:~{1$++}*s__,(As*-!}g

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

Как это устроено

q                        Read all input.
 {                   }g  Do:
  :~                       Evaluate each character. Maps '0' -> 0 and '1' -> 1.
    {    }*                Fold; for each integer but the first:
     1$                      Copy the second-topmost integer.
       ++                    Add all three integers on the stack.
           s__             Cast to string and push two copies.
              ,(           Calculate string length and subtract 1.
                As         Push the string "10".
                  *        Repeat the string length-1 times.
                   -       Remove its elements from the string representation
                           of the integer.
                    !      Apply logical NOT.
                         If `!' pushed 1, repeat the loop.
Деннис
источник
Вы должны повторить "10"строку length-1времени, или вы можете пропустить декремент?
DLosc
Вычитание 1 из длины превращается "10"в, ""если целое число имеет одну цифру. Это гарантирует, что код не попадет в бесконечный цикл.
Деннис
2
Увлекательный, капитан. }: ^ |
DLosc
7

Пип, 28 27 байт

Ta=1|aRMta:$+(^a)*2**RV,#aa

Принимает ввод в качестве аргумента командной строки. Мы хотим , чтобы петли до тех пор , a=1или aсодержит некоторый символ (ы) , кроме 0 и 1 -х годов. Последнее условие проверяется путем RMввода всех символов в t= 10from a. Если что-то осталось, условие правдивое.

Внутри цикла преобразование работает следующим образом:

a:$+(^a)*2**RV,#a

              ,#a  range(len(a))
            RV     reversed
         2**       2 to the power of each element
    (^a)*          multiplied item-wise with each digit in split(a)
  $+               Sum
a:                 and assign back to a

Ставить aв конце автопечать.

Рекурсивное решение в 28 байтов:

a<2|aRMt?a(f$+(^a)*2**RV,#a)
DLosc
источник
6

Python 2, 52

f=lambda n:n>1<'2'>max(`n`)and f(n%10+2*f(n/10))or n

Проще думать об этом как о двух рекурсивных функциях:

g=lambda n:n and n%10+2*g(n/10)
f=lambda n:n>1<'2'>max(`n`)and f(g(n))or n

Функция gпреобразует десятичное значение в двоичное, и функция fприменяется gповторно, если ее аргумент состоит из цифр 0 и 1 ( '2'>max(`n`)) и не имеет значения 1. Гольф-код объединяет их в одну функцию, вставляя определение g(n)для f(n), заменяя рекурсивный вызов на gна f. Базовый корпус n=0из gавтоматически обрабатываются чекаn>1 .

XNOR
источник
Приятно :) Единственное, к чему относится обычная проблема - надоедливый Lот repr...
Sp3000 11.11.15
4

Пролог, 220 212 байт

:-use_module(library(clpfd)).
x(B,N):-reverse(B,C),foldl(y,C,0-0,_-N).
y(B,J-M,I-N):-B in 0..1,N#=M+B*2^J,I#=J+1.
b(N,I):-N>47,N<50,I is(N-48).
p(N):-N>1,number_codes(N,L),maplist(b,L,Y),x(Y,B),p(B);write(N).

Объяснение
р является основной функцией и выполняет следующие шаги (с помощью b, x, y):

  • проверяет, является ли текущий номер больше 1
  • преобразует целое число в список ascii представлений цифр
  • проверяет, что все числа равны 0 или 1
  • преобразовывает список ASCII в двоичный список целых чисел
  • преобразует двоичный список целых чисел в десятичное число
  • рекурсивно
  • печатает, когда предикат терпит неудачу.

Изменить: 8 байтов сохранены путем объединения p-предложений с ИЛИ.

Emigna
источник
3

Mathematica 107 106

С байтом, сохраненным DLosc.

j@d_:=(p=0;v=IntegerDigits@d;
Which[d<2,1,Complement[v,{0,1}]=={},j@Fold[#+#2 2^p++&,0,Reverse@v],1<2,d])

Разбейте ввод на его цифры. Если вход 1, выведите 1.

Если входными данными являются числа, состоящие из 0 и 1, преобразуйте их в десятичную и снова выполните.

В противном случае верните ввод.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

Первый шаг дает 1011, который в свою очередь дает 3.


Здесь мы тестируем, начиная с 1011.

j[1011]

3

DavidC
источник
3

Javascript, 132 , 123 байта

Ну, это не самый лучший ответ, но ..

К вашему сведению, если указан неверный ввод, он отображает то же самое для пользователя.

function c(x){while(x!=0&&!/[2-9]/.test(x)){for(i=r=0;x;i++)r+=x%10*Math.pow(2,i),x=parseInt(x/10);x=r}alert(x)}c(prompt())

LearningDeveloper
источник
1
Вы можете сохранить 19 байтов , используя forвместо этого whileи устанавливая значения непосредственно в операторе (это также уменьшает некоторые {}), отбрасывая некоторые ;, используя описание функции ES6, увеличивая значение iinline. Это будет выглядеть следующим образом : c=x=>{for(r=0;x&&!/[2-9]/.test(x);x=r)for(i=0;x>0;r+=x%10*Math.pow(2,i++),x=parseInt(x/10));alert(x)};c(prompt()).
имя пользователя здесь
1
114:function c(x){while(x^0&&!/[2-9]/.test(x)){for(i=r=0;x;i++)r+=x%10*Math.pow(2,i),x=0|x/10;x=r}alert(x)}c(prompt())
Мама Fun Roll
@insertusernamehere, спасибо за предложение, но я не понял с c=x=>самого начала, не работал на консоли Chrome или Firefox. :( @ ן nɟuɐɯɹɐ ן oɯ, не могу обернуть голову вокруг условия XOR, и x=0|x/10‌вместо этого parseIntя включил остальные изменения. Спасибо ..
LearningDeveloper
@GauthamPJ Извините, код как-то сломался при копировании и содержал непечатные символы. Вот правильный вариант: c=x=>{for(r=0;x!=0&&!/[2-9]/.test(x);x=r)for(i=r=0;x;)r+=x%10*Math.pow(2,i++),x=parseInt(x/10);alert(x)};c(prompt()). Это определенно работает в Firefox 42, попробуйте эту скрипку . Обратите внимание, что эта более удачная версия, а также ваш оригинальный код не работают 1и будут бесконечно повторяться. c=x=>это как function c(x){}см. « Функции стрелок ».
имя пользователя здесь
2

JavaScript ES6, 52

Как функция. Аргумент функции должен быть либо строкой двоичных цифр, либо числом, десятичное представление которого содержит только 1 и 0.

Протестируйте приведенный ниже фрагмент кода в браузере, совместимом с EcmaScript 6, - реализуя функции стрелок, строки шаблонов и оператор распространения (я использую Firefox)

f=s=>s<2|[...s+''].some(c=>(n+=+c+n,c>1),n=0)?s:f(n)

// To test
console.log=(...x)=>O.innerHTML+=x+'\n';

// Basic test cases
;[[1,1],[1010,2],[1011,3],[1100100,4],[1100101,5],[1111110011,3]]
.forEach(t=>console.log(t[0]+' -> '+f(t[0])+' expected '+t[1]))

function longtest() {
  var o=[],i;
  for (i=1;i<1e6;i++)
    b=i.toString(2),v=f(b),v!=i?o.push(b+' '+v):0;
  O.innerHTML=o.join`\n`
}
Click to run the long test <button onclick="longtest()">go</button>
<pre id=O></pre>

edc65
источник
1
Очень нравится n+=+c+nдля двоичного преобразования. Так элегантно ...
nderscore
2

Математика, 62 59 55 48 байтов

Сохранено 7 байтов благодаря Мартину Бюттнеру.

#//.a_/;Max[b=IntegerDigits@a]<2:>Fold[#+##&,b]&
alephalpha
источник
1

Javascript (ES7) 87 80 78 77 74 байта

Демонстрационная версия фрагмента для поддержки браузеров (в настоящее время только Firefox каждую ночь поддерживает экспоненциальный оператор)

f=x=>[...x].reverse(i=y=j=0).map(z=>(j|=z,y+=z*2**i++))&&j<2&y>1?f(y+[]):x
<input type="text" id="x" value="1111110011"><button onclick="o.innerHTML=f(x.value)">Run</button><div id="o"></div>

f=x=>
[...x].reverse(i=y=j=0) // reverse string as array, initialize vars
.map(z=>( // iterate over the all chatacters
    j|=z, // keep track of whether a digit higher than 1 is encountered
    y+=z*2**i++ // build decimal result from binary
))&&
j<2&y>1? // if we encountered only 1's and 0's and result > 1
    f(y+[]) // then call recursively and cast to a string
    :x // else return x

Javascript (ES6) 81 байт

Демонстрационная версия фрагмента поддержки браузеров

f=x=>[...x].reverse(i=y=j=0).map(z=>y+=z*Math.pow(2,i++,j|=z))&&j<2&y>1?f(y+[]):x
<input type="text" id="x" value="1111110011"><button onclick="o.innerHTML=f(x.value)">Run</button><div id="o"></div>

nderscore
источник
1

𝔼𝕊𝕄𝕚𝕟, 37 символов / 54 байта

↺;ï>1⅋(⬯+ï)ĉ/^[01]+$⌿);)ï=+('ᶀ'+ï);ôï

Try it here (Firefox only).

Не уверен, что +оператор считается встроенным для двоичного преобразования ...

Mama Fun Roll
источник
1

Perl 6 , 67 байт

get,{$_=0;for $^a.comb {$_+<=1;$_+=$^b};$_}...1|/<-[01]>/;say $_//1
Брэд Гилберт b2gills
источник
1

PHP, 210 204 байта

Я впервые пишу здесь, так что надеюсь, вам, ребята, понравится! Даже если это явно не лучший способ написать это, я все равно рад показать это здесь!

Код

<?function j($a){$c=0;if($a==1){return 1;}else{if(preg_match("#^[01]+$#",$a)){$b=strlen($a);$a=str_split($a);foreach($a as$d){$c+=($d==0?0:2**($b-1));$b--;}return j($c);}else{return$a;}}}echo j($_GET[0]);

Я сделал рекурсивную функцию "j", которая сначала проверит, равен ли ввод 1. Если это так, функция возвращает 1, как и ожидалось, иначе она разделит число в массиве для вычисления десятичного значения, но только если число двоичное. Если это не так, он вернет номер как есть.

Код без правил

<?
function j($a) {
  $c = 0;
  if ($a == 1) {
    return 1;
  }
  else {
    if (preg_match("#^[01]+$#", $a) {
      $b = strlen($a);
      $a = str_split($a);
      foreach ($a as $d) {
        $c += ($d == 0 ? 0 : 2 ** ($b - 1));
        $b--;
      }
      return j($c);
    }
    else {
      return $a;
    }
  }
}
echo j($_GET[0]);

Я использовал выражение «foreach» вместо своего начального «for», что позволило мне получить 6 байтов, но я уверен, что есть еще много чего сделать.

Винсент Дуэ
источник
1

PHP, 114 112 байт

также работает для 0. Беги с -r.

for($n=$argv[1];count_chars($s="$n",3)<2&$s>1;)for($i=$n=0;""<$c=$s[$i++];)$n+=$n+$c;echo$s;

count_chars($s,3)возвращает строку, содержащую все символы из строки (как это array_uniqueделает для массивов). Для двоичных чисел, то это будет 0, 1или 01. Для других чисел это будет содержать цифру больше, чем 1, поэтому <2вернет true только для двоичных чисел.

&$s>1 нужен для особого случая 1 .

Остальное просто: переберите биты, сдвинув значение и добавив текущий бит, и, наконец, скопируйте число (приведенное к строке) в $ s для теста внешнего цикла.

Titus
источник
0

CoffeeScript, 92 89 байт

f=(x)->x>1&/^[01]+$/.test(x)&&f(''+x.split('').reverse().reduce ((p,v,i)->p+v*2**i),0)||x

JavaScript (ES6), 105 101 90 байт

f=y=>y>1&/^[01]+$/.test(y)?f(''+[...y].reverse().reduce(((p,v,i)=>p+v*Math.pow(2,i)),0)):y

демонстрация

Работает только в ES6-совместимых браузерах, таких как Firefox и Microsoft Edge

f=y=>y>1&/^[01]+$/.test(y)?f(''+[...y].reverse().reduce(((p,v,i)=>p+v*Math.pow(2,i)),0)):y

// Snippet stuff
$(`form`).submit((e) => {
  document.getElementById(`y`).textContent = f(document.getElementById(`x`).value);
  e.preventDefault()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <label>Input:
    <input pattern=^[01]+$ required id=x>
  </label>
  <button type=submit>Go</button>
  <p>Output:
    <output id=y></output>
  </p>
</form>

rink.attendant.6
источник
Если вы используете eval, вы можете осуществить неявный возврат.
Mama Fun Roll
На 5 байт короче с eval и анонимными функциями
Downgoat
@ ן nɟuɐɯɹɐ ן oɯ По какой-то причине функция eval'd не работает 1. потому что это не входит в цикл, я предполагаю
rink.attendant.6
1
@nderscore Спасибо, но рекурсия была на 4 байта короче :-)
rink.attendant.6
0

Scala, 128 байт

def b(s:String):String=if(s.matches("[10]{2,}"))b(""+s.reverse.zipWithIndex.collect{case('1',i)=>Math.pow(2,i)}.sum.toInt)else s
Иаков
источник
0

Матлаб (115)

@(a)num2str(sum((fliplr(a)-48).*arrayfun(@(x)2^x,0:nnz(a)-1)));a=ans(input('','s'));while(find(a<50))a=ans(a);end,a

  • Анонимная функция - преобразование типа числа ( bin2dec)
Abr001am
источник