Prendi un byte da esso!


24

Il tuo compito è, dato un numero intero senza segno n, trovare il numero più grande che può essere creato rimuovendo un singolo byte (8 bit consecutivi) di dati.


Esempio

Dato il numero 7831, lo convertiamo prima in binario (rimuovendo eventuali zeri iniziali):

1111010010111

Troviamo quindi il gruppo consecutivo di 8 bit che, una volta rimosso, produrrà il nuovo più grande risultato. In questo caso, ci sono 3 soluzioni, mostrate di seguito

1111010010111
  ^      ^       
   ^      ^
    ^      ^

Rimuovendo questo uno di questi rendimenti 11111, che poi riconvertiamo nel suo valore decimale 31per la risposta.


Casi test

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

Regole

  • È garantito che la lunghezza in bit di nsarà maggiore di 8.
  • La tua soluzione dovrebbe teoricamente funzionare per qualsiasi lunghezza di bit nsuperiore a 8, ma in pratica deve funzionare solo per numeri interi 255 <n <2 16
  • Input / Output dovrebbe essere in decimale.
  • È possibile inviare un programma completo o una funzione.
  • Questo è , quindi vince il programma più breve (in byte)!

1
Non capisco perché la gente metta punti esclamativi nei titoli delle sfide! Penso che potrebbe essere un limite al personaggio! Potrebbe essere solo così la gente nota la sfida però!
dkudriavtsev,

1
@Mendeleev È una frase imperativa. Questi di solito terminano con punti esclamativi. È solo la punteggiatura corretta, perché ti disturba così tanto?
Arthur,

1
@Mendeleev Le persone usano spesso un punto esclamativo per indicare uno scherzo. L'OP sta mettendo in evidenza il fatto che sta facendo un gioco di parole. A Scott Fitzgerald non è piaciuto , ma in questo contesto, mi sembra perfetto. Se non fosse lì, probabilmente le persone si lamenterebbero della sua ortografia.
bornfromanegg,

@Mendeleev perché è un brutto gioco di
parole

@bornfromanegg Sento che la gente
noterebbe

Risposte:


16

Gelatina , 6 byte

BḄ-8ƤṀ

Un collegamento monadico che prende un numero e restituisce un numero.

Provalo online!

Come?

Utilizza un bel rapido , Ƥsviluppato da miglia ...

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

> _> ... Wow mi hai battuto di 10 byte
Mr. Xcoder il

8

J , 12 byte

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

Provalo online!

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

Quale abile algoritmo hai lì dentro? Potresti aggiungere una spiegazione?
Mr. Xcoder,

@Sig. Xcoder FrownyFrog converte il numero in un elenco di cifre binarie (#:), quindi converte tutti gli 8 outfix o l'elenco con gli infissi consecutivi a 8 bit rimossi in un sistema di numeri decimali (8 #. \.) E infine prende il il più grande. [: limita semplicemente i due verbi precedenti, facendo> ./ da eseguire monadicamente (solo con l'argomentazione giusta)
Galen Ivanov,

Mi hai insegnato a proposito dell'outfix oggi, grazie per quello! È un peccato che non sembra essere più breve da usare sotto &.; questo è il tipo perfetto di problema per questo.
Cole


6

JavaScript (ES6), 54 byte

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>

Funziona fino a 2 ** 31-1. Perché qualcuno ha chiesto una risposta poco accattivante ...



3

Mathematica, 69 byte

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

Provalo online!

Questa soluzione funziona per grandi numeri Provalo online!

-3 byte da KellyLowder


Salva altri 3 byte:Max[c=#~RealDigits~2;Array[Drop[c[[1]],#;;#+7]~FromDigits~2&,Last@c-7]]&
Kelly Lowder il

1
@KellyLowder nice! Ho risolto un po 'di più la tua soluzione
J42161217


3

Wolfram Language (Mathematica) , 46 byte

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

Provalo online!

Questa versione può gestire solo input fino a 2 518 -1, altrimenti ci imbattiamo nel limite delle dimensioni dello stack di Mathematica. (Il limite può variare tra le installazioni di Mathematica.) La seconda soluzione in questa risposta lo evita.

Come funziona

Un approccio ricorsivo basato sulla seguente logica:

  • Il valore massimo dovrebbe essere 0per qualsiasi input inferiore a 256, poiché l'eliminazione di un byte dal numero consuma l'intero numero. Questo è il nostro caso di base, motivo per cui è incluso anche se le specifiche ci promettono che non dovremo gestire tali input.
  • Altrimenti, prendiamo le Maxdue opzioni: mangia il byte più basso (dandoci l'input diviso per 256) o tagliamo il bit più basso, ricerchiamo il numero intero rimanente e aggiungiamo il bit più basso quando abbiamo finito.

Wolfram Language (Mathematica) , 55 byte

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

Provalo online!

Una versione alternativa che crea una tabella anziché la ricorsione, quindi funziona per numeri di qualsiasi dimensione che Mathematica può gestire.


2
La profondità di ricorsione viene superata per numeri superiori a 10 ^ 160 sebbene matematica sia in grado di gestire numeri più grandi. Ma credo che OP
vada

2

Retina , 71 67 64 byte

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

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

Provalo online! Link include solo i casi di test più veloci, in modo da non sovraccaricare indebitamente il server di Dennis. Modifica: 3 byte salvati grazie a @MartinEnder. Spiegazione:

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

Converti da decimale a binario.

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

A`_

Costruire un elenco di stringhe ottenute eliminando 8 cifre consecutive in tutti i modi possibili.

O^`
1G`

Ordinali in ordine inverso e prendi il primo (il più grande).

+1`\B
:$`:
1

Converti nuovamente in decimale. (Vedi la spiegazione di @ MartinEnder .)


1
Ho trovato questo binario più breve in conversione decimale qualche tempo fa. Ho spiegato come funziona in questa risposta .
Martin Ender,


2

ReRegex , 294 275 byte

19 byte salvati utilizzando definizioni migliori di "funzioni"

Direi che questo è abbastanza buono per una lingua solo Regex.

La libreria di base consente la conversione tra Unario e Decimale (che è necessario poiché la specifica della sfida indica esplicitamente il decimale), ma non supporta Binario; Quindi ho dovuto scriverlo come parte dello script aggiungendo 120 byte ad esso.

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

Provalo online!

Per singoli regimi.

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

passi

Innanzitutto, importiamo la libreria "base", che fornisce due regex. Uno che si converte u<numbers>in unario. E uno che si converte d<unary_underlines>nuovamente in decimale. Questo perché la sfida richiede IO in base10.

Quindi definiamo una manciata di regex che convertono unario in binario.

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

Il primo di questi, b(\d*):(_*)\2_b/b1$1:$2b/cerca b, facoltativamente seguito da alcune cifre binarie, quindi a :, quindi qualsiasi quantità di sottolineature, seguita dalla stessa identica quantità di sottolineature più una, e infine un'altra b.

Sostituiamo quindi quello con b1seguito dalle cifre binarie di prima :, e solo la prima metà dei caratteri di sottolineatura, e infine l'ultimab .

Quindi questo controlla se l'unario non è divisibile per due e, in tal caso, antepone 1 alle sue cifre binarie, quindi lo divide meno uno per due.

Il secondo, b(\d*):(_+)\2b/b0$1:$2b/è quasi identico, tuttavia non controlla un extra _, il che significa che corrisponde solo se è divisibile per due, e in questo caso antepone un0 invece.

Il terzo controlla se non abbiamo cifre unarie e, in tal caso, rimuove l'imbottitura per lasciare solo le cifre binarie.

L'ultimo controlla se non sono mai state fornite cifre binarie e in quel caso se ne va 0 .

Il prossimo gruppo di Regex che definiamo è di convertire i binari in unari e sono leggermente più semplici.

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

Il primo di questo gruppo, B(_*):1/B$1$1_:/molto simile alla sua antitesi, rileva quindi una B, seguita da qualsiasi quantità di cifre unarie :1. In Bquesto caso non controlla la corrispondenza , in quanto cerca solo una cifra alla volta. Se corrisponde, raddoppia la quantità di cifre unarie precedentemente abbinata e ne aggiunge una, quindi rimuove quella.

Il secondo, B(_*):0/B$1$1:/è quasi identico al primo, tranne le partite a 0piuttosto che a1 , e non aggiunge una cifra unaria aggiuntiva.

L'ultimo di questi, B(_*):B/$1/ controlla se non ci sono più cifre binarie e, in tal caso, scartare il unario. A differenza della sua antitesi, questo non ha bisogno di un caso 0 speciale.

Successivamente definiamo le jregex, che agiscono come una funzione di divisione.

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

Il primo, j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/fa la maggior parte del sollevamento pesante. Cerca j, facoltativamente seguito da cifre binarie che sono "incrementatore", quindi una virgola seguita da un incrementatore quindi esattamente 8 cifre binarie seguite dal resto del numero binario, quindi a :. La prima delle 8 cifre viene aggiunta all'incremento, quindi incrementandola, quindi tutto tranne quelle 8 cifre dall'input binario viene aggiunto dopo il :seguente a ,. Quindi (se stessimo usando 2 cifre anziché 8) j,1001:diventerebbe j1:1001:,01allora j10:1001,01,11. Inoltre, gli elementi dell'array aggiunti sono racchiusi in Bs, per convertirli in unari.

L'altro, j(\d*),\1\d{0,7}:,?(.*)/,$2,/controlla se ci sono meno di 8 cifre binarie da controllare dopo l'incrementatore e, in tal caso, rimuove tutto tranne l'array racchiuso in ,s. Per esempio.,_,___,

Durante e dopo la creazione dell'array definiamo le regex di confronto.

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

Il primo di questi, ,((_+)_+),(\2),/,$1,/controlla una virgola seguita da un numero di caratteri di sottolineatura, poi un po 'di più, seguito da una virgola, quindi il primo numero di caratteri di sottolineatura, rispetto a una virgola. Quindi lo sostituisce con la quantità totale di caratteri di sottolineatura nel primo elemento circondato da, s.

L'ultimo, ,(_+),(\1_*),/,$2,/ controlla una virgola seguita da un numero di caratteri di sottolineatura seguito da un'altra virgola, quindi lo stesso importo o più caratteri di sottolineatura e un'ultima virgola. Questo invece lascerà l'elemento giusto.

Alla fine, quando sull'elemento rimane così corrispondente ^,(_*),$, rimuoviamo le virgole circostanti e riconvertiamo in decimale viad<> . Quindi non possono più attivarsi regex e viene presentato l'output.

L'input viene inizialmente inserito nel modello j,b:u<(?#input)>b:, che prima converte l'input decimale in unario, ad es. 5-> j,b:_____b:, quindi il risultato unario in binario, j,101:quindi suddivide il binario (che non funziona per l'esempio), ottiene l'elemento più grande, converte torna al decimale e fatto.


2

C (gcc), 91 byte

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 byte dal Colera Su

Supporta fino a 2**31-1

Provalo online!

Inizia con gli 8 bit bassi (j=0), quindi sale, modificando l'uscita se il numero con i bit [j,j+8)tagliati è maggiore della nostra corrente e continuando fino a quando x non ha bit sopraj+8


2
Archivia x>>j+8e x>>j+8<<j|x%(1<<j)in una variabile (parentesi rimosse) lo ridurrà a 68 byte .
Colera,


1

JavaScript (ES6), 94 91 byte

-3 byte grazie 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

Basta lanciare una soluzione basata su stringhe JavaScript, ma spero che qualcuno pubblicherà una soluzione separata basata su bit in modo che io possa imparare qualcosa.

La mia soluzione prende ricorsivamente un pezzo di 8 bit dalla stringa, prendendo il valore massimo che si trova.


1
Penso che tu possa eliminare +(...)ciò che converte '0b'+c[1]+c[2]in un numero, perché Math.maxgià lo fa. Provalo online! ( specifiche per riferimento futuro )
Justin Mariner,

@JustinMariner, dolce grazie!
Rick Hitchcock,

1

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

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

Provalo online!

+13 per using System;

Immagino che ci sia un modo per farlo senza usare Convert . Ad ogni modo, sono sicuro che questo potrebbe essere ridotto.

Ringraziamenti

-2 byte grazie 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;
}

È possibile salvare un byte modificando whilein fore inserendolo var b:for(var b=Convert.ToString(n,2);i<b.Length-7;)
Kevin Cruijssen,

E puoi salvare un altro byte aggiungendo una nuova variabile int ,te non utilizzando Math.Max, ma un controllo manuale invece: 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 byte )
Kevin Cruijssen

1

PHP, 67 + 1 byte

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

Esegui come pipe -nRo provalo online .


1

Pyth, 19 byte

eSmi.>>.<.BQd8d2a6l

Risposta alternativa:

eSmi.<<8.>.BQdd2a6l

Spiegazione:

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)

L'altra risposta utilizza un approccio simile, tranne per il fatto che ruota prima a destra e ottiene tutti i bit tranne gli ultimi 8.


1

MATL , 23 21 byte

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

Provalo 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.

Purtroppo, Bn8-:8:!+q&)produce solo le sezioni da rimuovere, non il resto che vorremmo conservare.


Questo permette di risparmiare un paio di byte: Bn8-:"GB[]@8:q+(XBvX>(assegnazione []con (invece di usare &), e sostituire &:da :e aggiunta)
Luis Mendo

@LuisMendo Grazie. Ho letto male i documenti, che dicevano da qualche parte che è possibile utilizzare un solo indice per assegnazioni nulle, ma per una situazione diversa.
Sanchises,


0

Ottava , 81 80 byte

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

Provalo online!

Questa è una soluzione diversa al mio tentativo originale, salvando altri 14 byte.

Il codice è suddiviso come segue:

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

Sulla sesta riga il numero di gruppi viene calcolato trovando l'esponente della potenza successiva di due più grande dell'input (numero di bit nel numero di input) e sottraendo 7 mentre stiamo rimuovendo 8 bit da ciascun gruppo - il numero risultante è conservato bper dopo.

Calcoliamo quindi un array di potenze di due sulla quinta riga che è abbastanza grande per tutti i possibili gruppi che possono essere rimossi. Lo salviamo in variabile cper dopo.

Nella riga successiva (quarta riga), moltiplichiamo l'input per l'array di potenze di due (essenzialmente spostando in bit ciascun numero verso l'alto) e convertiamo il risultato in binario. Se prendiamo l'esempio di 7831, questo si traduce in un array 2D contenente:

000001111010010111
000011110100101110
000111101001011100
001111010010111000
011110100101110000
111101001011100000

Se poi eliminiamo gli 8 bit centrali, ciò equivale a rimuovere ciascuno dei gruppi di 8 bit. Questo viene fatto dalla terza riga.

La matrice risultante viene riconvertita in decimale sulla seconda riga. Dobbiamo anche dividere cper annullare il ridimensionamento che è stato fatto inizialmente a ciascun gruppo.

Alla prima riga viene dichiarata una funzione anonima e viene calcolato il valore massimo di tutti i gruppi.


  • Salvare 1 byte usando nextpow2(x+1)anzichénnz(bin2dec(x))


Tentativo originale - 120 98 95 byte

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

Provalo online!

Il codice è suddiviso come segue:

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

Fondamentalmente calcola una matrice contenente i possibili gruppi di valori che possono essere rimossi, e quindi risolve il problema, che finisce per fornire il numero più grande.

Lavorando riga per riga, la quinta riga calcola i gruppi che possono essere rimossi. Ad esempio, prendi 7831. Questo è un numero a 13 bit, che fornisce ai gruppi:

1111100000000
1111000000001
1110000000011
1100000000111
1000000001111
0000000011111

Il risultato della quinta riga è un array logico 2D che può essere utilizzato per l'indicizzazione.

La quarta riga del codice converte l'input in un array di bit (rappresentato come caratteri '0' e '1'), quindi lo replica n-7 volte (dove nin numero di bit) fornendo una riga per ogni possibile raggruppamento. La maschera di gruppo sopra è utilizzata per rimuovere ciascuno dei possibili gruppi.

Sulla terza riga, il risultato viene quindi rimodellato per annullare l'appiattimento indesiderato risultante dall'applicazione della maschera di gruppo. La seconda riga viene riconvertita in un array di numeri decimali risultanti. E la prima riga definisce la funzione anonima come valore massimo dell'array di possibili gruppi.


  • Salvato 22 byte generando la matrice di gruppi usando la matematica.
  • Salvato 3 byte nella conversione da stringhe binarie a maschera di gruppo logica.



0

Perl, 53 byte

(il use 5.10.1per portare il perl al livello lanugage 5.10.1 è gratuito)

Fornire il numero di input su STDIN. Esaurirà la memoria per i grandi numeri, ma il numero a 32 bit nell'input non è ancora un problema

#!/usr/bin/perl
use 5.10.1;
$_=sprintf"%b",<>;/.{8}(?{\$F[oct"0b$`$'"]})^/;say$#F
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.