Tire um byte dele!


24

Sua tarefa é, dado um número inteiro não assinado n, encontrar o maior número que pode ser criado removendo um único byte (8 bits consecutivos) de dados.


Exemplo

Dado o número 7831, primeiro o convertemos em binário (removendo quaisquer zeros iniciais):

1111010010111

Em seguida, encontramos o grupo consecutivo de 8 bits que, quando removido, produzirá o maior resultado novo. Nesse caso, existem 3 soluções, mostradas abaixo

1111010010111
  ^      ^       
   ^      ^
    ^      ^

Removendo isso, qualquer um desses rendimentos 11111, que depois convertemos de volta ao seu valor decimal 31para a resposta.


Casos de teste

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

Regras

  • É garantido que o comprimento do bit nserá maior que 8.
  • Teoricamente, sua solução deve funcionar com qualquer bit nmaior que 8, mas, na prática, só precisa funcionar para números inteiros 255 <n <2 16
  • Entrada / Saída deve estar em decimal.
  • Você pode enviar um programa completo ou uma função.
  • Isso é , então o programa mais curto (em bytes) vence!

11
Não entendo por que as pessoas colocam pontos de exclamação nos títulos de desafio! Eu acho que pode ser uma coisa de limite de caracteres! Pode ser que as pessoas percebam o desafio!
dkudriavtsev

11
@ Mendeleev É uma sentença imperativa. Esses geralmente são terminados com pontos de exclamação. É apenas pontuação correta, por que isso te incomoda tanto?
Arthur

11
@Mendeleev As pessoas costumam usar um ponto de exclamação para indicar uma piada. O OP está destacando o fato de que ele está fazendo um trocadilho. F. Scott Fitzgerald não gostou , mas neste contexto, parece bom para mim. Se não estivesse lá, você provavelmente faria as pessoas reclamarem da ortografia dele.
bornfromanegg

@Mendeleev porque é um trocadilho ...
FlipTack 15/11

@bornfromanegg eu sinto que as pessoas notariam o trocadilho
dkudriavtsev

Respostas:


16

Gelatina , 6 bytes

BḄ-8ƤṀ

Um link monádico pegando um número e retornando um número.

Experimente online!

Quão?

Usa uma agradável rápida , Ƥdesenvolvido por milhas ...

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

> _> ... Uau você bater meus por 10 bytes
Mr. Xcoder

8

J , 12 bytes

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

Experimente online!

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

Que algoritmo bacana você tem aí? Você poderia adicionar uma explicação?
Xcoder

@Sr. O Xcoder FrownyFrog converte o número em uma lista de dígitos binários (#:), depois converte todos os 8-outfixes ou a lista com os infixes de 8 bits consecutivos removidos de volta ao sistema de números decimais (8 #. \.) E finalmente obtém o pedra grande. [: Simplesmente limita o os dois verbos anteriores, fazendo> ./ a ser executado monadically (apenas com o argumento direita)
Galen Ivanov

Você me ensinou sobre outfix hoje, obrigado por isso! É uma pena que não pareça ser mais curto para usar sob &.; esse é o tipo perfeito de problema para isso.
cole


6

JavaScript (ES6), 54 bytes

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>

Funciona até 2 ** 31-1. Porque alguém pediu uma resposta um pouco tímida ...



3

Mathematica, 69 bytes

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

Experimente online!

Esta solução funciona para grandes números Experimente online!

-3 bytes de KellyLowder


Economize mais 3 bytes:Max[c=#~RealDigits~2;Array[Drop[c[[1]],#;;#+7]~FromDigits~2&,Last@c-7]]&
Kelly Lowder

11
@KellyLowder nice! I golfed sua solução um pouco mais
J42161217


3

Wolfram Language (Mathematica) , 46 bytes

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

Experimente online!

Esta versão pode lidar apenas com entradas de até 2 518 -1, caso contrário, corremos para o limite de tamanho de pilha do Mathematica. (O limite pode variar entre as instalações do Mathematica.) A segunda solução nesta resposta evita isso.

Como funciona

Uma abordagem recursiva baseada na seguinte lógica:

  • O valor máximo deve ser 0para qualquer entrada menor que 256, uma vez que retirar um byte do número consome o número inteiro. Este é o nosso caso base, e é por isso que está incluído, mesmo que as especificações nos prometam que não precisaremos lidar com essas entradas.
  • Caso contrário, adotamos as Maxduas opções: coma o byte mais baixo (fornecendo a entrada dividida por 256) ou corte o bit mais baixo, recorra no número inteiro restante e acrescente o bit mais baixo quando terminarmos.

Wolfram Language (Mathematica) , 55 bytes

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

Experimente online!

Uma versão alternativa que cria uma tabela em vez de recursão; portanto, funciona para números de qualquer tamanho que o Mathematica possa manipular.


2
A profundidade de recursão é excedida para números maiores que 10 ^ 160, embora o mathematica possa lidar com números maiores. Mas eu acho que OP é muito bem com ele
J42161217

2

Retina , 71 67 64 bytes

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

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

Experimente online! O link inclui apenas os casos de teste mais rápidos, para não sobrecarregar indevidamente o servidor de Dennis. Editar: salvou 3 bytes graças a @MartinEnder. Explicação:

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

Converta de decimal para binário.

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

A`_

Construa uma lista de seqüências de caracteres obtidas excluindo 8 dígitos consecutivos de todas as maneiras possíveis.

O^`
1G`

Classifique-os na ordem inversa e pegue o primeiro (maior).

+1`\B
:$`:
1

Converta de volta para decimal. (Veja a explicação de @ MartinEnder .)


11
Eu vim com essa conversão binária para decimal mais curta há um tempo. Eu expliquei como isso funciona nesta resposta .
Martin Ender


2

ReRegex , 294 275 bytes

Economizou 19 bytes usando melhores definições de 'função'

Eu diria que isso é muito bom para um idioma exclusivo do Regex.

A lib base permite a conversão entre Unário e Decimal (o que é necessário, pois a especificação do desafio declara explicitamente decimal), mas não suporta Binário; Então eu tive que escrever isso como parte do script, adicionando 120 bytes a ele.

#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:

Experimente online!

Por regexes individuais.

#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:

Passos

Primeiramente, importamos a biblioteca 'base', que fornece duas regexes. Um que se converte u<numbers>em unário. E um que converted<unary_underlines> novamente em decimal. Isso ocorre porque o desafio requer E / S na base10.

Em seguida, definimos um punhado de expressões regulares que convertem unário em binário.

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

O primeiro deles, b(\d*):(_*)\2_b/b1$1:$2b/busca b, opcionalmente seguido por alguns dígitos binários, depois a :, Então qualquer quantidade de sublinhados, seguido pela mesma quantidade exata de sublinhados mais um e, finalmente, outro b.

Em seguida, substituímos isso por b1seguido pelos dígitos binários de antes :, e apenas a primeira metade dos sublinhados e, finalmente, o último b.

Portanto, isso verifica se o unário não é divisível por dois e, em caso afirmativo, acrescenta 1 aos dígitos binários, depois o divide menos um por dois.

O segundo, b(\d*):(_+)\2b/b0$1:$2b/é quase idêntico, no entanto, não verifica um extra _, o que significa que só corresponde se for divisível por dois e, nesse caso, precede um 0.

O terceiro verifica se estamos com dígitos unários e, nesse caso, retira o preenchimento para deixar os dígitos binários.

O último verifica se nunca houve dígitos binários fornecidos e, nesse caso, apenas sai 0.

O próximo grupo de Regexes que definimos é converter o binário novamente em unário e é um pouco mais simples.

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

O primeiro desse grupo, B(_*):1/B$1$1_:/assim como sua antítese, detecta a B, seguido por qualquer quantidade de dígitos unários :1. Não verifica a correspondência Bnesse caso, pois está procurando apenas um dígito por vez. Se isso corresponder, ele dobra a quantidade anteriormente combinada de dígitos unários e adiciona um, depois o remove.

O segundo B(_*):0/B$1$1:/,, é quase idêntico ao primeiro, exceto que corresponde 0a um 1e não a e não adiciona um dígito unário adicional.

O último deles, B(_*):B/$1/verifica se não há mais dígitos binários e, se for o caso, desembrulha o unário. Ao contrário de sua antítese, isso não precisa de um caso 0 especial.

Em seguida, definimos as jexpressões regulares, que atuam como uma função de divisão.

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

O primeiro, j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/faz a maior parte do trabalho pesado. Ele procura j, opcionalmente seguido por dígitos binários que são o "incrementador", depois uma vírgula seguida pelo incrementador e, em seguida, exatamente 8 dígitos binários seguidos pelo restante do número binário, depois a :. O primeiro dos 8 dígitos é anexado ao incrementador, incrementando-o e, em seguida, tudo, exceto os 8 dígitos da entrada binária, é acrescentado após o :seguinte a ,. Então (se estivéssemos usando 2 dígitos em vez de 8) j,1001:ficaria j1:1001:,01então j10:1001,01,11. Além disso, os elementos da matriz anexados são agrupados em Bs, para convertê-los novamente em unários.

O outro j(\d*),\1\d{0,7}:,?(.*)/,$2,/verifica se há menos de 8 dígitos binários para verificar após o incrementador e, se houver, remove tudo que não seja a matriz agrupada em ,s. Por exemplo.,_,___,

Durante e após a criação da matriz, definimos os regexes de comparação.

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

O primeiro deles ,((_+)_+),(\2),/,$1,/verifica uma vírgula seguida de uma quantidade de sublinhados e, em seguida, um pouco mais, seguida por uma vírgula e, em seguida, a primeira quantidade de sublinhados, que uma vírgula. Em seguida, o substitui pela quantidade total de sublinhados no primeiro elemento cercado por ,s.

O último, ,(_+),(\1_*),/,$2,/verifica uma vírgula seguida por uma quantidade de sublinhados seguida por outra vírgula, depois a mesma quantidade ou mais sublinhados e uma última vírgula. Em vez disso, isso deixará o elemento certo.

Finalmente, quando houver um elemento à esquerda correspondente ^,(_*),$, removemos as vírgulas ao redor e as convertemos novamente em decimal via d<>. Em seguida, não mais regexes podem ser acionadas e a saída é apresentada.

A entrada é inicialmente colocada no modelo j,b:u<(?#input)>b:, que primeiro converte a entrada decimal em unária, por exemplo 5- -> j,b:_____b:, depois a unária resultante em binária. j,101:Em seguida , divide o binário (que não funciona no exemplo), obtém o maior elemento e converte de volta ao decimal e pronto.


2

C (gcc), 91 bytes

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 bytes de Colera Su

Suporta até 2**31-1

Experimente online!

Começa com os 8 bits baixos (j=0) e aumenta, alterando a saída se o número com bits [j,j+8)cortados for maior que a atual e continuando até que x não tenha bits acimaj+8


2
Armazenar x>>j+8e x>>j+8<<j|x%(1<<j)em uma variável (parênteses removidos) reduzirá para 68 bytes .
Colera Su


1

JavaScript (ES6), 94 91 bytes

-3 bytes graças a Justin Mariner

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

Estou lançando uma solução baseada em string JavaScript, mas espero que alguém publique uma solução baseada em bits separada para que eu possa aprender alguma coisa.

Minha solução pega recursivamente um pedaço de 8 bits da string, assumindo o valor máximo encontrado.


11
Eu acho que você pode soltar o +(...)que se converte '0b'+c[1]+c[2]em um número, porque Math.maxjá faz isso. Experimente online! ( Spec para referência futura )
Justin Mariner

@JustinMariner, doce, obrigado!
21417 Rick

1

C # (.NET Core) , 122 + 13 = 135 120 + 13 = 133 bytes

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;}

Experimente online!

+13 para using System;

Eu imagino que existe uma maneira de fazer isso sem usar Convert. De qualquer maneira, tenho certeza que isso pode ser reduzido.

Agradecimentos

-2 bytes graças a Kevin Cruijssen

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;
}

Você pode salvar um byte, alterando o whilea fore colocando o var bem que:for(var b=Convert.ToString(n,2);i<b.Length-7;)
Kevin Cruijssen

E você pode economizar mais 1 byte adicionando uma nova variável int ,te não usando Math.Max, mas uma verificação manual: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 bytes )
Kevin Cruijssen

1

PHP, 67 + 1 bytes

do$r=max($r,$argn&($x=2**$i++-1)|$z=$argn>>8&~$x);while($z);echo$r;

Execute como pipe -nRou experimente online .


1

Pitão, 19 bytes

eSmi.>>.<.BQd8d2a6l

Resposta alternativa:

eSmi.<<8.>.BQdd2a6l

Explicação:

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)

A outra resposta usa uma abordagem semelhante, exceto que ela gira primeiro para a direita e obtém todos os bits, exceto os últimos 8.


1

MATL , 23 21 bytes

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

Experimente online!

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.

Infelizmente, Bn8-:8:!+q&)apenas produz as fatias a serem removidas, e não o restante que gostaríamos de manter.


Isso economiza um par de bytes: Bn8-:"GB[]@8:q+(XBvX>(Atribuir []com (em vez de usar &), e substituir &:por :e adição)
Luis Mendo

@LuisMendo Thanks. Eu li mal os documentos, que diziam que em algum lugar você pode usar apenas um único índice para atribuições nulas, mas para uma situação diferente.
Sanchises


0

Oitava , 81 80 bytes

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

Experimente online!

Esta é uma solução diferente da minha tentativa original, economizando mais 14 bytes.

O código é dividido da seguinte maneira:

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

Na sexta linha, o número de grupos é calculado encontrando o expoente da próxima potência de dois maiores que a entrada (número de bits no número de entrada) e subtraindo 7 ao removermos 8 bits de cada grupo - o número resultante é armazenado bpara mais tarde.

Em seguida, calculamos um conjunto de potências de dois na quinta linha, que é grande o suficiente para todos os grupos possíveis que podem ser removidos. Guardamos isso na variávelc para mais tarde.

Na próxima linha acima (quarta linha), multiplicamos a entrada pela matriz de potências de duas (essencialmente deslocando cada número para cima) e convertemos o resultado em binário. Se usarmos o exemplo de 7831, isso resultará em uma matriz 2D contendo:

000001111010010111
000011110100101110
000111101001011100
001111010010111000
011110100101110000
111101001011100000

Se então cortarmos o centro de 8 bits, isso equivale a remover cada um dos grupos de 8 bits. Isso é feito pela terceira linha.

A matriz resultante é convertida novamente em decimal na segunda linha. Também temos que dividir cpara desfazer o dimensionamento que foi feito para cada grupo inicialmente.

Finalmente, na primeira linha, uma função anônima é declarada e o valor máximo de todos os grupos é calculado.


  • Economize 1 byte usando em nextpow2(x+1)vez dennz(bin2dec(x))


Tentativa original - 120 98 95 bytes

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

Experimente online!

O código é dividido da seguinte forma:

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

Basicamente, calcula uma matriz contendo os possíveis grupos de valores que podem ser removidos e, em seguida, elabora o que acaba dando o maior número.

Trabalhando linha por linha, a quinta linha calcula os grupos que podem ser removidos. Por exemplo, pegue 7831. Este é um número de 13 bits, fornecendo aos grupos:

1111100000000
1111000000001
1110000000011
1100000000111
1000000001111
0000000011111

O resultado da quinta linha é uma matriz lógica 2D que pode ser usada para indexação.

A quarta linha do código converte a entrada em uma matriz de bits (representada como caracteres '0' e '1') e depois a replica n-7 vezes ( nem número de bits), fornecendo uma linha para cada agrupamento possível. A máscara de grupo acima é usada para remover cada um dos grupos possíveis.

Na terceira linha, o resultado é reconfigurado para desfazer o achatamento indesejado resultante da aplicação da máscara de grupo. A segunda linha é convertida novamente em uma matriz de números decimais resultantes. E a primeira linha define a função anônima como o valor máximo da matriz de grupos possíveis.


  • Economizou 22 bytes gerando a matriz de grupos usando matemática.
  • Salva 3 bytes na conversão de cadeias binárias em máscara de grupo lógico.



0

Perl, 53 bytes

(a use 5.10.1 para levar o perl para o nível 5.10.1 do lanugage é gratuito)

Dê o número de entrada no STDIN. Ficará sem memória para grandes números, mas o número de 32 bits na entrada ainda não é um problema

#!/usr/bin/perl
use 5.10.1;
$_=sprintf"%b",<>;/.{8}(?{\$F[oct"0b$`$'"]})^/;say$#F
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.