Multiplizieren Sie zwei Zahlen ohne Verwendung von Zahlen

30

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, floats, unsigned longs 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.) charS 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 chars ist erlaubt.)

Sie können die Einschränkung möglicherweise nicht umgehen. Dies schließt die Verwendung von numerischen Typen innerhalb einer evalTypfunktion, 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 9999999999und 9999999999Ihr 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*bzuweisen und dann darüber iterieren. Denken Sie also daran, dass Antworten dieses Formulars nicht gewinnberechtigt sind.

Das ist , also gewinnt die kürzeste gültige Lösung (in Bytes).

Nathaniel
quelle
Können wir "12345"von STDIN eher akzeptieren als 12345? Oder können wir beide Zahlen als akzeptieren "12345", "42"?
Justin
Mein erster Gedanke war, eine Funktion zu schreiben, die Zeichenfolgenargumente mit der Länge mund nein Argument mit der Länge zurückgibt m*n. Aber da die Zeichenfolgen buchstäblich die ASCII-Darstellung der Zahlen enthalten müssen, verstößt dies vermutlich gegen die Regeln.
Level River St
1
@xnor in vielen Sprachen kann es kürzer sein, alle Fälle auszuschreiben. Aber ich habe diesen Weg in Python gefunden:a,b="0123456789x".split('0');c=iter(b).next() if c=='x': c='0'
Nathaniel
1
oder in Python 3,a,b="0123456789x".split(x);c,*d=b if c=='x': c='0'
Nathaniel
2
@ Nathanield='123456789';I=dict(zip('0'+d,d+'0'))
Justin

Antworten:

6

Haskell - 180 206 214

r=reverse
f=filter
z=['0'..'9']
a?f|f="1"!a
a?_=a
(a:b)!(c:d)=e:b!d?(e<a)where e=fst$last$zip(f(>=c)z++z)$f(<=a)z
a!c=a++c
a%(b:c)=foldr(!)('0':a%c)$f(<b)z>>[a]
_%b=b
a#b=r$r a%r b

Implementiert 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 Typ String -> String -> String:

*> :set +s
*> "9990123456789"#"9999876543210"
"99900001219316321126352690"
(0.02 secs, 9862288 bytes)
mniip
quelle
Sieht so aus, als hätten wir einen neuen Gewinner! (Obwohl ich nach wie vor Haskell von diesem Grad an Raffinesse nicht lesen kann - kann jemand unabhängig prüfen, ob er die Spezifikation erfüllt?)
Nathaniel,
(Auch die ['0' .. '9'] fühlt sich an, als würde man Zeichen implizit als Zahlen behandeln, die iteriert werden können. Gibt es eine kurze Möglichkeit, diese Liste stattdessen aus der Zeichenfolge "0123456789" zu generieren?)
Nathaniel
@Nathaniel Nun zunächst einmal die Zeichenfolge "0123456789" ist die Liste ['0'..'9']. Zweitens können in Haskell [a..b], einer Aufzählung, Typen, die Instanzen der EnumTypenklasse deklariert haben, auf diese Weise aufgezählt werden, und die Deklaration beschreibt, wie die Aufzählung funktioniert. Boolhat der Boolesche Typ auch eine Instanz, und daher können Sie dies auch tun [False..True]. Es sind kaum Zahlen beteiligt.
Mittwoch,
14

sed, 339 338 Bytes

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

s/[1-9]/0&/g
s/[5-9]/4&/g
y/8/4/
s/9/4&/g
s/4/22/g
s/[37]/2x/g
s/[26]/xx/g
s/[1-9]/x/g
:o
s/\( .*\)0$/0\1/
/x$/{
x
G
s/ .*/\n/
:a
s/\(.*\)0\(x*\)\n\(.*\)0\(x*\)\n/\1\n\3\n0\2\4/
ta
s/\n//g
:c
s/^x/0x/
s/0xxxxxxxxxx/x0/
tc
x
s/x$//
}
/ 0/bo
g
s/0x/-x/g
s/xx/2/g
y/x/1/
s/22/4/g
s/44/8/g
s/81/9/g
s/42/6/g
s/21/3/g
s/61/7/g
s/41/5/g
s/-//g

Dieses sed-Skript erwartet zwei Dezimalzahlen als Eingabe, die durch ein Leerzeichen getrennt sind

Tests:

time test 518490 = $(./40297.sed <<<)"12345 42" || echo fail
time test 99999999980000000001 = $(./40297.sed <<<"9999999999 9999999999") || echo fail
time test 1522605027922533360535618378132637429718068114961380688657908494580122963258952897654000350692006139 = $(./40297.sed <<<"37975227936943673922808872755445627854565536638199 40094690950920881030683735292761468389214899724061") || echo fail
time test 1230186684530117755130494958384962720772853569595334792197322452151726400507263657518745202199786469389956474942774063845925192557326303453731548268507917026122142913461670429214311602221240479274737794080665351419597459856902143413 = $(./40297.sed <<<"33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917") || echo fail

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:

  • Q6600:> 1 Minute
  • i7-3770: 26 Sekunden
  • i7-6700: 22 Sekunden

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:

 42 => _xxxx_xx

Bei unärer Dezimalstelle ist die Addition einfach. Wir iterieren von der niedrigstwertigen zur höchstwertigen Ziffer und verketten die x:

   X=965                   Y=106                                 SUM
   _xxxxxxxxx_xxxxxx_xxxxx _x__xxxxxx
   _xxxxxxxxx_xxxxxx       _x_                          _xxxxxxxxxxx
   _xxxxxxxxx              _x                    _xxxxxx_xxxxxxxxxxx
                                      _xxxxxxxxxx_xxxxxx_xxxxxxxxxxx

Wir entfernen dann Whitespace und beschäftigen uns mit dem Übertragen, indem wir 10 aufeinanderfolgende x in eine der nächsten Einheiten umwandeln:

 _xxxxxxxxxx_xxxxxx_xxxxxxxxxxx       10.6.11
 _xxxxxxxxxx_xxxxxxx_x                10.7.1
 _x__xxxxxxx_x                        1.0.7.1 

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

#!/bin/sed -f

# Convert to unary decimal.  We save two or three bytes of code by
# reusing 0 as the digit separator.
s/[1-9]/0&/g
s/[5-9]/4&/g
y/8/4/
s/9/4&/g
s/4/22/g
s/[37]/2x/g
s/[26]/xx/g
s/[1-9]/x/g

# until y==0

:one

# y ends in zero => x *= 10 and y /= 10
s/\( .*\)0$/0\1/

# while y%10, acc += x, y -= 1
/x$/{
x
G
s/ .*/\n/
# Add x
:add
s/\(.*\)0\(x*\)\n\(.*\)0\(x*\)\n/\1\n\3\n0\2\4/
tadd
s/\n//g
:carry
s/^x/0x/
s/0xxxxxxxxxx/x0/
tcarry

# repeat for each unit of y
x
s/x$//
}

# y?
/ 0/bone


# convert hold space to decimal
g
s/0x/-x/g
s/xx/2/g
y/x/1/
s/22/4/g
s/44/8/g
s/81/9/g
s/42/6/g
s/21/3/g
s/61/7/g
s/41/5/g
s/-//g
Toby Speight
quelle
1
Sehr befriedigende Antwort, danke!
Nathaniel
9

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:

s/[0-9]/<&/g
s/0//g
s/1/|/g
s/2/||/g
s/3/|||/g
s/4/||||/g
s/5/|||||/g
s/6/||||||/g
s/7/|||||||/g
s/8/||||||||/g
s/9/|||||||||/g
:t
s/|</<||||||||||/g
tt
s/<//g
s/.*\*$/0/
s/^\*.*/0/
s/*|/*/
:m
s/\(|*\)\*|/\1<\1*/
tm
s/*//g
s/<//g
:b
s/||||||||||/</g
s/<\([0-9]*\)$/<0\1/
s/|||||||||/9/
s/||||||||/8/
s/|||||||/7/
s/||||||/6/
s/|||||/5/
s/||||/4/
s/|||/3/
s/||/2/
s/|/1/
s/</|/g
tb

Grundsätzliche Erklärung

  • Trennen Sie jede Ziffer. So 12*3wird es<1<2*<3
  • Konvertieren Sie jede Ziffer in diese Anzahl von |Zeichen. So <1<2*<3wird es<|<||*<|||
  • Ersetzen Sie wiederholt |<mit <||||||||||, um höhere Dezimalstellen bis zur Einheitsposition zu verschieben. So <|<||*<|||wird es<||||||||||||*<|||
  • Entfernen <. So <||||||||||||*<|||wird es||||||||||||*|||
  • Entfernen Sie 1 |von der rechten Seite des *. So ||||||||||||*|||wird es||||||||||||*||
  • Ersetzen Sie jedes |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||||||||||||||||||||||||||||||||||||*
  • Entfernen *. So ||||||||||||||||||||||||||||||||||||*wird es||||||||||||||||||||||||||||||||||||
  • wandle die Zahl von |zurück zu dezimal um, indem du die ersten Schritte rückgängig machst. So ||||||||||||||||||||||||||||||||||||wird es 36.

Ausgabe:

$ echo "04*3
4*3
40*3
42*32
150*20
1*3
3*1
0*3
3*0" | sed -f mult.sed
12
12
120
1344
3000
3
3
0
0
$

Leider scheitert es kläglich am Zeitbedarf - 200*1000auf meiner Ubuntu-VM dauert es 41 Sekunden, und die Laufzeit scheint empirisch mit dem Quadrat des Endprodukts übereinzustimmen.

Digitales Trauma
quelle
1
Dies ist fast algorithmisch äquivalent zu meiner gelöschten JS-Antwort, abgesehen von der Rückkonvertierung in einen Zahlenteil.
Optimierer
@Optimizer vereinbart. Der Unterschied ist, dass Sie verwenden, 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önnen length()- vielleicht könnten Sie stattdessen eine ähnliche Regex-Substitution durchführen?
Digital Trauma
1
Sehr schön, aber die einminütige Beschränkung soll speziell verhindern, dass Lösungen funktionieren, indem sie bis zur Antwort gezählt werden. Ich würde jedoch gerne eine vollständige Lösung sehen.
Nathaniel
1
Ich habe eine Antwort , die bei großen Zahlen funktioniert (z. B. größer als der Adressraum des Systems).
Toby Speight
@TobySpeight ja, sehr gut. Ich denke, ich muss deine schon vor einiger Zeit aufgewertet haben :)
Digital Trauma
9

Python - 312 286 273

D={}
e=t=""
N=[e]
for c in"0123456789":D[c]=t;D[t]=c;t+="I";N+=N
B=lambda s:[D[c]for c in reversed(s)]
Y=B(input())+N
for a in B(input())+N:
 for c in a:
    s=[];o=e
    for a,b in zip(N,Y):i=a+b+o;o=t<=i and"I"or e;s+=i.replace(t,e),;N=s
 Y=[e]+Y
print e.join(B(N)).lstrip("0")

Wenn (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 Is 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, Ifalls erforderlich.

Hier ist eine ungolfed Version:

N = [""] # zero object: list with a lot of empty strings
D = {}   # dictionary for conversion from and to digits
i = ""   # iterates over digits
for c in "0123456789":
    D[c] = i  # map digit to Roman digit
    D[i] = c  # and vice versa
    i += "I"  # increments Roman digit
    N += N    # add leading zeros to zero

ten = "IIIIIIIIII" # Roman digit ten

# Conversion function
B = lambda s: [D[c] for c in reversed(s)]

def Add(x,y):
    Sum = []
    carryover = ""
    for a,b in zip(x,y):
        increment = a+b+carryover
        carryover = "I" if ten in increment else ""
        increment = increment.replace(ten,"") # take increment modulo ten
        Sum += [increment]
    return Sum

def M(x,y):
    Sum = N[:] # Initiate Sum as zero
    X = B(x)+N # Convert and add leading zeros
    Y = B(y)+N
    for a in X:
        for c in a:
            Sum = Add(Sum,p+Y)
        Y = [""] + Y # multiply Y by 10
    return "".join(B(Sum)).lstrip("0") # Convert back and to string, remove leading zeros.

M(input(),input())
Wrzlprmft
quelle
1
Was ist das für eine Zauberei! Wie funktioniert es! Wow. Auch hier ist ein anderes Golf, das Sie tun könnten: 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, das t in i and"1"or""sollte funktionieren.
Justin
@Quincunx: Das Definieren Sals 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.
Wrzlprmft
Das ist ziemlich erstaunlich. Es bekommt vorerst das grüne Häkchen. (Ich habe die Frage bearbeitet, um zu verdeutlichen, dass führende Nullen in der Ausgabe nicht zulässig sind - sorry!)
Nathaniel
7

Ruby: 752 698

Dies geschieht nur, um eine Antwort zu erhalten, und zwar aus Neugier. Bearbeitet: jetzt ein bisschen golfen.

$F='0123456789'
$G="#{$F}abcdefghij"
def x(a,b);p(a=~/[13579]$/?b:"",a==""?"":x(Hash[*%w(b0 5 b1 6 b2 7 b3 8 b4 9)].to_a.inject(a.tr($F,'0011223344').chars.zip(a.tr($F,'ababababab').chars).flatten.join("")){|n,q|k,v=q;n.gsub(k,v)}.gsub(/[ab]/,'').sub(/^0*/,''),p(b,b)));end
def p(a,b);j,k=["0#{a}","0#{b}"].map{|c|c.gsub(/./,'0')};c="#{k}#{a}".chars.zip("#{j}#{b}".chars).drop_while{|z|z==%w(0 0)}.map{|m|$G.sub(/#{m.map{|n|"122333444455555666666777777788888888999999999".chars.select{|c|c==n}}.flatten.map{|c|'.'}.join("")}/,"").chars.first}.flatten.join("");d=nil;
while c!=d
 d=c;c="0#{d}".gsub(/[0-9][a-j]/) {|m| m.tr($G,"123456789a#{$F}")}.sub(/^0/,'')
end;c;end
puts x(ARGV.shift,ARGV.shift)

Verwendung: Ich hatte dies in einer Datei namens peasant.rb:

$ time ruby peasant.rb 9999999999 9999999999
99999999980000000001

real    0m0.129s
user    0m0.096s
sys 0m0.027s

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.

bazzargh
quelle
1
Sehr clevere Antwort, genau das, was ich mir erhofft hatte!
Nathaniel
1
Eigentlich hoffe ich, dass jemand eine mit den Nummern der Kirche posten wird!
bazzargh
Das wäre cool, obwohl ich nicht sicher bin, ob es mit der Effizienzanforderung klappen würde - ich denke, das Umrechnen zwischen Zeichenfolgen und Church-Zahlen würde effektiv das Zählen von bis zu 99999999980000000001 beinhalten.
Nathaniel,
7

Brainfuck (1328 Bytes)

Überlegungen zuerst:

  • Ich bin mir nicht sicher, ob Brainfuck eine gültige Antwort auf diese Frage ist, da ich nicht sicher bin, ob Sie die Zellwerte als 'numerische Typen' betrachten oder nicht. Ich glaube nicht, da bf keine Typen kennt, aber das ist meine eigene Meinung, bitte korrigiere mich, wenn ich mich irre.
  • Eine Implementierung, die (fast) unbegrenzte Werte unterstützt, ist erforderlich.
  • Es könnte viel zu langsam sein, basierend auf der Implementierung.

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:

,
>++++++[<----->-]<--
[                                           # read input until space
    >,
    >++++++[<----->-]<--                    # decrease cell by 32 to check if it's a space
]
>>>+<<<<                                    # set multiplier to 1

[

    >>++++[<<---->>-]<<                     # decrease by 16 to get cell value of number

    [>>>>[>+>+<<-]>>[<<+>>-]<<<<<<-]        # multiply value by multiplier
    >>>>>[<<<<<+>>>>>-]                     # copy value back
    <[>++++++++++<-]>[<<+>>-]               # multiply multiplier by 10
    <<<<<                                   # go back to number

    [->+<]>[-<+>]                           # add value to next cell and move sum to previous cell

    <<                                      # go to next number
]

>>>>[-]<                                    # delete old multiplier

,[>,]                                       # read second number until end of input
>>>+<<<<                                    # set new multiplier

[

    >>+++++++[<<------->>-]<<+              # decrease by 48 to get cell value of number

    [>>>>[>+>+<<-]>>[<<+>>-]<<<<<<-]        # multiply value by multiplier
    >>>>>[<<<<<+>>>>>-]                     # copy value back
    <[>++++++++++<-]>[<<+>>-]               # multiply multiplier by 10
    <<<<<                                   # go back to number

    [->+<]>[-<+>]                           # add value to next cell and move sum to previous cell

    <<                                      # go to next number
]

>>>>[-]<<<<<                                # delete multiplier

[>>[>+>+<<-]>>[<<+>>-]<<<<-]>>[-]>          # multiply both values

# magical algorithm for printing cell value as number taken from Cedric Mamo's code from a previous question
[<+>-]<[>>+>+<<<-]>>>[<<<+>>>-]<[[-]<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<-]>[<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<->>[-]]+>-]<-]<<+>]<[>>+<<-]>>[<<<[>+>+<<-]>>[<<+>>-]>-]<<[<<->>-]<[-]<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[>>]+[<<]>[>[>>]<+<[<<]>-]<<<<<<<<<<[>>+>+<<<-]>>>[<<<+>>>-]+[<+>-]<<<[-]>>[<<+>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+<<-]>>[<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<<->>>[-]]+>-]<-]<<<+>>]<[-]<<<<[-]>>>[<<<+>>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<+>-]<]<[>+>+<<-]>>[<<+>>-]<[>+<[-]]+>[<[-]<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[[-]>>>>>>>>[>>]<[<[<<]<<<<<+>>>>>>>[>>]<-]<-<<[<<]<<<<<>++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<.[-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]+[<->-]<<<<<[-]>>>>[<<<<+>>>>-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]<[<+>-]<]<[-]]<[>>++++++[<++++++++>-]<.[-]<[-]]<[-]<[-]>>>>>>>>>>>>[>[-]>]<<[-<<]<<<<<<<<<<<<<<<<<[-]<[-]

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!

var NUM_CELLS = 30000;var ITERS_PER_SEC = 100000;var TIMEOUT_MILLISECS = 5000;function clear_output(){document.getElementById("output").value="";document.getElementById("stderr").innerHTML=""}function stop(){running=false;document.getElementById("run").disabled=false;document.getElementById("stop").disabled=true;document.getElementById("clear").disabled=false;document.getElementById("wrap").disabled=false;document.getElementById("timeout").disabled=false;document.getElementById("eof").disabled=false}function interrupt(){error(ERROR_INTERRUPT)}function error(e){document.getElementById("stderr").innerHTML=e;stop()}function run(){clear_output();document.getElementById("run").disabled=true;document.getElementById("stop").disabled=false;document.getElementById("clear").disabled=true;document.getElementById("wrap").disabled=true;document.getElementById("timeout").disabled=true;document.getElementById("eof").disabled=true;code=document.getElementById("code").value;input=document.getElementById("input").value;wrap=document.getElementById("wrap").value;timeout=document.getElementById("timeout").checked;eof=document.getElementById("eof").value;loop_stack=[];loop_map={};for(var e=0;e<code.length;++e){if(code[e]=="["){loop_stack.push(e)}else if(code[e]=="]"){if(loop_stack.length==0){error(ERROR_BRACKET);return}else{var t=loop_stack.pop();loop_map[t]=e;loop_map[e]=t}}}if(loop_stack.length>0){error(ERROR_BRACKET);return}running=true;start_time=Date.now();code_ptr=0;input_ptr=0;cell_ptr=Math.floor(NUM_CELLS/2);cells={};iterations=0;bf_iter(1)}function bf_iter(e){if(code_ptr>=code.length||!running){stop();return}var t=Date.now();for(var n=0;n<e;++n){if(cells[cell_ptr]==undefined){cells[cell_ptr]=0}switch(code[code_ptr]){case"+":if(wrap=="8"&&cells[cell_ptr]==255||wrap=="16"&&cells[cell_ptr]==65535||wrap=="32"&&cells[cell_ptr]==2147483647){cells[cell_ptr]=0}else{cells[cell_ptr]++}break;case"-":if(cells[cell_ptr]==0){if(wrap=="8"){cells[cell_ptr]=255}if(wrap=="16"){cells[cell_ptr]=65535}if(wrap=="32"){cells[cell_ptr]=2147483647}}else{cells[cell_ptr]--}break;case"<":cell_ptr--;break;case">":cell_ptr++;break;case".":document.getElementById("output").value+=String.fromCharCode(cells[cell_ptr]);break;case",":if(input_ptr>=input.length){if(eof!="nochange"){cells[cell_ptr]=parseInt(eof)}}else{cells[cell_ptr]=input.charCodeAt(input_ptr);input_ptr++}break;case"[":if(cells[cell_ptr]==0){code_ptr=loop_map[code_ptr]}break;case"]":if(cells[cell_ptr]!=0){code_ptr=loop_map[code_ptr]}break}code_ptr++;iterations++;if(timeout&&Date.now()-start_time>TIMEOUT_MILLISECS){error(ERROR_TIMEOUT);return}}setTimeout(function(){bf_iter(ITERS_PER_SEC*(Date.now()-t)/1e3)},0)}var ERROR_BRACKET="Mismatched brackets";var ERROR_TIMEOUT="Timeout";var ERROR_INTERRUPT="Interrupted by user";var code,input,wrap,timeout,eof,loop_stack,loop_map;var running,start_time,code_ptr,input_ptr,cell_ptr,cells,iterations
<div style="font-size:12px;font-family:Verdana, Geneva, sans-serif;"> <div style="float:left; width:50%;"> Code: <br> <textarea id="code" rows="4" style="overflow:scroll;overflow-x:hidden;width:90%;">,>++++++[<----->-]<--[>,>++++++[<----->-]<--]>>>+<<<<[>>++++[<<---->>-]<<[>>>>[>+>+<<-]>>[<<+>>-]<<<<<<-]>>>>>[<<<<<+>>>>>-]<[>++++++++++<-]>[<<+>>-]<<<<<[->+<]>[-<+>]<<]>>>>[-]<,[>,]>>>+<<<<[>>+++++++[<<------->>-]<<+[>>>>[>+>+<<-]>>[<<+>>-]<<<<<<-]>>>>>[<<<<<+>>>>>-]<[>++++++++++<-]>[<<+>>-]<<<<<[->+<]>[-<+>]<<]>>>>[-]<<<<<[>>[>+>+<<-]>>[<<+>>-]<<<<-]>>[-]>[<+>-]<[>>+>+<<<-]>>>[<<<+>>>-]<[[-]<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<-]>[<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<->>[-]]+>-]<-]<<+>]<[>>+<<-]>>[<<<[>+>+<<-]>>[<<+>>-]>-]<<[<<->>-]<[-]<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[>>]+[<<]>[>[>>]<+<[<<]>-]<<<<<<<<<<[>>+>+<<<-]>>>[<<<+>>>-]+[<+>-]<<<[-]>>[<<+>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+<<-]>>[<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<<->>>[-]]+>-]<-]<<<+>>]<[-]<<<<[-]>>>[<<<+>>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<+>-]<]<[>+>+<<-]>>[<<+>>-]<[>+<[-]]+>[<[-]<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[[-]>>>>>>>>[>>]<[<[<<]<<<<<+>>>>>>>[>>]<-]<-<<[<<]<<<<<>++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<.[-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]+[<->-]<<<<<[-]>>>>[<<<<+>>>>-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]<[<+>-]<]<[-]]<[>>++++++[<++++++++>-]<.[-]<[-]]<[-]<[-]>>>>>>>>>>>>[>[-]>]<<[-<<]<<<<<<<<<<<<<<<<<[-]<[-]</textarea> <br>Input: <br> <textarea id="input" rows="2" style="overflow:scroll;overflow-x:hidden;width:90%;">7 6</textarea> <p> Wrap: <select id="wrap"> <option value="8">8-bit</option> <option value="16">16-bit</option> <option value="32" selected="selected">32-bit</option> </select> &nbsp; Timeout: <input id="timeout" type="checkbox"></input>&nbsp; EOF: <select id="eof"> <option value="nochange">Same</option> <option value="0" selected="selected">0</option> <option value="-1">-1</option> </select> </p> </div> <div style="float:left; width:50%;"> Output: <br> <textarea id="output" rows="6" style="overflow:scroll;width:90%;"></textarea> <p> <input id="run" type="button" value="Run" onclick="run()"></input> <input id="stop" type="button" value="Stop" onclick="interrupt()" disabled="true"></input> <input id="clear" type="button" value="Clear" onclick="clear_output()"></input> &nbsp; <span id="stderr" style="color:red"></span></p></div></div>

Chiffre
quelle
Ich weiß auch nicht, ob es gültig ist! Ich denke, entweder ist in Brainfuck alles eine Zahl oder nichts.
Nathaniel
Ich mag diese Antwort. Ich habe in letzter Zeit mit mir selbst rumgespielt. Es gibt Aufschluss darüber, dass auf Maschinenebene sowieso alles nur Token sind. Schwer zu sagen, ob dies wirklich den Regeln entspricht oder nicht.
Octopus
6

Python, 394 349 340 Zeichen

D='0123456789'
R=reversed
U=lambda x:[R for y in D if y<x]
T=U(':')
def A(a,b,r='',c=[]):
 for x,y in map(None,R(a),R(b)):
    d=U(x)+U(y)+c;t=T;c=[R]
    if d<T:t=c=[]
    r=min(k for k in D if U(k)+t>=d)+r
 if c:r='1'+r
 return r
a,b=input()
m=''
while b:
 if list(b).pop()in'13579':m=A(m,a)
 b=list(A(b,A(b,A(b,A(b,b)))));b.pop();a=A(a,a)
print m

Laufen Sie wie folgt:

echo '"9999999999","9999999999"' | ./mulstr.py

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. Ukonvertiert zu unär, wobei Rals unäres Zeichen verwendet wird. Wir berechnen b/=2als b=b*5/10.

Keith Randall
quelle
Ein paar Golfplätze: def A(a,b):\n r='';c=[]-> def A(a,b,r='',c=[]):ähnlich für def 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önnten if. Kann auch if list(b).pop()in'13579'nur sein if b[:].pop()in'13579'?
Justin
@ Quincunx: Danke. Der letzte wird nicht funktionieren, da es sich bei der ersten Iteration bum eine Zeichenfolge handelt, nicht um eine Liste.
Keith Randall
Sie könnten Mein komplettes Programm überspringen und schreiben; a,b=input() ist erlaubt.
Justin
1
b * 5/10 ist ein schöner Trick.
bazzargh
Ich stolperte über reduce, was Ihnen erlaubt, nicen A(b,A(b,A(b,A(b,b))))zu reduce(A,[b,b,b,b,b]). Leider hat dies keinen Einfluss auf die Anzahl der Zeichen.
Wrzlprmft
5

JavaScript (E6) 375 395 411 449

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

M=(x,y,S=a=>a.shift()||z,R=a=>[...a].reverse(),e=R('9876543210'),d=[...e])=>
  R(y)[T='map'](b=>
     R(x)[T](a=>(
       u=R[e[a+=b]+v],
       v=R[S[a]+(u<v?'1':z)],
       p[P](t=R[S(o)+u]),
       t<u?v=R[v+'1']:v
     ),o=p,p=[])
    +(v>z&&p[P](v),x+=v=z),
    d[T](a=>d[T](b=>e[P='push'](R[a+b]=S(e)))+e[P](S(e))),  
    d[T](a=>d[T](b=>e[d[T](c=>v=c<a?(u=R[u+b])<b?R[v+'1']:v:v,v=u=z='0'),S[a+b]=v,a+b]=u)),
    p=[v=z]
  )&&R(p).join(o)

Weniger Golf (vielleicht werde ich morgen eine Erklärung hinzufügen)

M=(x,y)=>(
  R=a=>[...a].reverse(),
  // Addition table s 
  s={},
  e=[...'9012345678'],
  [for(a of(d='0123456789'))for(b of(e.push(e.shift()),d))e.push(s[a+b]=c=e.shift())],
  // Multiplication table m,n
  m={},n={},
  [for(a of d)for(b of d)(
     [for(c of(z=u=v='0',d))
     c<a&&(t=s[u+b],t<u?v=s[v+'1']:v,u=t)
     ],m[a+b]=u,n[a+b]=v
  )],
  x=R(x),v=z,o=[],p=[],
  [for(b of R(y))(
     [for(a of x)(
       u=s[m[a+b]+v],v=s[n[a+b]+(u<v?'1':z)],
       p.push(t=s[(o.shift()||z)+u]),
       t<u?v=s[v+'1']:v
     )],
     v>z?p.push(v):o,o=p,p=[],x.unshift(v=z)
  )],
  R(o).join('')
)

Test In FireFox / Firebug - Konsole

t0=-new Date
r=M('9999999999','9999999999')
t1=-new Date
console.log("Result",r, "time ms", t0-t1)

Ausgabe

Result 99999999980000000001 time ms 14
edc65
quelle
Möglicherweise gibt es einen kleinen Fehler - die Ausgabe aus dem 9999999999Fall sollte es 99999999980000000001nicht sein99999999980000000081
Nathaniel
:( werde
nachsehen
Wenn Sie Multiplikationstabellen verwenden, wie können Sie umgehen, dass eine Summierung nicht zulässig ist?
COTO
1
Die Summierung mit einer Hash-Tabelle (s im Code) ist zulässig. Ex. s ['34 '] ->' 7 '. Nur Symbole, keine Zahlen. Könnte sein, s ['cd'] -> 'g'
edc65
5

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

r=reverse
n="9876543210"
t=True
c&(x:y)|c==x=head y|t=c&y
m%[]="1";m%(c:s)|c==last m=head m:m%s|t=c&m:s
[]!y=y;x![]=x;(x:a)!('0':b)=x:a!b;x!y=(r n%x)!(n%y)
"0"?_="0";x?('0':y)|all(=='0')y="0"|t=('0':x)?y;x?y=x?(n%y)!x
x#y=r$r x?r y

Dieser Ansatz ist schnell genug, dass selbst auf einem 2008er-Laptop im nicht optimierten ghci REPL der Testfall nur einen Bruchteil einer Sekunde dauert:

λ> :set +s
λ> let test = replicate 10 '9'
(0.00 secs, 0 bytes)
λ> test
"9999999999"
(0.00 secs, 1069784 bytes)
λ> test # test
"99999999980000000001"
(0.06 secs, 13451288 bytes)

Hier ist eine Überprüfung, ob alle zweistelligen Produkte korrekt sind:

λ> and [ show (x * y) == (show x # show y) | x <- [0..100], y <- [0..100] ]
True
Matt Noonan
quelle
Sieht so aus, als hätten wir einen neuen Anführer! (Ich kann Haskell allerdings nicht lesen - kann jemand unabhängig bestätigen, dass es der Spezifikation entspricht?)
Nathaniel
1
Ja, das ist perfekt gelungen, es passt zur Spezifikation und funktioniert wie beworben. Gut gemacht!
Bazzargh
4

Bash + ImageMagick: 52

convert -size ${a}x${b} xc:red txt:-|grep -v g|wc -l

Erwartet, dass sich die Eingabe in den Shell-Variablen aund befindet b. Es ist nicht besonders clever oder effizient, aber es erledigt die Arbeit. Es ist wahrscheinlich schon einmal gemacht worden.

Beachten Sie, dass das xdie 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

Millinon
quelle
Netter Versuch, aber ich bin mir sicher, dass dies für Eingaben 9999999999und in weniger als einer Minute (oder überhaupt auf einer vorhandenen Maschine) nicht funktioniert 9999999999.
Nathaniel
4
Dies funktioniert auch: dd if=/dev/zero bs=$a count=$b 2>&-|wc -c.
Jimmy23013
1
Ein 9999999999x9999999999Bild 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.
Nathaniel
1
Sie können 2 Bytes sparen, indem Sie $banstelle von verwenden ${b}.
Nyuszika7h
1
Sie können auch 5 Bytes sparen, indem Sie grep -vc ganstelle von verwenden grep -v g|wc -l.
Nyuszika7h
2

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 9999999999x9999999999in 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.

import re
D='123456789'
D=dict(zip('0'+D,D+'0'))

def toRlist(s):
    if s:t,h=re.match(r'(\d*)(\d)',s).groups();return[h,toRlist(t)]
    return''

def increment(r):
    if not r:return['1','']
    h,t=r
    return[D[h],increment(t)if h=='9'else t]

def toString(r):
    if not r:return''
    h,t=r
    return h+toString(t)

def listify(r,L):
    if not r:return
    h,t=r
    if h=='1':L.append('')
    if h=='2':L.extend(['',''])
    if h=='3':L.extend(['','',''])
    if h=='4':L.extend(['','','',''])
    if h=='5':L.extend(['','','','',''])
    if h=='6':L.extend(['','','','','',''])
    if h=='7':L.extend(['','','','','','',''])
    if h=='8':L.extend(['','','','','','','',''])
    if h=='9':L.extend(['','','','','','','','',''])
    listify(t,L);listify(t,L);listify(t,L);listify(t,L);listify(t,L)
    listify(t,L);listify(t,L);listify(t,L);listify(t,L);listify(t,L)

def add(r1,r2):
    L=[];listify(r2,L)
    for _ in L:r1=increment(r1)
    return r1

def multiply(a,b):
    total=''
    r=toRlist(a)
    L=[];listify(toRlist(b),L)
    for _ in L:total=r if total=='' else add(total,r)
    return''.join(reversed(toString(total)))

Beispiele:

multiply('12','5') #returns the string 60

multiply('1869','1243') #returns the string 2323167
Calvins Hobbys
quelle
1
+1, weil es die Spezifikation erfüllt (abgesehen von der Effizienzanforderung), soweit ich das beurteilen kann
Nathaniel
2

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 9999999999x9999999999Fall in weniger als 0,03 s auf meinem Computer.

d="123456789";I=dict(zip('0'+d,d+'0'))
def r(x):return reversed(x)
def s(x):return''.join(x)
def i(x):
    try:
        h=I[x.next()]
        if h!='0':h+=s(x)
        else:h+=i(x)
        return h
    except:return'1'
def b(x,y):
    for c in'0'+d:
        if c==y:break
        x=iter(i(x))
    return x
def a(x,y):
    z=''
    for c in y:
        x=b(x,c)
        try:z+=x.next()
        except:z+='0'
    return z+s(x)
def n(x,y):
    z='0'
    for c in'0'+d:
        if c==y:break
        z=a(iter(z),x)
    return z
def o(x,y):
    x=s(x)
    l='';z=''
    for c in y:
        z=a(iter(z),l+s(n(x,c)))
        l+='0'
    return z
def m(x,y):
    return s(r(o(r(x),r(y))))

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:

  • rund ssind Buchhaltungsfunktionen. ( rist nur ein Alias ​​für reversed, der einen Reverse-Iterator erzeugt und sIteratoren in Strings umwandelt.)

  • ierhöht die Zahl in einer Zeichenfolge um 1, einschließlich Fällen wie 39+1=40und 99+1=100.

  • bfügt xund hinzu y, ydarf aber nur eine Ziffer sein. Es funktioniert durch Inkrementieren der x yZeiten.

  • aAddiert zwei Zahlen, die beide mehrere Ziffern haben können, indem Sie bjede Ziffer in aufrufen y.

  • nmultipliziert xund y, ydarf aber nur eine Ziffer sein. Es funktioniert, indem xes sich ymal addiert .

  • omultipliziert xund y, wobei beide Argumente mehrstellig sein können. Es verwendet die klassische Langmultiplikation

  • mkonvertiert einfach seine Zeichenketteneingaben in umgekehrte Iteratoren und übergibt sie an o, kehrt dann das Ergebnis um und konvertiert es in eine Zeichenkette.

Nathaniel
quelle
Paar Golf: 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 Sie x=s(x)in x=s(x);l='';z='', in der for-Schleife, entfernen Sie in ähnlicher Weise Zeilenumbrüche + Paces; Verwenden Sie stattdessen ;. Auch ich denke das if h!='0':h+=s(x)\nelse:h+=i(x)kann einfach sein h+=h!='0'and i(x)or s(x); vielleicht sogar h+=(h!='0'and i or s)(x); Andernfalls wechseln Sie einfach zu if'0'!=h. Auch Dinge wie def r(x):return reversed(x)->r=reversed
Justin
Außerdem habe ich vergessen, für 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.
Justin,
Oh, und noch eins: für deine forSchleifen: 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.
Justin
@Quincunx danke! Ich sehe heute Morgen noch ein paar Verbesserungen. (Meistens werden die Schleifen verschachtelt, anstatt Funktionen zu definieren.) Diese Änderungen werden vorgenommen, wenn wettbewerbsfähigere Antworten angezeigt werden. Dies scheint wahrscheinlich. Derzeit würde dies mich an die Spitze bringen. Ich musste länger darüber nachdenken.
Nathaniel
2

JavaScript: 3710 3604 Bytes

  • Verwenden von String-Nachschlagetabellen mit 1-stelliger Multiplikation und Hinzufügen mit Carry.
  • Die Multiplikation erfolgt mit Ziffer x Ziffer anstelle der Ziffer x Zeile.

Golf:

var M={
'00':'0','01':'0','02':'0','03':'0','04':'0','05':'0','06':'0','07':'0','08':'0','09':'0',
'10':'0','11':'1','12':'2','13':'3','14':'4','15':'5','16':'6','17':'7','18':'8','19':'9',
'20':'0','21':'2','22':'4','23':'6','24':'8','25':'10','26':'12','27':'14','28':'16','29':'18',
'30':'0','31':'3','32':'6','33':'9','34':'12','35':'15','36':'28','37':'21','38':'24','39':'27',
'40':'0','41':'4','42':'8','43':'12','44':'16','45':'20','46':'24','47':'28','48':'32','49':'36',
'50':'0','51':'5','52':'10','53':'15','54':'20','55':'25','56':'30','57':'35','58':'40','59':'45',
'60':'0','61':'6','62':'12','63':'18','64':'24','65':'30','66':'36','67':'42','68':'48','69':'54',
'70':'0','71':'7','72':'14','73':'21','74':'28','75':'35','76':'42','77':'49','78':'56','79':'63',
'80':'0','81':'8','82':'16','83':'24','84':'32','85':'40','86':'48','87':'56','88':'64','89':'72',
'90':'0','91':'9','92':'18','93':'27','94':'36','95':'45','96':'54','97':'63','98':'72','99':'81'
};
var A={
'000':'0','001':'1','002':'2','003':'3','004':'4','005':'5','006':'6','007':'7','008':'8','009':'9',
'010':'1','011':'2','012':'3','013':'4','014':'5','015':'6','016':'7','017':'8','018':'9','019':'10',
'020':'2','021':'3','022':'4','023':'5','024':'6','025':'7','026':'8','027':'9','028':'10','029':'11',
'030':'3','031':'4','032':'5','033':'6','034':'7','035':'8','036':'9','037':'10','038':'11','039':'12',
'040':'4','041':'5','042':'6','043':'7','044':'8','045':'9','046':'10','047':'11','048':'12','049':'13',
'050':'5','051':'6','052':'7','053':'8','054':'9','055':'10','056':'11','057':'12','058':'13','059':'14',
'060':'6','061':'7','062':'8','063':'9','064':'10','065':'11','066':'12','067':'13','068':'14','069':'15',
'070':'7','071':'8','072':'9','073':'10','074':'11','075':'12','076':'13','077':'14','078':'15','079':'16',
'080':'8','081':'9','082':'10','083':'11','084':'12','085':'13','086':'14','087':'15','088':'16','089':'17',
'090':'9','091':'10','092':'11','093':'12','094':'13','095':'14','096':'15','097':'16','098':'17','099':'18',
'100':'1','101':'2','102':'3','103':'4','104':'5','105':'6','106':'7','107':'8','108':'9','109':'10',
'110':'2','111':'3','112':'4','113':'5','114':'6','115':'7','116':'8','117':'9','118':'10','119':'11',
'120':'3','121':'4','122':'5','123':'6','124':'7','125':'8','126':'9','127':'10','128':'11','129':'12',
'130':'4','131':'5','132':'6','133':'7','134':'8','135':'9','136':'10','137':'11','138':'12','139':'13',
'140':'5','141':'6','142':'7','143':'8','144':'9','145':'10','146':'11','147':'12','148':'13','149':'14',
'150':'6','151':'7','152':'8','153':'9','154':'10','155':'11','156':'12','157':'13','158':'14','159':'15',
'160':'7','161':'8','162':'9','163':'10','164':'11','165':'12','166':'13','167':'14','168':'15','169':'16',
'170':'8','171':'9','172':'10','173':'11','174':'12','175':'13','176':'14','177':'15','178':'16','179':'17',
'180':'9','181':'10','182':'11','183':'12','184':'13','185':'14','186':'15','187':'16','188':'17','189':'18',
'190':'10','191':'11','192':'12','193':'13','194':'14','195':'15','196':'16','197':'17','198':'18','199':'19'
} 
Array.prototype.e=function(){return(''+this)==='';}
String.prototype.s=function(){return this.split('').reverse();}
function B(a,b,c) {
var r='',s='';
a=a.s();
b=b.s();
while (!a.e()||!b.e()||c!=='0') {
x=a.e()?'0':a.shift();
y=b.e()?'0':b.shift();
s=A[c+x+y];
s=s.s();
r=s.shift()+r;
c=s.e()?'0':'1';
}
return r;
}
function m(a,b) {
var s='0',m='';
b.split('').reverse().forEach(function(e){
var z=m;
a.split('').reverse().forEach(function(f){s=B(s,M[e+f]+z,'0');z+='0';});
m+='0';
});
return s;
}

Ungolfed mit Tests:

var mul = {
'00':'0','01':'0','02':'0','03':'0','04':'0','05':'0','06':'0','07':'0','08':'0','09':'0',
'10':'0','11':'1','12':'2','13':'3','14':'4','15':'5','16':'6','17':'7','18':'8','19':'9',
'20':'0','21':'2','22':'4','23':'6','24':'8','25':'10','26':'12','27':'14','28':'16','29':'18',
'30':'0','31':'3','32':'6','33':'9','34':'12','35':'15','36':'28','37':'21','38':'24','39':'27',
'40':'0','41':'4','42':'8','43':'12','44':'16','45':'20','46':'24','47':'28','48':'32','49':'36',
'50':'0','51':'5','52':'10','53':'15','54':'20','55':'25','56':'30','57':'35','58':'40','59':'45',
'60':'0','61':'6','62':'12','63':'18','64':'24','65':'30','66':'36','67':'42','68':'48','69':'54',
'70':'0','71':'7','72':'14','73':'21','74':'28','75':'35','76':'42','77':'49','78':'56','79':'63',
'80':'0','81':'8','82':'16','83':'24','84':'32','85':'40','86':'48','87':'56','88':'64','89':'72',
'90':'0','91':'9','92':'18','93':'27','94':'36','95':'45','96':'54','97':'63','98':'72','99':'81'
};

var adc = {
'000':'0','001':'1','002':'2','003':'3','004':'4','005':'5','006':'6','007':'7','008':'8','009':'9',
'010':'1','011':'2','012':'3','013':'4','014':'5','015':'6','016':'7','017':'8','018':'9','019':'10',
'020':'2','021':'3','022':'4','023':'5','024':'6','025':'7','026':'8','027':'9','028':'10','029':'11',
'030':'3','031':'4','032':'5','033':'6','034':'7','035':'8','036':'9','037':'10','038':'11','039':'12',
'040':'4','041':'5','042':'6','043':'7','044':'8','045':'9','046':'10','047':'11','048':'12','049':'13',
'050':'5','051':'6','052':'7','053':'8','054':'9','055':'10','056':'11','057':'12','058':'13','059':'14',
'060':'6','061':'7','062':'8','063':'9','064':'10','065':'11','066':'12','067':'13','068':'14','069':'15',
'070':'7','071':'8','072':'9','073':'10','074':'11','075':'12','076':'13','077':'14','078':'15','079':'16',
'080':'8','081':'9','082':'10','083':'11','084':'12','085':'13','086':'14','087':'15','088':'16','089':'17',
'090':'9','091':'10','092':'11','093':'12','094':'13','095':'14','096':'15','097':'16','098':'17','099':'18',
'100':'1','101':'2','102':'3','103':'4','104':'5','105':'6','106':'7','107':'8','108':'9','109':'10',
'110':'2','111':'3','112':'4','113':'5','114':'6','115':'7','116':'8','117':'9','118':'10','119':'11',
'120':'3','121':'4','122':'5','123':'6','124':'7','125':'8','126':'9','127':'10','128':'11','129':'12',
'130':'4','131':'5','132':'6','133':'7','134':'8','135':'9','136':'10','137':'11','138':'12','139':'13',
'140':'5','141':'6','142':'7','143':'8','144':'9','145':'10','146':'11','147':'12','148':'13','149':'14',
'150':'6','151':'7','152':'8','153':'9','154':'10','155':'11','156':'12','157':'13','158':'14','159':'15',
'160':'7','161':'8','162':'9','163':'10','164':'11','165':'12','166':'13','167':'14','168':'15','169':'16',
'170':'8','171':'9','172':'10','173':'11','174':'12','175':'13','176':'14','177':'15','178':'16','179':'17',
'180':'9','181':'10','182':'11','183':'12','184':'13','185':'14','186':'15','187':'16','188':'17','189':'18',
'190':'10','191':'11','192':'12','193':'13','194':'14','195':'15','196':'16','197':'17','198':'18','199':'19'
} 

Array.prototype.isEmpty = function() {
  return (''+this) === '';
}

function add(a, b, c) {
  var r = '', s = '';
  a = a.split("").reverse();
  b = b.split("").reverse();
  while (!a.isEmpty() || !b.isEmpty() || c !== '0') {
    x = a.isEmpty() ? '0' : a.shift();
    y = b.isEmpty() ? '0' : b.shift();
    s = adc[c + x + y];
    s = s.split("").reverse();
    r = (s.shift()) + r;
    c = (s.isEmpty()) ? '0' : '1';
  }
  return r;
}

function mult(a, b) {
  var s = '0';
  var m = '';
  b.split('').reverse().forEach(function(e) {
    var z = m;
    a.split('').reverse().forEach(function(f) {
      s = add(s, mul[e + f] + z, '0');
      z = z + '0';
    });
    m = m + '0';
  } );
  return s;
}

function test(a, b) {
  var t0 = (new Date()).getTime();
  var r = mult(a,b);
  var t1 = (new Date()).getTime();
  var e = t1 - t0;
  console.log('mult ' + a + ' * ' + b + ' = ' + r + " (" + e + " ms)");
}

test('12345', '42');
test('9999999999', '9999999999');

Dies gibt aus:

mult 12345 * 42 = 518490 (3 ms) 
mult 9999999999 * 9999999999 = 99999999980000000001 (47 ms) 
Stephen Quan
quelle
2

Haskell 507 496

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

data S=Z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R deriving(Enum, Ord, Eq)
p Z=id
p x=succ.p(pred x)
s Z=id
s x=pred.s(pred x)
z=s J
r[]=[]
r(x:y)|x<J=x:r y
r(x:[])=z x:[A]
r(x:y)=z x:(r$p A a:b)where(a:b)=r y
a x y=r$w(r x)(r y)
m Z _=[]
m _[]=[]
m x y=r$a y(m(pred x)y)
t[]_=[Z]
t _[]=[Z]
t(x:z)y=r$a(m x y)(Z:r(t z y))
i '0'=Z
i x=succ.i.pred$x
b Z='0'
b x=succ.b.pred$x
w[]y=y
w x[]=x
w(x:c)(y:d)=p x y:(w c d)
o=map
v=reverse
f=(o i).v
g=v.o b
main=getLine>>=putStrLn.(\[x,y]->g$t(f x)(f y)).words

Als Referenz ist S der benutzerdefinierte ganzzahlige Datentyp, pist 'plus' (Ziffer + Ziffernaddition), sist subtrahiert (zur Reduktion), rist reduziert (erweitert in digitale Zerlegung), aist Addition ( Ziffer + Ziffernaddition ), mist multiplizieren (Ziffer * Zahlenmultiplikation), tist mal (Ziffer * Zahlenmultiplikation), iist 'interpretieren' (Zeichenkette in Liste von umwandeln S), bist '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.

> time echo "9999999999 9999999999" | runhaskell multnonum.hs
99999999980000000001

real    0m0.246s
user    0m0.228s
sys     0m0.012s

Nur aus gutem Grund:

> time echo "99999999980000000001 99999999980000000001" | runhaskell multnonum.hs
9999999996000000000599999999960000000001

real    0m0.244s
user    0m0.224s
sys     0m0.016s

Lass uns verrückt werden!

> time echo "9999999996000000000599999999960000000001 9999999996000000000599999999960000000001" | runhaskell multnonum.hs
99999999920000000027999999994400000000699999999944000000002799999999920000000001

real    0m0.433s
user    0m0.424s
sys     0m0.004s

Bestätigung

Archaephyrryx
quelle
1

Python 2 - 1165, 712, 668, 664

I,T,V,N,X,J=raw_input,dict,reversed,None,zip,''.join
D='0123456789'
z,o='01'
A,B=I(),I()
r=i=""
K=map(J,X('666622222222911111551111555884444447773333333','678945672389954132987698765898967457989837654'))
P=T(X(K,map(J,X('344501110011800000440000332673322124652202211','628480244668154132507698505422648609367491852'))))
S=T(X(K,'cdef678945abi65243ed87a9cbaghcdab89egfcb6a987'))
for d in D:P[z+d]=z;S[z+d]=d
def Z(A,B,R=r):
 for a,b in V(map(N,V(z+A),V(z+B))):c=(a or z)+(b or z);s=S[min(c)+max(c)];R=Z(R,o)+T(X('abcdefghi',D))[s]if s>"?"else R+s
 return R
for a in V(A):
 j=""
 for b in V(B):r=Z(r,P[min(a+b)+max(a+b)]+i+j).lstrip(z);j+=z
 i+=z
print r if r else z

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

A = raw_input()
B = raw_input()

P = {'00':'00','01':'00','02':'00','03':'00','04':'00','05':'00','06':'00','07':'00','08':'00','09':'00',
     '10':'00','11':'01','12':'02','13':'03','14':'04','15':'05','16':'06','17':'07','18':'08','19':'09',
     '20':'00','21':'02','22':'04','23':'06','24':'08','25':'10','26':'12','27':'14','28':'16','29':'18',
     '30':'00','31':'03','32':'06','33':'09','34':'12','35':'15','36':'28','37':'21','38':'24','39':'27',
     '40':'00','41':'04','42':'08','43':'12','44':'16','45':'20','46':'24','47':'28','48':'32','49':'36',
     '50':'00','51':'05','52':'10','53':'15','54':'20','55':'25','56':'30','57':'35','58':'40','59':'45',
     '60':'00','61':'06','62':'12','63':'18','64':'24','65':'30','66':'36','67':'42','68':'48','69':'54',
     '70':'00','71':'07','72':'14','73':'21','74':'28','75':'35','76':'42','77':'49','78':'56','79':'63',
     '80':'00','81':'08','82':'16','83':'24','84':'32','85':'40','86':'48','87':'56','88':'64','89':'72',
     '90':'00','91':'09','92':'18','93':'27','94':'36','95':'45','96':'54','97':'63','98':'72','99':'81',
     }
S = {'00':'0','01':'1','02':'2','03':'3','04':'4','05':'5','06':'6','07':'7','08':'8','09':'9',
     '10':'1','11':'2','12':'3','13':'4','14':'5','15':'6','16':'7','17':'8','18':'9','19':'a',
     '20':'2','21':'3','22':'4','23':'5','24':'6','25':'7','26':'8','27':'9','28':'a','29':'b',
     '30':'3','31':'4','32':'5','33':'6','34':'7','35':'8','36':'9','37':'a','38':'b','39':'c',
     '40':'4','41':'5','42':'6','43':'7','44':'8','45':'9','46':'a','47':'b','48':'c','49':'d',
     '50':'5','51':'6','52':'7','53':'8','54':'9','55':'a','56':'b','57':'c','58':'d','59':'e',
     '60':'6','61':'7','62':'8','63':'9','64':'a','65':'b','66':'c','67':'d','68':'e','69':'f',
     '70':'7','71':'8','72':'9','73':'a','74':'b','75':'c','76':'d','77':'e','78':'f','79':'g',
     '80':'8','81':'9','82':'a','83':'b','84':'c','85':'d','86':'e','87':'f','88':'g','89':'h',
     '90':'9','91':'a','92':'b','93':'c','94':'d','95':'e','96':'f','97':'g','98':'h','99':'i',
     }
L = {'a':'0','b':'1','c':'2','d':'3','e':'4','f':'5','g':'6','h':'7','i':'8'}

def strSum(A, B):
    R = ""
    for a, b in reversed(map(None, reversed("0" + A), reversed("0" + B))):
        if a == None: a = '0'
        if b == None: b = '0'
        s = S[a + b]
        if s.isdigit():
            R += s
        else:
            R = strSum(R, "1") + L[s]
    return R

i = ""
r = "0"
for a in reversed(A):
    j = ""
    for b in reversed(B):
        p = P[a + b] + i + j
        r = strSum(r, p)
        j += "0"
    i += "0"

r = r.lstrip("0")
if r == "":
    r = "0"

print r
Falko
quelle
Ich würde sagen, dass die Verwendung von min () - und max () -Funktionen nicht zulässig sein sollte, da diese tatsächliche Ganzzahlwerte vergleichen, nicht wahr?
WorldSEnder
@WorldSEnder: Ich würde sagen, sie vergleichen Charaktere, was in dieser Herausforderung erlaubt ist. ("Lexikografischer Vergleich von Zeichen ist erlaubt.")
Falko
1

Scala, 470 Zeichen

(Die sind Standard-Scala, können aber auch durch ersetzt werden, =>wenn wir Bytes zählen.)

def p(a: String,b: String)={type D=List[Char]
val d="0123456789".toList
def v(s: String)=s.toList.map{c⇒d.takeWhile(c.!=)}
def u(l:D, a:D):(Char,D)=l match {
case _::_::_::_::_::_::_::_::_::_::m⇒u(m,'a'::a)
case _⇒(('a'::l).zip(d).last._2,a)}
val o=(("", List[Char]())/:v(a).tails.toList.init.map{l⇒(v(b) map {_.flatMap(_⇒l.head)})++l.tail.map(_⇒Nil) reverse}.reduce(_.zipAll(_, Nil, Nil).map{t⇒t._1++t._2}))({(t,e)⇒val s=u(t._2++e,Nil);(s._1+t._1,s._2)})
u(o._2, Nil)._1+o._1}

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 flatMapund unsere Zeilen mit reduce. uErledigt 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.

lmm
quelle