Найти следующее 1-разреженное двоичное число


27

Целое положительное число N является K- разреженным, если между двумя любыми двумя последовательными единицами в его двоичном представлении есть по крайней мере K 0.

Итак, число 1010101 является 1-разреженным, а 101101 - нет.

Ваша задача - найти следующий 1-разреженный номер для заданного входного номера. Например, если входное значение равно 12 ( 0b1100), выходное значение должно быть 16 ( 0b10000), а если входное значение равно 18 ( 0b10010), выходное значение должно быть 20 ( 0b10100).

Наименьшая программа или функция (в байтах) побеждает! Стандартные лазейки запрещены.


«Следующий» как в «следующем наивысшем» или как «с наименьшей абсолютной разницей»?
FUZxxl

«следующий» как в «следующем наивысшем».
артикуно

Какой диапазон ввода должен быть обработан?
mbomb007

Я собираюсь предположить, что отрицательные числа не должны быть.
mbomb007

@articuno Можем ли мы создать функцию или она должна быть полной программой? Функции довольно стандартные.
mbomb007

Ответы:



9

CJam, 14 11 байтов

3 байта сохранены благодаря DigitalTrauma.

l~{)___+&}g

Проверьте это здесь.

объяснение

l~          "Read and eval input.";
  {      }g "Do while...";
   )_       "Increment and duplicate (call this x).";
     __+    "Get two more copies and add them to get x and 2x on the stack.";
        &   "Take their bitwise AND. This is non-zero is as long as x's base-2
             representation contains '11'.";

Это оставляет последний номер в стеке, который автоматически печатается в конце программы.


8

Python 2, 44 байта

Это полная программа на Python, которая читает на n и печатает ответ. Я думаю, что это довольно хорошо в субконкурсе читаемости.

n=input()+1
while'11'in bin(n):n+=1
print n

Результаты теста:

$ echo 12 | python soln.py 
16
$ echo 18 | python soln.py 
20

6

Pyth, 12 11 байтов

f!}`11.BThQ

Попробуйте онлайн: Pyth Compiler / Executor .

               implicit: Q = input()            
f        hQ    find the first integer T >= Q + 1, 
               that satisfies the condition:
 !}`11.BT         "11" is not in the binary representation of T

1
Вы можете сохранить персонажа, превратившись "11"в `11.
Orlp

@orlp Спасибо, должен был это заметить.
января

5

Mathematica, 41 30 байт

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

#+1//.i_/;BitAnd[i,2i]>0:>i+1&

3
Не могли бы вы добавить описание, пожалуйста?
mbomb007

4

Perl, 31

#!perl -p
sprintf("%b",++$_)=~/11/&&redo

Или из командной строки:

 perl -pe'sprintf("%b",++$_)=~/11/&&redo' <<<"18"

4

APL, 18 байт

1∘+⍣{~∨/2∧/⍺⊤⍨⍺⍴2}

Это оценивает монадическую функцию. Попробуй это здесь. Использование:

   1∘+⍣{~∨/2∧/⍺⊤⍨⍺⍴2} 12
16

объяснение

1∘+                    ⍝ Increment the input ⍺
   ⍣{            }     ⍝ until
     ~∨/               ⍝ none of
        2∧/            ⍝ the adjacent coordinates contain 1 1 in
           ⍺⊤⍨⍺⍴2      ⍝ the length-⍺ binary representation of ⍺.

4

J, 20 знаков

Монадический глагол. Исправлено, чтобы подчиняться правилам.

(+1 1+./@E.#:)^:_@>:

объяснение

Во-первых, это глагол с пробелами, а затем чуть меньше в гольфе:

(+ 1 1 +./@E. #:)^:_@>:
[: (] + [: +./ 1 1 E. #:)^:_ >:

Читать:

    ]                             The argument
      +                           plus
        [: +./                    the or-reduction of
               1 1 E.             the 1 1 interval membership in
                      #:          the base-2 representation of the argument,
[: (                    )^:_      that to the power limit of
                             >:   the incremented argument

Аргумент плюс или сокращение 1 1интервала членства в представлении аргумента base-2, которое соответствует пределу мощности, примененному к увеличенному аргументу.

Я в основном вычисляю, если 1 1происходит в представлении base-2 ввода. Если это так, я увеличиваю ввод. Это ограничено по мощности, что означает, что оно применяется до тех пор, пока результат больше не изменится.


Хороший алгоритм! Он имеет такую же длину в APL: {⍵+∨/2∧/⍵⊤⍨⍵⍴2}⍣=.
Згарб

@ Рандомра А, понятно.
FUZxxl

4

Javascript, 25 19

Используя тот факт, что для 1-разреженного двоичного числа x&2*x == 0:

f=x=>x++&2*x?f(x):x

3

JavaScript (ES6), 39 43

Нет регулярных выражений, нет строк, рекурсивно:

R=(n,x=3)=>x%4>2?R(++n,n):x?R(n,x>>1):n

Итерационная версия:

F=n=>{for(x=3;x%4>2?x=++n:x>>=1;);return n}

Это очень просто, просто используя правое смещение, чтобы найти последовательность 11. Когда я нахожу ее, переходите к следующему номеру. Рекурсивная версия напрямую вытекает из итеративной.

Неуправляемый и более очевидный. В гольфе самая сложная часть - это объединение внутренней и внешней петель (при запуске нужно начинать с x до 3)

F = n=>{
  do {
    ++n; // next number
    for(x = n; x != 0; x >>= 1) {
      // loop to find 11 in any position
      if ((x & 3) == 3) { // least 2 bits == 11
        break;
      }
    }
  } while (x != 0) // if 11 was found,early exit from inner loop and x != 0
  return n
}

Это %4>2похоже на колдовство из теории чисел, не могли бы вы объяснить || предоставить ссылку?
Джейкоб

@Jacob (x% 4> 2) это просто ((x & 3) == 3), но с приоритетом оператора является JS, вы избегаете двух скобок
edc65

Просто, чем я думал. Теперь с негольфированной версией все ясно. Благодарность!
Джейкоб

3

Python 2, 37 байт

f=input()+1
while f&2*f:f+=1
print f

Использовал логику x & 2*x == 0для 1-разреженного числа.
Спасибо @Nick и @CarpetPython.


Почему отрицательный голос? Это работает отлично, и хорошо в гольф.
ETHproductions

Добро пожаловать в PPCG, кстати, и хороший первый ответ! Я призываю вас продолжать отвечать на вызовы на сайте :-)
ETHproductions

2

JavaScript, 75 66 62 байта

Спасибо Мартину Бюттнеру за сохранение 9 байтов и Pietu1998 за 4 байта!

function n(a){for(a++;/11/.test(a.toString(2));a++);return a;}

Как это работает: он запускает forцикл, начиная сa + 1 тех пор, пока текущее число не является 1-разреженным, и если это так, цикл прерывается, и он возвращает текущее число. Чтобы проверить, является ли число 1-разреженным, он преобразует его в двоичное и проверяет, не содержит ли оно числа 11.

Негольфированный код:

function nextOneSparseNumber(num) {
    for (num++; /11/.test(num.toString(2)); num++);
    return num;
}

2

Юлия, 40 байт

n->(while contains(bin(n+=1),"11")end;n)

Это создает анонимную функцию, которая принимает одно целое число в качестве входных данных и возвращает следующее наибольшее 1-разреженное целое число. Чтобы назвать его, дайте ему имя, напримерf=n->... , и сделать f(12).

Ungolfed + объяснение:

function f(n)

    # While the string representation of n+1 in binary contains "11",
    # increment n. Once it doesn't, we've got the answer!

    while contains(bin(n += 1), "11")
    end

    return(n)
end

Примеры:

julia> f(12)
16

julia> f(16)
20

Предложения и / или вопросы приветствуются как всегда!


2

> <> (Рыба) , 31 + 3 = 34 байта

1+:>:  4%:3(?v~~
;n~^?-1:,2-%2<

Использование:

>python fish.py onesparse.fish -v 12
16

3 байта добавлено для -vфлага.


1

JavaScript (ECMAScript 6), 40

По рекурсии:

g=x=>/11/.test((++x).toString(2))?g(x):x

JavaScript, 56

То же самое без функций стрелок.

function f(x){return/11/.test((++x).toString(2))?f(x):x}

1

Скала, 65 байт

(n:Int)=>{var m=n+1;while(m.toBinaryString.contains("11"))m+=1;m}

(если требуется именованная функция, решение будет 69 байтов)


1

Python, 39 33 байта

Попробуйте это здесь: http://repl.it/gpu/2

В лямбда-форме (спасибо xnor за игру в гольф):

f=lambda x:1+x&x/2and f(x+1)or-~x

Стандартный синтаксис функции на этот раз оказался короче лямбды!

def f(x):x+=1;return x*(x&x*2<1)or f(x)

Вы можете сократить лямбда одного до 33 байт: f=lambda x:1+x&x/2and f(x+1)or-~x. Оказывается, что из вас бит-сдвиг вправо, а не влево, вы можете использовать x/2вместо, (x+1)/2потому что разница всегда в нулевых битах x+1. Спецификация просит программу, хотя.
xnor

Я спросил, и он сказал, что мы можем выполнять функции. Большинство ответов уже есть.
mbomb007


0

Руби, 44

->(i){loop{i+=1;break if i.to_s(2)!~/11/};i}

Довольно простой. Лямбда с бесконечным циклом и регулярным выражением для проверки двоичного представления. Я желаю, чтобы loopполучился и индекс.


@ mbomb007 сделано. Спасибо за совет.
Макс

0

Matlab ( 77 74 байта)

m=input('');for N=m+1:2*m
if ~any(regexp(dec2bin(N),'11'))
break
end
end
N

Заметки:

  • Достаточно проверить числа m+1до того 2*m, где mнаходится вход.
  • ~any(x)является , trueесли xсодержит все нули или если xпусто

0

C (32 байта)

f(int x){return 2*++x&x?f(x):x;}

Рекурсивная реализация того же алгоритма, что и многие другие ответы.




0

Желе , 7 байт

‘&Ḥ¬Ɗ1#

Полная программа, принимающая одно неотрицательное целое число, которое печатает положительное целое число (в качестве монадической ссылки она выдает список, содержащий одно положительное целое число).

Попробуйте онлайн!

Как?

Начиная с v=n+1и увеличивая, удваивайте, vчтобы сдвинуть каждый бит вверх на одно место, и побитовое И с, vа затем выполните логическое НЕ, чтобы проверить, vявляется ли 1-разреженным, пока не будет найдено одно такое число.

‘&Ḥ¬Ɗ1# - Main Link: n   e.g. 12
‘       - increment           13
     1# - 1-find (start with that as v and increment until 1 match is found) using:
    Ɗ   -   last three links as a dyad:
  Ḥ     -   double v
 &      -   (v) bit-wise AND (with that)
   ¬    -   logical NOT (0->1 else 1)
        - implicit print (a single item list prints as just the item would)

0

Stax , 5 байт

╦>ù╤x

Запустите и отладьте его

Это работает, используя эту процедуру. Ввод начинается сверху стека.

  • Увеличить и скопировать в два раза.
  • Разделить пополам вершину стека.
  • Побитовые и верхние два элемента в стеке.
  • Если результат верен (отличен от нуля), повторите всю программу.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.