将两个数字相乘而不使用任何数字


30

给出两个以10为底的正整数的字符串作为输入,例如"12345""42""518490"在这种情况下,您的任务是输出包含其产品的字符串。

所不同的是,您不得在代码中使用任何数字类型。No intsfloats,unsigned longs等,没有内置的复数类型或任意精度的整数,或沿这些线的任何内容。您可能没有使用这些类型的文字,也没有使用返回它们的任何函数,方法,运算符等。

可以使用字符串,布尔值,数组或其他通常不用于表示数字的东西。(但是请注意,不调用数字类型就不可能索引到数组或获取数组的长度。)chars是允许的,但是您不能对它们执行任何算术或按位运算,也不能将其视为除表示字符串一部分的令牌。(char允许对s进行字典比较。)

您可能无法解决该限制。这包括(但不限于)在eval类型函数内使用数字类型,将隐式类型转换为数字类型,对支持它们的非数字类型使用数字或按位运算符,使用存储在容器类型内部的数字类型或调用函数或外部程序以字符串形式返回数值结果。(如果答案中出现其他解决方法,我保留添加到此列表的权利。)您必须仅使用非数字类型自己实现乘法。

输入和输出可以通过任何方便的方法进行,只要数据以字符串形式进入和退出您的代码即可。您可以假定两个输入参数中的每个参数仅包含ASCII字符,[0-9]并且不会以开头0。您的输出也不应该有前导零。

还有一件事:您的代码必须正确处理至少10个字符的输入,并且必须在一分钟之内在现代计算机上运行该范围内的所有输入。发布之前,请检查给定输入9999999999和时9999999999,程序99999999980000000001在不到一分钟的时间内输出。专门存在此限制是为了避免通过分配大小数组a*b然后对其进行迭代来起作用的答案,因此请记住,该形式的答案将不符合要求。

这是,因此最短的有效解决方案(以字节为单位)获胜。


我们可以接受"12345"STDIN而不是接受12345吗?还是我们都可以接受两个数字作为"12345", "42"
贾斯汀2014年

我首先想到的是写一个函数取长度的字符串参数mn和返回长度的参数m*n。但是由于字符串必须从字面上包含数字的ASCII表示形式,所以我认为这违反了规则。
级圣河

1
@xnor在许多语言中,写出所有情况可能会更短。但是我确实在Python中找到了这种方法:a,b="0123456789x".split('0');c=iter(b).next() if c=='x': c='0'
Nathaniel 2014年

1
或使用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'))
贾斯汀

Answers:


6

哈斯克尔-180206214

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

通过重复加法来实现乘法,并且通过移动和过滤['0'..'9']列表来处理各种数字魔术。定义#类型的运算符String -> String -> String

*> :set +s
*> "9990123456789"#"9999876543210"
"99900001219316321126352690"
(0.02 secs, 9862288 bytes)

看来我们有了新的赢家!(尽管像以前一样,我看不懂Haskell的这种复杂程度-有人可以独立检查其是否符合规范吗?)
Nathaniel 2015年

(另外['0'..'9']有点像将char隐式地视为可以迭代的数字-是否有一种简短的方法可以从字符串“ 0123456789”生成该列表?)
Nathaniel

@Nathaniel首先,字符串"0123456789" 列表['0'..'9']。其次,在Haskell [a..b]中是一个枚举,Enum可以像这样枚举已声明类型类实例的类型,该声明描述了枚举的工作方式。Bool,布尔类型也有一个实例,因此您也可以这样做[False..True]。几乎没有涉及任何数字。
mniip

14

sed,339338字节

我知道这是一个古老的网站,但是我正在浏览,这引起了我的兴趣。足以实际注册为用户!我想我对“ 我很想看到完整的解决方案– Nathaniel ”。

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

此sed脚本期望输入两个十进制数字,并用一个空格分隔

测试:

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

您可能会将最后两个识别为RSA-100(50 x 50位数)和RSA-768(116 x 116位数)。

在不太现代的版本(2007年以前的Intel Core 2)上使用GNU sed,其中的最后一个需要一分钟,但是在更新的处理器上速度更快:

  • Q6600:> 1分钟
  • i7-3770:26秒
  • i7-6700:22秒

问题中指定的微不足道的10位数乘法在其中任何一个上都花了不到一秒钟的时间(尽管充满了病理性的9)。

我相信它是标准的sed,没有扩展。POSIX保证仅保留8192字节的空间,这将我们限制为乘以400x400数字,但是实现可以提供更多空间。GNU sed仅受可用内存的限制,因此,如果您愿意等待,可以管理更大的东西。

而且我有信心遵守规则-这几乎是一种没有数字的语言。:-)

说明

我使用一元/十进制混合,将十进制数字转换为一元序列:

 42 => _xxxx_xx

以一进制十进制表示,加法很容易。我们从最低有效数字到最高有效数字进行迭代,将x串联在一起:

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

然后,我们删除空格,并通过将10个连续的x转换为下一单位之一来处理进位:

 _xxxxxxxxxx_xxxxxx_xxxxxxxxxxx       10.6.11
 _xxxxxxxxxx_xxxxxxx_x                10.7.1
 _x__xxxxxxx_x                        1.0.7.1 

一旦加法,乘法就成为可能。我们通过考虑y的最后一位乘以x * y。将x多次添加到累加器,然后移至下一位并将x左移一位小数。重复直到y为零。

扩展代码

#!/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

1
非常满意的答案,谢谢!
纳撒尼尔(Nathaniel)2015年

9

sed,379个字节

这个出色答案的功劳归功于Unix&Linux.SE上的@LuigiTiburzi:https://unix.stackexchange.com/a/372​​13/34061 。我几天前偶然偶然发现了这一点:

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

广泛的解释

  • 分开每个数字​​。因此12*3成为<1<2*<3
  • 将每个数字转换为该|字符数。因此<1<2*<3成为<|<||*<|||
  • 反复替换|<使用<||||||||||,以转移较高位小数全部下降到个位。因此<|<||*<|||成为<||||||||||||*<|||
  • 删除<。因此<||||||||||||*<|||成为||||||||||||*|||
  • |从的RHS中删除1 *。因此||||||||||||*|||成为||||||||||||*||
  • 反复|用所有|LHS 上的RHS 替换每个。这具有相乘的LHS和RHS数量的效果|,得到产物数量| 因此||||||||||||*||变得||||||||||||||||||||||||||||||||||||*
  • 删除*。因此||||||||||||||||||||||||||||||||||||*成为||||||||||||||||||||||||||||||||||||
  • |通过前几步的相反操作将数字转换为十进制。因此||||||||||||||||||||||||||||||||||||成为36

输出:

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

不幸的是,它在时间要求上惨遭失败- 200*1000在我的Ubuntu VM上耗时41秒,并且运行时经验上似乎与最终产品的平方成正比。


1
从算法上讲,这与我删除的JS答案几乎等效,除了转换回数字部分。
Optimizer

@Optimizer同意。区别在于您使用的length()是返回数字。此代码使用无数字类型的纯正则表达式替换。我认为您的答案可能是一个胜利者,尽管如果您可以删除 length()-也许您可以做一些类似的正则表达式替代呢?
Digital Trauma 2014年

1
很好,但是一分钟的限制是专门用来防止解决方案通过计算答案来起作用的。我很想看到完整的sed解决方案。
纳撒尼尔(Nathaniel)2014年

1
我有一个对大数字有效的答案(例如,大于系统的地址空间)。
Toby Speight

@TobySpeight是的,非常好。我想我一定早就支持您的了:)
Digital Trauma

9

蟒- 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")

如果允许(很多)前导零,则不需要最后12个字符。

这实质上是手工执行标准乘法。数字表示为重复的Is 字符串(如原始罗马数字)。数字以相反的顺序表示为数字列表。通过对字符串进行串联并I在必要时删除10来执行一位数字的加法。

这是一个非高尔夫版本:

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())

1
这是什么法术!它是如何工作的!哇。另外,这是您可以做的另一种高尔夫球:def A(x,y):\n S=[];o=""-> def A(x,y,S=[],o=""):。同样,不幸的["","1"][t in i]是,这是不允许的。它使用布尔值进行索引,将其视为数字。我认为t in i and"1"or""应该可以。
贾斯汀

@Quincunx:S用默认值定义为参数将不起作用,因为即使对于函数的不同调用,它始终是相同的列表,因此不会重置为[]。你说得对["","1"][t in i],我已解决。我还添加了一个解释。
Wrzlprmft

这真是太神奇了。现在得到绿色的勾号。(我已经编辑了问题,以阐明不允许输出中的前导零-对不起!)
Nathaniel 2014年

7

红宝石:752 698

这仅仅是出于好奇而做的一个答案。编辑:现在打了一点球。

$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)

用法:我在一个名为peasant.rb的文件中有此文件:

$ time ruby peasant.rb 9999999999 9999999999
99999999980000000001

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

说明:这是农民的乘法,所以我反复减半和加倍。通过将数字减半并标记余数来完成减半,如下所示:1234-> 0b1a1b2a; 然后找到并替换b:06a17a; 然后清理-> 617。

像这样进行加法操作...首先,我将两个字符串都填充到相同的长度,然后用数字配对。然后,我通过构造一个具有每个数字长度的字符串并进行连接来添加数字。我从“ 0123456789abcdefghij”的开头删除了该长度的字符串,然后保留了第一个字符。因此,例如“ 9” +“ 9”->“ i”。注意:在这里我避免实际使用长度函数来完全避免数字类型。删除前缀是使用regexp完成的。

所以现在我有了一个包含数字和字母的混合字符串。字母代表带有进位数字的数字;我在数字前加上0,然后用进位结果反复替换数字字母模式,直到加法完成为止。


1
非常聪明的答案,正是我希望看到的那种东西!
纳撒尼尔(Nathaniel)2014年

1
我实际上希望有人张贴带有教会数字的数字!
bazzargh 2014年

那会很酷,尽管我不确定它是否符合效率要求-我认为在字符串和教堂数字之间进行转换实际上将涉及多达99999999980000000001的计数。–
Nathaniel

7

Brainfuck(1328字节)

首先考虑:

  • 不确定Brainfuck是否是此问题的有效答案,因为我不确定您是否将单元格值视为“数字类型”。我不这么认为,因为bf不知道类型,但这是我自己的看法,如果我错了,请纠正我。
  • 支持(几乎)无限值的实现是必要的。
  • 根据实现,它可能太慢了。

我只使用自己的解释器测试了该程序,您可以在这里找到它。

输入的两个数字都必须用单个ASCII空格分隔。

打高尔夫球:

,>++++++[<----->-]<--[>,>++++++[<----->-]<--]>>>+<<<<[>>++++[<<---->>-]<<[>>>>[>+>+<<-]>>[<<+>>-]<<<<<<-]>>>>>[<<<<<+>>>>>-]<[>++++++++++<-]>[<<+>>-]<<<<<[->+<]>[-<+>]<<]>>>>[-]<,[>,]>>>+<<<<[>>+++++++[<<------->>-]<<+[>>>>[>+>+<<-]>>[<<+>>-]<<<<<<-]>>>>>[<<<<<+>>>>>-]<[>++++++++++<-]>[<<+>>-]<<<<<[->+<]>[-<+>]<<]>>>>[-]<<<<<[>>[>+>+<<-]>>[<<+>>-]<<<<-]>>[-]>[<+>-]<[>>+>+<<<-]>>>[<<<+>>>-]<[[-]<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<-]>[<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<->>[-]]+>-]<-]<<+>]<[>>+<<-]>>[<<<[>+>+<<-]>>[<<+>>-]>-]<<[<<->>-]<[-]<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[>>]+[<<]>[>[>>]<+<[<<]>-]<<<<<<<<<<[>>+>+<<<-]>>>[<<<+>>>-]+[<+>-]<<<[-]>>[<<+>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+<<-]>>[<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<<->>>[-]]+>-]<-]<<<+>>]<[-]<<<<[-]>>>[<<<+>>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<+>-]<]<[>+>+<<-]>>[<<+>>-]<[>+<[-]]+>[<[-]<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[[-]>>>>>>>>[>>]<[<[<<]<<<<<+>>>>>>>[>>]<-]<-<<[<<]<<<<<>++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<.[-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]+[<->-]<<<<<[-]>>>>[<<<<+>>>>-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]<[<+>-]<]<[-]]<[>>++++++[<++++++++>-]<.[-]<[-]]<[-]<[-]>>>>>>>>>>>>[>[-]>]<<[-<<]<<<<<<<<<<<<<<<<<[-]<[-]

取消高尔夫:

,
>++++++[<----->-]<--
[                                           # 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
[<+>-]<[>>+>+<<<-]>>>[<<<+>>>-]<[[-]<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<-]>[<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<->>[-]]+>-]<-]<<+>]<[>>+<<-]>>[<<<[>+>+<<-]>>[<<+>>-]>-]<<[<<->>-]<[-]<[>>>>>>>>+<<<<<<<<-]>>>>>>>>>[>>]+[<<]>[>[>>]<+<[<<]>-]<<<<<<<<<<[>>+>+<<<-]>>>[<<<+>>>-]+[<+>-]<<<[-]>>[<<+>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]++++++++++<[>>+<<-]>>[<[>>+>+<<<-]>>>[<<<+>>>-]<[>+<<-[>>[-]>+<<<-]>>>[<<<+>>>-]<[<-[<<<->>>[-]]+>-]<-]<<<+>>]<[-]<<<<[-]>>>[<<<+>>>-]<<<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[<+>-]<]<[>+>+<<-]>>[<<+>>-]<[>+<[-]]+>[<[-]<[>>>+>+<<<<-]>>>>[<<<<+>>>>-]<[[-]>>>>>>>>[>>]<[<[<<]<<<<<+>>>>>>>[>>]<-]<-<<[<<]<<<<<>++++++++++++++++++++++++++++++++++++++++++++++++[<+>-]<.[-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]+[<->-]<<<<<[-]>>>>[<<<<+>>>>-]<<<<[>>>>+>+<<<<<-]>>>>>[<<<<<+>>>>>-]<[<+>-]<]<[-]]<[>>++++++[<++++++++>-]<.[-]<[-]]<[-]<[-]>>>>>>>>>>>>[>[-]>]<<[-<<]<<<<<<<<<<<<<<<<<[-]<[-]

感谢作者的帮助,我采用了该答案输出值的代码!

该程序可能无效,但是无论哪种方式我都想与您共享^^

更新:由于@ Sp3000 对本次比赛回答以及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>


我也不知道这是否有效!我猜想这不是Brainfuck的全部数字,还是什么都没有。
纳撒尼尔(Nathaniel)2014年

我喜欢这个答案。最近我一直在和男友混在一起。这说明了在机器级别上无论如何一切都只是令牌。很难说这是否真的遵守规则。
章鱼

6

Python中,394 349 340个字符

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

运行像:

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

花费50毫秒。

使用俄罗斯农民乘法。添加数字时,我们将它们转换为一元('5'=> [R,R,R,R,R]),连接列表,然后再转换回。 U转换为一进制,R用作一进制数字。我们计算b/=2b=b*5/10


几次打高尔夫球:def A(a,b):\n r='';c=[]-> def A(a,b,r='',c=[]):,类似def M。您可能可以更改for z in D:d.pop()\n c=['X'][d.pop()for z in D];c=['X'],在这种情况下,您甚至可以将其折叠到上一个if。另外,可以if list(b).pop()in'13579'if b[:].pop()in'13579'吗?
贾斯汀

@Quincunx:谢谢。最后一个将不起作用,因为在第一次迭代中b是字符串,而不是列表。
基思·兰德尔

您可以跳过M并编写完整的程序;a,b=input() 被允许。
贾斯汀2014年

1
b * 5/10是一个不错的技巧。
bazzargh 2014年

我偶然发现reduce,这让你高兴A(b,A(b,A(b,A(b,b))))起来reduce(A,[b,b,b,b,b])。可悲的是,这不会影响字符数。
Wrzlprmft

5

JavaScript(E6)375395411449

编辑 Golfed
编辑错误修正:失踪清除进位标志

只需在接近0的时间内进行符号操作即可完成。
在此版本中,您可以使用任何char代替数字,只要符号按升序排列即可。

注意:使用字符串,带有字符串键的哈希图,用作列表的数组。没有索引,使用'map'遍历数组或使用push&shift旋转数组。
所有的“ +”都是字符串连接。

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)

少打高尔夫球(也许我明天会添加解释)

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('')
)

在FireFox / FireBug控制台中测试

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

输出量

Result 99999999980000000001 time ms 14

可能有一个小错误- 9999999999案件的输出应该是99999999980000000001,而不是99999999980000000081
Nathaniel 2014年

:(要检查
edc65

如果您使用的是乘法表,那么如何避免不允许加法的事实呢?
COTO

1
允许使用哈希表(代码中的s)进行汇总。例如 s ['34']->'7'。只是符号,而不是数字。可能是S [ 'CD'] - >的'g'
edc65

5

Haskell,231个字节

这定义了一个运算符#,该运算符将两个自然数的字符串表示形式相乘。它通过在字符串上定义基本的递增/递减运算来工作,然后使用它来建立加法和乘法。一点点额外的魔术可以使速度成指数增长,从而使一切变为可能。

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

这种方法足够快,即使在未优化的ghci REPL的2008笔记本电脑上,测试用例也只需一秒钟的时间:

λ> :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)

检查所有两位数的产品是否正确:

λ> and [ show (x * y) == (show x # show y) | x <- [0..100], y <- [0..100] ]
True

看来我们有一位新的领导者!(不过我看不懂Haskell,有人可以独立确认它是否符合规范吗?)
Nathaniel 2014年

1
是的,这完全是糊状的haskell,符合规范,并且可以按广告宣传工作。做得好!
2014年

4

Bash + ImageMagick:52

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

期望输入在外壳变量中 a和中b。它不是特别聪明或高效,但是可以完成工作。可能以前已经做过。

请注意 x表示图像的尺寸;在这种情况下,它不是算术运算符。

我尚未对此进行测试,但是我愿意假设对于非极端输入,它将在一分钟内完成。我明天可以测试。

如果ImageMagick版本有任何有趣的事情,这就是我正在使用的版本: ImageMagick 6.7.7-10


不错的尝试,但是我敢肯定,输入9999999999和会在一分钟之内(或者实际上在任何现有机器上根本无法)工作9999999999
纳撒尼尔(Nathaniel)2014年

4
这也适用于:dd if=/dev/zero bs=$a count=$b 2>&-|wc -c
jimmy23013 2014年

1
9999999999x99999999998位格式的图像将占用地球上当前存在的所有硬盘空间。当然,如果您无需先创建原始图像就可以创建png,则png会小很多。(尽管我强烈怀疑您将在这样大小的图像上出现整数溢出问题。)但是,这样的方法几乎肯定会受到字符串漏洞的影响。
纳撒尼尔(Nathaniel)2014年

1
您可以使用$b代替来保存2个字节${b}
nyuszika7h 2014年

1
另外,您可以使用grep -vc g代替来节省5个字节grep -v g|wc -l
nyuszika7h 2014年

2

Python 2(概念证明)

该解决方案仅使用字符串和列表以及一些正则表达式起作用。我相信它完全符合规范,只是无法做到9999999999x9999999999一分钟。尽管有足够的时间,它将起作用。它可以快速地将4位数字相乘。

由于它在技术上是无效的,因此我还没有完全打高尔夫球的麻烦。如果规则改变,我会这样做。

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

例子:

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

multiply('1869','1243') #returns the string 2323167

1
+1是因为据我所知,它确实符合规格(除了效率要求)
Nathaniel 2014年

2

Python 2(555)

通常,我通常不会这么快(或根本没有)回答自己的挑战,但我想证明它是可以做到的。(幸运的是,在此之前还有其他答案,但是我忍不住想要完成它。)还有一些其他的高尔夫运动可以做,但是我认为这是合理的。它可以9999999999x9999999999在我的机器上以不到0.03s的速度处理案件。

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

使用示例: m("12345","42")

它通过使用字符串操作进行长乘法来工作。有时变量是字符串,有时它们是字符串的迭代器,这使得无需使用整数即可获取第一个元素。一切都以数字反转存储,因此第一个元素是最低有效数字。

以下是逐个功能的说明:

  • rs簿记功能。(r只是一个别名reversed,它构成一个反向迭代器,s并将迭代器转换为字符串。)

  • i 将字符串中的数字加1,包括以下情况 39+1=40和的情况99+1=100

  • bxy,但y只能是一位。它通过递增来工作x y时间来工作。

  • a 通过调用将两个数字加起来可以同时具有多个数字 b中的每个数字,y

  • nx和相乘y,但y只能为一位。通过添加x自身来工作y时间来工作。

  • oxy,其中两个参数可以有多个数字。它使用经典的长乘法

  • m只需将其字符串输入转换为反向迭代器并将其交给o,然后将结果反向并将其转换为字符串。


情侣高尔夫:def a(x,y):-> def a(x,y,z=''):删除下一行;其他功能的类似技巧,在中def o(x,y):,将更x=s(x)改为x=s(x);l='';z='',在for循环中,类似地删除换行符+速度;改为使用;。另外,我认为if h!='0':h+=s(x)\nelse:h+=i(x)可以简单地做到h+=h!='0'and i(x)or s(x);也许甚至h+=(h!='0'and i or s)(x); 否则,只需更改为if'0'!=h。还有类似的东西def r(x):return reversed(x)->r=reversed
贾斯汀(Justin)

另外,我忘了提了sms=lambda x:''.join(x)m=lambda x,y:s(r(o(r(x),r(y))))而不是整个函数声明。仅凭我知道的工作,这会使您的字节数减少到521。–
Justin

哦,还有一个:对于您的for循环: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),尽管这可能会大大改变程序的速度。
贾斯汀

@Quincunx谢谢!今天早上我还能看到其他一些改进。(通常嵌套循环而不是定义函数。)如果出现一些更具竞争力的答案,我将做出这些更改,这似乎很可能-目前,它们使我处于领先地位,这似乎有点不公平,因为这是我的问题,我我已经考虑了更长的时间了。
纳撒尼尔(Nathaniel)2014年

2

JavaScript:3710 3604字节

  • 使用具有1位数乘法的字符串查找表,并带有进位加法。
  • 乘法是通过数字x数字而不是数字x行完成的。

高尔夫球:

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

取消测试:

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');

输出:

mult 12345 * 42 = 518490 (3 ms) 
mult 9999999999 * 9999999999 = 99999999980000000001 (47 ms) 

2

哈斯克尔507 496

这适用于任意大整数。我定义了从0到18的自然数的自定义表示形式(最大自然数等于两位数的总和),并以数字*数乘的方式定义了小尾数乘法,这是我以数+数加法的方式定义的,我用数字+数字加法定义。我有一个归约函数,可以将10--18的值扩展为数字分解。然后,这仅读取并反转两个字符串,转换为自定义绑定,相乘,然后转换回,反转以得到正确的结果。

编辑2

我通过创建我多次使用的多字符命令,以及去掉空格和括号,短本地别名并通过更换保存几个大字(- )双,$在可能的情况。

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

作为参考,S是自定义类整数数据类型,p是'plus'(数字+数字加法),s是减法(用于缩减),r是减少(扩展为数字分解),a是加法(数字+数字加法),m是乘(数字*数字乘),t是时间(数字*数字乘),i是“解释”(将字符串转换为的列表S),b是“后退”(将S的列表转换为字符串),f和g只是打高尔夫球的缩写目的。我没有使用数字,甚至没有使用数字。我最接近的是使用继任者和前任者,这些继任者比自然数的加法和乘法要高得多。

编辑

忘记包含时间资料。

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

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

只是为了好措施:

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

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

快疯了!

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

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

确认


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

请注意,我没有使用像这样的逻辑索引Z = [X, Y][N == "0"],因为这可以解释为强制转换为数字索引的布尔值。

取消高尔夫:

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

我会说不允许使用min()和max()函数,因为它们正在比较实际的整数值,不是吗?
WorldSEnder 2014年

@WorldSEnder:我想说他们比较角色,这项挑战中允许这样做。(“允许按字符进行字词比较。”)
Falko,2014年

1

Scala,470个字符

(这是标准的scala,但=>如果我们要计算字节,则可以等效地替换为)

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}

在这里,我们使用列表的长度来模拟数字,请注意不要使用任何数字运算-仅折叠,地图,邮编等。数字是这些数字的列表(在计算过程中,策略上顺序颠倒的顺序);我们将个位数与相乘,flatMap并将行与相乘reduceu处理找出进位(通过直接匹配> 10个元素的列表并递归)并将数字转换回字符,然后我们使用a /:来沿堆栈进行工作。所需的示例将在不到一秒钟的时间内完成。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.