Возьми байт из этого!


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
Я не понимаю, почему люди ставят восклицательные знаки в заголовках задач! Я думаю, что это может быть ограничением персонажа! Может быть, люди просто заметят проблему!
дкудрявцев

1
@Mendeleev Это обязательное предложение. Они обычно заканчиваются восклицательными знаками. Это только правильная пунктуация, почему тебя это так огорчает?
Артур

1
@Mendeleev Люди часто используют восклицательный знак, чтобы указать на шутку. ОП подчеркивает тот факт, что он делает каламбур. Ф. Скотту Фицджеральду это не понравилось , но в этом контексте мне кажется, что это нормально. Если бы этого не было, вы бы, вероятно, заставили людей жаловаться на его правописание.
bornfromanegg

@Mendeleev, потому что это плохой каламбур ...
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 #. \.) И, наконец, принимает самый большой. [: просто перекрывает два предыдущих глагола, заставляя> ./ исполняться монадически (только с правильным аргументом)
Гален Иванов

Вы рассказали мне сегодня об outfix, спасибо за это! Обидно, кажется, не короче использовать под &.; это идеальная проблема для него.
Коул


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

Mathematica, 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

Wolfram Language (Mathematica) , 46 байтов

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

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

Эта версия может обрабатывать только входы до 2 518 -1, в противном случае мы столкнемся с ограничением размера стека Mathematica. (Граница может варьироваться в зависимости от установки Mathematica.) Второе решение в этом ответе позволяет избежать этого.

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

Рекурсивный подход, основанный на следующей логике:

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

Wolfram Language (Mathematica) , 55 байтов

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

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

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


2
Глубина рекурсии превышена для чисел, превышающих 10 ^ 160, хотя mathematica может обрабатывать большие числа. Но я думаю, что с OP все в порядке
J42161217

2

Retina , 71 67 64 байта

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

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

Попробуйте онлайн! Ссылка включает только более быстрые тестовые случаи, чтобы не перегружать сервер Денниса. Редактировать: 3 байта сохранены благодаря @MartinEnder. Объяснение:

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

Преобразовать из десятичной в двоичную.

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

A`_

Составьте список строк, полученных путем удаления 8 последовательных цифр всеми возможными способами.

O^`
1G`

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

+1`\B
:$`:
1

Конвертировать обратно в десятичную. (См @ MartinEnder по мотивам .)


1
Я придумал этот более короткий двоичный код в десятичное преобразование некоторое время назад. Я объяснил, как это работает в этом ответе .
Мартин Эндер


2

ReRegex , 294 275 байт

Сохранено 19 байт, используя лучшие определения 'function'

Я бы сказал, что это очень хорошо для языка Regex.

Базовая библиотека допускает преобразование между унарным и десятичным (что необходимо, поскольку в спецификации вызова явно указывается десятичное число), но не поддерживает двоичный код; Поэтому мне пришлось написать это как часть скрипта, добавив в него 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> обратно в десятичную. Это потому, что проблема требует ввода-вывода в base10.

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

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, возможно, следуют несколько двоичных цифр, затем a :, затем любое количество подчеркиваний, за которым следует точно такое же количество подчеркиваний плюс один и, наконец, еще один 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/проверяет, нет ли больше двоичных цифр и разворачивает ли унарный символ. В отличие от своей противоположности, для этого не требуется особый случай.

Далее мы определяем 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 двоичных цифр, за которыми следует остальная часть двоичного числа, а затем a :. Первая из 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 байта от Колеры Су

Поддерживает до 2**31-1

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

Начинается с младших 8 битов (j=0), затем идет вверх, изменяя выход, если число с [j,j+8)вырезанными битами больше нашего тока, и продолжается до тех пор, пока у x не будет битов выше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 байт )
Кевин Круйссен,


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 Спасибо. Я неправильно прочитал документы, где говорилось, что вы можете использовать только один индекс для нулевых назначений, но для другой ситуации.
Sanchises


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

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

Четвертая строка кода преобразует входные данные в массив битов (представленных в виде символов «0» и «1»), а затем копирует его n-7 раз (где nв количестве битов), давая одну строку для каждой возможной группировки. Маска группы выше используется для удаления каждой из возможных групп.

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


  • Сохранено 22 байта путем генерации матрицы групп с использованием математики.
  • Сохранено 3 байта при преобразовании из двоичных строк в маску логической группы.



0

Perl, 53 байта

( use 5.10.1перевод на Perl до уровня языка 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.