Sie erhalten als Eingabe zwei Zeichenfolgen, die positive Ganzzahlen in Basis 10 darstellen, wie z. B. "12345"
und "42"
. "518490"
In diesem Fall müssen Sie eine Zeichenfolge ausgeben, die das Produkt enthält .
Der Clou ist, dass Sie in Ihrem Code keine numerischen Typen verwenden dürfen. Nein ints
, float
s, unsigned long
s usw., keine integrierten Typen komplexer Zahlen, Ganzzahlen mit willkürlicher Genauigkeit oder ähnliches. Sie verwenden oft weder Literale dieser Art noch Funktionen, Methoden, Operatoren usw., die sie zurückgeben.
Sie können Zeichenfolgen, Boolesche Werte, Arrays oder andere Elemente verwenden, die normalerweise nicht zur Darstellung einer Zahl verwendet werden. (Beachten Sie jedoch, dass es wahrscheinlich nicht möglich ist, ein Array zu indizieren oder seine Länge zu ermitteln, ohne einen numerischen Typ aufzurufen.) char
S sind zulässig, aber Sie dürfen keine arithmetischen oder bitweisen Operationen an ihnen ausführen oder sie auf andere Weise als etwas anderes behandeln ein Token, das einen Teil einer Zeichenfolge darstellt. (Lexikographischer Vergleich von char
s ist erlaubt.)
Sie können die Einschränkung möglicherweise nicht umgehen. Dies schließt die Verwendung von numerischen Typen innerhalb einer eval
Typfunktion, implizite Typkonvertierungen in numerische Typen, die Verwendung von numerischen oder bitweisen Operatoren für nicht numerische Typen, die diese unterstützen, die Verwendung von in Containertypen gespeicherten numerischen Typen oder das Aufrufen von Funktionen oder ein Externe Programme, die numerische Ergebnisse in Zeichenfolgenform zurückgeben. (Ich behalte mir das Recht vor, diese Liste zu ergänzen, wenn die Antworten andere Problemumgehungen enthalten.) Sie müssen die Multiplikation selbst nur mit nicht numerischen Typen implementieren.
Die Ein- und Ausgabe kann auf jede bequeme Weise erfolgen, sofern die Daten in Form einer Zeichenfolge in den Code eingegeben und aus ihm ausgegeben werden. Sie können davon ausgehen, dass jedes der beiden Eingabeargumente nur die ASCII-Zeichen enthält [0-9]
und nicht mit beginnt 0
. Ihre Ausgabe sollte auch keine führenden Nullen haben.
Eine weitere Sache: Ihr Code muss korrekt Eingaben verarbeitet bis zu mindestens 10 Zeichen lang sein und muss in weniger als eine Minute auf einem modernen Computer läuft für alle Eingaben in diesem Bereich. Vor der Veröffentlichung, überprüfen Sie bitte , dass , wenn Eingaben gegeben 9999999999
und 9999999999
Ihr Programm gibt einen Ausgang 99999999980000000001
, in weniger als eine Minute. Diese Einschränkung dient speziell dazu, Antworten zu verhindern, die funktionieren, indem Sie ein Array mit einer bestimmten Größe a*b
zuweisen und dann darüber iterieren. Denken Sie also daran, dass Antworten dieses Formulars nicht gewinnberechtigt sind.
Das ist Code-Golf , also gewinnt die kürzeste gültige Lösung (in Bytes).
quelle
"12345"
von STDIN eher akzeptieren als12345
? Oder können wir beide Zahlen als akzeptieren"12345", "42"
?m
undn
ein Argument mit der Länge zurückgibtm*n
. Aber da die Zeichenfolgen buchstäblich die ASCII-Darstellung der Zahlen enthalten müssen, verstößt dies vermutlich gegen die Regeln.a,b="0123456789x".split('0');c=iter(b).next()
if c=='x':
c='0'
a,b="0123456789x".split(x);c,*d=b
if c=='x':
c='0'
d='123456789';I=dict(zip('0'+d,d+'0'))
Antworten:
Haskell - 180
206 214Implementiert die Multiplikation durch wiederholtes Hinzufügen, und alle Arten von Ziffernmagie werden durch Verschieben und Filtern der
['0'..'9']
Liste behandelt. Definiert einen Operator#
vom TypString -> String -> String
:quelle
"0123456789"
ist die Liste['0'..'9']
. Zweitens können in Haskell [a..b], einer Aufzählung, Typen, die Instanzen derEnum
Typenklasse deklariert haben, auf diese Weise aufgezählt werden, und die Deklaration beschreibt, wie die Aufzählung funktioniert.Bool
hat der Boolesche Typ auch eine Instanz, und daher können Sie dies auch tun[False..True]
. Es sind kaum Zahlen beteiligt.sed,
339338 BytesIch weiß, dass dies eine alte ist, aber ich habe mich umgesehen und dies hat mein Interesse geweckt. Genug, um sich tatsächlich als Benutzer zu registrieren! Ich denke, ich wurde von " Ich würde gerne eine vollständige Lösung sehen - Nathaniel " beeinflusst ...
Dieses sed-Skript erwartet zwei Dezimalzahlen als Eingabe, die durch ein Leerzeichen getrennt sind
Tests:
Sie können die letzten beiden als RSA-100 (50 x 50 Stellen) und RSA-768 (116 x 116 Stellen) erkennen.
Wenn Sie GNU sed auf einem nicht sehr modernen (Intel Core 2 der Ära 2007) verwenden, dauert der letzte Vorgang mehr als eine Minute, auf einem neueren Prozessor ist er jedoch schneller:
Die mickrige 10-stellige Multiplikation, die in der Frage angegeben ist, benötigt bei all diesen (obwohl sie voller pathologischer Neunen ist) weit weniger als eine Sekunde.
Ich glaube, es ist Standard-Sed, ohne Erweiterungen. POSIX garantiert einen Speicherplatz von nur 8192 Bytes, was uns auf das Multiplizieren von Zahlen mit 400 x 400 Stellen beschränkt, aber Implementierungen können mehr bieten. GNU sed ist nur durch den verfügbaren Speicher begrenzt. Wenn Sie also warten möchten, können Sie etwas viel Größeres verwalten.
Und ich bin zuversichtlich, dass ich mich an die Regeln gehalten habe - das ist in einer Sprache ohne Zahlen fast selbstverständlich. :-)
Erläuterung
Ich verwende ein Unary / Decimal-Hybrid, das Dezimalzahlen in eine Folge von Unary umwandelt:
Bei unärer Dezimalstelle ist die Addition einfach. Wir iterieren von der niedrigstwertigen zur höchstwertigen Ziffer und verketten die x:
Wir entfernen dann Whitespace und beschäftigen uns mit dem Übertragen, indem wir 10 aufeinanderfolgende x in eine der nächsten Einheiten umwandeln:
Sobald wir die Addition haben, ist eine Multiplikation möglich. Wir multiplizieren x * y mit der letzten Ziffer von y. Addiere x so oft zum Akkumulator, gehe dann zur nächsten Ziffer und verschiebe x um eine Dezimalstelle nach links. Wiederholen, bis y Null ist.
Erweiterter Code
quelle
sed, 379 bytes
Der Dank für diese brillante Antwort geht an @LuigiTiburzi bei Unix & Linux.SE: https://unix.stackexchange.com/a/37213/34061 . Ich bin gerade vor ein paar Tagen darauf gestoßen:
Grundsätzliche Erklärung
12*3
wird es<1<2*<3
|
Zeichen. So<1<2*<3
wird es<|<||*<|||
|<
mit<||||||||||
, um höhere Dezimalstellen bis zur Einheitsposition zu verschieben. So<|<||*<|||
wird es<||||||||||||*<|||
<
. So<||||||||||||*<|||
wird es||||||||||||*|||
|
von der rechten Seite des*
. So||||||||||||*|||
wird es||||||||||||*||
|
auf der rechten Seite wiederholt durch alle|
auf der linken Seite. Dies hat den Effekt, dass die LHS- und RHS-Nummer multipliziert wird|
, um die Produktnummer von|
Thus||||||||||||*||
zu erhalten||||||||||||||||||||||||||||||||||||*
*
. So||||||||||||||||||||||||||||||||||||*
wird es||||||||||||||||||||||||||||||||||||
|
zurück zu dezimal um, indem du die ersten Schritte rückgängig machst. So||||||||||||||||||||||||||||||||||||
wird es36
.Ausgabe:
Leider scheitert es kläglich am Zeitbedarf -
200*1000
auf meiner Ubuntu-VM dauert es 41 Sekunden, und die Laufzeit scheint empirisch mit dem Quadrat des Endprodukts übereinzustimmen.quelle
length()
was eine Zahl zurückgibt. Dieser verwendet eine reine Regex-Substitution ohne numerische Typen. Ich denke, Ihre Antwort ist möglicherweise ein Gewinner, wenn Sie die entfernen könnenlength()
- vielleicht könnten Sie stattdessen eine ähnliche Regex-Substitution durchführen?Python -
312286273Wenn (viele) führende Nullen zulässig sind, werden die letzten 12 Zeichen nicht benötigt.
Dies führt im Wesentlichen die Standardmultiplikation von Hand durch. Ziffern werden als Zeichenfolgen von wiederholten
I
s dargestellt (wie primitive römische Ziffern). Zahlen werden in umgekehrter Reihenfolge als Ziffernlisten dargestellt. Das Hinzufügen einzelner Ziffern erfolgt durch Verknüpfen von Zeichenfolgen und Entfernen von zehn Sekunden,I
falls erforderlich.Hier ist eine ungolfed Version:
quelle
def A(x,y):\n S=[];o=""
->def A(x,y,S=[],o=""):
. Auch ist leider["","1"][t in i]
nicht erlaubt; Es verwendet einen Bool zum Indizieren und behandelt ihn als Zahl. Ich denke, dast in i and"1"or""
sollte funktionieren.S
als Argument mit einem Default hätte nicht funktioniert, da es auch bei unterschiedlichen Aufrufen der Funktion immer die gleiche Liste wäre und somit nicht zurückgesetzt wird[]
. Sie hatten Recht["","1"][t in i]
, das habe ich behoben. Ich habe auch eine Erklärung hinzugefügt.Ruby:
752698Dies geschieht nur, um eine Antwort zu erhalten, und zwar aus Neugier. Bearbeitet: jetzt ein bisschen golfen.
Verwendung: Ich hatte dies in einer Datei namens peasant.rb:
Erklärung: Es ist eine bäuerliche Vermehrung, also halbiere und verdopple ich wiederholt. Die Halbierung erfolgt durch Halbieren von Ziffern und Markieren von Resten wie folgt: 1234 -> 0b1a1b2a; dann finde und ersetze auf dem b: 06a17a; dann aufräumen -> 617.
Die Addition erfolgt wie folgt: Zuerst fülle ich beide Zeichenfolgen auf die gleiche Länge auf und bilde Paare aus den Ziffern. Dann füge ich die Ziffern hinzu, indem ich einen String konstruiere, der die Länge jeder Ziffer hat und verkettet; Ich entferne eine Zeichenfolge dieser Länge vom Anfang von '0123456789abcdefghij' und behalte dann das erste Zeichen. Also zB "9" + "9" -> "i". Anmerkung: Ich vermeide es, Längenfunktionen zu verwenden, um Nummerntypen vollständig zu vermeiden. Das Entfernen des Präfixes erfolgt stattdessen mit einem regulären Ausdruck.
Jetzt habe ich eine Zeichenfolge mit einer Mischung aus Ziffern und Buchstaben. Die Buchstaben stellen Zahlen mit einer Übertragsziffer dar; Ich stelle der Zahl 0 voran und ersetze dann wiederholt Ziffern-Buchstaben-Muster mit dem Ergebnis des Übertrags, bis die Addition abgeschlossen ist.
quelle
Brainfuck (1328 Bytes)
Überlegungen zuerst:
Ich habe das Programm nur mit meinem eigenen Interpreter getestet, Sie finden es hier .
Die Eingabe muss aus beiden Zahlen bestehen, die durch ein einzelnes ASCII-Leerzeichen getrennt sind.
Golf gespielt:
Ungolfed:
Ich habe den Code für die Ausgabe des Werts dieser Antwort entnommen , danke an den Autor dafür!
Das Programm ist möglicherweise nicht gültig, aber ich wollte es auf jeden Fall mit Ihnen teilen ^^
Update: Sie können es jetzt hier testen (nur für kleine Multiplikationen), dank der Antwort von @ Sp3000 auf diesen Wettbewerb und den neuen Stack Snippets von SE!
quelle
Python,
394349340 ZeichenLaufen Sie wie folgt:
Dauert 50 Millisekunden.
Verwendet die russische Bauernmultiplikation . Wenn wir Ziffern hinzufügen, konvertieren wir sie in unäre ('5' => [R, R, R, R, R]), verketten die Listen und konvertieren sie dann zurück.
U
konvertiert zu unär, wobeiR
als unäres Zeichen verwendet wird. Wir berechnenb/=2
alsb=b*5/10
.quelle
def A(a,b):\n r='';c=[]
->def A(a,b,r='',c=[]):
ähnlich fürdef M
. Sie könnten in der Lage sein , zu ändern ,for z in D:d.pop()\n c=['X']
zu ,[d.pop()for z in D];c=['X']
in dem Fall , dass Sie es sogar auf die vorherigen kollabieren könntenif
. Kann auchif list(b).pop()in'13579'
nur seinif b[:].pop()in'13579'
?b
um eine Zeichenfolge handelt, nicht um eine Liste.M
ein komplettes Programm überspringen und schreiben;a,b=input()
ist erlaubt.reduce
, was Ihnen erlaubt, nicenA(b,A(b,A(b,A(b,b))))
zureduce(A,[b,b,b,b,b])
. Leider hat dies keinen Einfluss auf die Anzahl der Zeichen.JavaScript (E6) 375
395 411 449Edit Golfed
Edit Bug behoben: Fehlendes Löschen eines Carry Flags
Dies kann mit nur einer Symbolmanipulation in der Nähe von 0-Zeit erfolgen.
In dieser Version können Sie anstelle der Ziffern ein beliebiges Zeichen verwenden, sofern sich das Symbol in aufsteigender Reihenfolge befindet.
Anmerkungen: Verwenden von Strings, Hashmap mit String-Schlüssel, Arrays, die als Liste verwendet werden. Keine Indizierung, die Arrays werden mit 'map' durchlaufen oder mit push & shift gedreht.
Alle '+' sind Zeichenfolgenverkettung.
Weniger Golf (vielleicht werde ich morgen eine Erklärung hinzufügen)
Test In FireFox / Firebug - Konsole
Ausgabe
quelle
9999999999
Fall sollte es99999999980000000001
nicht sein99999999980000000081
Haskell, 231 Bytes
Dies definiert einen Operator #, der zwei Zeichenfolgendarstellungen natürlicher Zahlen multipliziert. Es funktioniert, indem eine elementare Inkrementierungs- / Dekrementierungsoperation für Zeichenfolgen definiert und dann zum Aufbau von Addition und Multiplikation verwendet wird. Ein wenig zusätzliche Magie gibt einige exponentielle Beschleunigungen, die alles möglich machen ..
Dieser Ansatz ist schnell genug, dass selbst auf einem 2008er-Laptop im nicht optimierten ghci REPL der Testfall nur einen Bruchteil einer Sekunde dauert:
Hier ist eine Überprüfung, ob alle zweistelligen Produkte korrekt sind:
quelle
Bash + ImageMagick: 52
Erwartet, dass sich die Eingabe in den Shell-Variablen
a
und befindetb
. Es ist nicht besonders clever oder effizient, aber es erledigt die Arbeit. Es ist wahrscheinlich schon einmal gemacht worden.Beachten Sie, dass das
x
die Abmessungen des Bildes angibt; es ist in diesem Zusammenhang kein arithmetischer Operator.Ich habe das noch nicht getestet, gehe aber davon aus, dass es für nicht extreme Eingaben in weniger als einer Minute abgeschlossen sein wird. Ich kann es morgen testen.
Für den Fall, dass es mit ImageMagick-Versionen ein lustiges Geschäft gibt, ist dies das, was ich verwende:
ImageMagick 6.7.7-10
quelle
9999999999
und in weniger als einer Minute (oder überhaupt auf einer vorhandenen Maschine) nicht funktioniert9999999999
.dd if=/dev/zero bs=$a count=$b 2>&-|wc -c
.9999999999x9999999999
Bild im 8-Bit-Format belegt den gesamten derzeit auf der Erde vorhandenen Festplattenspeicher. Natürlich wäre ein PNG viel kleiner, wenn Sie es erstellen könnten, ohne vorher das Rohbild zu erstellen. (Obwohl ich stark vermute, dass Sie bei einem Bild dieser Größe Probleme mit dem Überlauf von Ganzzahlen haben würden.) Dennoch würde eine solche Methode mit ziemlicher Sicherheit die Regelungslücke für das Aufrufen von Dingen, die numerische Ergebnisse als Zeichenfolgen zurückgeben, verletzen.$b
anstelle von verwenden${b}
.grep -vc g
anstelle von verwendengrep -v g|wc -l
.Python 2 (Proof of Concept)
Diese Lösung funktioniert nur mit Strings und Listen und ein wenig Regex. Ich glaube, es passt zur Spezifikation, außer dass es
9999999999x9999999999
in einer Minute unmöglich ist, es zu tun . Obwohl es genügend Zeit gab, würde es funktionieren. Es kann 4-stellige Zahlen ziemlich schnell multiplizieren.Da es technisch ungültig ist, habe ich mich noch nicht darum gekümmert, es komplett zu golfen. Ich werde es tun, wenn sich die Regeln ändern.
Beispiele:
quelle
Python 2 (555)
Normalerweise würde ich meine eigene Herausforderung nicht so schnell (oder überhaupt nicht) beantworten, aber ich wollte beweisen, dass dies möglich ist. (Glücklicherweise haben dies schon einige andere Antworten gegeben, aber ich konnte nicht anders, als es beenden zu wollen.) Es könnte noch etwas mehr Golf gespielt werden, aber ich denke, das ist vernünftig. Es behandelt den
9999999999x9999999999
Fall in weniger als 0,03 s auf meinem Computer.Beispiel Verwendung:
m("12345","42")
Es funktioniert durch lange Multiplikation mit Zeichenfolgenmanipulationen. Manchmal sind die Variablen Zeichenfolgen und manchmal sind sie Iteratoren über Zeichenfolgen, sodass das erste Element ohne Verwendung eines Integer-Literal abgerufen werden kann. Alles wird mit umgekehrten Ziffern gespeichert, sodass das erste Element die niedrigstwertige Ziffer ist.
Hier ist eine Erklärung der einzelnen Funktionen:
r
unds
sind Buchhaltungsfunktionen. (r
ist nur ein Alias fürreversed
, der einen Reverse-Iterator erzeugt unds
Iteratoren in Strings umwandelt.)i
erhöht die Zahl in einer Zeichenfolge um 1, einschließlich Fällen wie39+1=40
und99+1=100
.b
fügtx
und hinzuy
,y
darf aber nur eine Ziffer sein. Es funktioniert durch Inkrementieren derx
y
Zeiten.a
Addiert zwei Zahlen, die beide mehrere Ziffern haben können, indem Sieb
jede Ziffer in aufrufeny
.n
multipliziertx
undy
,y
darf aber nur eine Ziffer sein. Es funktioniert, indemx
es sichy
mal addiert .o
multipliziertx
undy
, wobei beide Argumente mehrstellig sein können. Es verwendet die klassische Langmultiplikationm
konvertiert einfach seine Zeichenketteneingaben in umgekehrte Iteratoren und übergibt sie ano
, kehrt dann das Ergebnis um und konvertiert es in eine Zeichenkette.quelle
def a(x,y):
->def a(x,y,z=''):
und nächste Zeile entfernen; ähnliche Tricks für andere Funktionen,def o(x,y):
ändern Siex=s(x)
inx=s(x);l='';z=''
, in der for-Schleife, entfernen Sie in ähnlicher Weise Zeilenumbrüche + Paces; Verwenden Sie stattdessen;
. Auch ich denke dasif h!='0':h+=s(x)\nelse:h+=i(x)
kann einfach seinh+=h!='0'and i(x)or s(x)
; vielleicht sogarh+=(h!='0'and i or s)(x)
; Andernfalls wechseln Sie einfach zuif'0'!=h
. Auch Dinge wiedef r(x):return reversed(x)
->r=reversed
s
,m
:s=lambda x:''.join(x)
,m=lambda x,y:s(r(o(r(x),r(y))))
anstelle der gesamten Funktionsdeklaration zu erwähnen . Mit nur den Dingen, von denen ich weiß, dass sie funktionieren, verringert sich Ihre Byteanzahl auf 521.for
Schleifen:for c in'0'+d:\nif c==y:break\nz=a(iter(z),x)
->for c in'0'+d:\nif c!=y:z=a(iter(z),x)
, obwohl dies die Geschwindigkeit deines Programms erheblich verändern könnte.JavaScript:
37103604 BytesGolf:
Ungolfed mit Tests:
Dies gibt aus:
quelle
Haskell
507496Dies funktioniert für beliebig große ganze Zahlen. Ich definiere benutzerdefinierte Darstellungen für die natürlichen Zahlen von 0 bis 18 (die größte natürliche Zahl entspricht der Summe aus zwei Ziffern) und definiere Little-Endian-Multiplikation in Form von Ziffern * Zahlen-Multiplikation, die ich in Form von Zahl + Zahlenaddition definiere , die ich als Ziffer + Ziffernaddition definiere. Ich habe eine Reduktionsfunktion, die 10--18 Werte in ihre digitale Zerlegung erweitert. Dabei werden nur die beiden Zeichenfolgen gelesen und umgekehrt, die benutzerdefinierten Bindungen werden übersetzt, multipliziert und rückwärts übersetzt, um das richtige Ergebnis zu erzielen.
Bearbeiten 2
Ich habe ein paar Zeichen gespart, indem ich kurze lokale Aliase für Befehle mit mehreren Zeichen erstellt habe, die ich mehrmals verwende, sowie Leerzeichen und Klammern entfernt und
(
-)
Paare durch ersetzt habe,$
wenn dies möglich ist.Als Referenz ist S der benutzerdefinierte ganzzahlige Datentyp,
p
ist 'plus' (Ziffer + Ziffernaddition),s
ist subtrahiert (zur Reduktion),r
ist reduziert (erweitert in digitale Zerlegung),a
ist Addition ( Ziffer + Ziffernaddition ),m
ist multiplizieren (Ziffer * Zahlenmultiplikation),t
ist mal (Ziffer * Zahlenmultiplikation),i
ist 'interpretieren' (Zeichenkette in Liste von umwandelnS
),b
ist 'zurück' (Liste von S in Zeichenkette) und f und g sind nur Abkürzungen für das Golfen Zwecke. Ich habe nicht einmal implizit Zahlen verwendet. Das nächste, was ich bekam, war die Verwendung von Nachfolgern und Vorgängern, die mathematische Konzepte auf einer viel höheren Ebene darstellen als das Addieren und Multiplizieren von natürlichen Zahlen.Bearbeiten
Ich habe vergessen, das Zeitprofil anzugeben.
Nur aus gutem Grund:
Lass uns verrückt werden!
Bestätigung
quelle
Python 2 -
1165, 712, 668,664Beachten Sie, dass ich keine logische Indizierung verwende
Z = [X, Y][N == "0"]
, da dies als Boolescher Wert interpretiert werden könnte, der in einen numerischen Index umgewandelt wird.Ungolfed:
quelle
Scala, 470 Zeichen
(Die
⇒
sind Standard-Scala, können aber auch durch ersetzt werden,=>
wenn wir Bytes zählen.)Hier emulieren wir Ziffern anhand der Länge von Listen, wobei wir darauf achten, keine numerischen Operationen zu verwenden - nur Falten, Karten, Reißverschlüsse und dergleichen. Eine Zahl ist eine Liste dieser Ziffern (Reihenfolge in der Mitte der Berechnung strategisch umgekehrt). Wir multiplizieren einzelne Ziffern mit
flatMap
und unsere Zeilen mitreduce
.u
Erledigt das Herausfinden des Übertrags (indem er direkt mit einer Liste von> 10 Elementen abgeglichen wird und rekursiv) und konvertiert Ziffern zurück in Zeichen, und wir verwenden a/:
, um uns damit durch den Stapel zu arbeiten. Das erforderliche Beispiel ist in weniger als einer Sekunde abgeschlossen.quelle