Спростіть двійкове


20

Виклик

Давши двійкове число як вхід за допомогою будь-яких засобів, "спростіть" число за допомогою повної програми або функції.

Вхідні дані

[binary]
  • binary - це число у двійковій формі, яке перевищує 0.

Вихідні дані

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

Інша інформація

  • Якщо вхід 1, просто виведіть 1. Ваша програма не повинна продовжувати безмежно спрощувати 1.

  • Це кодовий гольф, тому найкоротша відповідь у байтах до вівторка (17 листопада) виграє.

  • Якщо щось заплутане, залиште коментар із зазначенням того, що мені потрібно очистити, і я відповідним чином відредагую його.

  • Вбудовані для базового перетворення заборонені.

Приклади

     Input | Output

         1 | 1
      1010 | 2
      1011 | 3
   1100100 | 4
   1100101 | 5
1111110011 | 3

4
Можливо використати пару тестових випадків.
isaacg

Чи є вхідним рядком ASCII, чи це фактично 1 та 0?
Том Карпентер

@TomCarpenter 1s і 0s.
The_Basset_Hound

@isaacg Додано способи отримати 1-5 як вихід.
The_Basset_Hound

Чи дозволені функції, які перетворюють рядок у задану базу?
isaacg

Відповіді:


14

Pyth, 20 16 байт

u?-GTG`u+yNsTG0z

4 байти завдяки Jakube

Половина коду ( 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помічає, що значення перестало змінюватися.


4
Вітаємо, ви перемогли Денніса! На даний момент ...
Conor O'Brien

9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Секрет - Піт.
isaacg

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'ing всіх символів у 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)

6

Пітон 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. Golfed код згортає їх в одну функцію, вставивши визначення g(n)для f(n), замінивши рекурсивний виклик gз f. Базовий корпус n=0з gавтоматично обробляються чекою n>1.


Приємно :) Єдине, що стосується звичайної проблемиLrepr
досадно

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).

Пояснення
p є основною функцією і виконує наступні кроки (за допомогою b, x, y):

  • перевіряє, чи поточне число більше 1
  • перетворює ціле число до списку представлень цифр ascii
  • перевіряє, чи всі числа 0 або 1
  • перетворює список ascii у бінарний цілий список
  • перетворює двійковий цілий список у десяткове число
  • повторюється
  • друкує, коли присудок не вдається.

Редагувати: збережено 8 байтів, об'єднавши p-пропозиції з OR.


3

Математика 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


3

Javascript, 132 , 123 байт

Ну, це не найкраща відповідь, але ..

FYI, якщо дано недійсний ввід, він відображає те саме, що і користувачеві.

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())


1
Ви можете зберегти 19 байт , використовуючи forзамість цього whileта встановлюючи значення безпосередньо в операторі (це також зменшує деякі {}), відкидаючи деякі ;, використовуючи опис функції ES6, збільшуючи iвбудований. Це буде виглядати наступним чином : 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())
Mama Fun Roll

@insertusernameтуку, дякую за пропозицію, але я 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){}див. " Функції стрілки ".
insertusernameту

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>


1
Дійсно подобається n+=+c+nбінарне перетворення. Так елегантно ...
nderscore

2

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

Збережено 7 байт завдяки Мартіну Бюттнеру.

#//.a_/;Max[b=IntegerDigits@a]<2:>Fold[#+##&,b]&

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>


1

𝔼𝕊𝕄𝕚𝕟, 37 знаків / 54 байти

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

Try it here (Firefox only).

Не впевнений, чи +вважає оператор вбудованим для бінарного перетворення ...



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" замість свого початкового "для", що дозволить мені отримати 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повернеться істинно лише для двійкових чисел.

&$s>1потрібен для особливої ​​справи 1.

Решта прямо вперед: проведіть біти зі зміщенням значення і додавши поточний біт, нарешті скопіюйте число (відведене до рядка) до $ s для тесту зовнішньої петлі.


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>


Якщо ви використовуєте eval, ви, можливо, зможете зняти неявне повернення.
Mama Fun Roll

На 5 байт коротше, з функціями eval і анонім
грудня 15:15

@ ן 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.