Ihre Aufgabe ist es, bei einer vorzeichenlosen Ganzzahl n
die größte Zahl zu finden, die durch Entfernen eines einzelnen Bytes (8 aufeinanderfolgende Bits) von Daten erstellt werden kann.
Beispiel
Angesichts der Zahl 7831
konvertieren wir sie zuerst in eine Binärzahl (wobei führende Nullen entfernt werden):
1111010010111
Wir finden dann die aufeinanderfolgende Gruppe von 8 Bits, die, wenn sie entfernt werden, das größte neue Ergebnis liefern. In diesem Fall gibt es drei Lösungen:
1111010010111
^ ^
^ ^
^ ^
Entfernen Sie diese Ausbeuten 11111
, und wandeln Sie sie 31
für die Antwort wieder in ihren Dezimalwert um.
Testfälle
256 -> 1
999 -> 3
7831 -> 31
131585 -> 515
7854621 -> 31261
4294967295 -> 16777215 (if your language can handle 32 bit integers)
Regeln
- Es ist garantiert, dass die Bitlänge von
n
größer als 8 ist. - Ihre Lösung sollte theoretisch für alle Bitlängen
n
größer als 8 funktionieren, in der Praxis muss sie jedoch nur für Ganzzahlen 255 <n <2 16 funktionieren - Eingabe / Ausgabe sollte dezimal sein.
- Sie können ein vollständiges Programm oder eine Funktion einreichen.
- Das ist Code-Golf , also gewinnt das kürzeste Programm (in Bytes)!
Antworten:
Gelee , 6 Bytes
Ein monadischer Link, der eine Nummer aufnimmt und eine Nummer zurückgibt.
Probieren Sie es online!
Wie?
Verwendet eine schöne schnelle ,
Ƥ
von Meilen entwickelte ...quelle
J , 12 Bytes
Probieren Sie es online!
quelle
&.
. das ist die perfekte Art von Problem dafür.Python 2 , 41 Bytes
Probieren Sie es online!
quelle
JavaScript (ES6), 54 Byte
Funktioniert bis zu 2 ** 31-1. Weil jemand nach einer etwas kribbelnden Antwort gefragt hat ...
quelle
Pyth , 21 Bytes
Dies ist eine rekursive Funktion (muss mit
y
oder über den Link aufgerufen werden ).Probieren Sie es hier aus!
quelle
Mathematica, 69 Bytes
Probieren Sie es online!
Diese Lösung funktioniert für große Zahlen Probieren Sie es online!
-3 Bytes von KellyLowder
quelle
Max[c=#~RealDigits~2;Array[Drop[c[[1]],#;;#+7]~FromDigits~2&,Last@c-7]]&
Python 3 ,
686660 Bytes-2 Bytes dank Mr. Xcoder!
-4 Bytes dank ovs!
-2 Bytes dank Erik dem Outgolfer!
Probieren Sie es online!
quelle
n.bit_length()-8
ist äquivalent zulen(bin(n))-10
.Wolfram Language (Mathematica) , 46 Byte
Probieren Sie es online!
Diese Version kann nur Eingaben bis zu 2 518 -1 verarbeiten, andernfalls stoßen wir auf die maximale Stapelgröße von Mathematica. (Die Grenze kann zwischen Mathematica-Installationen variieren.) Die zweite Lösung in dieser Antwort vermeidet dies.
Wie es funktioniert
Ein rekursiver Ansatz, der auf der folgenden Logik basiert:
0
für jede Eingabe kleiner als sein256
, da ein Byte aus der Zahl die ganze Zahl frisst. Dies ist unser Basisfall, weshalb er enthalten ist, obwohl die Spezifikationen uns versprechen, dass wir solche Eingaben nicht verarbeiten müssen.Max
zwei Möglichkeiten: das niedrigste Byte essen (Eingabe dividiert durch256
) oder das niedrigste Bit abhacken, die verbleibende Ganzzahl erneut verarbeiten und das niedrigste Bit zurückhängen, wenn wir fertig sind.Wolfram Language (Mathematica) , 55 Byte
Probieren Sie es online!
Eine alternative Version, die eine Tabelle anstelle einer Rekursion erstellt, sodass sie für Zahlen jeder Größe funktioniert, die Mathematica verarbeiten kann.
quelle
Retina ,
716764 BytesProbieren Sie es online! Link enthält nur die schnelleren Testfälle, um Dennis 'Server nicht unnötig zu überlasten. Bearbeiten: 3 Bytes dank @MartinEnder gespeichert. Erläuterung:
Konvertiert von Dezimal in Binär.
Erstellen Sie eine Liste von Zeichenfolgen, indem Sie 8 aufeinanderfolgende Ziffern auf alle möglichen Arten löschen.
Sortiere sie in umgekehrter Reihenfolge und nimm die erste (größte).
Zurück in Dezimalzahl konvertieren. (Siehe @ MartinEnder Erklärung .)
quelle
Java (OpenJDK 8) ,
138 bis134 ByteProbieren Sie es online!
quelle
i.toBinaryString(i)
kann seini.toString(i,2)
.ReRegex ,
294275 BytesDurch Verwendung besserer 'Funktions'-Definitionen wurden 19 Bytes eingespart
Ich würde sagen, das ist ziemlich gut für eine Regex-Sprache.
Die Basisbibliothek ermöglicht die Konvertierung zwischen Unary und Decimal (was erforderlich ist, da die Challenge-Spezifikation explizit Decimal angibt), unterstützt jedoch nicht Binary. Also musste ich das als Teil des Skripts schreiben und 120 Bytes hinzufügen.
Probieren Sie es online!
Nach individuellen Regeln.
Schritte
Zunächst importieren wir die 'base'-Bibliothek, die zwei reguläre Ausdrücke enthält. Eine, die sich
u<numbers>
in eine unäre umwandelt . Und eine, die sichd<unary_underlines>
wieder in Dezimalzahlen umwandelt . Dies liegt daran, dass die Herausforderung IO in base10 erfordert.Dann definieren wir eine Handvoll regulärer Ausdrücke, die unär in binär konvertieren.
Der erste
b(\d*):(_*)\2_b/b1$1:$2b/
sucht nachb
, optional gefolgt von einigen Binärziffern, dann nach a:
, dann nach einer beliebigen Anzahl von Unterstreichungen, gefolgt von genau der gleichen Anzahl von Unterstreichungen plus einer und schließlich einer weiterenb
.Wir ersetzen das dann durch
b1
gefolgt von den Binärziffern von zuvor:
und nur der ersten Hälfte der Unterstriche und schließlich der letztenb
.Dies überprüft also, ob der Unary nicht durch zwei teilbar ist, und stellt in diesem Fall 1 vor die Binärziffern und dividiert sie dann minus eins durch zwei.
Das zweite
b(\d*):(_+)\2b/b0$1:$2b/
ist fast idendisch, prüft jedoch nicht auf ein Extra_
, dh es stimmt nur überein, wenn es durch zwei teilbar ist, und stellt in diesem Fall stattdessen ein voran0
.Die dritte prüft, ob wir keine unären Ziffern mehr haben, und entfernt in diesem Fall die Polsterung, um nur die binären Ziffern zu belassen.
Der letzte prüft, ob keine Binärziffern angegeben wurden, und geht dann einfach
0
.Die nächste Gruppe von Regexen, die wir definieren, besteht darin, Binärdaten wieder in Unärdaten umzuwandeln. Sie sind etwas einfacher.
Die erste dieser Gruppe
B(_*):1/B$1$1_:/
erkennt, ähnlich wie ihre Antithese, aB
, gefolgt von einer beliebigen Anzahl von unären Ziffern:1
.B
In diesem Fall wird nicht nach Übereinstimmungen gesucht, da immer nur nach einer Ziffer gesucht wird. Wenn dies zutrifft, verdoppelt es die zuvor übereinstimmende Anzahl von unären Ziffern und fügt eine hinzu und entfernt dann die eine.Die zweite,
B(_*):0/B$1$1:/
ist fast identisch mit der ersten, abgesehen von Übereinstimmungen mit a0
anstelle von a1
, und fügt keine zusätzliche unäre Ziffer hinzu.Der letzte
B(_*):B/$1/
Befehl prüft, ob keine Binärziffern mehr vorhanden sind, und packt den Unären aus, falls dies der Fall ist. Im Gegensatz zu seiner Antithese benötigt dies keinen speziellen 0-Fall.Als nächstes definieren wir die
j
regulären Ausdrücke, die als Aufteilungsfunktion fungieren.Der erste
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
macht den größten Teil des schweren Hebens. Es wird gesuchtj
, optional gefolgt von Binärziffern, die der "Inkrementierer" sind, dann ein Komma, gefolgt vom Inkrementierer, dann genau 8 Binärziffern, gefolgt vom Rest der Binärzahl, dann a:
. Die erste der 8 Ziffern wird an den Inkrementierer angehängt, wodurch dieser inkrementiert wird. Danach wird nach dem:
folgenden a alles andere als diese 8 Ziffern vom Binäreingang angehängt,
. Also (wenn wir 2 statt 8 Ziffern verwendenj,1001:
würden ) würde esj1:1001:,01
dann werdenj10:1001,01,11
. Darüber hinaus werden die angehängten Array-Elemente inB
s eingeschlossen, um sie wieder in unary umzuwandeln.Die andere
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
prüft, ob nach dem Inkrementierer weniger als 8 Binärziffern übrig sind, und entfernt in diesem Fall alles andere als das in,
s eingeschlossene Array . Z.B.,_,___,
Während und nach der Erstellung des Arrays definieren wir die Vergleichsregexes.
Bei der ersten
,((_+)_+),(\2),/,$1,/
Option wird ein Komma gefolgt von einer bestimmten Anzahl von Unterstrichen und einer weiteren, gefolgt von einem Komma gefolgt von der ersten Anzahl von Unterstrichen und einem Komma überprüft. Anschließend wird es durch die Gesamtzahl der Unterstriche im ersten Element ersetzt, das von,
s umgeben ist.Letzteres
,(_+),(\1_*),/,$2,/
sucht nach einem Komma, gefolgt von einer bestimmten Anzahl von Unterstrichen, gefolgt von einem weiteren Komma, der gleichen Menge oder mehreren Unterstrichen und einem letzten Komma. Dies wird stattdessen das richtige Element belassen.Wenn schließlich noch ein passendes Element übrig ist
^,(_*),$
, entfernen wir die umgebenden Kommas und konvertieren zurück in das Dezimal-Viad<>
. Dann können keine regulären Ausdrücke mehr ausgelöst werden und die Ausgabe wird präsentiert.Die Eingabe wird anfangs in die Vorlage eingefügt
j,b:u<(?#input)>b:
, die zuerst die Dezimaleingabe in Unär umwandelt, z. B.5
->j,b:_____b:
, dann die resultierende Unärzahl in Binärzahl,j,101:
dann die Binärzahl aufteilt (was für das Beispiel nicht funktioniert), das größte Element erhält, konvertiert zurück zur Dezimalzahl und fertig.quelle
C (gcc)
91Bytes-23 Bytes von Colera Su
Unterstützt bis zu
2**31-1
Probieren Sie es online!
Beginnt mit den niedrigen 8 Bits
(j=0)
, steigt dann an und ändert die Ausgabe, wenn die Zahl mit den ausgeschnittenen Bits[j,j+8)
größer als unsere aktuelle ist, und fährt fort, bis x keine Bits mehr darüber hatj+8
quelle
x>>j+8
undx>>j+8<<j|x%(1<<j)
in einer Variablen (Klammern entfernt) reduziert es auf 68 Bytes .Gelee , 12 Bytes
Probieren Sie es online!
Gespeicherte Bytes dank Jonathan Allan !
quelle
JavaScript (ES6),
9491 Byte-3 Bytes dank Justin Mariner
Wir werfen nur eine auf JavaScript-Strings basierende Lösung raus, aber ich hoffe, dass jemand eine separate auf Bit basierende Lösung veröffentlicht, damit ich etwas lernen kann.
Meine Lösung greift rekursiv nach einem 8-Bit-Block aus der Zeichenfolge und nimmt den gefundenen Maximalwert.
Code-Snippet anzeigen
quelle
+(...)
, die sich'0b'+c[1]+c[2]
in eine Zahl umwandelt , weil dasMath.max
schon geht. Probieren Sie es online! ( Spec für zukünftige Referenz )C # (.NET Core) ,
122 + 13 = 135,120 + 13 = 133 ByteProbieren Sie es online!
+13 für
using System;
Ich stelle mir vor, es gibt eine Möglichkeit, dies ohne Verwendung von zu tun
Convert
. Ich bin mir sicher, dass dies reduziert werden könnte.Danksagung
-2 Bytes dank Kevin Cruijssen
Ungolfed
quelle
while
zufor
und setzen dievar b
darin:for(var b=Convert.ToString(n,2);i<b.Length-7;)
,t
undMath.Max
stattdessen nicht die manuelle Prüfung verwenden: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 )PHP, 67 + 1 Bytes
Laufen Sie als Pipe mit
-nR
oder versuchen Sie es online .quelle
Pyth, 19 Bytes
Alternative Antwort:
Erläuterung:
Die andere Antwort verwendet einen ähnlichen Ansatz, außer dass sie sich zuerst nach rechts dreht und alle Bits mit Ausnahme der letzten 8 abruft.
quelle
MATL ,
2321 BytesProbieren Sie es online!
Leider werden
Bn8-:8:!+q&)
nur die zu entfernenden Scheiben erzeugt, nicht der Rest, den wir behalten möchten.quelle
Bn8-:"GB[]@8:q+(XBvX>
(Zuweisen[]
mit(
anstelle von Verwenden&)
und Ersetzen&:
durch:
und Hinzufügen)Java (OpenJDK 8) , 73 Byte
Probieren Sie es online!
quelle
Oktave ,
8180 BytesProbieren Sie es online!
Dies ist eine andere Lösung als mein ursprünglicher Versuch, weitere 14 Bytes einzusparen.
Der Code setzt sich wie folgt zusammen:
In der sechsten Zeile wird die Anzahl der Gruppen berechnet, indem der Exponent der nächsten Zweierpotenz ermittelt wird, der größer ist als die Eingabe (Anzahl der Bits in der Eingabenummer), und 7 subtrahiert wird, wenn 8 Bits aus jeder Gruppe entfernt werden
b
für später gespeichert .Wir berechnen dann ein Array von Zweierpotenzen in der fünften Zeile, das groß genug für alle möglichen Gruppen ist, die entfernt werden können. Wir speichern dies
c
für später in einer Variablen .In der nächsten Zeile (vierten Zeile) multiplizieren wir die Eingabe mit dem Array von Zweierpotenzen (im Wesentlichen Bitverschiebung jeder Zahl nach oben) und konvertieren das Ergebnis in binär. Wenn wir das Beispiel von 7831 nehmen, ergibt dies ein 2D-Array mit:
Wenn wir dann die mittleren 8 Bits herausschneiden, entspricht dies dem Entfernen jeder der 8-Bit-Gruppen. Dies geschieht in der dritten Zeile.
Das resultierende Array wird in der zweiten Zeile wieder in Dezimalzahlen umgewandelt. Wir müssen auch durch teilen
c
, um die Skalierung, die anfangs für jede Gruppe durchgeführt wurde , rückgängig zu machen.Schließlich wird in der ersten Zeile eine anonyme Funktion deklariert und der Maximalwert aller Gruppen berechnet.
nextpow2(x+1)
anstatt verwendennnz(bin2dec(x))
Ursprünglicher Versuch -
120 9895 BytesProbieren Sie es online!
Der Code ist wie folgt aufgeteilt:
Grundsätzlich wird eine Matrix berechnet, die die möglichen Wertegruppen enthält, die entfernt werden können, und anschließend wird berechnet, welche die größte Zahl ergibt.
Die fünfte Zeile berechnet zeilenweise die Gruppen, die entfernt werden können. Nehmen Sie zum Beispiel 7831. Dies ist eine 13-Bit-Zahl mit den folgenden Gruppen:
Das Ergebnis der fünften Zeile ist ein logisches 2D-Array, das zur Indizierung verwendet werden kann.
Die vierte Codezeile konvertiert die Eingabe in ein Array der Bits (dargestellt als Zeichen '0' und '1') und repliziert es dann
n
-7 Mal (wobei dien
Anzahl der Bits angegeben ist), wobei für jede mögliche Gruppierung eine Zeile angegeben wird. Die Gruppenmaske oben wird verwendet, um jede der möglichen Gruppen zu entfernen.In der dritten Zeile wird das Ergebnis dann umgeformt, um die unerwünschte Verflachung aufzuheben, die durch das Anwenden der Gruppenmaske verursacht wurde. Die zweite Zeile konvertiert zurück in ein Array von resultierenden Dezimalzahlen. Und die erste Zeile definiert die anonyme Funktion als den Maximalwert des Arrays möglicher Gruppen.
quelle
Perl 5 , 78 + 1 (
-p
) = 79 BytesProbieren Sie es online!
quelle
Ruby , 55 Bytes
Probieren Sie es online!
quelle
Perl, 53 Bytes
(das
use 5.10.1
perl auf lanugage level 5.10.1 bringen ist kostenlos)Geben Sie die Eingangsnummer bei STDIN ein. Der Speicher für große Zahlen wird knapp, aber die 32-Bit-Zahl in der Eingabe ist noch kein Problem
quelle