Візьміть з нього байт!


24

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


Приклад

Враховуючи число 7831, ми спочатку перетворюємо його у двійкове (видаляючи будь-які провідні нулі):

1111010010111

Потім ми знаходимо послідовну групу з 8 біт, яка при видаленні дасть найбільший новий результат. У цьому випадку є 3 рішення, показані нижче

1111010010111
  ^      ^       
   ^      ^
    ^      ^

Видаляючи це будь-який із цих результатів 11111, який ми перетворюємо назад у його десяткове значення 31для відповіді.


Випробування

256        ->   1
999        ->   3
7831       ->   31
131585     ->   515
7854621    ->   31261
4294967295 ->   16777215 (if your language can handle 32 bit integers)

Правила

  • Гарантується, що довжина бітів nбуде більше 8.
  • Теоретично ваше рішення повинно працювати для будь-якої довжини бітів, що nперевищує 8, але на практиці потрібно працювати лише для цілих чисел 255 <n <2 16
  • Введення / вихід повинен бути десятковим.
  • Ви можете подати повну програму або функцію.
  • Це , тому найкоротша програма (у байтах) виграє!

1
Я не розумію, чому люди ставлять знаки оклику в заголовках викликів! Я думаю, що це може бути обмеження характеру! Можливо, просто так, щоб люди помітили виклик!
dkudriavtsev

1
@ Менделєєв Це імперативний вирок. Зазвичай вони закінчуються знаками оклику. Це лише правильна пунктуація, чому це так вас засмучує?
Артур

1
@ Менделеев Люди часто використовують знак оклику, щоб позначити жарт. ОП підкреслює той факт, що він робить каламбур. Ф. Скотту Фіцджеральду це не сподобалось , але в цьому контексті мені це здається прекрасним. Якби його не було, ви, мабуть, змусили людей скаржитися на його написання.
bornfromanegg

@ Менделєєв, тому що це поганий каламбур ...
FlipTack

@bornfromanegg Я відчуваю, що люди помітять каламбур
dkudriavtsev

Відповіді:


16

Желе , 6 байт

BḄ-8ƤṀ

Монадійне посилання, що приймає номер і повертає номер.

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

Як?

Використовує хороший швидкий , Ƥ, розроблений миль ...

BḄ-8ƤṀ - Link: number
B      - convert to a binary list
    Ƥ  - for loop over some slices to be determined...
  -8   - this is a negative nilad, therefore: use overlapping outfixes of length 8
       -   (exactly what the specification asks us to inspect)
 Ḅ     -   convert from a binary list to an integer (vectorises)
     Ṁ - maximum

> _> ... Вау, ти побив мене на 10 байт
містер Xcoder

8

J , 12 байт

[:>./8#.\.#:

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

          #:     to binary
     8  \.       remove consecutive groups of eight
      #.         convert each result to decimal
  >./            maximum
[:               do nothing, this lets me avoid parentheses

Який витончений алгоритм у вас є? Чи можете ви додати пояснення?
Містер Xcoder

@Містер. Xcoder FrownyFrog перетворює число до списку двійкових цифр (#:), потім перетворює всі 8-вирядники або список із послідовними 8-бітовими інфіксами, видаленими назад, у десяткову систему числення (8 #. \). найбільший. [: просто обмежує два попередні дієслова, роблячи> ./ виконуватись монадно (лише з правильним аргументом)
Гален Іванов

Ти навчив мене сьогодні про перехід, спасибі за це! Прикро, що, здається, не коротше використовувати недо- &.; це ідеальна проблема для нього.
Коул


6

JavaScript (ES6), 54 байти

f=(n,v=n>>8,b=1,m=0)=>b>v?m:f(n,(v^n)&b^v,b+b,v>m?v:m)
<input type=number min=256 max=2147483647 oninput=o.textContent=f(this.value)><pre id=o>

Працює до 2 ** 31-1. Тому що хтось попросив трохи подвійну відповідь ...



3

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

Max@Array[Drop[#&@@s,#;;#+7]~FromDigits~2&,Last[s=#~RealDigits~2]-7]&

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

Це рішення працює для великої кількості Спробуйте в Інтернеті!

-3 байти від KellyLowder


Збережіть ще 3 байти:Max[c=#~RealDigits~2;Array[Drop[c[[1]],#;;#+7]~FromDigits~2&,Last@c-7]]&
Келлі Лоудер

1
@KellyLowder приємно! Я трохи більше пограла на ваше рішення
J42161217


3

Мова Вольфрама (Mathematica) , 46 байт

Floor@If[#<256,0,Max[#/256,2#0[#/2]+#~Mod~2]]&

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

Ця версія може обробляти лише входи до 2 518 -1, інакше ми стикаємося з обмеженням розміру стека Mathematica. (Обмеження може відрізнятися між установками Mathematica.) Друге рішення у цій відповіді уникає цього.

Як це працює

Рекурсивний підхід, заснований на такій логіці:

  • Максимальне значення має бути 0для будь-якого введення менше 256, оскільки виведення байта з числа з'їдає все число. Це наш базовий випадок, і тому він включений, навіть якщо специфікації обіцяють нам, що нам не доведеться обробляти такі входи.
  • В іншому випадку ми беремо Maxдва варіанти: з'їдаємо найнижчий байт (даючи нам вхід розділений на 256) або рубаємо найнижчий біт, повторюємо решту цілого числа і додаємо найнижчий біт назад, коли ми закінчимо.

Мова Вольфрама (Mathematica) , 55 байт

Max@Table[Mod[#,m=2^k]+Floor[#/m/2^8]m,{k,0,Log2@#-8}]&

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

Альтернативна версія, яка створює таблицю замість рекурсії, тому вона працює для чисел будь-якого розміру, з якими може мати Mathematica.


2
Глибина рекурсії перевищується для чисел більше 10 ^ 160, хоча математика може обробляти більші числа. Але я здогадуюсь, що ОП із цим добре
J42161217

2

Сітківка , 71 67 64 байт

.+
$*
+`(1+)\1
$+0
01
1
.
$`_$'¶
_.{7}

A`_
O^`
1G`
+1`\B
:$`:
1

Спробуйте в Інтернеті! Посилання включає лише більш швидкі тестові випадки, щоб не надмірно перевантажувати сервер Dennis. Редагувати: збережено 3 байти завдяки @MartinEnder. Пояснення:

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

Перетворити з десяткової у двійкову.

.
$`_$'¶
_.{7}

A`_

Побудуйте список рядків, отриманих шляхом видалення 8 послідовних цифр усіма можливими способами.

O^`
1G`

Сортуйте їх у зворотному порядку і візьміть перший (найбільший).

+1`\B
:$`:
1

Перетворити назад у десятковий. (Див. Пояснення @ MartinEnder .)




2

ReRegex , 294 275 байт

Збережено 19 байт, використовуючи кращі визначення функції

Я б сказав, що це досить добре для мови, що відповідає лише Regex.

Базова вкладка дозволяє перетворювати між Unary та Decimal (Що потрібно, оскільки специфікація виклику чітко зазначає десятковий), але не підтримує Binary; Тому мені довелося написати це як частину сценарію, додавши до нього 120 байт.

#import base
b(\d*):(_*)\2_b/b1$1:$2b/b(\d*):(_+)\2b/b0$1:$2b/b(\d+):b/$1/b:b/0/B(_*):1/B$1$1_:/B(_*):0/B$1$1:/B(_*):B/$1/j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/j(\d*),\1\d{0,7}:,?(.*)/,$2,/,((_+)_+),(\2),/,$1,/,(_+),(\1_*),/,$2,/^,(_*),$/d<$1>/j,b:u<(?#input)>b:

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

За окремими реджексами.

#import base
b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
^,(_*),$/d<$1>/
j,b:u<(?#input)>b:

Кроки

По-перше, ми імпортуємо «базову» бібліотеку, яка дає два регулярні вирази. Той, який перетворюється u<numbers>в одинарний. І той, який перетворюється d<unary_underlines>назад у десятковий. Це тому, що для виклику потрібен IO в базі10.

Тоді ми визначаємо жменю регулярних виразів, які перетворюють унарне в бінарне.

b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/

Перший з них - b(\d*):(_*)\2_b/b1$1:$2b/пошук, за bбажанням - кілька двійкових цифр, потім - а :, потім будь-яка кількість підкреслень, а потім точно така ж кількість підкреслень плюс одна, і нарешті інша b.

Потім ми замінюємо це b1наступним двійковим розрядом від раніше, :і лише першою половиною підкреслення, і, нарешті, останньою b.

Таким чином, це перевіряє, чи унар не ділиться на два, і якщо так, то попередньо 1 до його двійкових цифр, а потім ділить його мінус одна на дві.

Другий b(\d*):(_+)\2b/b0$1:$2b/- майже ідеальний, проте не перевіряє додатковість _, тобто він відповідає лише тому, що він розділений на два, і в цьому випадку створює попереднє 0замість цього.

Третій перевіряє, чи немає у нас одинарних цифр, а якщо так, то знімає прокладку, щоб просто залишити двійкові цифри.

Останній перевіряє, чи ніколи не було надано жодних двійкових цифр, і в цьому випадку просто залишає 0.

Наступна група регексів, яку ми визначимо, - перетворити бінарне назад в одинарне і є дещо простішим.

B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/

Перший з цієї групи, B(_*):1/B$1$1_:/як і його антитеза, виявляє a B, а потім будь-яку кількість унарних цифр :1. У Bцьому випадку він не перевіряє відповідність , оскільки він шукає лише одну цифру за один раз. Якщо це збігається, він подвоює попередньо узгоджену кількість одинарних цифр і додає одну, а потім видаляє одну.

Другий, B(_*):0/B$1$1:/майже ідеальний для першого, за винятком відповідностей, 0а не а 1, і не додає додаткових одинарних цифр.

Останній із них B(_*):B/$1/перевіряє, чи немає більше двійкових цифр, і якщо так розгортається одинарний. На відміну від його антитези, для цього не потрібен спеціальний випадок 0.

Далі ми визначаємо jрегулярні вирази, які виконують функції розщеплення.

j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/

Перший, j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/робить більшість важких підйомів. Він шукає, за jбажанням, слідом за двійковими цифрами, які є "інкрементом", потім комою, за якою збільшується, точнісінько 8 двійкових цифр, а потім решта двійкового числа, а потім :. Перша з 8 цифр додається до інкременту, збільшуючи його, тоді все, крім цих 8 цифр від двійкового вводу, додається після :наступного a ,. Тож (якби ми використовували 2 цифри замість 8), j,1001:це стане j1:1001:,01тоді j10:1001,01,11. Крім того, додані елементи масиву загортаються в Bs, щоб перетворити їх назад в одинакові.

Інший, j(\d*),\1\d{0,7}:,?(.*)/,$2,/перевіряє, чи залишилось менше 8 двійкових цифр для перевірки після інкременту, і якщо так, видаляє все, крім масиву, загорнутого в ,s. Напр.,_,___,

Під час та після створення масиву ми визначаємо регекси порівняння.

,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/

Перший з них ,((_+)_+),(\2),/,$1,/перевіряє кому, а потім деяку кількість підкреслення, потім ще декілька, після чого кома, потім перша кількість підкреслення, ніж кома. Потім він замінює його загальною кількістю підкреслень у першому елементі, оточеному ,s.

Останнє, ,(_+),(\1_*),/,$2,/перевіряє наявність коми через якусь кількість підкреслень, а потім інша кома, потім така ж кількість або більше підкреслення і остання кома. Це замість цього залишить потрібний елемент.

Нарешті, коли на елементі залишився такий елемент, що збігається ^,(_*),$, ми видаляємо навколишні коми і перетворюємо назад у десятковий знак через d<>. Тоді більше регексів не може вистрілити, і результат буде представлений

Вхід спочатку поміщається в шаблон j,b:u<(?#input)>b:, який спочатку перетворює десятковий вхід в одинарний, наприклад 5-> j,b:_____b:, потім отриманий унарний у двійковий, j,101:Потім розбиває двійковий (який не працює для прикладу), отримує найбільший елемент, перетворює повернутися до десяткової, і зроблено.


2

C (gcc), 91 байт

j;m;t;f(x){for(j=m=0;t=x>>j+8;m<t?m=t:j++)t=t<<j|x%(1<<j);return m;}

-23 байти від Colera Su

Підтримує до 2**31-1

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

Починається з низьких 8 біт (j=0), потім піднімається вгору, змінюючи вихід, якщо число з [j,j+8)вирізаними бітами більше, ніж наше поточне, і продовжується, поки х не має бітів вищеj+8


2
Зберігати x>>j+8і x>>j+8<<j|x%(1<<j)в змінної (круглі дужки видалені) зменшить його до 68 байт .
Колера Су


1

JavaScript (ES6), 94 91 байт

-3 байти завдяки Джастіну Марінеру

f=(n,d='',c=n.toString(2).match(`(${d}).{8}(.*)`))=>c?Math.max('0b'+c[1]+c[2],f(n,d+'.')):0

Просто викидаючи на основі рядка JavaScript рішення, але я сподіваюся, що хтось опублікує окреме розрядне рішення, щоб я міг щось навчитися.

Моє рішення рекурсивно захоплює 8-бітний шматок із рядка, приймаючи максимальне значення, яке знайдено.


1
Я думаю, ви можете відкинути те, +(...)що перетворюється '0b'+c[1]+c[2]на число, бо це Math.maxвже робиться. Спробуйте в Інтернеті! ( специфікація для подальшої довідки )
Джастін Марінер

@JustinMariner, солодкий, дякую!
Рік Хічкок

1

C # (.NET Core) , 122 + 13 = 135 120 + 13 = 133 байт

n=>{int m=0,i=0,t;for(var b=Convert.ToString(n,2);i<b.Length-7;m=t>m?t:m)t=Convert.ToInt32(b.Remove(i++,8),2);return m;}

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

+13 для using System;

Я думаю, є спосіб зробити це за допомогою використання Convert. Так чи інакше, я впевнений, що це можна зменшити.

Подяка

-2 байти завдяки Кевіну Крейсейну

UnGolfed

n=>{
    int m=0,
        i=0,
        t;

    // convert n to a binary string,
    // go through removing each possible byte,
    // check if this is the biggest int so far
    for (var b=Convert.ToString(n,2); i<b.Length-7; m=t>m?t:m)
        t=Convert.ToInt32(b.Remove(i++,8),2); // remove 8 bits from position i, then convert from binary string to int

    return m;
}

Ви можете зберегти байти, змінюючи whileдо forі поклавши var bв ньому:for(var b=Convert.ToString(n,2);i<b.Length-7;)
Кевін Cruijssen

І ви можете зберегти ще 1 байт, додавши нову змінну int, ,tне використовуючи Math.Max, а замість цього встановіть вручну перевірку: n=>{int m=0,i=0,t;for(var b=Convert.ToString(n,2);i<b.Length-7;m=t>m?t:m)t=Convert.ToInt32(b.Remove(i++,8),2);return m;}( 120 + 13 байт )
Kevin Cruijssen


1

Pyth, 19 байт

eSmi.>>.<.BQd8d2a6l

Альтернативна відповідь:

eSmi.<<8.>.BQdd2a6l

Пояснення:

eSmi.>>.<.BQd8d2a6lQ | Implicit Q at the end, where Q = input
  m             a6lQ | Map the over [0, 1, 2, ... , floor(log base 2 of Q) - 7]
         .BQ         |  Convert Q to binary string
       .<   d        |  Cyclically rotate left by d
      >      8       |  Get string from position 8 to end.
    .>        d      |  Cyclically rotate right by d
   i           2     |  Convert from binary string to integer
eS                   | Find the last element of sorted list (maximum value)

Інша відповідь використовує аналогічний підхід, за винятком того, що він спочатку обертається прямо і отримує всі біти, крім 8 останніх.


1

MATL , 23 21 байт

Bn8-:"GB[]@8:q+(XBvX>

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

B                       % Implicitly grab input, convert to binary
 n8-:                   % Create list of 1,2,... n-8, with n the size of the binary string
     "                  % Loop over this list
      GB                % Grab the input again, convert to binary once more.
        @8:q+           % Create indices of a slice of length 8
             [](        % Index into binary string, delete the slice
                XB    % Convert the remainder from binary to integer
                  vX> % Get the maximum number so far.

На жаль, Bn8-:8:!+q&)тільки шматочки потрібно видалити, а не залишок, який ми хотіли б зберегти.


Це економить пару байтів: Bn8-:"GB[]@8:q+(XBvX>(надайте []з (замість того , щоб використовувати &), і замінити &:на :і доповнення)
Luis Mendo

@LuisMendo Дякую Я неправильно прочитав документи, які десь сказали, що ви можете використовувати лише один індекс для нульових завдань, але для іншої ситуації.
Санчіз


0

Октава , 81 80 байт

@(x)max(bin2dec(dec2bin(x*(c=2.^(0:(b=nextpow2(x+1)-8))))(:,[1:b b+9:end]))'./c)

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

Це інше рішення моєї оригінальної спроби, заощадивши ще 14 байт.

Код розбивається так:

@(x)max(                                                                       )
        bin2dec(                                                          )'./c
                                                         (:,[1:b b+9:end])
                dec2bin(x*(                            ))
                           c=2.^(0:                   )
                                   (b=nextpow2(x+1)-8)

На шостому рядку кількість груп обчислюється шляхом знаходження показника наступної потужності на дві більше, ніж вхідний (кількість біт у вхідному номері), і віднімання 7, як ми вилучаємо 8 біт з кожної групи - отримане число зберігається в bподальшому.

Потім обчислюємо масив потужностей двох на п’ятому рядку, який достатньо великий для всіх можливих груп, які можна видалити. Ми зберігаємо це у змінній cдля подальшого.

На наступному рядку вгору (четвертий рядок) ми множимо вхід на масив двох потужностей (по суті, бітове зміщення кожного числа вгору) і перетворюємо результат у бінарний. Якщо взяти приклад 7831, це призведе до двовимірного масиву, що містить:

000001111010010111
000011110100101110
000111101001011100
001111010010111000
011110100101110000
111101001011100000

Якщо ми потім відсікаємо 8 біт по центру, це еквівалентно видаленню кожної з груп з 8 біт. Це робиться третім рядком.

Отриманий масив перетворюється назад у десятковий у другому рядку. Нам також слід розділити, cщоб скасувати масштабування, яке було зроблено для кожної групи спочатку.

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


  • Збережіть 1 байт за допомогою, nextpow2(x+1)а неnnz(bin2dec(x))


Оригінальна спроба - 120 98 95 байт

@(x)max(bin2dec(reshape(repmat(a=(d=@dec2bin)(x)',1,b=nnz(a)-7)(d(255*2.^(0:b-1))'<49),[],b)'))

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

Код розбивається так:

@(x)max(                                                                                      )
        bin2dec(                                                                             )
                reshape(                                                              ,[],b)'
                        repmat(a=(d=@dec2bin)(x)',1,b=nnz(a)-7)(                     )
                                                                d(255*2.^(0:b-1))'<49

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

Робоча лінія за рядком, п'ятий рядок обчислює групи, які можна видалити. Наприклад, візьміть 7831. Це 13-бітове число, яке дає групи:

1111100000000
1111000000001
1110000000011
1100000000111
1000000001111
0000000011111

Результатом п'ятого рядка є 2D логічний масив, який можна використовувати для індексації.

Четвертий рядок коду перетворює вхід у масив бітів (представлений у вигляді символів '0' і '1'), а потім повторює його n-7 разів (де nкількість біт), даючи по одному рядку для кожної можливої ​​групування. Наведена вище маска групи використовується для видалення кожної з можливих груп.

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


  • Збережено 22 байти, генеруючи матрицю груп за допомогою математики.
  • Збережено 3 байти при перетворенні з бінарних рядків у маску логічної групи.



0

Perl, 53 байти

( use 5.10.1доведення перла до рівня затримки 5.10.1 безкоштовно)

Дайте вхідний номер на STDIN. Пам’яті для великої кількості не вистачить, але 32-бітове число на вході ще не є проблемою

#!/usr/bin/perl
use 5.10.1;
$_=sprintf"%b",<>;/.{8}(?{\$F[oct"0b$`$'"]})^/;say$#F
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.