Ich habe auf der Code Review-Website eine Frage gefunden, die interessant erscheint. Ich denke, OP macht es falsch, kann aber nicht sicher sein ... Also lasst es uns für ihn lösen! (Schreiben Sie ein Programm, keine Funktion / Prozedur)
Eingabe (stdin oder ähnlich):
Eine Ganzzahl x
in Dezimalschreibweise. Es ist größer als 1 und kleiner als 2 ^ 31.
Ausgabe (stdout oder ähnlich):
Eine Ganzzahl y
in Dezimalschreibweise. Das Produkt x * y
in Dezimaldarstellung darf nur die Ziffern 0 und 1 enthalten. Es muss die minimale Zahl größer als 0 sein.
Hinweis: Ausgang nicht begrenzt ist - wenn die minimal y
etwa 10 ^ 100, Ihr Programm muss Ausgang alle seine 100 Ziffern (ich weiß nicht , ob es eine vernünftige Grenze ist, wie 2 ^ 64, auf y
- lösen hat es nicht ).
Ihr Programm sollte in einer angemessenen Zeit (1 Sekunde? 1 Stunde? - so ähnlich) für alle x
in Reichweite beendet sein.
Bonus:
Wenn Ihr Programm keine Begrenzung der Größe der Eingabe (außer RAM) und eine polynomielle Komplexität aufweist, multiplizieren Sie die Byteanzahl Ihres Programms mit 0.8
und runden Sie ab.
Beispiel: Eingabe 2
; Ausgabe 5
, weil 2 * 5 = 10
Beispiel: Eingabe 21
; Ausgabe 481
, da 21 * 481 = 10101
Haftungsausschluss: Ich bin nicht verantwortlich für die Frage auf der Code Review-Website. Im Falle von Unstimmigkeiten sollte nur die obige Beschreibung als ordnungsgemäße Spezifikation angesehen werden.
Antworten:
Pyth, 9 Bytes
Demonstration
Konvertieren Sie für jedes Multiple in einen String, subtrahieren Sie die Ziffern in
10
(in diesem Fall verwenden Sie Pyths handliches int, um str zu verwenden) und negieren Sie das Ergebnis logisch. Beenden Sie die Suche nur, wenn das richtige Multiple gefunden wurde.Bonuslösung, 10 Bytes:
Diese Lösung überprüft tatsächlich, ob die Zeichenfolgendarstellung der Zahl als Binärzahl (
i ... 2
) behandelt werden kann, und wird beendet, wenn bei diesem Versuch kein Fehler ausgelöst wird.quelle
Python 2, effiziente Lösung, 99
Danke Sp3000 für ein paar Golftipps.
Ich fordere alle anderen auf, (in ihren eigenen Antworten) anzugeben, wie lange es dauert, das Ergebnis für die Eingabe zu erhalten,
72
oder99
:) Wenn diese sehr schnell sind, versuchen Sie es mit so etwas wie79992
next (hier noch <1 Sek.).Erläuterung:
Ich dachte, das wäre nicht nötig (da der Code ziemlich lesbar ist), aber ich habe eine Anfrage bekommen, also hier ist es:
Die erste Idee ist, dass eine binär aussehende Zahl eine Summe von 1 oder mehr verschiedenen Zehnerpotenzen ist. Daher können wir versuchen, verschiedene Zehnerpotenzen auf unterschiedliche Weise zu addieren, bis wir den Rest 0 erhalten.
Wenn wir das naiv machen, ist es dasselbe wie alle binär aussehenden Zahlen zu generieren und sie zu testen. Aber viele Reste werden gleich sein. Eine bessere Möglichkeit besteht darin, nur die kleinste Zahl aufzuzeichnen, die einen bestimmten Rest ergibt, und den von uns aufgezeichneten Zahlen nacheinander größere Potenzen von 10 hinzuzufügen. Das macht das Programm.
d
ist ein Wörterbuch / eine Karte, in der Schlüssel Reste sind und Werte binär aussehende Zahlen mit diesem Rest sind. Die Initialen:0
ist ein Sonderfall: Es soll sein,0:0
dass wir damit beginnen können, Potenzen hinzuzufügen, aber der Algorithmus stoppt, wenn Schlüssel 0 gefunden wird, also habe ichn
stattdessen verwendet, was garantiert den gleichen Effekt hat und die anderen Werte nicht beeinträchtigt.Dann addieren wir Potenzen von 10 (gespeichert in
k
) zu allen vorhandenen Zahlen und zeichnen die Reste auf. Wir addierenk
zum Rest:(x+k)%n
und zur Zahl:d[x]+k
und notieren sie nur, wenn es sich um einen neuen Rest handelt:d.setdefault(…)
und gehen dann zur nächsten Potenz:k*=10
und wiederholen, bis wir den Schlüssel 0 erhalten:while min(d)
Am Ende wird
d[0]
die binär aussehende Zahl angegeben, die den Rest 0 modn
hat. Wir teilen sie also durchn
, um die Lösung zu erhalten.Hinweis: Das Programm kann effizienter gestaltet werden, indem große Zahlen vermieden werden (Aufzeichnen von Exponenten anstelle von Zehnerpotenzen und Berechnen von Resten von Potenzen aus vorherigen Werten), aber es ist Codegolf, also ...
Tatsächlich habe ich hier eine schnellere Version geschrieben:
quelle
Python 2, 47 Bytes
Verfolgt die eingegebene Nummer
n
und das aktuelle Vielfachea
. Wenn esa
wie binär aussieht, geben Sie das Verhältnis ausa/n
. Um zu überprüfen, ob eine Nummer aus0
's und' s besteht1
' s besteht, vergleichen wir das maximale Zeichen in seiner Zeichenfolgendarstellung mit'1'
.Verwendet,
str(a)
anstatt`a`
zu vermeiden, dass Sehnsüchte auf endenL
. Leider'L'
ist größer als'1'
.quelle
Perl, 27 Bytes
Zählt man den Shebang als einen, wird die Eingabe von stdin übernommen.
Beispielnutzung
Perl, 25 Bytes
Eine Verbesserung um zwei Bytes durch @skmrx .
Anstatt gegen einen regulären Ausdruck zu prüfen, wird stattdessen versucht, das Produkt als binäres Literal zu bewerten. Bei einem Fehler wird mit dem nächsten fortgefahren. Typischerweise die
oct
Funktion für diesen Zweck verwendet, schneidet jedoch unbemerkt ungültige Ziffern ab, was für diese Herausforderung nicht hilfreich ist.Perl, 40 Bytes
Eine weitaus effizientere Lösung. Wir iterieren über binäre Darstellungen, interpretieren sie als Basis 10 und überprüfen dann die Teilbarkeit. Laufzeiten für alle Werte unter 100 sind vernachlässigbar.
Beispielnutzung
quelle
eval"0b".$_*++$\||redo}{
use bigint
oct'0b'.++$\*$_
, aber es schneidet stumm ungültige Ziffern ab. Ich hätte nicht gedacht,eval
stattdessen zu verwenden .Javascript, 43 Bytes
Dies endete viel kürzer als ich dachte. Es erhöht
y
sich grundsätzlich um 1 bisy * (input number) = (binary-looking number)
. Offensichtlich ziemlich ineffizient.Javascript (effizientere Lösung), 53 Bytes
Dieser wird
y
binär inkrementiert bisy / (input number) = (number without a remainder)
. Dann gibt es aus(number without a remainder)
.Javascript (noch effizientere Lösung), 76 Bytes
Dieser kombiniert beide oben beschriebenen Methoden. Es prüft Inkremente
y
bis entwedery * (input number) = (binary-looking number)
(was bedeutet, dass der Ausgang isty
) ODERy / (input number) = (number without a remainder)
(was bedeutet, dass der Ausgang ist(number without a remainder)
).quelle
Haskell,
7270646058 BytesEdit: @Jan Dvorak hat mir geholfen, 4 Bytes zu sparen.
Edit: @BlackCap sparte 2 Bytes durch Umschalten auf
do
Notation. Vielen Dank!quelle
main=print.f=<<readLn
main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
main=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0
Python 2,
67656360 BytesDanke an Status für 2 Bytes und Shebang für 5 Bytes!
quelle
b=1
any(c in`a*b`for c in'23456789')
not c in`a*b`for c in'10'
funktionieren?set('a*b')&set('23456789')
.`
produziert eineL
für lange und lange'L'>'1'
.JavaScript (ES6) 222
250Verwenden von Mathematik mit willkürlicher Genauigkeit (Arbeiten mit Zeichenfolgen mit Dezimalstellen)
Dies kann ein wenig mehr golfen werden(erledigt), aber ich mag die Tatsache, dass es nicht auf JS-Standardnummern (17 Dezimalstellen Genauigkeit) beschränkt ist und dass es schnell ist.Testen Sie das folgende Snippet in einem EcmaScript 6-kompatiblen Browser. Bis zu 9998 ist die Zeit akzeptabel - versuchen Sie es nicht mit 9999 und seien Sie geduldig mit 999.
Mehr lesbar
Dies ist die erste Version mit Modul und langer Division als getrennte Funktionen.
quelle
Perl, 45 Bytes
quelle
Pyth, 10 Bytes
Führen Sie den Code aus.
Ein Port meine Python Antwort , von der Einnahme Maltysen die Verwendung
f
die erste positive Zahl zu finden , das eine Bedingung erfüllt.quelle
PHP, 50 Bytes
Einige Testfälle
quelle
CJam,
191716 BytesProbieren Sie es online aus
Brute-Force-Lösung, bei der Werte nacheinander ausprobiert werden, bis eine gefunden wird, die die Bedingung erfüllt.
Die neueste Version speichert 2 Bytes dank Verwendung
As
statt"01"
eine Zeichenfolge zu bauen enthält0
und1
, wie von @aditsu vorgeschlagen. Die vollständige vorgeschlagene Lösung im Kommentar speichert ein weiteres Byte, sieht jedoch etwas anders aus als das meine, sodass ich es nicht unter meinem Namen veröffentlichen wollte.Und 1 weiteres Byte von @Dennis gespeichert.
Erläuterung:
quelle
li0{1$+_sAs-}g\/
As
, um die Saite zu bauen, da es sich um eine sehr lokale Änderung handelt, an die ich im Nachhinein (was immer viel einfacher ist ...) hätte denken sollen.li:V!{)_V*sAs-}g
Auch0{)_easi*sAs-}g
(15 Bytes) arbeitet mit den Java - Interpreter und Befehlszeilenargumenten.Python
32,10176 Bytes-25 Bytes dank @aditsu
fast so effizient wie @ aditsus Lösung
Anstatt zu versuchen, die Vielfachen in aufsteigender Reihenfolge durchzugehen, versuche ich, die Produkte durchzugehen, die ich in 'binärer' Form generiere.
quelle
n=input()
),while b%n:
(initialisierenb
auf 1), keine Einrückungbin(m)[2:]
sollte kürzer als der Formatstring sein. Doppelte Zuweisung aufb=m=1
sollte auch einige retten.Java, 213 Bytes
Verwendet
BigInteger
s und hat als solches (für alle vernünftigen Absichten und Zwecke) eine unbegrenzte Eingabegröße. Wir sind uns nicht sicher über die Komplexität, die von der Wachstumsrate unserer Funktion hier abhängt.Dank an Geobits und ypnypn für das Speichern einer Handvoll Bytes.
quelle
static
Modifikator zur Methode hinzufügen .b.ONE
und!(b.multiply(c)+"")
(anstelle vontoString()
) schneiden .C 3675 Bytes
So lange für Code Golf ...
Führen Sie das Programm ohne Befehlszeilenparameter
n
ausstdin
und gibt das Ergebnis anstdout
. Führen Sie mit einem Dateinamen aus - es schreibt die Ergebnisse fürn = 1...10000
in diese Datei und misst die Zeit.Leistung für 1 ... 10000: 140 ms
Dieser Code verwendet den von aditsu vorgeschlagenen Algorithmus , der aus Geschwindigkeitsgründen in C implementiert ist. Ich habe mich nicht bemüht, Golf zu spielen, damit der Code leichter zu lesen ist.
Ich habe es zuerst in C ++ implementiert
std::map
, um die Ergebnisse der Suche aufzuzeichnen, und es war ziemlich langsam. Die Tasten vonmap
sind jedoch aufeinanderfolgende Ganzzahlen (ich nenne siemod
s, weil sie Zahlen modulo darstellenn
), daher ist es natürlich, ein Array zu verwenden - also habe ich es in C umgeschrieben.Eine zusätzliche Optimierung betrifft die Werte des Mappings. Um zu vermeiden, dass für jedes Mapping eine große Ganzzahl gespeichert wird
mod
, speichere ich dort nur die größte Potenz von 10 - es sind gerade genug Informationen, um zum vorherigen zu wechselnmod
. Das Array ist also wirklich ein Suchbaum / -graph. Wenn die Suche angekommen istmod = 0
, werden die Potenzen von 10 in absteigender Reihenfolge angegeben, wenn die Knoten des Baums bis zur Wurzel zurückverfolgt werden.Da die Suche in der Regel ziemlich schnell stoppt und nur ein kleiner Teil der Knoten besucht wird, benötige ich eine Liste der aktiven Knoten. Es ist als Array
mod_list
mit Länge implementiertmod_list_length
.Einige Laufzeitstatistiken (auf einem Computer mit 16 GB RAM, was für große Computer wichtig zu sein scheint
n
, da das Programm5n
Bytes an Speicher zuweist):99999999
- 2 Sekunden999999999
- 27 Sekunden (das Ergebnis ist111111111222222222333333333444444444555555555666666666777777777888888889
- wahrscheinlich das größtmögliche Ergebnis für 32-Bit-Ganzzahlen)2147483647
- 26 Sekunden (das Ergebnis ist4661316525084584315813
)1999999998
- 52 Sekunden (wahrscheinlich die längste mögliche Laufzeit für 32-Bit-Ganzzahlen)quelle
C ++ 11, viele Bytes, sehr schnell, wow (1,5 s bei 1999999998, 0,2 s bei 1… 10000)
(Golf-Python-Version unten.)
Wir beginnen mit einem Konzept, das der Lösung von aditsu ähnelt und bei dem wir induktiv eine Sammlung modularer Reste aufbauen, die in n Schritten erreichbar sind. Aber anstatt zu warten, bis wir den Rest 0 gefunden haben, suchen wir nach zwei gefundenen Resten a und b, so dass a · 10 ^ n + b = 0. Dieser Ansatz des Meet-in-the-Middle halbiert die Tiefe des Suchbaums viel schneller bei großen Eingängen und verbraucht viel weniger Speicher.
Einige Benchmarks:
Code:
Python, 280 Bytes (8,6 Sekunden bei 1999999998 mit PyPy)
quelle
Mathematica 115 Bytes
quelle
Java 156 Bytes
Massiver Dank an Aditsu :)
quelle
[]
,y
können eslong
auch sein, Sie haben denx*y+""
Trick im 2. Programm vergessen , verwenden SieisEmpty
anstelle der Überprüfung der Länge, verwenden Sie;
anstelle von{}
long
wenn man den Code verkürzt, würde man ihn nichtlong x=…,y;
y
muss bei 1 beginnen, du kannst es in der Deklaration initialisieren, deine Klasse muss nicht öffentlich sein und du kannsty++
zux*y
part (x*y++
)Pyth -
1211 BytesVerwendet Filter mit numerischem Argument, um die erste natürliche Zahl zu erhalten, die das Prädikat erfüllt. Standard ist 1, was wir wollen. Setwise diff, um zu prüfen, ob nur Nullen und Einsen vorhanden sind.
Test Suite .
quelle
"01
. Spart ein Zeichen.R, 45 Bytes
Verwendung:
quelle
Java,
198193181 BytesVielen Dank an @aditsu für das Abschneiden von 5 Bytes UND das Erhöhen des Bereichs testbarer Zahlen!
Beachten Sie, dass einige Werte aufgrund der Art und Weise, wie Java Ganzzahlen analysiert, eine negative Schleife bilden. Dies könnte durch BigInteger umgangen werden, aber der Bonus war einfach weniger wertvoll.
Ich weiß, dass ich nicht gewinnen werde, aber ich hoffe, dass dies andere, kürzere Antworten inspiriert.
Ungefled:
quelle
Long
ist kürzer alsInteger
:)C,
107101 Bytes (10599 Bytes für 32 Bits)Es gibt einen deutlichen Mangel an Antworten in C auf Code Golf. In der Tat ist C nicht die beste Wahl, um das kleinstmögliche Programm zu schreiben, aber es ist nicht so schlimm:
Sie können auf das #includes verzichten, aber dann sind alle Funktionsdefinitionen implizit. Der Hauptnachteil ist, dass dies die Annahme hervorruft, dass alle Funktionen ints zurückgeben. Dies ist ein Problem auf 64-Bit-Computern für Funktionen, die tatsächlich einen Zeiger zurückgeben. Wenn Sie sich auf einem 32-Bit-Computer befinden, können mit der obigen Lösung 2 Byte gespart werden:
Etwas besser lesbare Version:
quelle
C # -Zeit nahe 5 Sekunden (1 bis 10000)
Wie gewünscht, finden Sie hier ein Golf-C # -Programm, das die ursprüngliche Herausforderung beantwortet. Eingabe als Kommandozeilenargument, Ausgabe an Konsole.
Dann, was das Kopfgeld betrifft: Das Kopfgeld sollte an Aditsu gehen, da ich denke, dass sein Algorithmus in Bezug auf die Leistung nicht zu übertreffen ist. Aber anatolyg Selbstantwort ist auch erstaunlich.
Hier ist meine schnelle Implementierung in C #. Ich nehme an, dass es in C ++ schneller sein könnte (vielleicht 2x). Kompiliert und getestet mit Visual Studio 2010, .NET Framework 4, 64 Bit, Ausgabe nach nul umleiten. Zeit: 00: 00: 05.2604315
quelle
Keys.Reverse
? Ist die Reihenfolge wichtig? Wenn es nur darum geht, Parallelitätsprobleme zu vermeiden,ToList
ist es kürzer.C mit GMP (621 Bytes, schnell)
Ich habe versucht, schnell und kurz zu sein, aber schnell bevorzugt. Diese Implementierung verwendet eine leicht verbesserte Version der zahlentheoretischen Beschleunigung, die ich in einem Kommentar zu Aditsus Antwort erwähnt habe .
Speichern unter
pseudobinary.c
und kompilieren mitgcc pseudobinary.c -lgmp -o pseudobinary
. Beachten Sie, dass dadurch so viel Speicher für große Eingaben reserviert wird, dass Sie ihn für eine 64-Bit-Plattform kompilieren müssen.Loop-Version für das Timing (751 Bytes)
Ungolfed Loop-Version
quelle
C + GMP, 669
Dies ist sehr schnell für kleinere Zahlen; Es beginnt zu ersticken, wenn das Ergebnis mehr als 64 Stellen hat.
Version, die eine Schleife auf 10000 (671 Byte) durchführt:
Hier sind einige Befehle zum Testen meines Codes sowie der Ergebnisse meiner Konkurrenten auf meinem Laptop:
quelle
T-SQL,
164156155154159 Bytes(-1 Byte. Danke Jonathan!)
(-1 mehr, weil ich nachgestellte Leerzeichen in Zeilen habe? SMH)
(+5 haben gemerkt, dass mein Golfspiel etwas kaputt gemacht hat)
Ich weiß nicht, warum ich immer wieder auf diese Fragen zurückkomme, bei denen ich nach Binary konvertieren soll ... T-SQL weiß nicht, wie man das richtig macht.
In jedem Fall ist hier ein SQLFiddle .
Nicht golfen:
Soweit mir bekannt ist, ist das meiste davon erforderlich, um eine Funktion in T-SQL zu schreiben.
Erstellen Sie eine leere Zeichenfolge, die wir als Binärzahl speichern.
Speichern Sie den Eingabewert für die Verwendung am Ende. Es scheint, dass es eine Möglichkeit geben sollte, die ursprüngliche Eingabe zu verwenden, auch wenn wir den Wert ändern, aber ich kann keinen finden.
Wir nehmen also unsere ursprüngliche Eingabe, MOD it with 2, um den Rest zu finden, und das wird unsere nächstkleinere Ziffer sein. Zum Beispiel 5% 2 = 1
Dann nehmen wir unsere Zahl und teilen sie in zwei Hälften. Da es sich um einen
int
Typ handelt, wird er auf die nächste ganze Zahl abgerundet, also 5/2 = 2. ENDE Wir durchlaufen diesen dann, bis der Wert 0 ist. Am Ende erhalten wir 5% 2 = 1 5/2 = 2 2 % 2 = 0 2/2 = 1 1% 2 = 1 1/2 = 0, wodurch wir unseren binären String-Wert von 101 erhalten.Wir nehmen unseren Binärstring und konvertieren ihn wieder in einen
int
.Wir geben unsere Binärzeichenfolge
int
dividiert durch unseren ursprünglichen Wert nach dem Ursprung der Frage zurück.quelle
@>0 SELECT
nicht wegzulassen?Ruby, 46 Bytes
Ich sollte die while-Schleife wirklich mit einer alternativen Schleife beseitigen.
Edit: Danke @manatwork für das Rasieren von 1 Byte!
Edit2: Danke @histocraft für die verrückten 9 Bytes!
Edit: Nochmals vielen Dank an @manatwork für das Abschneiden von 7 Bytes!
quelle
z!=z[/[01]+/]
ist kürzer.z[/[^01]/]
ist noch kürzer.z="#{n.to_i*k+=1}"while z[/[^01]/]
Scala, 114 Bytes
Lesbare Version
quelle
gawk4 Brute Force, 28 + 2 = 30 Bytes
Muss mit dem angerufen werden
-M
Option zur Verwendung großer Nummern werden. Natürlich ist dies lächerlich langsam, wenn große Zahlen verwendet werden, wird es sogar noch langsamer, aber theoretisch ist die Eingabe nicht begrenzt, und die RAM-Auslastung ist vernachlässigbar.Anwendungsbeispiel (wenn Sie Zeit zum Verschwenden haben
;)
)gawk4 optimiert, 69 + 2 = 71 bytes
Nun, dies war ein Klon von Aditsus Antwort. Nach dem Anschauen dieser Frage ich mir hatte, überlegte ich immer noch, wie ich den Teil der Teilmengen-Summe codieren sollte, als ich nicht anders konnte, als die anderen Antworten hier zu betrachten.
In awk haben Array-Elemente das (seltsame?) Verhalten, dass, wenn Sie ein nicht vorhandenes Element mit etwas vergleichen, es vor dem Vergleich als leer initialisiert wird (ich gebe zu, dass ich nicht ganz sicher bin, was dort passiert). Nach dem Prüfen startet
!a[0]
diefor(i in a)
Schleife also auch ohne Initialisierunga[$0]
auf0
wie aditsu tat.Natürlich die
-M
Option genutzt werden.Obwohl es ziemlich schnell ist, ist es immer noch bemerkenswert langsamer als Python. Für
79992
diese dauert etwa 14 Sekunden auf meinem 2GHz Core2Duo. Und ich würde nicht sagen, dass es für Eingaben bis zu 2 ^ 31 funktioniert, weil es im schlimmsten Fall ein Array von großen Zahlen erstellen muss (gawk4 verwendet hierfür GMP), das die Größe der Eingabenummer hat. Als "Bonus" sind große Arrays in awk sehr, sehr langsam ...quelle
Dyalog APL , 25
Dies definiert ein richtiges Programm "P" (nicht nur eine unbenannte Funktion):
2∘
mit 2 als linke Argument beginnen ,0::
wenn es ein Fehler ist ...⍵∇⍨1+⍺
nennen sich mit einem linken Argument erhöht⍺×⍵
mehrfach nach links und rechts Argumente⍕
in String machen⍎¨
machen jedes Zeichen in einer Reihe~
versuchen , nicht logisch (wenn es fehlschlägt, gehen Sie auf die Fehlerbehandlung oben, sonst ...) gibt⍺⊣
das aktuelle linke Argument zurück.quelle