¡Saca un byte!

24

Su tarea es, dado un número entero sin signo n, encontrar el número más grande que se puede crear eliminando un solo byte (8 bits consecutivos) de datos.


Ejemplo

Dado el número 7831, primero lo convertimos a binario (eliminando los ceros iniciales):

1111010010111

Luego encontramos el grupo consecutivo de 8 bits que, cuando se eliminan, producirán el mayor resultado nuevo. En este caso, hay 3 soluciones, que se muestran a continuación

1111010010111
  ^      ^       
   ^      ^
    ^      ^

Eliminando esto cualquiera de estos rendimientos 11111, que luego convertimos de nuevo a su valor decimal 31para la respuesta.


Casos de prueba

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

Reglas

  • Se garantiza que la longitud de bits nserá mayor que 8.
  • Teóricamente, su solución debería funcionar para cualquier longitud de bits nmayor que 8, pero en la práctica, solo necesita trabajar para enteros 255 <n <2 16
  • La entrada / salida debe estar en decimal.
  • Puede enviar un programa completo o una función.
  • Este es el , por lo que gana el programa más corto (en bytes)
FlipTack
fuente
1
¡No entiendo por qué las personas ponen signos de exclamación en los títulos de los desafíos! ¡Creo que podría ser un límite de carácter! Sin embargo, ¡podría ser solo para que la gente note el desafío!
dkudriavtsev
1
@Mendeleev Es una oración imperativa. Esos generalmente se terminan con signos de exclamación. Es solo la puntuación correcta, ¿por qué te molesta tanto?
Arthur
1
@Mendeleev Las personas a menudo usan un signo de exclamación para indicar una broma. El OP destaca el hecho de que está haciendo un juego de palabras. A F. Scott Fitzgerald no le gustó , pero en este contexto, me parece bien. Si no estuviera allí, probablemente haría que la gente se quejara de su ortografía.
bornfromanegg
@Mendeleev porque es un mal juego de palabras ...
FlipTack
@bornfromanegg Siento que la gente se daría cuenta del juego de palabras
dkudriavtsev

Respuestas:

16

Jalea , 6 bytes

BḄ-8ƤṀ

Un enlace monádico que toma un número y devuelve un número.

Pruébalo en línea!

¿Cómo?

Utiliza un buen rápida , Ƥdesarrollado por millas ...

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
Jonathan Allan
fuente
> _> ... Wow me
ganaste
8

J , 12 bytes

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

Pruébalo en línea!

          #:     to binary
     8  \.       remove consecutive groups of eight
      #.         convert each result to decimal
  >./            maximum
[:               do nothing, this lets me avoid parentheses
FrownyFrog
fuente
¿Qué ingenioso algoritmo tienes ahí? ¿Podría agregar una explicación?
Sr. Xcoder
@Señor. Xcoder FrownyFrog convierte el número en una lista de dígitos binarios (#:), luego convierte todos los 8-outfixes, o la lista con infijos consecutivos de 8 bits eliminados de nuevo al sistema de números decimales (8 #. \.) Y finalmente toma el piedra grande. [: simplemente limita los dos verbos anteriores, haciendo que> ./ se ejecute de manera monádica (solo con un argumento correcto)
Galen Ivanov el
Hoy me enseñaste sobre outfix, ¡gracias por eso! Es una pena que no parezca ser más corto de usar debajo &.; Este es el tipo de problema perfecto para ello.
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 hasta 2 ** 31-1. Porque alguien pidió una respuesta un poco retorcida ...

Neil
fuente
4

Pyth , 21 bytes

L&K.>b8eS,K+*2y/b2%b2

Esta es una función recursiva (debe llamarse con y, o ver el enlace).

Pruébalo aquí!

Sr. Xcoder
fuente
3

Mathematica, 69 bytes

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

Pruébalo en línea!

Esta solución funciona para grandes cantidades ¡ Pruébelo en línea!

-3 bytes de KellyLowder

J42161217
fuente
Ahorre 3 bytes más:Max[c=#~RealDigits~2;Array[Drop[c[[1]],#;;#+7]~FromDigits~2&,Last@c-7]]&
Kelly Lowder
1
@KellyLowder bien! Jugué un poco más su solución
J42161217
3

Wolfram Language (Mathematica) , 46 bytes

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

Pruébalo en línea!

Esta versión solo puede manejar entradas de hasta 2 518 -1, de lo contrario nos encontramos con el límite de tamaño de pila de Mathematica. (El límite puede variar entre las instalaciones de Mathematica.) La segunda solución en esta respuesta lo evita.

Cómo funciona

Un enfoque recursivo basado en la siguiente lógica:

  • El valor máximo debe ser 0para cualquier entrada menor que 256, ya que tomar un byte del número se come todo el número. Este es nuestro caso base, por lo que está incluido a pesar de que las especificaciones nos prometen que no tendremos que manejar tales entradas.
  • De lo contrario, tomamos las Maxdos opciones: comer el byte más bajo (dándonos la entrada dividida por 256) o cortar el bit más bajo, recurrir al entero restante y agregar el bit más bajo cuando hayamos terminado.

Wolfram Language (Mathematica) , 55 bytes

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

Pruébalo en línea!

Una versión alternativa que crea una tabla en lugar de recursividad, por lo que funciona para números de cualquier tamaño que Mathematica pueda manejar.

Misha Lavrov
fuente
2
La profundidad de recursión se supera para números mayores que 10 ^ 160, aunque Mathica puede manejar números mayores. Pero supongo que OP está bien con eso
J42161217
2

Retina , 71 67 64 bytes

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

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

Pruébalo en línea! Link solo incluye los casos de prueba más rápidos, para no sobrecargar excesivamente el servidor de Dennis. Editar: Guardado 3 bytes gracias a @MartinEnder. Explicación:

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

Convierte de decimal a binario.

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

A`_

Construya una lista de cadenas obtenidas eliminando 8 dígitos consecutivos de todas las formas posibles.

O^`
1G`

Ordénelos en orden inverso y tome el primero (el más grande).

+1`\B
:$`:
1

Convertir de nuevo a decimal. (Ver la explicación de @ MartinEnder ).

Neil
fuente
1
Se me ocurrió esta conversión binaria a decimal más corta hace un tiempo. He explicado cómo funciona en esta respuesta .
Martin Ender
2

Java (OpenJDK 8) , 138 134 bytes

i->{int l=0,m=0,x;String y=i.toString(i,2);for(;l<y.length()-7;m=x>m?x:m)x=i.valueOf(y.substring(0,l)+y.substring(l+++8),2);return m;}

Pruébalo en línea!

Roberto Graham
fuente
1
i.toBinaryString(i)puede ser i.toString(i,2).
Kevin Cruijssen
2

ReRegex , 294 275 bytes

Ahorró 19 bytes usando mejores definiciones de 'función'

Yo diría que esto es bastante bueno para un lenguaje único de Regex.

La base lib permite la conversión entre Unary y Decimal (que es necesario ya que la especificación de desafío declara explícitamente decimal), pero no admite Binary; Así que tuve que escribir eso como parte del script agregando 120 bytes.

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

Pruébalo en línea!

Por expresiones regulares individuales.

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

Pasos

En primer lugar, importamos la biblioteca 'base', que da dos expresiones regulares. Uno que se convierte u<numbers>en unario. Y uno que convierte de d<unary_underlines>nuevo a decimal. Esto se debe a que el desafío requiere IO en base10.

Luego definimos un puñado de expresiones regulares que convierten unario en binario.

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

El primero de ellos, b(\d*):(_*)\2_b/b1$1:$2b/busca b, opcionalmente seguido por algunos dígitos binarios, luego a :, luego cualquier cantidad de subrayados, seguido de exactamente la misma cantidad de subrayados más uno, y finalmente otro b.

Luego reemplazamos eso con b1seguido de los dígitos binarios de antes :, y solo la primera mitad de los guiones bajos, y finalmente la última b.

Entonces esto verifica si el unario no es divisible por dos, y si es así, antepone 1 a sus dígitos binarios, luego lo divide menos uno por dos.

El segundo, b(\d*):(_+)\2b/b0$1:$2b/es casi idéntico, sin embargo, no busca un extra _, lo que significa que solo coincide si es divisible por dos, y en este caso antepone un 0en su lugar.

El tercero verifica si no tenemos dígitos unarios, y si es así, quita el relleno para dejar solo los dígitos binarios.

El último verifica si nunca se proporcionaron dígitos binarios, y en ese caso simplemente se va 0.

El siguiente grupo de expresiones regulares que definimos es convertir binario nuevamente en unario, y son un poco más simples.

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

El primero de este grupo, B(_*):1/B$1$1_:/al igual que su antítesis, detecta a B, seguido de cualquier cantidad de dígitos unarios :1. En Beste caso, no comprueba la coincidencia , ya que solo busca un dígito a la vez. Si esto coincide, duplica la cantidad previamente coincidente de dígitos unarios y agrega uno, luego elimina el uno.

El segundo, B(_*):0/B$1$1:/es casi idéntico al primero, excepto que coincide con a en 0lugar de a 1, y no agrega un dígito unario adicional.

El último de estos, B(_*):B/$1/comprueba si no hay más dígitos binarios, y si es así, desenvuelve el unario. A diferencia de su antítesis, esto no necesita un caso especial 0.

A continuación definimos las jexpresiones regulares, que actúan como una función de división.

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

El primero, j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/hace la mayor parte del trabajo pesado. Busca j, opcionalmente seguido por dígitos binarios que son el "incrementador", luego una coma seguida por el incrementador, luego exactamente 8 dígitos binarios seguidos por el resto del número binario, luego a :. El primero de los 8 dígitos se agrega al incrementador, incrementándolo así, luego todo lo que no sean esos 8 dígitos de la entrada binaria se agrega después del :siguiente a ,. Entonces (si estuviéramos usando 2 dígitos en lugar de 8) j,1001:sería j1:1001:,01entonces j10:1001,01,11. Además, los elementos de matriz adjuntos se envuelven en Bs, para convertirlos de nuevo a unario.

El otro, j(\d*),\1\d{0,7}:,?(.*)/,$2,/verifica si quedan menos de 8 dígitos binarios para verificar después del incrementador, y si es así, elimina todo lo que no sea la matriz envuelta en ,s. P.ej.,_,___,

Durante y después de la creación de la matriz, definimos las expresiones regulares de comparación.

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

El primero de ellos, ,((_+)_+),(\2),/,$1,/verifica una coma seguida de una cierta cantidad de guiones bajos, luego un poco más, seguida de una coma, luego la primera cantidad de guiones bajos, que una coma. Luego lo reemplaza con la cantidad total de guiones bajos en el primer elemento rodeado por ,s.

El último, ,(_+),(\1_*),/,$2,/busca una coma seguida de una cierta cantidad de guiones bajos seguidos de otra coma, luego la misma cantidad o más guiones bajos y una última coma. En su lugar, esto dejará el elemento correcto.

Finalmente, cuando queda un elemento que coincide ^,(_*),$, eliminamos las comas circundantes y las convertimos a decimal a través de d<>. Entonces no se pueden disparar más expresiones regulares y se presenta la salida.

La entrada se coloca inicialmente en la plantilla j,b:u<(?#input)>b:, que primero convierte la entrada decimal en unario, por ejemplo 5-> j,b:_____b:, luego el unario resultante en binario, j,101:luego divide el binario (que no funciona para el ejemplo), obtiene el elemento más grande, convierte volver al decimal, y listo.

Un taco
fuente
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

Soporta hasta 2**31-1

Pruébalo en línea!

Comienza con los 8 bits bajos (j=0), luego sube, cambiando la salida si el número con bits [j,j+8)recortados es mayor que nuestra corriente, y continúa hasta que x no tenga bits por encimaj+8

pizzapants184
fuente
2
Almacenar x>>j+8y x>>j+8<<j|x%(1<<j)en una variable (paréntesis eliminados) lo reducirá a 68 bytes .
Colera Su
1

JavaScript (ES6), 94 91 bytes

-3 bytes gracias 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

Simplemente lanzo una solución basada en cadenas de JavaScript, pero espero que alguien publique una solución basada en bits por separado para que pueda aprender algo.

Mi solución toma recursivamente un fragmento de 8 bits de la cadena, tomando el valor máximo que se encuentra.

Rick Hitchcock
fuente
1
Creo que puedes soltar el +(...)que se convierte '0b'+c[1]+c[2]en un número, porque Math.maxya lo hace. Pruébalo en línea! ( especificación para referencia futura )
Justin Mariner
@JustinMariner, dulce, gracias!
Rick Hitchcock
1

C # (.NET Core) , 122 + 13 = 135120 + 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;}

Pruébalo en línea!

+13 para using System;

Me imagino que hay una manera de hacer esto sin usar Convert. De cualquier manera, estoy seguro de que esto podría reducirse.

Expresiones de gratitud

-2 bytes gracias a Kevin Cruijssen

Sin golf

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;
}
Ayb4btu
fuente
Puede guardar un byte cambiando el whilea fory poniéndolo var ben él:for(var b=Convert.ToString(n,2);i<b.Length-7;)
Kevin Cruijssen
Y puede guardar 1 byte más agregando una nueva variable int ,ty no usando Math.Max, sino una verificación manual en su lugar: 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;

Ejecutar como tubería -nRo probarlo en línea .

Titus
fuente
1

Pyth, 19 bytes

eSmi.>>.<.BQd8d2a6l

Respuesta alternativa:

eSmi.<<8.>.BQdd2a6l

Explicación:

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)

La otra respuesta utiliza un enfoque similar, excepto que primero gira a la derecha y obtiene todos los bits, excepto los últimos 8.

K Zhang
fuente
1

MATL , 23 21 bytes

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

Pruébalo en línea!

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.

Lamentablemente, Bn8-:8:!+q&)solo produce las rebanadas que se eliminarán, no el resto que nos gustaría conservar.

Sanchises
fuente
Esto ahorra un par de bytes: Bn8-:"GB[]@8:q+(XBvX>(asignar []con en (lugar de usar &)y reemplazar &:por :y además)
Luis Mendo
@LuisMendo Gracias. Leí mal los documentos, que decían en alguna parte que solo puedes usar un solo índice para asignaciones nulas, pero para una situación diferente.
Sanchises
0

Octava , 81 80 bytes

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

Pruébalo en línea!

Esta es una solución diferente a mi intento original, ahorrando otros 14 bytes.

El código se desglosa de la siguiente manera:

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

En la sexta línea, el número de grupos se calcula al encontrar el exponente de la siguiente potencia de dos más grande que la entrada (número de bits en el número de entrada), y restando 7 a medida que eliminamos 8 bits de cada grupo; el número resultante es almacenado bpara más tarde.

Luego calculamos una matriz de potencias de dos en la quinta línea que es lo suficientemente grande para todos los grupos posibles que se pueden eliminar. Guardamos esto en variable cpara más adelante.

En la siguiente línea hacia arriba (cuarta línea), multiplicamos la entrada por la matriz de potencias de dos (esencialmente el desplazamiento de bits de cada número hacia arriba) y convertimos el resultado a binario. Si tomamos el ejemplo de 7831, esto da como resultado una matriz 2D que contiene:

000001111010010111
000011110100101110
000111101001011100
001111010010111000
011110100101110000
111101001011100000

Si luego cortamos los 8 bits centrales, eso es equivalente a eliminar cada uno de los grupos de 8 bits. Esto se hace por la tercera línea.

La matriz resultante se convierte de nuevo a decimal en la segunda línea. También tenemos que dividir cpara deshacer la escala que se hizo a cada grupo inicialmente.

Finalmente en la primera línea se declara una función anónima y se calcula el valor máximo de todos los grupos.


  • Ahorre 1 byte utilizando en nextpow2(x+1)lugar dennz(bin2dec(x))


Intento 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)'))

Pruébalo en línea!

El código se divide de la siguiente manera:

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

Básicamente, calcula una matriz que contiene los posibles grupos de valores que se pueden eliminar, y luego calcula cuál termina dando el mayor número.

Trabajando línea por línea, la quinta línea calcula los grupos que se pueden eliminar. Por ejemplo, tome 7831. Este es un número de 13 bits, que le da a los grupos:

1111100000000
1111000000001
1110000000011
1100000000111
1000000001111
0000000011111

El resultado de la quinta línea es una matriz lógica 2D que se puede usar para indexar.

La cuarta línea del código convierte la entrada en una matriz de bits (representada como caracteres '0' y '1'), y luego la replica n-7 veces ( nen número de bits) dando una línea para cada posible agrupamiento. La máscara de grupo anterior se usa para eliminar cada uno de los grupos posibles.

En la tercera línea, el resultado se reforma para deshacer el aplanamiento no deseado que resultó de aplicar la máscara de grupo. La segunda línea se convierte de nuevo en una matriz de números decimales resultantes. Y la primera línea define la función anónima como el valor máximo de la matriz de grupos posibles.


  • Ahorró 22 bytes al generar la matriz de grupos usando matemáticas.
  • Guardado 3 bytes en la conversión de cadenas binarias a la máscara de grupo lógico.
Tom Carpenter
fuente
0

Perl, 53 bytes

(el use 5.10.1traer perl al nivel de lanugage 5.10.1 es gratis)

Dé el número de entrada en STDIN. Se quedará sin memoria para números grandes, pero el número de 32 bits en la entrada aún no es un problema

#!/usr/bin/perl
use 5.10.1;
$_=sprintf"%b",<>;/.{8}(?{\$F[oct"0b$`$'"]})^/;say$#F
Ton Hospel
fuente