คูณสองตัวเลขโดยไม่ใช้ตัวเลขใด ๆ


30

คุณจะได้รับเป็น input สองสายที่เป็นตัวแทนของจำนวนเต็มบวกใน 10 ฐานเช่นและ"12345" "42"งานของคุณคือการส่งออกสตริงที่มีผลิตภัณฑ์ของพวกเขา"518490"ในกรณีนี้

การบิดคือคุณไม่สามารถใช้ชนิดตัวเลขในรหัสของคุณได้ ไม่ints, floats, unsigned longs, ฯลฯ , ไม่มีชนิดจำนวนเชิงซ้อนในตัวหรือจำนวนเต็มความแม่นยำโดยพลการหรืออะไรก็ได้ตามบรรทัดเหล่านั้น คุณหลายคนไม่ได้ใช้ตัวอักษรประเภทเหล่านั้นหรือฟังก์ชั่นใด ๆ วิธีการผู้ประกอบการ ฯลฯ ที่ส่งกลับพวกเขา

คุณสามารถใช้สตริงบูลีนอาร์เรย์หรืออะไรก็ได้ที่ปกติจะไม่ใช้แทนตัวเลข (แต่โปรดทราบว่าไม่อนุญาตให้มีการทำดัชนีในอาร์เรย์หรือรับความยาวโดยไม่ต้องเรียกใช้ตัวเลข) chars แต่คุณไม่สามารถดำเนินการทางคณิตศาสตร์หรือการดำเนินการระดับบิตกับพวกเขามิฉะนั้นถือว่าเป็นอย่างอื่น โทเค็นที่แสดงถึงส่วนหนึ่งของสตริง ( charอนุญาตให้มีการเปรียบเทียบพจนานุกรมของs)

คุณไม่สามารถแก้ไขข้อ จำกัด ได้ ซึ่งรวมถึง (แต่ไม่ จำกัด เพียง) โดยใช้ชนิดตัวเลขภายในevalฟังก์ชันประเภทประเภทการแปลงโดยนัยเป็นประเภทตัวเลขโดยใช้ตัวดำเนินการตัวเลขหรือบิตในประเภทที่ไม่ใช่ตัวเลขที่รองรับพวกเขาโดยใช้ประเภทตัวเลขที่เก็บไว้ในประเภทคอนเทนเนอร์หรือฟังก์ชันการโทรหรือ โปรแกรมภายนอกที่ส่งคืนผลลัพธ์ตัวเลขในรูปแบบสตริง (ฉันขอสงวนสิทธิ์ที่จะเพิ่มลงในรายการนี้หากการแก้ไขปัญหาอื่น ๆ ปรากฏในคำตอบ) คุณต้องใช้การคูณด้วยตัวคุณเองโดยใช้ประเภทที่ไม่ใช่ตัวเลขเท่านั้น

การป้อนข้อมูลและการส่งออกอาจเป็นวิธีที่สะดวกสบายตราบใดที่ข้อมูลเข้าและออกรหัสของคุณในรูปแบบของสตริง คุณอาจจะสมมติแต่ละสองข้อโต้แย้งการป้อนข้อมูลมีเพียงตัวอักษรแอสกีและจะไม่เริ่มต้นด้วย[0-9] 0ผลลัพธ์ของคุณไม่ควรมีเลขศูนย์นำหน้าด้วย

อีกอย่างหนึ่ง: รหัสของคุณจะต้องจัดการอินพุตที่มีความยาวอย่างน้อย 10 อักขระอย่างถูกต้องและต้องทำงานภายในหนึ่งนาทีบนคอมพิวเตอร์ที่ทันสมัยสำหรับอินพุตทั้งหมดในช่วงนั้น ก่อนที่จะโพสต์โปรดตรวจสอบว่าเมื่อได้รับอินพุต9999999999และ9999999999โปรแกรมของคุณให้ผลลัพธ์เป็น99999999980000000001เวลาน้อยกว่าหนึ่งนาที ข้อ จำกัด นี้มีไว้เพื่อป้องกันคำตอบที่ทำงานโดยจัดสรรขนาดให้เหมาะสมa*bแล้ววนซ้ำดังนั้นโปรดจำไว้ว่าคำตอบของแบบฟอร์มนั้นจะไม่มีสิทธิ์ชนะ

นี่คือดังนั้นวิธีแก้ปัญหาที่สั้นที่สุดที่ถูกต้อง (เป็นไบต์) ชนะ


เราสามารถยอมรับ"12345"จาก STDIN มากกว่าได้12345ไหม? หรือเราสามารถยอมรับได้ทั้งตัวเลขเป็น"12345", "42"?
Justin

ความคิดแรกของฉันคือการเขียนฟังก์ชั่นการมีปากเสียงสตริงของความยาวmและและกลับมาโต้แย้งของความยาวn m*nแต่เนื่องจากสตริงต้องมีการแสดงตัวเลข ASCII อย่างแท้จริงฉันเดาว่าผิดกฎ
เลเวลริเวอร์เซนต์

1
@ xnor ในหลาย ๆ ภาษาอาจสั้นกว่าที่จะเขียนทุกกรณี แต่ฉันไม่พบวิธีนี้ในหลาม:a,b="0123456789x".split('0');c=iter(b).next() if c=='x': c='0'
นาธาเนียล

1
หรือใน Python 3a,b="0123456789x".split(x);c,*d=b if c=='x': c='0'
นาธาเนียล

2
@Nathanield='123456789';I=dict(zip('0'+d,d+'0'))
Justin

คำตอบ:


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

ใช้การคูณด้วยการเพิ่มซ้ำและเวทมนต์ทุกประเภทได้รับการจัดการโดยการเลื่อนและการกรอง['0'..'9']รายการ กำหนดโอเปอเรเตอร์#ของประเภทString -> String -> String:

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

ดูเหมือนว่าเรามีผู้ชนะคนใหม่! (แม้ว่าจะเป็นก่อนหน้านี้ฉันไม่สามารถอ่าน Haskell ในระดับความซับซ้อนนี้ได้ - ใครบางคนสามารถตรวจสอบว่าเป็นไปตามข้อกำหนดหรือไม่)
นาธาเนียล

(เช่น ['0' .. '9'] ให้ความรู้สึกเหมือนเป็นตัวอักษรโดยนัยเป็นตัวเลขที่สามารถทำซ้ำได้ - มีวิธีสั้น ๆ ในการสร้างรายการจากสตริง "0123456789" แทนหรือไม่)
นาธาเนียล

@Nathaniel ดีครั้งแรกของทุกสตริง"0123456789" เป็น['0'..'9']รายการ ประการที่สองใน Haskell [a..b] เป็นการแจงนับชนิดที่ประกาศอินสแตนซ์ของประเภทงานEnumพิมพ์สามารถระบุได้เช่นนั้นและการประกาศอธิบายวิธีการทำงานของการแจงนับ Boolประเภทบูลีนก็มีอินสแตนซ์ดังนั้นคุณสามารถทำได้เช่น[False..True]กัน แทบจะไม่มีตัวเลขใด ๆ ที่เกี่ยวข้อง
mniip

14

sed, 339 338 ไบต์

ฉันรู้ว่านี่เป็นของเก่า แต่ฉันก็กำลังค้นหาและสิ่งนี้ทำให้ฉันสนใจ เพียงพอที่จะลงทะเบียนเป็นผู้ใช้จริง! ฉันคิดว่าฉันโดนอิทธิพลจาก " ฉันอยากเห็นวิธีแก้ปัญหาแบบเต็ม - นาธาเนียล " ...

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 หลัก)

การใช้ GNU ติดตั้งบน Core-2 ที่ไม่ทันสมัย ​​(ยุค 2007 Intel Core 2) ตัวสุดท้ายจะใช้เวลานานกว่าหนึ่งนาที แต่มันเร็วขึ้นสำหรับโปรเซสเซอร์รุ่นใหม่:

  • Q6600:> 1 นาที
  • i7-3770: 26 วินาที
  • i7-6700: 22 วินาที

ตัวเลข 10 หลักแบบทวีคูณที่ระบุไว้ในคำถามนั้นใช้เวลาไม่เกินหนึ่งวินาทีในคำถามเหล่านี้ (แม้จะเต็มไปด้วยเก้าพยาธิวิทยา)

ฉันเชื่อว่าเป็นมาตรฐานที่ไม่มีส่วนขยาย POSIX รับประกันพื้นที่ว่าง 8192 ไบต์เท่านั้นซึ่ง จำกัด ให้เราคูณตัวเลข 400x400 หลัก แต่การใช้งานสามารถให้มากกว่านี้ GNU sed ถูก จำกัด ด้วยหน่วยความจำที่มีอยู่เท่านั้นดังนั้นสามารถจัดการบางอย่างที่ใหญ่กว่านี้ได้ถ้าคุณเต็มใจที่จะรอ

และฉันมั่นใจว่าฉันได้ปฏิบัติตามกฎ - เกือบเป็นภาษาที่ไม่มีตัวเลข :-)

คำอธิบาย

ฉันใช้ไฮบริดแบบ unary / ทศนิยมโดยแปลงตัวเลขทศนิยมให้เป็นลำดับแบบ unary:

 42 => _xxxx_xx

ในทศนิยมที่ไม่มีการเติมให้ง่าย เราวนซ้ำจากค่านัยสำคัญน้อยที่สุดไปเป็นตัวเลขที่สำคัญที่สุดโดยทำการต่อค่า x's:

   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 

เมื่อเราเพิ่มการคูณก็เป็นไปได้ เราคูณ x * y โดยพิจารณาตัวเลขสุดท้ายของ y เพิ่ม 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
คำตอบที่น่าพอใจมากขอบคุณ!
นาธาเนียล

9

sed, 379 ไบต์

เครดิตสำหรับคำตอบที่ยอดเยี่ยมนี้ไป @LuigiTiburzi กว่าบน Unix และ Linux.SE: https://unix.stackexchange.com/a/37213/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กลายเป็น<|<||*<|||
  • แทนที่|<ด้วยซ้ำหลายครั้ง<||||||||||เพื่อเลื่อนตำแหน่งทศนิยมที่สูงขึ้นทั้งหมดลงสู่ตำแหน่งหน่วย จึง<|<||*<|||กลายเป็น<||||||||||||*<|||
  • <ลบ จึง<||||||||||||*<|||กลายเป็น||||||||||||*|||
  • ลบ 1 |จาก RHS *ของ จึง||||||||||||*|||กลายเป็น||||||||||||*||
  • แทนที่แต่ละครั้ง|บน RHS ด้วยซ้ำ|บน LHS ทั้งหมด นี้มีผลของการคูณและ 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ใช้เวลา 41 วินาทีบน Ubuntu VM ของฉันและรันไทม์เชิงประจักษ์จะปรากฏขึ้นพร้อมกับสี่เหลี่ยมจัตุรัสของผลิตภัณฑ์ขั้นสุดท้าย


1
นี่เกือบจะเป็นอัลกอริทึมที่เทียบเท่ากับคำตอบ JS ที่ฉันลบไปยกเว้นสำหรับการแปลงกลับไปเป็นหมายเลขชิ้นส่วน
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer ตกลง ความแตกต่างคือคุณใช้length()ซึ่งส่งกลับตัวเลข อันนี้ใช้การทดแทน regex ล้วนๆโดยไม่มีชนิดตัวเลข ฉันคิดว่าคำตอบของคุณอาจเป็นผู้ชนะ แต่ถ้าคุณสามารถลบออกได้ length()- บางทีคุณสามารถทดแทน regex ที่คล้ายกันแทนได้หรือไม่
Digital Trauma

1
ดีมาก แต่ข้อ จำกัด เพียงหนึ่งนาทีมีขึ้นเพื่อป้องกันไม่ให้โซลูชันที่ทำงานโดยนับถึงคำตอบ ฉันอยากจะเห็นวิธีการแก้ปัญหาเต็มรูปแบบแม้ว่า
นาธาเนียล

1
ฉันมีคำตอบที่ใช้กับตัวเลขขนาดใหญ่ (เช่นใหญ่กว่าพื้นที่ที่อยู่ของระบบ)
Toby Speight

@TobySpeight ใช่ดีมาก ฉันคิดว่าฉันต้องยกระดับการสนับสนุนของคุณไปสักพักแล้ว :)
บาดเจ็บทางดิจิตอล

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

หากอนุญาตให้มีเลขศูนย์นำหน้า (จำนวนมาก) ไม่จำเป็นต้องใช้อักขระ 12 ตัวสุดท้าย

วิธีนี้จะทำการคูณมาตรฐานด้วยมือเป็นหลัก ตัวเลขถูกแสดงเป็นสตริงของIs ซ้ำ(เช่นเลขโรมันดั้งเดิม) ตัวเลขแสดงเป็นรายการตัวเลขตามลำดับย้อนกลับ การเติมเลขหลักเดียวทำได้โดยการเพิ่มสตริงและลบสิบIs หากจำเป็น

นี่คือเวอร์ชั่นที่ไม่ได้รับการอวด:

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""จะใช้ได้นะ
Justin

@Quincunx: การกำหนดเป็นอาร์กิวเมนต์ที่มีค่าเริ่มต้นหนึ่งจะไม่ได้ทำงานตามที่มันมักจะเป็นรายการเดียวกันแม้สำหรับสายที่แตกต่างกันของการทำงานจึงไม่รีเซ็ตS []คุณถูกต้องเกี่ยวกับ["","1"][t in i]ฉันคงที่ ฉันยังเพิ่มคำอธิบาย
Wrzlprmft

มันช่างน่าอัศจรรย์ทีเดียว ตอนนี้ได้รับเครื่องหมายสีเขียวแล้ว (ฉันได้แก้ไขคำถามเพื่อให้ความกระจ่างว่าศูนย์นำหน้าในผลลัพธ์ไม่ได้รับอนุญาต - ขออภัย!)
นาธาเนียล

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's: 06a17a; จากนั้นทำความสะอาด -> 617

การเพิ่มจะทำอย่างนั้น ... ก่อนอื่นเลยฉันจะวางทั้งสองสายให้ยาวเท่ากันและสร้างคู่จากตัวเลข จากนั้นฉันเพิ่มตัวเลขด้วยการสร้างสตริงที่มีความยาวของแต่ละหลักและต่อกัน ฉันลบสตริงของความยาวนั้นออกจากจุดเริ่มต้นของ '0123456789abcdefghij' แล้วเก็บถ่านตัวแรก ดังนั้นเช่น "9" + "9" -> "i" NB ฉันหลีกเลี่ยงการใช้ฟังก์ชันความยาวที่นี่เพื่อหลีกเลี่ยงประเภทตัวเลขทั้งหมด; การลบคำนำหน้าจะทำด้วย regexp แทน

ตอนนี้ฉันมีสตริงที่มีตัวเลขและตัวอักษรผสมกัน ตัวอักษรแทนตัวเลขด้วยหลักนำ; ฉันเติมตัวเลข 0 เป็นตัวเลขจากนั้นแทนที่รูปแบบตัวอักษรตัวเลขซ้ำ ๆ ด้วยผลลัพธ์ของการยกจนกว่าการเติมจะเสร็จสมบูรณ์


1
คำตอบที่ฉลาดมากคือสิ่งที่ฉันหวังว่าจะได้เห็น!
นาธาเนียล

1
ฉันหวังว่าจะมีใครบางคนโพสต์ด้วยเลขคริสตจักร!
bazzargh

แม้ว่าฉันจะไม่แน่ใจว่ามันจะทำงานได้ตามความต้องการประสิทธิภาพหรือไม่ - ฉันคิดว่าการแปลงระหว่างสตริงและตัวเลขในศาสนจักรจะเกี่ยวข้องกับการนับได้อย่างมีประสิทธิภาพสูงสุดถึง 99999999980000000001
นาธาเนียล

7

Brainfuck (1328 ไบต์)

ข้อควรพิจารณาในตอนแรก:

  • ไม่แน่ใจว่า brainfuck เป็นคำตอบที่ถูกต้องสำหรับคำถามนี้หรือไม่เพราะฉันไม่แน่ใจว่าคุณพิจารณาว่าค่าของเซลล์เป็น 'ชนิดตัวเลข' หรือไม่ ฉันไม่คิดอย่างนั้นเนื่องจาก bf ไม่รู้ประเภท แต่เป็นความเห็นของฉันเองโปรดแก้ไขให้ฉันถ้าฉันผิด
  • จำเป็นต้องมีการติดตั้งใช้งานที่รองรับค่าเกือบไม่ จำกัด
  • อาจช้าเกินไปตามการนำไปใช้

ฉันเพียงการทดสอบโปรแกรมที่มีล่ามของตัวเองคุณสามารถค้นหาได้ที่นี่

อินพุตต้องเป็นตัวเลขทั้งสองคั่นด้วยช่องว่าง ASCII เดียว

แข็งแรงเล่นกอล์ฟ:

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

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

ฉันได้เอาโค้ดสำหรับเอาท์พุทของค่าจากคำตอบนี้ไปแล้วขอบคุณผู้เขียนคนนั้น!

โปรแกรมอาจไม่ถูกต้อง แต่อย่างใดฉันต้องการแบ่งปันกับคุณ ^^

อัปเดต:ตอนนี้คุณสามารถทดสอบได้ (สำหรับการทวีคูณเล็ก ๆ ) ที่นี่ต้องขอบคุณคำตอบของ @ 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 หรือไม่มีอะไรเลย
นาธาเนียล

ฉันชอบคำตอบนี้ ฉันเคยยุ่งกับ bf ตัวเองเมื่อเร็ว ๆ นี้ มันเป็นสิ่งที่ทำให้แสงสว่างในความจริงที่ว่าในระดับเครื่องทุกอย่างเป็นเพียงสัญญาณต่อไป ยากที่จะบอกว่าสิ่งนี้เป็นไปตามกฎหรือไม่
Octopus

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 มิลลิวินาที

ใช้รัสเซียชาวนาคูณ เมื่อเพิ่มตัวเลขเราจะแปลงเป็น unary ('5' => [R, R, R, R, R]) เชื่อมต่อรายการแล้วแปลงกลับ Uแปลงเป็นเอกภาพโดยใช้Rเป็นตัวเลขเอก เราคำนวณเป็นb/=2b=b*5/10


คู่ Golfs: 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'?
Justin

@Quincunx: ขอบคุณ อันสุดท้ายจะไม่ทำงานเพราะในการทำซ้ำครั้งแรกbคือสตริงไม่ใช่รายการ
Keith Randall

คุณสามารถข้ามMและเขียนโปรแกรมที่สมบูรณ์ a,b=input() ได้รับอนุญาต.
Justin

1
b * 5/10 เป็นกลอุบายที่ดี
bazzargh

ฉันเพียงแค่สะดุดreduceซึ่งช่วยให้คุณสามารถ nicen ไปA(b,A(b,A(b,A(b,b)))) reduce(A,[b,b,b,b,b])น่าเศร้าที่สิ่งนี้ไม่ส่งผลต่อจำนวนตัวละคร
Wrzlprmft

5

JavaScript (E6) 375 395 411 449

แก้ไขการ
แก้ไขข้อผิดพลาดGolfed : ไม่มีการล้างการดำเนินการตั้งค่าสถานะ

มันสามารถทำได้ด้วยการจัดการสัญลักษณ์เพียงในเวลาใกล้ 0
ในรุ่นนี้คุณสามารถใช้อักขระใด ๆ แทนตัวเลขตราบใดที่สัญลักษณ์อยู่ในลำดับจากน้อยไปหามาก

หมายเหตุ: การใช้สตริง hashmap พร้อมคีย์สตริงอาร์เรย์ที่ใช้เป็นรายการ ไม่มีการจัดทำดัชนีอาร์เรย์ถูกส่งผ่านโดยใช้ '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)

หัก Golfed (อาจจะเพิ่มคำอธิบายในวันพรุ่งนี้)

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
นาธาเนียล

:( ไปตรวจสอบ
edc65

หากคุณใช้ตารางทวีคูณคุณจะรู้ได้อย่างไรว่าการรวมไม่ได้รับอนุญาต
COTO

1
การสรุปนั้นอนุญาตให้ใช้ hashtable (ในรหัส) อดีต 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

วิธีนี้เร็วพอที่จะใช้งานกับแล็ปท็อปปี 2008 ใน ghci REPL ที่ไม่ได้เพิ่มประสิทธิภาพกรณีทดสอบใช้เวลาเพียงเสี้ยววินาที

λ> :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 ได้ - ใครบางคนสามารถยืนยันได้อย่างอิสระว่าเหมาะกับสเป็คหรือไม่)
นาธาเนียล

1
ใช่นั่นคือกลอนอย่างสมบูรณ์แบบมันเหมาะกับสเป็คและทำงานตามที่โฆษณาไว้ เยี่ยมมาก!
bazzargh

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
นาธาเนียล

4
dd if=/dev/zero bs=$a count=$b 2>&-|wc -cนอกจากนี้ยังทำงาน:
jimmy23013

1
9999999999x9999999999ภาพในรูปแบบ 8bit จะใช้เวลาทั้งหมดพื้นที่ฮาร์ดไดรฟ์ที่มีอยู่ในปัจจุบันบนโลก แน่นอนว่า png จะเล็กกว่ามากหากคุณสามารถสร้างมันได้โดยไม่ต้องสร้างภาพดิบก่อน (แม้ว่าฉันจะสงสัยอย่างยิ่งว่าคุณจะมีปัญหาล้นจำนวนเต็มกับภาพขนาดนั้น) แต่ถึงกระนั้นวิธีการดังกล่าวก็เกือบจะไม่เป็นที่น่าพอใจจากช่องโหว่ที่เรียกว่า
นาธาเนียล

1
คุณสามารถบันทึก 2 ไบต์โดยใช้แทน$b ${b}
nyuszika7h

1
นอกจากนี้คุณยังสามารถบันทึก 5 ไบต์โดยใช้แทนgrep -vc g grep -v g|wc -l
nyuszika7h

2

Python 2 (พิสูจน์แนวคิด)

โซลูชันนี้ทำงานโดยใช้สตริงและรายการเท่านั้นและ regex เล็กน้อย ฉันเชื่อว่ามันเหมาะกับสเป็คทั้งหมดยกเว้นว่าไม่มีวิธีที่สามารถทำได้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 เพราะมันตรงตามข้อกำหนด (นอกเหนือจากความต้องการด้านประสิทธิภาพ) เท่าที่ฉันสามารถบอกได้
นาธาเนียล

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

มันทำงานโดยการคูณยาวโดยใช้การจัดการสตริง บางครั้งตัวแปรเป็นสตริงและบางครั้งก็เป็นตัววนซ้ำของสตริงซึ่งทำให้สามารถรับองค์ประกอบแรกได้โดยไม่ต้องใช้ตัวอักษรจำนวนเต็ม ทุกอย่างถูกเก็บไว้ด้วยตัวเลขที่ตรงกันข้ามดังนั้นองค์ประกอบแรกคือตัวเลขที่สำคัญที่สุด

นี่คือคำอธิบายแบบทีละฟังก์ชัน:

  • rและsเป็นฟังก์ชั่นการทำบัญชี ( rเป็นเพียงนามแฝงreversedซึ่งทำให้ตัววนกลับย้อนกลับและsแปลงตัววนซ้ำเป็นสตริง)

  • iเพิ่มจำนวนในสตริงโดย 1 รวมทั้งกรณีเช่นและ39+1=4099+1=100

  • bเพิ่มxและyแต่yต้องมีเพียงหนึ่งหลัก มันทำงานโดยการเพิ่มx yเวลา

  • aเพิ่มตัวเลขสองร่วมกันว่าทั้งสองสามารถมีตัวเลขหลายโดยการเรียกแต่ละหลักในby

  • nคูณxและyแต่yต้องมีเพียงหนึ่งหลัก มันทำงานโดยการเพิ่มเวลาของxตัวเองy

  • oทวีคูณxและyที่อาร์กิวเมนต์ทั้งสองสามารถมีได้หลายหลัก มันใช้การคูณแบบยาวคลาสสิก

  • mเพียงแปลงอินพุตสตริงของมันให้เป็นตัววนซ้ำแบบย้อนกลับและส่งต่อให้กับoมันจากนั้นกลับผลลัพธ์และแปลงเป็นสตริง


กอล์ฟคู่: def a(x,y):-> def a(x,y,z=''):และลบบรรทัดถัดไป เทคนิคที่คล้ายกันสำหรับฟังก์ชั่นอื่น ๆdef o(x,y):เปลี่ยนx=s(x)ไปx=s(x);l='';z=''ในการที่ห่วงกันเอาขึ้นบรรทัดใหม่ + ก้าว; ;แทนที่จะใช้ นอกจากนี้ฉันคิดว่า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
จัสติน

นอกจากนี้ฉันลืมที่จะพูดถึงs, m: s=lambda x:''.join(x), m=lambda x,y:s(r(o(r(x),r(y))))แทนการประกาศฟังก์ชั่นทั้งหมด มีเพียงสิ่งที่ฉันรู้ว่าการทำงานนี้จะนำคุณไบต์นับลงไป 521.
จัสติน

โอ้และอีกอย่าง: สำหรับ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)แม้ว่าสิ่งนี้อาจเปลี่ยนความเร็วของโปรแกรมได้อย่างมาก
Justin

@Quincunx ขอบคุณ! ฉันสามารถเห็นการปรับปรุงอีกสองสามครั้งเช่นกันเมื่อเช้านี้ (ส่วนใหญ่ทำรังวนซ้ำแทนการกำหนดฟังก์ชั่น) ฉันจะทำการเปลี่ยนแปลงเหล่านี้หากมีคำตอบที่แข่งขันได้มากขึ้นซึ่งดูเหมือนว่าน่าจะเป็น - ในปัจจุบันพวกเขาจะทำให้ฉันเป็นผู้นำ ฉันต้องคิดอีกต่อไปแล้ว
นาธาเนียล

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

Ungolfed ด้วยการทดสอบ:

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

Haskell 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คือ 'บวก' (บวก + ตัวเลขหลัก +) 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"]นี้สามารถตีความได้ว่าเป็นบูลีนหล่อดัชนีดัชนี

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

ฉันจะบอกว่าไม่ควรอนุญาตให้ใช้ฟังก์ชัน min () และ max () เพราะสิ่งเหล่านี้กำลังเปรียบเทียบค่าจำนวนเต็มจริงใช่ไหม
WorldSEnder

@WorldSEnder: ฉันว่าพวกเขาเปรียบเทียบตัวละครที่ได้รับอนุญาตในความท้าทายนี้ ("อนุญาตให้ทำการเปรียบเทียบตัวอักษรของตัวอักษร")
Falko

1

สกาลา 470 ตัวอักษร

( เป็นมาตรฐานสกาล่า แต่สามารถถูกแทนที่ด้วย=>หากเรานับไบต์)

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 จัดการการหาค่าพกพา (โดยการจับคู่กับรายการขององค์ประกอบ> 10 และการเรียกซ้ำ) โดยตรงและแปลงตัวเลขกลับเป็นตัวอักษรและเราใช้ a เพื่อทำงานผ่านสแต็กกับสิ่งนั้น ตัวอย่างที่ต้องการเสร็จสมบูรณ์ในเวลาน้อยกว่าหนึ่งวินาทีreduceu/:

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.