Біт пробіг


43

Враховуючи ціле число n > 0, виведіть довжину найдовшої безперервної послідовності 0або 1у її двійковому поданні.

Приклади

  • 6пишеться 110двійковою; найдовша послідовність 11, тому ми повинні повернутися2
  • 16100004
  • 89311011111015
  • 13373711010001101000000110116
  • 111
  • 99655461001100000001111111010107


Чи можемо ми припустити будь-яку граничну величину цілого числа, як 32 біт або 64 біт?
xnor

@xnor так, ви можете припустити, що міжнародна ціна становить 32 біти
Арно

Відповіді:


30

Python 2 , 46 45 байт

f=lambda n,k=1:`k`in bin(n^n/2)and-~f(n,k*10)

Спробуйте в Інтернеті!

Як це працює

За допомогою XORing n і n / 2 (ділення на 2, по суті, відсікає останній біт), ми отримуємо нове ціле число m , невстановлені біти вказують на збіг сусідніх бітів у n .

Наприклад, якщо n = 1337371 , маємо наступне.

n    = 1337371 = 101000110100000011011₂
n/2  =  668685 =  10100011010000001101₂
m    = 1989654 = 111100101110000010110₂

Це зменшує завдання знайти найдовший пробіг нулів. Оскільки двійкове подання додатного цілого цілого завжди починається з 1 , ми спробуємо знайти найдовший 10 * рядок цифр, який з’являється у двійковому поданні m . Це можна зробити рекурсивно.

Ініціалізуйте k як 1 . Кожен раз, коли виконується f , ми спочатку перевіряємо, чи десяткове подання k з'являється у двійковому поданні m . Якщо це так, множимо k на 10 і знову викликаємо f . Якщо це не так, код праворуч від andне виконується, і ми повертаємо False .

Для цього спочатку обчислюємо bin(k)[3:]. У нашому прикладі bin(k)повертається '0b111100101110000010110', а 0b1на початку видаляється за допомогою [3:].

Тепер, -~перед рекурсивними збільшеннями виклику False / 0 раз на кожен раз, коли f викликається рекурсивно. Коли 10 {j} ( 1 з подальшим j повторенням 0 ) не з’являється у двійковому поданні k , найдовший пробіг нулів у k має довжину j - 1 . Оскільки j - 1 послідовних нулів у k вказують на j, що відповідають сусіднім бітам у n , бажаний результат дорівнює j , який ми отримуємо, збільшуючи False / 0в цілому j разів.


2
Це справді розумно!
CraigR8806

1
Нічого собі, це розумно. Ніколи не міг про це подумати.
HyperNeutrino

Хороший трюк з потужністю 10, але хіба вони не стають довгими з L?
xnor

@xnor Врешті-решт, але це лише обмеження типу даних. Відповіді на це також страждають відповіді C, JavaScript та PHP.
Денніс

Це було б серйозно неможливо досягти, якщо його використовувати у виробництві. Коротше кажучи (гхе-го) гольф досяг, дірка в одному :)
JAK

17

Python 2, 46 байт

f=lambda n,r=1:max(r,n and f(n/2,1+~-n/2%2*r))

Спробуйте в Інтернеті

Витягує двійкові цифри із nзворотного боку, повторно приймаючи n/2і n%2. Відстежує довжину поточного пробігу rрівних цифр, скидаючи його на 0, якщо останні дві цифри неоднакові, а потім додаючи 1.

Вираз ~-n/2%2- це показник того, чи є останні дві цифри рівними, тобто n0 або 3 по модулю 4. Перевірка двох останніх цифр разом виявилася коротшою, ніж запам'ятовування попередньої цифри.


14

05AB1E , 6 байт

b.¡€gM

Спробуйте в Інтернеті!

Пояснення

b       # convert to binary
 .¡     # split at difference
   €g   # map length on each
     M  # take max

2
ХА! Нарешті! Використання для , я можу припинити змушувати себе спробувати його використовувати.
Чарівний восьминога Урна

@carusocomputing: Досить впевнений, що я використав його в парі відповідей.
Емінья

9

Математика, 38 байт

Max[Length/@Split[#~IntegerDigits~2]]&

або

Max[Tr/@(1^Split[#~IntegerDigits~2])]&

9

Пітон, 53 байти

import re;lambda g:max(map(len,re.findall('1+|0+',bin(g))))

Функція анонімної лямбда.



9

Рубі, 41 40 байт

->b{("%b%b"%[b,~b]).scan(/1+/).max.size}

Знайдіть найдовшу послідовність '1' в b або її зворотну.

Завдяки манатурності за економію 1 байта.


2
Не впевнений в інших версіях, але в 2.3.1 немає необхідності у просторі між %bs.
манатура

Ви праві, негативні двійкові числа починаються з "..". Дякую.
ГБ

7

JavaScript (ES6), 54 байти

f=(n,r=0,l=1,d=2)=>n?f(n>>1,d^n&1?1:++r,r>l?r:l,n&1):l

Рекурсивне рішення з великою кількістю маніпуляцій. nзберігає вхід, rзберігає довжину поточного пробігу, lзберігає довжину найдовшого пробігу і dзберігає попередню цифру.

Фрагмент тесту

f=(n,r=0,l=1,d=2)=>n?f(n>>1,d^n&1?1:++r,r>l?r:l,n&1):l

for(var i of [0,1,2,3,4,5,6,7,8,9,16,893,1337371]) console.log(`f(${i}): ${f(i)}`)


1
Та ж ідея, але використовуючи більше бітових операцій та використовуючи конверсію за замовчуванням для невизначеного до 0. Не соромтеся позичати:f=(x,b,n,m)=>x?f(x>>1,x&1,n=x&1^b||-~n,m>n?m:n):m
edc65

7

Рубі, 51 44 43 байт

Функціональне рішення.

@manatwork зроблений з магії

->s{('%b'%s).scan(/0+|1+/).map(&:size).max}

Чи перевіряє це наявність послідовних однакових цифр чи просто послідовних 0s?
ngenisis

2
Неправильний результат за
893.

@orlp вже не! : D
Значення чорнила

1
Я б поєднати 1 - й і 2 - го рішення: ->s{s.to_s(2).scan(/0+|1+/).map(&:size).max}.
манатство

6

Python 2, 57 байт

a=lambda n:n and max((n&-n|~n&-~n).bit_length()-1,a(n/2))

Рекурсивне рішення. Можливо, може бути коротша форма для трохи чарів.


6

Perl, 43 байти

#!perl -p
\@a[$a+=$_-1+($_>>=1)&1||-$a]while$_;$_=@a

Підрахувавши шебанг як один, вхід береться з stdin.

Спробуйте в Інтернеті!


Шебангс рахується як 0 байт.
CalculatorFeline

@CalculatorFeline консенсус щодо мета - це те, що #!perlвважається нулем, а не #!perl -p.
примо

@CalculatorFeline: -pВитрати 1, якщо припустити, що у вашому командному рядку Perl так чи інакше буде аргумент (наприклад, -eабо -M5.010), тож ви можете просунути pодразу після одного з дефісів. #!perlВільно (хоча немає необхідності).

Добре знати. .
CalculatorFeline

5

Піп , 16 байт

Здається, що повинен бути коротший спосіб отримати пробіги однієї цифри ...

MX#*(TBa`1+|0+`)

Вводиться як аргумент командного рядка. Спробуйте в Інтернеті!

Пояснення

     TBa          1st cmdline arg, To Binary
    (   `1+|0+`)  Find all matches of this regex
  #*              Map length operator to that list
MX                Get the maximum and autoprint it

5

Perl 6 , 36 байт

{(.base(2)~~m:g/1+|0+/)».chars.max}

Пояснення:

{                                 }   # a lambda
  .base(2)                            # convert the argument to base 2
          ~~m:g/     /                # regex match, with global matching turned on
                1+|0+                 # match one or more 1, or one or more 0
 (                    )».chars        # replace each match by its length
                              .max    # take the maximum number

Спробуйте в Інтернеті .


4

Хаскелл, 79 символів

maximum.map length.group.i

де

import Data.List
i 0=[]
i n=mod n 2:i(div n 2)

Або у безгольовій версії:

import Data.List
pcg :: Int -> Int
pcg = maximum . map length . group . intToBin

intToBin :: Int -> [Int]
intToBin 0 = []
intToBin n = n `mod` 2 : intToBin (n `div` 2)

Пояснення:

intToBinперетворює int у список двійкових цифр (lsb спочатку). groupгрупує суміжні послідовності, такі, що [1, 1, 0, 0, 0, 1]стає [[1, 1],[0, 0, 0],[1]]. maximum . map lengthобчислює для кожного внутрішнього списку його довжину і повертає довжину найдовшої.

Редагування: Дякую @xnor та @Laikoni за збереження байтів


2
groupза замовчуванням не в Prelude, вам потрібно зробити це, import Data.Listщоб використовувати його.
xnor

1
Зверніть увагу , що ви можете використовувати охоронець на місці let: i n|(q,r)<-n`quotRem`2=r:i q. Подивіться наші поради щодо гольфу Haskell . quotRemможе бути divMod. Я думаю, ви можете використовувати i 0=[]в якості базового випадку.
xnor

1
Використання divі modбезпосередньо ще коротше: i n=mod n 2:i(div n 2).
Лайконі

3

Pyth, 7 байт

heSr8.B

Виконайте кодування довжини бінарного рядка, після чого відсортуйте його так, щоб найдовші запуски були останніми, а потім візьміть перший елемент (довжину) останнього елемента (найдовший запуск) списку.

У псевдокоді:

'  S     ' sorted(
'   r8   '   run_length_encode(
'     .BQ'     bin(input()) ))  \
'he      '   [-1][0]

3

J , 21 байт

[:>./#:#;.1~1,2~:/\#:

Спробуйте в Інтернеті!

Пояснення

[:>./#:#;.1~1,2~:/\#:  Input: integer n
                   #:  Binary digits of n
              2   \    For each continuous subarray of 2 digits
               ~:/       Reduce it using not-equals
            1,         Prepend a 1 to those results
     #:                Binary digits of n
        ;.1~           Cut the binary digits at each location with a 1
       #                 Get the length of each cut
[:>./                  Reduce those lengths using maximum and return

3

MATLAB 71 байт

m=1;a=diff(int8(dec2bin(a)));while(any(a==0)),m=m+1;a=diff(a);end;m

Це перетворює цілу змінну 'a' в двійковий масив int8, а потім підраховує кількість разів, яку результат повинен бути диференційований, поки в результаті не буде нуля.

Я тут новий. Чи дозволяється такий спосіб введення та однолінійного дозволу правилами PCG?


3
Ласкаво просимо до PPCG! За замовчуванням приймаються лише функції або повноцінні програми (не фрагменти коду). У вашому випадку це означає , вам потрібно ввести aз a=input('');. Також кілька порад щодо гольфу: ~aзамість a==0. Вам справді потрібно int8)?
Луїс Мендо

3

Октава , 31 байт

@(n)max(runlength(+dec2bin(n)))

Спробуйте в Інтернеті!

Пояснення

Це переклад моєї відповіді MATL. Мій початковий план був іншим підходом, а саме @(n)max(diff(find(diff([0 +dec2bin(n) 0])))). Але виявляється, що у Octave є runlengthфункція (про яку я щойно дізнався). За замовчуванням він виводить тільки масив довжини виконання, тому бажаним результатом є maxцей масив. Вихід dec2bin, що представляє собою масив char (рядок), що містить '0'і '1', повинен бути перетворений в числовий масив, використовуючи +, тому що runlengthочікує числовий ввід.


3

Утиліти Bash / Unix, 66 65 42 байти

Завдяки @DigitalTrauma за значні покращення (23 байти!)

dc<<<`dc -e2o?p|fold -1|uniq -c|sort -n`rp

Спробуйте в Інтернеті!


1
@DigitalTrauma Дякую за вдосконалення, особливо за включення складки, яка ще не була в моєму звичайному арсеналі.
Мітчелл Спектор

3

Bash (+ coreutils, + GNU grep), 33, 32 байти

ЗМІНИ:

  • Мінус 1 байт (вилучені лапки навколо вираження grep )

Гольф

dc -e2o$1p|grep -Po 1+\|0+|wc -L

Пояснив

 #Convert to binary
 >dc -e2o893p
 1101111101

 #Place each continuous run of 1es or 0es on its own line
 >dc -e2o893p|grep -Po '1+|0+'
 11
 0
 11111
 0
 1

 #Output the length of the longest line
 >dc -e2o893p|grep -Po '1+|0+'|wc -L
 5

Спробуйте в Інтернеті!


AFAIK, grep не є ні частиною bash, ні coreutils, хоча підтримується і розповсюджується самостійно . Не впевнений у постійному доступі, але він був автономним інструментом у світі GNU. Єдиним, що входить до складу ядер, є wc.
Мореакі

@Moreaki, grep - це POSIX, тому будь-яка відповідь на основі оболонки означає, що вона вже доступна. DC не є POSIX, але є стандартною частиною майже кожної * системи Nix навколо, тому зазвичай не згадується як окрема залежність.
зеппелін

Я вважаю, що ми знаходимося тут у двох різних напрямках думок: моя думка не полягала в тому, якщо grep - POSIX чи ні, моя думка полягала в тому, що заголовок вашого представлення мені вказував на те, що для того, щоб ваше рішення працювало, вам знадобиться bash + coreutils. це здається не так. Коли я прочитав її вперше, ця інформація мене бентежила. Якщо ви спробуєте своє рішення на завантаженій для macOS bash оболонці, воно не буде працювати; і не має значення, встановили ви Coreutils чи ні; вам знадобиться GNU grep, щоб він працював.
Мореакі

@Moreaki, так, я просто маю на увазі систему GNU, коли я кажу + coreutils, але це не завжди так. Я оновив назву, щоб бути більш точним.
зеппелін


2

C #, 106 байт

n=>{int l=1,o=0,p=0;foreach(var c in System.Convert.ToString(n,2)){o=c!=p?1:o+1;l=o>l?o:l;p=c;}return l;};

Відформатована версія:

System.Func<int, int> f = n =>
{
    int l = 1, o = 0, p = 0;
    foreach (var c in System.Convert.ToString(n, 2))
    {
        o = c != p ? 1 : o + 1;

        l = o > l ? o : l;

        p = c;
    }

    return l;
};

І альтернативний підхід, що отримує доступ до рядка за індексом у 118 байт, з пробілом, видаленим:

System.Func<int, int> f2 = n =>
{
    var s = System.Convert.ToString(n, 2);

    int l = 1, c = 1, i = 0;

    for (; i < s.Length - 1; )
    {
        c = s[i] == s[++i] ? c + 1 : 1;
        l = l < c ? c : l;
    }

    return l;
};

2

Javascript, 66 байт

x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.leng‌​th))

Завдяки манатурності за код.

Пояснення

x.toString(2)

Перетворити число у двійковий рядок.

split(/(0+|1+)/g)

Розділити різні символи (0 або 1) (цей регулярний вираз охоплює порожні пробіли, але їх можна ігнорувати)

map(y=>y.length)

Для кожного елемента масиву отримайте його довжину і помістіть його у повернутий масив.

...

Перетворити масив у список аргументів ([1,2,3] -> 1,2,3)

Math.max()

Отримайте найбільшу кількість аргументів.


1
З кредитування Значення Ink «и рішення Ruby , за натхнення, це може бути перетворено в x=>x.toString(2).split(/(0+|1+)/g).map(y=>y.length).sort().pop(). Або ж довжина: x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.length)).
манатура

3
Я думаю, вам може знадобитися додати предикат до функції сортування sort((a,b)=>b-a). За замовчуванням функція сортування розміщується 10між 1і 2.
Mama Fun Roll

Або ви можете використовувати Math.max, як пропонують манатурки.
Mama Fun Roll

Wtf, але вони числа. JS, будь ласка.

2

Диво , 27 байт

max.map#len.mstr`0+|1+`g.bn

Використання:

(max.map#len.mstr`0+|1+`g.bn)123

Перетворюється на двійкові, відповідає кожній послідовності 0 і 1, отримує тривалість кожного матчу та отримує максимум.


Чи перетворює це вхід у двійковий?
Лайконі

oooooh Я пропустив цю частину. Швидке виправлення: P
Mama Fun Roll

2

Пакетна, 102 байти

@set/a"n=%1/2,d=%1%%2,r=1+(%3+0)*!(0%2^d),l=%4-(%4-r>>5)
@if not %n%==0 %0 %n% %d% %r% %l%
@echo %l%

Порт відповіді @ edc65. %2.. %4буде порожнім під час першого дзвінка, тому я повинен записати вирази таким чином, що вони все ще працюватимуть. Найзагальніший випадок, про %3який мені довелося писати (%3+0). %2простіше, як це може бути 0або 1, що однакові в восьмериці, так 0%2працює тут. %4виявилося ще простіше, так як мені потрібно лише відняти від нього. (%4-r>>5)використовуються для порівняння lз , rяк Batch - й set/aне мають оператора порівняння.


2

Діалог APL , 22 байти

Анонімний поїзд функції

⌈/∘(≢¨⊢⊂⍨1,2≠/⊢)2⊥⍣¯1

⌈/∘(... Максимум результатів наступного анонімного тренінгу ...

≢¨  підрахунок кожного

⊢⊂⍨ розділ аргументу, де розділення визначається тими, що в

1, один прикинувся

2≠/ попарно неоднакові

 аргумент

) застосовується до

2⊥⍣¯1 від-base-2 застосовується негативно один раз (тобто до-base-2, один раз) до

 аргумент

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


2

Japt, 15 байт

2o!q¢ c ml n gJ

Перевірте це в Інтернеті! або Перевірте всі тестові випадки одразу .

Як це працює

                 // Implicit: U = input integer, J = -1
2o               // Create the range [0...2), or [0,1].
  ! ¢            // Map each item Z in this range to U.s(2)
   q             //                                        .q(Z).
                 // This returns the runs of 1's and 0's in the binary
                 // representation of U, respectively.
      c          // Flatten into a single list.
        ml       // Map each item Z to Z.length.
           n gJ  // Sort the result and grab the item at index -1, or the last item.
                 // This returns the largest element in the list.
                 // Implicit: output result of last expression

2

R, 45 34 байт

max(rle(miscFuncs::bin(scan()))$l)

Виправлено нерозумне непорозуміння завдяки @rturnbull та @plannapus.


Можливо, мені щось не вистачає, але чи не вхід повинен бути цілим числом, а не двійковим числом? І ми шукаємо максимальний пробіг 0чи 1не просто 0, правда?
rturnbull

@plannapus Я чесно не знаю. Повинен повністю пропустити специфікацію. Виправлено зараз.
Billywob

2

PowerShell , 78 74 73 байт

([regex]::Matches([convert]::ToString("$args",2),'0+|1+')|% Le*|sort)[-1]

Спробуйте в Інтернеті!

Тьху ці методи .Net

Це просто використовує регулярний вираз, щоб знайти (і співставити) суміжні послідовності одиниць і нулів, потім він бере Lengthвластивість (з новою схемою, яку я знайшов, що використовує маловідомий набір параметрів ForEach-Object, щоб зберегти 1 байт) отриманих об'єктів відповідності, сортує їх і виводить останній (найбільший).


1

J, 27 байт

>./>#&.>((1,2~:/\[)<;.1])#:

Дещо інший (і, на жаль, довший) підхід до відповіді миль .

Використання:

    >./>#&.>((1,2~:/\[)<;.1])#:893
5

Пояснення

>./>#&.>((1,2~:/\[)<;.1])#:
                         #: Convert to base 2
        (               )   A fork
                       ]    Previous result
         (1,2~:/\[)         Find where each new sequence begins
                   <;.1     Cut the string of integers based on where each sequence begins and box them
    #&.>                    Count under open - open each box and count the items in it
>./>                        Open all the boxes and find the maximum value

Я не думаю, що це дійсно - це не функція, і це фрагмент.
Conor O'Brien

@ ConorO'Brien Добре, я перегляну це ще пізніше.
Гарет
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.