Вычислить самую длинную серию из 1 в двоичном значении целого числа

32

Цель

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

Когда дан вход 0, вернитесь 0.

Если число имеет несколько полос одинаковой длины, вы должны вернуть позицию последней полосы.

вход

Целое число больше или равно 0.

Выход

Целое число, рассчитанное, как описано ниже.

правила

  • Это код-гольф, поэтому выигрывает самый короткий код в байтах на каждом языке.
  • Стандартные лазейки запрещены.

Примеры и тестовые случаи

Пример 1

  • Вашей функции передано целое число 142
  • 142 равно 10001110 в двоичном
  • Самая длинная полоса - "111" (полоса из трех)
  • Полоса начинается с позиции 2 ^ 1
  • Ваша функция возвращает 1 как результат

Пример 2

  • Вашей функции передано целое число 48
  • 48 равно 110000 в двоичном
  • Самая длинная полоса - "11" (полоса из двух)
  • Полоса начинается с позиции 2 ^ 4
  • Ваша функция возвращает 4 в результате

Пример 3

  • Вашей функции передано целое число 750
  • 750 равно 1011101110 в двоичном
  • Самая длинная полоса - "111" (полоса из трех)
  • Поскольку есть две полосы одинаковой длины, мы возвращаем более позднюю полосу.
  • Поздняя полоса начинается с позиции 2 ^ 5
  • Ваша функция возвращает 5 как результат
Де-факто
источник
1
Вам нужен критерий выигрыша, такой как code-golf
Okx
@Okx Это было упомянуто в самом теле, поэтому я добавил тег.
полностью человек
Убедитесь, что люди тестируют 0. Это важный контрольный пример.
mbomb007
2
Вместо «последней полосы» или «последней полосы» я бы предложил «полосу с наибольшей ценностью места».
aschepler
@Okx Зачем нужен критерий победы? Почему это не может быть просто загадкой?
CorsiKa

Ответы:

21

Желе , 10 8 байт

Ba\ÐƤṀċ¬

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

Как это работает

Ba\ÐƤṀċ¬  Main link. Argument: n


B         Binary; convert n to base 2.

   ÐƤ     Apply the link to the left to all postfixes of the binary array.
 a\         Cumulatively reduce by logical AND.

          For example, the array

          [1, 0, 1, 1, 1, 0, 1, 1, 1, 0]

          becomes the following array of arrays.

          [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
             [0, 0, 0, 0, 0, 0, 0, 0, 0]
                [1, 1, 1, 0, 0, 0, 0, 0]
                   [1, 1, 0, 0, 0, 0, 0]
                      [1, 0, 0, 0, 0, 0]
                         [0, 0, 0, 0, 0]
                            [1, 1, 1, 0]
                               [1, 1, 0]
                                  [1, 0]
                                     [0]

     Ṁ    Take the lexicographical maximum, i.e., the array with the most 1's at
          the beginning, breaking ties by length.

       ¬  Yield the logical NOT of n, i.e., 0 if n > 0 and 1 if n = 0.

      ċ   Count the occurrences of the result to the right in the one to the left.
Деннис
источник
Поздравляем!
Defacto
24

JavaScript (ES6), 41 40 36 34 байта

Сохранено 4 байта благодаря @ThePirateBay

f=x=>(k=x&x/2)?f(k):Math.log2(x)|0

Контрольные примеры

Как?

Общий случай x> 0

Мы рекурсивно И вход х с х / 2 который постепенно уменьшает последовательности последовательных установленных битов, пока не останется только самый правый бит последовательности. Мы сохраняем копию последнего ненулевого значения и определяем позицию его старшего значащего бита, округляя логарифм по основанию 2.

Ниже приведены шаги, которые мы проходим для x = 750 ( 1011101110 в двоичном виде).

    1011101110 --.
,----------------'
'-> 1011101110
AND 0101110111
    ----------
=   0001100110 --.
,----------------'
'-> 0001100110
AND 0000110011
    ----------
=   0000100010 --.  --> output = position of MSB = 5  (0000100010)
,----------------'                                         ^
'-> 0000100010
AND 0000010001
    ----------
=   0000000000

Крайний случай x = 0

Особый случай x = 0сразу приводит к Math.log2(0) | 0. Логарифм 0вычислений до -Infinityи двоичного побитового ИЛИ приводит к приведению к 32-разрядному целому числу. В соответствии со спецификацией абстрактной операции ToInt32 это дает ожидаемое 0:

Если число является NaN , +0 , −0 , + ∞ или −∞ , вернуть +0

Arnauld
источник
Это ошибки для ввода 0, который является частью диапазона ввода.
Джастин Маринер
@JustinMariner Исправлено.
Арно
А что Math.log2(k)|0вместо 31-Math.clz32(k)? Или я что-то упустил?
@ThePirateBay Math.log2(k)|0на самом деле и короче, и проще для особого случая x=0. Спасибо. :)
Арно
1
Очень хороший алгоритм и хорошее объяснение. Я реализовал это в 14 байтах машинного кода x86 .
Питер Кордес
12

машинный код x86, 14 байт

С помощью @ алгоритма Arnauld в части x &= x>>1и берущих самую высокую битовую позицию , установленную в предыдущем шаге xстановится 0.

Вызывается из C / C ++ с подписью unsigned longest_set(unsigned edi);в x86-64 System V ABI. Те же байты машинного кода будут декодироваться одинаково в 32-битном режиме, но стандартные соглашения о 32-битных вызовах не помещают первый аргумент edi. (Изменение регистра ввода на ecxили edxдля Windows _fastcall/ _vectorcallили gcc -mregparmможет быть сделано, не нарушая ничего.)

   address   machine-code
             bytes
                         global longest_set
 1                       longest_set:
 2 00000000 31C0             xor  eax, eax    ; 0 for input = 0
 3                       
 4                       .loop:               ; do{
 5 00000002 0FBDC7           bsr  eax, edi    ;  eax = position of highest set bit
 6                           ;; bsr leaves output unmodified when input = 0 (and sets ZF)
 7                           ;; AMD documents this; Intel manuals say unspecified but Intel CPUs implement it
 8 00000005 89F9             mov  ecx, edi
 9 00000007 D1E9             shr  ecx, 1
10 00000009 21CF             and  edi, ecx
11 0000000B 75F5             jnz .loop        ; } while (x &= x>>1);
12                       
13 0000000D C3               ret

Инструкция x86BSR (Bit Scan Reverse) идеально подходит для этого, предоставляя нам бит-индекс напрямую, а не считая начальные нули. ( bsrнапрямую не 32-lzcnt(x)выдает 0 для input = 0, как хотелось бы, но нам нужно bsr = 31-lzcnt для ненулевых входов, поэтому lzcntдаже не буду сохранять инструкции, не говоря уже о количестве байтов. Обнуление eax до работы цикла из-за bsr' s полуофициальное поведение оставления пункта назначения неизменным, когда ввод равен нулю.)

Это было бы еще короче, если бы мы могли вернуть позицию MSB самого длинного пробега. В этом случае lea ecx, [rdi+rdi](3 байта) будет копировать + left -shift вместо mov+ shr(4 байта).

Видеть эту ссылку TIO для вызывающего абонента asm, который делаетexit(longest_set(argc-1));

Тестирование с помощью цикла оболочки:

l=(); for ((i=0;i<1025;i++));do 
    ./longest-set-bitrun "${l[@]}";   # number of args = $i
    printf "$i %#x: $?\n" $i; 
    l+=($i); 
done | m

0 0: 0
1 0x1: 0
2 0x2: 1
3 0x3: 0
4 0x4: 2
5 0x5: 2
6 0x6: 1
7 0x7: 0
8 0x8: 3
9 0x9: 3
10 0xa: 3
11 0xb: 0
12 0xc: 2
13 0xd: 2
14 0xe: 1
15 0xf: 0
16 0x10: 4
17 0x11: 4
18 0x12: 4
19 0x13: 0
20 0x14: 4
21 0x15: 4

...

747 0x2eb: 5
748 0x2ec: 5
749 0x2ed: 5
750 0x2ee: 5
751 0x2ef: 0
752 0x2f0: 4
753 0x2f1: 4
754 0x2f2: 4
Питер Кордес
источник
1
Ницца! Примечание для тех, кто (как и я) более знаком с другими диалектами ассемблера: мнемоника x86 BSR расшифровывается как «Bit Scan Reverse», а не «Branch to SubRoutine».
Арно
@Arnauld: хороший момент, отредактированный для декодирования мнемоники, а также имеющий ссылку на запись справочного руководства insn.
Питер Кордес
5

Желе , 19 17 11 байт

HÐĿ&\ḟ0ṪBL’

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

-6 (!) Байтов благодаря острым наблюдениям @ Денниса

Как это работает

HÐĿ&\ḟ0ṪBL’
HÐĿ         - halve repeatedly until reaching 0 due to rounding
   &\       - cumulative AND
     ḟ0Ṫ    - final non-zero, or 0 if all elements are 0
        BL  - length of binary representation (log base 2). 0->[0]->1
          ’ - decrement
fireflame241
источник
Ошибки для 0, который находится в диапазоне ввода.
г-н Xcoder
@ Mr.Xcoder Исправлено
fireflame241
Вы можете сохранить байт для исправления сȯ-µ...
Джонатан Аллан
@JonathanAllan Я не понимаю, как поможет ИЛИ. У тебя есть код?
fireflame241
1
Поскольку Bвсегда возвращает массив, который начинается с 1 , BUṪMṪ’×Ṡможет стать ṪBL’. Кроме того, вам не нужно , и ḟ0сохраняет один байт ¹Ðf.
Деннис
5

Python 2 , 45 байт

f=lambda x:f(x&x/2)if x&x/2else len(bin(x))-3

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

Благодаря Деннису сэкономлено много байтов! (Главы len(bin(...))-3вместо math.frexp)

Спасибо @xnor за обнаружение ошибки, которая, к счастью, была легко исправима!

Мистер Xcoder
источник
Это, кажется, дает неправильные ответы, такие как x=3, я думаю, потому что and/orкороткое замыкание неправильно, когда функция возвращает 0.
xnor
@xnor Спасибо, что заметили это! Это фиксированный.
г-н Xcoder
4

Perl 6 ,45 35 байт

Эта сильно улучшенная версия любезно предоставлена ​​@nwellnhof.

{.msb+1-(.base(2)~~m:g/1+/).max.to}

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

Ramillies
источник
Вы можете просто соответствовать, :gчтобы получить все совпадения. С оператором smart-match я мог бы {sort(.base(2).flip~~m:g/1+/).tail.from}
увеличить
И до 35 байт:{.msb+1-(.base(2)~~m:g/1+/).max.to}
nwellnhof
@nwellnhof, большое спасибо. Я как-то пропустил :gи не понял, как я могу использовать наречие с оператором smartmatch. Также этот .msbметод очень полезен, и я не знал об этом раньше.
Ramillies
3

Python 2 , 89 78 байт

m=t=i=j=0
for c in bin(input()):
 t=-~t*(c>'0');i+=1
 if t>m:j=i;m=t
print i-j

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

РЕДАКТИРОВАТЬ: Сохранено 11 байтов благодаря Mr. Xcoder.

Час Браун
источник
86 байтов
г-н Xcoder
78 байт
г-н Xcoder
@ Mr.Xcoder Я тоже думал об этом, хотя вопрос специально просит написать функцию.
Джонатан Фрех,
@JonathanFrech Я не думаю, что ОП действительно означало функцию . Вероятно, просто общий термин.
г-н Xcoder
@ Mr.Xcoder Пожалуйста, объясни это. Спасибо,
спасательный круг
3

05AB1E , 14 12 11 байт

bDγàŠrkrJgα

Попробуйте онлайн! или запустить тестовые случаи .

объяснение

bDγàŠrkrJgα  Implicit input (ex: 750)
bD           Convert input to binary string and duplicate
                 '1011101110', '1011101110'
  γ          Split into groups of 1s or 0s
                 '1011101110', ['1', '0', '111', '0', '111', '0']
   à         Pull out max, parsing each as an integer
                 '1011101110', ['1', '0', '0', '111', '0'], '111'
    Šrk      Rearrange stack and get first index of max run of ones
                 ['1', '0', '0', '111', '0'], 2
       rJg   Reverse stack, join the array to a string, and get its length
                 2, 7
          α  Get absolute difference
                 5
Джастин Маринер
источник
3

J , 18 17 байт

(#-0{#\\:#.~\)@#:

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

объяснение

(#-0{#\\:#.~\)@#:  Input: integer n
               #:  Binary
     #\            Length of each prefix
       \:          Sorted down using
         #.~\      Mixed base conversion on each prefix
   0{              Get the value at index 0
  -                Subtract from
 #                 Length
миль
источник
Очень гладко Не уверен, что я полностью понимаю, что происходит со смешанным базовым преобразованием. Почему он считает количество последовательных единиц в конце строки? Кроме того, если все основания, указанные на xдиаде, равны 0 и 1, что это значит? Номер базы 2 имеет цифры 0и 1, следовательно, номер базы 1имеет цифры ... 0? тогда что 1значит в этом контексте? И 0всегда 0ли базовый номер ?
Иона
@Jonah Это связано с тем, как реализовано смешанное базовое преобразование. x #. yсначала вычисляет, w =: */\. }. x , 1затем возвращает+/ w * y
мили
так что вы считаете это хакерством для гольфа, а не законным использованием #., поскольку вы полагаетесь на внутренние детали реализации, а не на публичный API?
Иона
3

C # (.NET Core) , 64 60 байт

T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)

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

AC # версия ответа @ Арнаулда

Подтверждения

4 байта сэкономлено благодаря Кевину Круйссену.

C # (.NET Core) , 131 123 + 18 = 141 байт

a=>{string s=Convert.ToString(a,2),t=s.Split('0').OrderBy(x=>x.Length).Last();return a<1?0:s.Length-s.IndexOf(t)-t.Length;}

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

+18 байт для using System.Linq;

Подтверждения

8 байтов сэкономлено благодаря Гжегож Пулавски.

Degolfed

a=>{
    string s=Convert.ToString(a,2),      // Convert to binary
    t=s.Split('0')                       // get largest group of 1's
       .OrderBy(x=>x.Length)
       .Last();
    return 
        a<1?0:                          // handle 0 case
        s.Length-s.IndexOf(t)-t.Length; // get position in reversed string
}

C # (.NET Core) , 164 161 байт

a=>{var s=Convert.ToString(a,2);int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;for(;i>=0;i--){if(s[i]>'0'){if(i==j||s[i+1]<'1'){p=i;c=0;}if(++c>=l){l=c;k=p;}}}return j-k;}

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

Нерешенное Linqрешение, которое, я уверен, могло бы быть улучшено, хотя ничего не видно сразу.

Degolfed

a=>{
    var s=Convert.ToString(a,2); // Convert to binary
    int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;
    for(;i>=0;i--)               // Loop from end of string
    {
        if(s[i]>'0')             // if '1'
        {
            if(i==j||s[i+1]<'1') // if first digit or previous digit was '0'
            {
                p=i;             // set the position of the current group
                c=0;             // reset the count
            }
            if(++c>=l)           // if count is equal or greater than current largest count
            {
                l=c;             // update largest count
                k=p;             // store position for this group
            }
        }
    }
    return j-k;                  // as the string is reversed, return string length minus position of largest group
}
Ayb4btu
источник
1
Вы можете сэкономить 8 байт, отказавшись rот первого ответа: tio.run/##dY9RS8MwFIWfza/…
Гжегож Пулавски
Вы можете сохранить два байта в вашем порту Арнаулда следующим образом:T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
Кевин Круйссен
1
Или даже еще два сохраненных байта ( 60 байтов ):T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Кевин Круйссен
2

Шелуха , 12 байт

→S§-€¤≠Lo▲gḋ

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

объяснение

                 Implicit input, e.g                           750
           ḋ     Convert to binary                             [1,0,1,1,1,0,1,1,1,0]
          g      Group equal elements                          [[1],[0],[1,1,1],[0],[1,1,1],[0]]
        o▲       Maximum                                       [1,1,1]
    €            Index of that substring in the binary number  3
     ¤≠L         Absolute difference of lengths                abs (3 - 10) = 7
 S§-             Subtract the two                              7 - 3 = 4
→                Increment                                     5
H.PWiz
источник
2

Желе ,  14 13 12  11 байт

Bµṣ0Ṫ$ƤMḢạL

Монадическая ссылка, принимающая и возвращающая неотрицательные целые числа.

Попробуйте онлайн! или посмотрите набор тестов .

Как?

Bµṣ0Ṫ$ƤMḢạL - Main link: number, n                   e.g. 750
B           - convert to a binary list                    [1,0,1,1,1,0,1,1,1,0]
 µ          - monadic chain separation, call that b
      Ƥ     - map over prefixes:  (i.e. for [1], [1,0], [1,0,1], [1,0,1,1],...)
     $      -   last two links as a monad:                e.g.: [1,0,1,1,1,0,1,1]
   0        -     literal zero                                   0
  ṣ         -     split (prefix) at occurrences of (0)           [[1],[1,1,1],[1,1]]
    Ṫ       -     tail                                                        [1,1]
       M    - maximal indices                             [5,9]
        Ḣ   - head                                        5
          L - length (of b)                               10
         ạ  - absolute difference                         5
Джонатан Аллан
источник
У меня было похожее решение, но ŒrṪPвместо этого я использовал префиксы.
миль
2

Желе , 19 байт

BŒgḄṀB
BwÇɓÇL+ɓBL_‘

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

Спасибо Джонатану Аллану за спасение  4  6 байтов!

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

объяснение

BŒgḄṀB - монадическая вспомогательная ссылка. Будет использоваться с Ç в следующей ссылке.

Б - Двоичное представление.
 Œg - Групповые прогоны последовательных равных элементов.
   Ḅ - конвертировать из двоичного в целое число.
    Ṁ - Максимальное значение.
     B - Преобразовать из целого числа в двоичное.


BwÇɓÇL + ɓBL_ '- Основная ссылка.

B - двоичное представление (входных данных).
  Last - Последняя ссылка как монада. Принимает входное целое число.
 w - Первый индекс подсписка.
   Start - Начать отдельную двоичную цепочку. Меняет аргументы.
    Last - Последняя ссылка как монада.
     L - длина.
      + - Дополнение
       Start - Начать отдельную двоичную цепочку. Меняет аргументы.
        Б - Двоичный.
         L - длина.
          _ '- Вычтите и увеличьте результат (потому что Jelly использует 1-индексирование).
              - неявно вывод.
Мистер Xcoder
источник
BŒgḄṀBВместо этого может быть ваша вспомогательная ссылка
Джонатан Аллан
@JonathanAllan Ого, спасибо!
г-н Xcoder
Ваша главная ссылка может бытьBwÇɓÇL+ɓBL_‘
Джонатан Аллан
@JonathanAllan Wow, еще раз спасибо!
Мистер Кскодер
2

Котлин , 77 байт

{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}

украшенный

{
    val b = it.toString(2)
    // Find the left position of the first instance of
    b.reversed().lastIndexOf(
            // The largest group of 1s
            b.split(Regex("0+")).max()!!)
}

Тест

var s:(Int)->Int =
{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}
fun main(args: Array<String>) {
    r(0, 0)
    r(142, 1)
    r(48, 4)
    r(750, 5)
}

fun r(i: Int, i1: Int) {
    var v = s(i)
    println("$i -> $v [$i1] ${i1 == v}")
}
jrtapsell
источник
Я не тестировал, но думаю, что это работает и в Scala.
В. Куртуа
2

Haskell , 101 98 96 75 байт

snd.maximum.(`zip`[0..]).c
c 0=[0]
c n|r<-c$div n 2=sum[r!!0+1|mod n 2>0]:r

Попробуйте онлайн! Использование: snd.maximum.(`zip`[0..]).c $ 142урожайность 1.

Объяснение:

  • cпреобразует входные данные в двоичный файл, одновременно считая длину одной полосы, собирая результаты в виде списка. r<-c$div n 2рекурсивно вычисляет остальную rчасть этого списка, в то время как sum[r!!0+1|mod n 2>0]:rдобавляет текущую длину полосы к r. Понимание списка проверяет mod n 2>0, является ли текущая двоичная цифра единицей, и если да, берет длину предыдущей строки (первый элемент r) и добавляет единицу. В противном случае список понимания пуст, и sum[]дает 0. Для примера ввода c 142выдает список [0,3,2,1,0,0,0,1,0].

  • (`zip`[0..])добавляет позицию к каждому элементу предыдущего списка в качестве второго компонента кортежа. Для примера это дает [(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)].

  • maximumнаходит в этом списке лексикографически максимальный кортеж, то есть длины полос считаются первыми, поскольку они являются первым компонентом, а в случае связывания решает второй компонент, а именно больший индекс. Это дает (3,1)в примере и sndвозвращает второй компонент кортежа.

Laikoni
источник
2

C (gcc) , 81 80 байт

i,l,c,r;f(n){for(i=l=c=r=0;n;n/=2,i++)c=n&1?c+1:c>=l?r=i-(l=c),0:0;n=c<l?r:i-c;}

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

C (gcc) , 43 байта

AC версия ответа @ Arnauld

k;f(n){n=(k=n&n/2)?f(k):(k=log2(n))<0?0:k;}

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

cleblanc
источник
Пропустить возврат n; или вернуть k; заявление
РосЛюП
Предложить n<1?0:log2(n)вместо(k=log2(n))<0?0:k
потолок кошка
2

MS SQL Server, 437 426 407 398 байт

SQL Fiddle

Я уверен, что смогу удалить разрывы строк и т. Д., Но это настолько компактно, насколько я был готов сделать это:

create function j(@ int)
returns int
as BEGIN
declare @a varchar(max)='',@b int,@c int=0,@d int=0,@e int=0,@f int=0,@g int=0,@h int=0
while @>0 BEGIN SELECT @a=cast(@%2 as char(1))+@a,@=@/2
END
SET @b=len(@a)
while @<@b
BEGIN
select @c=@d,@d=cast(substring(@a,@b-@,1)as int)
IF @d=1
BEGIN IF @c=0
SELECT @e=@,@g=1
else SET @g+=1 END
IF @g>=@h BEGIN select @h=@g,@f=@e END
SET @+=1
END
return @f
END

Вот более читаемая версия:

create function BinaryString(@id int)
returns int
as BEGIN
  declare @bin varchar(max)
  declare @binLen int
  declare @pVal int = 0
  declare @Val int = 0
  declare @stC int = 0 --start of current string of 1s
  declare @stB int = 0 --start of biggest string of 1s
  declare @lenC int = 0 --length of current string of 1s
  declare @lenB int = 0 --length of biggest string of 1s

  set @bin = ''

    while @id>0
      BEGIN
        SET @bin = cast(@id%2 as varchar(1)) + @bin
        SET @id = @id/2
      END

    SET @binLen = len(@bin)

    while @id<@binLen
      BEGIN
        set @pVal = @Val
        set @Val = cast(substring(@bin,@binLen-@id,1) as int)
        IF @Val = 1 and @pVal = 0
          BEGIN 
            SET @stC = @id
            SET @lenC = 1
          END
        IF @Val = 1 and @pVal = 1
          BEGIN 
            SET @lenC = @lenC + 1
          END
        IF @lenC >= @lenB
          BEGIN
            set @lenB = @lenC
            set @StB = @StC
          END

        SET @id = @id + 1 
      END

  return @StB
END

Реальная хитрость в том, что, насколько я мог найти, нет встроенной функции SQL для преобразования числа из десятичного в двоичное. В результате мне пришлось вручную закодировать преобразование в двоичное, а затем сравнить его как строку, по одному символу за раз, пока я не нашел нужное число.

Я уверен, что есть лучший способ сделать это, но я не увидел (n) ответа SQL, поэтому я решил, что я его выброшу.

phroureo
источник
Если вы можете играть в гольф больше, пожалуйста, сделайте это. Но в остальном это здорово! Добро пожаловать в PPCG!
NoOneIsHere
@ NoOneIsHere спасибо! Я понял, что тоже могу сократить имя своей функции;)
phroureo
2

APL (Dyalog Unicode) , 22 символа = 53 байта

Требуется ⎕IO←0по умолчанию во многих системах.

⊃⌽⍸(∨⌿↑⊆⍨b)⍷⌽b2⊥⍣¯1⊢⎕

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

 запрос на ввод

 дать это (отделяется ¯1от )

2⊥⍣¯1 преобразовать в базу-2, используя столько позиций, сколько необходимо

b← хранить как b(для б )

 обратный

(... ) отметить начальные позиции следующего в этом:

⊆⍨b самостоятельное разбиение b(т.е. 1-полоски b)

 mix (сделать список списков в матрицу, заполнение нулями)

∨⌿ вертикальное уменьшение ИЛИ (дает самую длинную полосу)

of индикаторы стартовых позиций

 обратный

 выберите первый (дает ноль, если ничего не доступно)

Адам
источник
вы пропустили ∇ в нижнем колонтитуле на tio
ngn
@ngn Ты прав.
адам
1

MATL , 15 байт

`tt2/kZ&t]xBnq&

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

Использует половину и идею. Он kнеобходим только для его завершения 1- по какой-то причине 1 И 0.5 возвращает 1, вызывая бесконечный цикл.

(альтернативное решение: BtnwY'tYswb*&X>)-путем преобразования в двоичное кодирование и кодирование по длине прогона)

Б. Мехта
источник
1

Google Sheets, 94 байта

=Len(Dec2Bin(A1))-Find(MAX(Split(Dec2Bin(A1),0)),Dec2Bin(A1))-Len(MAX(Split(Dec2Bin(A1),0)))+1

Нет, это не очень красиво. Было бы очень приятно иметь возможность хранить Dec2Bin(A1)в качестве переменной для справки.

Ключевой момент: как и в Excel, Dec2Binфункция имеет максимальное значение ввода 511. Все, что больше этого, возвращает ошибку, как показано ниже.

Полученные результаты

Инженер Тост
источник
1

R, 117 байт

z=rev(Reduce(function(x,y)ifelse(y==1,x+y,y),strtoi(intToBits(scan())),,,T));ifelse(!sum(z),0,33-which.max(z)-max(z))
Захиро Мор
источник
104 байта! Вместо этого revиспользуйте Reduce(...,T,T)для накопления справа (переключение x,yв определении функции). Тогда используйте, 1+max(z)-which.max(z)так как результат несколько отличается. Используйте "if"вместо того, чтобы "ifelse"нам не нужна векторизация; aa, и если вы используете any(z)вместо !sum(z)вас сбросить байт.
Джузеппе
Я думаю, что мы должны быть в состоянии получить это до менее чем 100 байтов.
Джузеппе
@giuseppe Я чувствую себя немного обманщиком, потому что я здесь, перед тобой! Будет делать раз TNX кучу!
Захиро Мор
Но хорошего подхода нет?
Захиро Мор
1
О, не беспокойтесь, я видел это раньше, но не хотел отвечать на него, потому что R настолько плох в битовых операциях ... Да, хорошая работа, вы получили мой +1
Giuseppe
1

Excel VBA, 54 44 байта

-10 байт благодаря @EngineerToast

Функция анонимного непосредственного окна VBE, которая берет входные данные из диапазона [A1]и выводит в непосредственное окно VBE

?Instr(1,StrReverse([Dec2Bin(A1)]),1)+[A1>0]
Тейлор Скотт
источник
1
Помимо того, что надзор C1все еще присутствует вместо A1, я думаю, вы можете вывести Instrрезультаты напрямую, слегка повернув для коррекции нулевого ввода: ?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)(46 байт). True = -1, потому что ... VBA.
Тост инженера
@EngineerToast - Сладкий! Я должен был увидеть это; Я смог отбросить его на 2 байта, введя >0в [A1]нотацию
Тейлор Скотт
0

R, 66 байт

function(i){a=rle(intToBits(i));max(0,a[[1]][which(a[[2]]==1)])}

Объяснение:

function(i){
  a = rle(                  # Run-length encode
    intToBits(i)            # The bits in i
  );                        # And assign it to a.
  max(0,                    # Return the maximum of zero and
      a[[1]][               # The lengths of a,
        which(a[[2]]==1)    # But only those where the repeated bit is 1
        ])
}
Джулиан Цукер
источник
1
Это возвращает длину самой длинной полосы, а не ее положение. Сверьтесь с контрольными примерами и спецификациями в верхней части.
user2390246
Я изменю свое отрицательное голосование на положительное, как только этот ответ будет исправлен. Также обратите внимание, что вы можете использовать a$lвместо a[[1]]и a$vвместо того, a[[2]]чтобы сохранять некоторые байты :), а также >0вместо ==1.
Джузеппе
0

Javascript, 54 символа

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) получает двоичную строку для целого числа.
  • .split(0)Получает каждый последовательный одни части в качестве элемента массива.
  • .sort().reverse() получает первую наивысшую ценность.
  • Это [0].lengthдает нам длину этого первого значения.
п-х
источник
the starting position of number of largest consecutive 1's
L3viathan
0

Perl 5, 45 + 1 (-p)

(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'

Если вы напишите это в командной строке большинства оболочек, вам, возможно, придется ввести это как:

perl -pE'(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'"'"

Танец кавычек в конце состоит в том, чтобы увидеть perl ', который иначе был бы использован оболочкой.


источник
0

Retina , 52 43 байта

Преобразовать в двоичный файл, а затем заменить его длиной, следующей за самой большой строкой из них.

.*
$*
+`(1+)\1
$+0
01
1

$'¶
O`
A-3`
^1+

.

Попробуйте онлайн - все тестовые случаи

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

mbomb007
источник
Вы можете использовать $+для ${1}. Но вы можете сэкономить еще больше, заменив последний этап следующим набором
Мартин Эндер
@MartinEnder Хорошо. ${1} был скопирован из вашего урока на Github.
mbomb007