ได้เวลาทำคณิตศาสตร์แล้ว


14

บทนำ

นี่คือปริศนาทางคณิตศาสตร์ที่ฉันโปรดปราน

ให้ตัวเลข (พูด 3) และจำนวนครั้งที่ใช้ตัวเลขนั้น (พูด 5) สร้าง 10 นิพจน์ซึ่งทำให้ 1, 2, 3, 4, 5, 6, 7, 8, 9 และ 10 ใช้เพียง +, -, ×, ÷, ^ และ√ (รูท) (วงเล็บอนุญาตให้ใช้งานกลุ่ม)

ตัวอย่างเช่น:

(3^3 + 3)/(3 + 3) = (33 - 3)/(3 + 3) = 3 + 3/3 + 3/3 = 5

โปรดทราบว่าทั้งหมดข้างต้นใช้ห้าและการดำเนินการทางคณิตศาสตร์และผลที่ 5 คุณยังสามารถใช้ 3 ก่อน√เพื่อแสดงถึงรูทคิวบ์ ไปสำหรับการใช้ 4 ก่อน√เพื่อแสดงว่ารูทที่สี่

โปรดทราบว่าสามารถใช้สองสามรูปแบบเป็น 33 หรืออีกสามสามารถนำมาใช้เป็น 333 และอื่น ๆ

ท้าทาย

  • คุณจะได้รับสองตัวเลข(ทั้งตั้งแต่ 1 ถึง 5)เป็นอาร์กิวเมนต์ของฟังก์ชัน, STDIN หรืออาร์กิวเมนต์บรรทัดคำสั่ง
  • ตัวเลขตัวแรกหมายถึงตัวเลขที่จะใช้และตัวเลขตัวที่สองแสดงถึงจำนวนครั้งที่ต้องใช้ตัวเลขในนิพจน์
  • โปรแกรมของคุณควรแสดงอาเรย์ที่มีขนาด 10 (หรือ 10 ตัวเลขคั่นด้วยช่องว่าง) โดยที่แต่ละองค์ประกอบแสดงว่านิพจน์ทางคณิตศาสตร์ (ใช้ตัวดำเนินการที่อนุญาต) ที่ทำให้เกิด(index + 1)จำนวนนั้นเป็นไปได้หรือไม่โดยใช้ค่าจริง / เท็จ

ตัวอย่างเช่นถ้าอินพุตเป็น

1 3

จากนั้นควรส่งออก

[1, 1, 1, 0, 0, 0, 0, 0, 0, 1]

เพราะมีเพียง 1, 2, 3 และ 10 เท่านั้นที่สามารถแสดงโดยใช้สาม 1

คะแนน

  • นี่คือเพื่อให้ความยาวรหัสขั้นต่ำเป็นไบต์ชนะ

โบนัส

พิมพ์ -em-all [−50]

ลบ 50 จากคะแนนของคุณหากองค์ประกอบอาร์เรย์เอาท์พุทเท่ากับจำนวนรวมทั้งหมดที่เป็นไปได้ในการรับ(index + 1)ค่าแทนค่าจริงหรือค่าเท็จ

ตัวอย่างเช่นถ้ามีเพียง 3 ชุดเป็นไปได้ห้า 3 ซึ่งส่งผลให้ 5 แล้วอาร์เรย์ออกของ 4 THรายการที่ควรจะเป็น 3

Extreme Maths [−100]

ลบ 100 ออกจากคะแนนของคุณหากองค์ประกอบอาร์เรย์ผลลัพธ์ประกอบด้วยนิพจน์จริงอย่างน้อยหนึ่งนิพจน์ซึ่งเป็น(index + 1)ค่า

ตัวอย่างเช่นถ้าใช้ห้า 3 แถวออกของ 4 THรายการสามารถเป็นได้ทั้ง(3^3 + 3)/(3 + 3), (33 - 3)/(3 + 3)หรือ3 + 3/3 + 3/3

มากเกินไป [−200]

ลบ 200 จากคะแนนของคุณหากองค์ประกอบอาเรย์เอาต์พุตมีชุดค่าผสมที่เป็นไปได้ทั้งหมด (คั่นด้วย|) โบนัสนี้จะถูกเพิ่มเข้าไปในโบนัสExtreme Mathsดังนั้นคุณจะได้รับรวม −300

ตัวอย่างเช่นถ้าใช้ห้า 3, 4 อาร์เรย์ออกของTHองค์ประกอบที่ควรจะเป็น(3^3 + 3)/(3 + 3)|(33 - 3)/(3 + 3)|3 + 3/3 + 3/3

หมายเหตุ:นิพจน์สองรายการใด ๆ เพื่อให้ได้ผลลัพธ์เดียวกันควรมีเหตุผลที่แตกต่างกันโดยใช้แนวทางที่ต่างกันในทั้งคู่

ตัวอย่างเช่นในการรับ 5 โดยใช้ห้า 3 นั้น3 + 3/3 + 3/3เป็นแบบเดียวกัน3/3 + 3 + 3/3หรือ3/3 + 3/3 + 3เพราะวิธีเดียวกันนี้ใช้สำหรับแต่ละวิธี (3^3 + 3)/(3 + 3)และ(33 - 3)/(3 + 3)แตกต่างกันเมื่อจำนวน 30 ในตัวเศษทำได้โดยใช้วิธีที่ต่างกัน

UPDATE : หลังจากผ่านคำตอบทั้งหมดแล้วพบว่าคำตอบทั้งหมดมีข้อบกพร่องเนื่องจากขอบกรณีของเอกภาพ-และ√ ดังนั้นการหายไปของคดีขอบเหล่านั้นก็ถือว่าโอเคเท่าที่ความสมบูรณ์ของคำตอบเกี่ยวข้อง

นี่เป็นคำถามที่ยาก แต่เป็นคำถามที่ค่อนข้างน่าสนใจ

มีความสุขในการเล่นกอล์ฟ!


1
ฉันขอโทษนี่อาจเป็นใบ้ แต่คุณจะได้ 10 ด้วยสาม1s ได้อย่างไร
FryAmTheEggman


1
อาดังนั้นฉันจึงโง่: p
FryAmTheEggman

4
นั่นเป็นกฎที่คลุมเครือมาก ฉันอาจตัดสินใจว่าสแควร์รูทของ 1, สแควร์รูทของสแควร์รูทของ 1, ฯลฯ เป็นวิธีการที่แตกต่างกันทั้งหมดและฉันมีคำตอบจำนวนอนันต์ + b แตกต่างจาก b + a หรือไม่ (-a) * (-b) แตกต่างจาก b * a หรือไม่
feersum

2
ฉันรู้เรื่องนี้ แต่ฉันไม่สามารถเป็นตัวแทนของ 4 ^ (4 ^ (4 ^ (4 ^ 4))) ในรูปแบบตัวเลขปกติใด ๆ - การจัดเก็บ 4 ^ (4 ^ (4 ^ (4 ^ 4)) เป็นจำนวนเต็มต้องการบิตมากกว่า กว่ามีอะตอมในจักรวาล) ดังนั้นหากฉันใช้ระบบพีชคณิตของคอมพิวเตอร์ที่สามารถจัดการกับตัวเลขดังกล่าวได้ (หากมีอยู่ทั้งหมด) ฉันต้องปฏิบัติต่อสิ่งเหล่านี้เป็นกรณีพิเศษ อย่างไรก็ตามเรื่องนี้ต้องใช้ตัวละครมากกว่าที่ฉันชนะด้วยการใช้ทักษะมากเกินไป ดังนั้นรางวัลเหล่านี้ไม่มีจุดหมายเว้นแต่คุณจะยกเว้นรากที่สองหลาย ๆ
Wrzlprmft

คำตอบ:


1

Python 3 (ไม่สมบูรณ์), 449 - 300 = 149

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

R=range
E=lambda z:eval(z.replace("^","**"))
def m(d,n):_=R(1,11);s={i:[]for i in _};r=R(1,n);n<2 and s[d].append(str(d));d=str(d);t=[[(d*i,i)for i in r]]+[[]]*n;h=[];[(h.append("("+A+o+B+")"),t[l].append((h[0],a+b))if a+b<n else E(*h)in _ and s[E(*h)].append(h[0]),h.pop())for l in r for j in R(l)for A,a in t[j]for k in R(l)for B,b in t[k]if a+b<=n for o in"+-*/^"if(o=="^"and-~-(0<E(B)<9)or 0==E(B)and"/"==o)-1];[print(i,set(s[i])or'')for i in _]

การดำเนินการนี้จะใช้เวลาหลายนาทีหากอาร์กิวเมนต์ที่สองคือ 5. ทดสอบโดยการโทรm(digit, number):

>>> m(1,3)
1 {'((1*1)^1)', '(1^(1+1))', '((1-1)+1)', '((1/1)/1)', '((1*1)*1)', '((1^1)/1)', '(1*(1*1))', '(1^(1*1))', '(1+(1-1))', '(1^(1^1))', '((1^1)*1)', '(1^(1/1))', '((1/1)*1)', '(1-(1-1))', '(1/(1^1))', '(1/(1*1))', '(1/(1/1))', '(1*(1^1))', '((1+1)-1)', '((1*1)/1)', '((1^1)^1)', '(1*(1/1))', '((1/1)^1)'}
2 {'(1*(1+1))', '((1^1)+1)', '((1+1)/1)', '((1*1)+1)', '((1+1)^1)', '(1+(1*1))', '((1/1)+1)', '(1+(1^1))', '(1+(1/1))', '((1+1)*1)'}
3 {'((1+1)+1)', '(1+(1+1))'}
4 
5 
6 
7 
8 
9 
10 {'(11-1)'}
>>> m(3,3)
1 {'((3/3)^3)'}
2 {'(3-(3/3))', '((3+3)/3)'}
3 {'(3-(3-3))', '((3-3)+3)', '((3/3)*3)', '(3*(3/3))', '(3/(3/3))', '((3+3)-3)', '(3^(3/3))', '(3+(3-3))', '((3*3)/3)'}
4 {'((3/3)+3)', '(3+(3/3))'}
5 
6 {'((3*3)-3)'}
7 
8 
9 {'(3+(3+3))', '((3+3)+3)', '((3^3)/3)'}
10 

4

Python (ไม่สมบูรณ์) 493 474 - 300 = 174

มีปัญหาจำนวนพอสมควรในการแก้ปัญหานี้ประการแรกมันไม่สนใจเลขชี้กำลังใด ๆ ที่ใหญ่เกินไป (ใด ๆ ที่เลขชี้กำลังมากกว่า 100) จริง ๆ แล้วฉันไม่คิดว่าจะลบความเป็นไปได้ใด ๆ สำหรับอินพุตที่น้อยกว่าหรือเท่ากับ 5 แต่ฉันไม่แน่ใจ 100%

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

ฉันยังพิจารณาด้วยว่าเกณฑ์ใดควรตัดสินใจว่าการแสดงออกสองอย่างนั้นเทียบเท่ากันหรือไม่ แต่ฉันไม่สามารถหาวิธีที่จะกำหนดอย่างเข้มงวดในวิธีที่ฉันพบว่าใช้งานง่ายดังนั้น (อย่างน้อยตอนนี้) ฉันไม่ได้ทำอะไรแบบนั้น นี่หมายความว่ามันให้ผลลัพธ์ค่อนข้างน้อยและยังใช้วงเล็บในลักษณะที่ไร้เดียงสาพอสมควร

ในบันทึกด้านข้างฉันคิดว่านี่อาจรวมรหัสบรรทัดเดียวที่ยาวที่สุดที่ฉันเขียน

R=range
F=lambda s:lambda a,b:eval(s)
L=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)|(b>99)else a**b")),('v',F("b**(1./a)if a and(a>=0 or b)and(b>=0 or int(1./a)==1./a)&(1./a<99)else''"))]if o(u,v)!='']
A=L(*input())
for i in R(11):
 for v,s in A:
    if v==i:print i,s[1:-1]

ตัวอย่าง: ('v' แทน '√')

2,3

0 2*(2-2)
0 2v(2-2)
0 (2-2)*2
0 (2-2)/2
0 (2-2)^2
1 2^(2-2)
1 2-(2/2)
1 2v(2/2)
1 (2/2)^2
2 2v(2+2)
2 2+(2-2)
2 2-(2-2)
2 2v(2*2)
2 2*(2/2)
2 2/(2/2)
2 2^(2/2)
2 2v(2^2)
2 (2+2)-2
2 (2+2)/2
2 (2-2)+2
2 (2*2)-2
2 (2*2)/2
2 (2/2)*2
2 (2/2)v2
2 (2^2)-2
2 (2^2)/2
3 2+(2/2)
3 (2/2)+2
6 2+(2+2)
6 2+(2*2)
6 2+(2^2)
6 (2+2)+2
6 (2*2)+2
6 (2^2)+2
8 2*(2+2)
8 2*(2*2)
8 2*(2^2)
8 (2+2)*2
8 (2*2)*2
8 (2^2)*2

ฉันพบสองสิ่งที่คุณสามารถทำได้เพื่อลดระยะเวลาL:L=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)or b>100 else a**b")),('v',F("''if a==0 or(b<0 and int(1./a)!=(1./a))or(b or a<0)or(1./a)>100 else b**(1./a)"))]if o(u,v)!='']
FryAmTheEggman

ฉันขอโทษความคิดเห็นนั้นดูไม่ดีจริง ๆ :( อย่างไรก็ตามเพื่ออธิบาย: เมื่อเปรียบเทียบกับ0ฉันพยายามที่จะคัดค้านคำสั่งแล้วสลับผลที่ตามมาฉันพบว่ามีสถานที่ให้ใช้ไม่กี่แห่ง|และ&แทนที่จะเป็นorและandเทคนิคทั้งสองนี้ อาจถูกใช้เพื่อย่นการโทรครั้งสุดท้ายไปยัง F แต่จะต้องใช้ Demorgan's และฉันหมดเวลาใช้งาน p
FryAmTheEggman

@FryAmTheEggman โอ้เป็นเรื่องที่ดีฉันได้อัปเดตคำตอบของคุณในสิ่งที่คุณโพสต์และเมื่อฉันมีเวลาฉันจะดูคำตอบสุดท้าย เงื่อนไขเหล่านั้นเพื่อตรวจสอบความถูกต้องของอินพุตได้รับหนักกว่าที่ฉันคาดไว้เล็กน้อย: /
KSab

+10 สำหรับความฉลาดของ lambdas ที่ซ้อนกันและ - evalมันใช้เวลาพอสมควรที่จะหาบรรทัดที่สองของคุณ! ฉันคิดว่าฉันให้คุณเอาชนะ "บรรทัดเดียวที่ยาวที่สุด" ;) ฉันเห็นด้วยกับการไม่ใช้เลขชี้กำลังขนาดใหญ่ อันที่จริงฉันคิดว่าเลขชี้กำลังใด ๆ ที่ใหญ่กว่า 9 จะไม่เป็นประโยชน์ (ยกเว้นเมื่อไม่ใช้งานเมื่อฐานเป็น 1)
DLosc

@DLosc 3 = 33 √ (3 ^ 33)ดีสถานการณ์หนึ่งที่คุณสามารถมีเป็นสิ่งที่ต้องการ ที่จริงแล้วเมื่อฉันเขียนสิ่งนี้ฉันรู้ว่าชุดค่าผสมสองชุด (ที่อาจเป็นเพียงสองชุดเท่านั้น) ที่คำตอบของฉันคิดถึงคือ4 = (4^4) √ (4 ^ (4^4))และการแสดงออกที่เทียบเท่ากับ5s ดูเหมือนว่ารากที่ยอมรับกันไม่ได้เพิ่มปัญหามากนักเนื่องจากส่วนใหญ่ของพวกมันถูกใช้เป็นแบบไม่มี ops ใน 0 หรือ 1, no-ops เมื่อรูตเป็น 1 หรือเพื่อยกเลิกพลังงาน
KSab

3

Python 3 - 349 346

r=range
l=lambda s:eval("lambda a"+s)
def T(u,f,X,Y):
    try:return u(f(X,Y))
    except:0
c=l(',x:{x}.union(*[{u(int("1"*a)*x)}|{T(u,f,X,Y)for j in r(1,a)for X in c(j,x)for Y in c(a-j,x)for f in[l(",b:a%sb"%o)for o in{"**"}|set("+-*/")]+[l(",b:a**b**-1")]}for u in[l(":-a")]+[l(":a**.5**%i"%k)for k in r(9)]])')
R=l(",i:[{n+1}<c(i,a)for n in r(10)]")

นี่เป็นเวอร์ชั่นที่ค่อนข้างไม่อวดดี:

def R(x,i):
    # Unary Operations
    U = [lambda a:-a] + [eval("lambda a:a**(1/2.**%i)" % j) for j in range(9)]
    # Binary Operations
    F = [eval("lambda a,b:a%sb"%o) for o in ["+","-","*","/","**"]] + [lambda a,b:a**(1./b)]

    def combos(i):
        L = {x}
        for u in U:
            # 3, 33, 333, etc.
            L |= {u(int(str(x)*i))}

            for j in range(1,i):
                for X in combos(j):
                    for Y in combos(i-j):
                        for f in F:
                            # To avoid trouble with division by zero, overflows and similar:
                            try:
                                L |= {u(f(X,Y))}
                            except:
                                pass
        return L

    return [n in combos(i) for n in range(1,11)]

สำหรับการทดสอบฉันขอแนะนำให้เปลี่ยน(9)บางสิ่งให้เล็กลงเนื่องจากนี่เป็นจำนวนรากที่สองที่คำนึงถึงซึ่งมีผลกระทบอย่างมากต่อประสิทธิภาพ

ในที่สุดสิ่งนี้ทำให้ฉันสงสัยว่าจำเป็นต้องลบเอกภาพหรือไม่ในบางกรณี ...


1
ฉันคิดว่าคุณพูดถูกเกี่ยวกับพวก unary '-' อาจจะไม่เพิ่มอะไรเลย (อย่างน้อยก็คำถามพื้นฐานโดยไม่มีโบนัส) สถานการณ์ที่ไม่สำคัญเพียงอย่างเดียวที่ฉันสามารถนึกได้ว่าจะเป็นเช่น1 = 3^3 * 3^(-3)นั้น แต่เมื่อพิจารณาถึงสิ่งเหล่านี้ฉันก็ยังสงสัยว่ามีตัวเลขใดบ้างที่เป็นวิธีแก้ปัญหาที่เป็นไปได้เมื่อไม่มีคนอื่น
KSab

1
คุณสามารถบันทึก 3 ไบต์โดยใช้a**.5**%iแทนa**(1/2**%i)การคำนวณรากที่สองหลาย
DLosc

@DLosc: แน่นอนขอบคุณ
Wrzlprmft

คุณสามารถบันทึกหกไบต์ได้โดยลดการเว้นวรรคสี่ส่วนให้เหลือหนึ่งช่องว่าง
สลายตัวเบต้า

@BetaDecay: ฉันไม่เคยใช้การเยื้องสี่ช่องว่าง (ตัวสั่น) ฉันใช้แท็บ ดูที่แหล่งที่มาของโพสต์ของฉัน การแลกเปลี่ยนแบบสแต็กจะแสดงผลเป็นสี่ช่องว่าง
Wrzlprmft

2

Mathematica - 246 ตัวอักษร (ไม่มีการอ้างสิทธิ์โบนัส)

f[x_,y_]:=x-y
g[x_,y_]:=x/y
h[x_,y_]:=x^(1/y)
j[x_,y_]:=FromDigits@Join[IntegerDigits@x,{y}]
z[{r_,n_,L_}]:=z[{L[[1]][r,n],n,Rest@L}]
z[{r_,n_,{}}]:=r
a[n_,t_]:=Union@Select[z[{n,n,#}]&/@Tuples[{Plus,f,Times,g,Power,h,j},t-1],IntegerQ@#&&0<#<11&]

คำอธิบาย

ฟังก์ชัน jต่อตัวเลขสองตัวเข้าด้วยกัน

ฟังก์ชั่นzรับผลลัพธ์rจำนวนnและรายการของฟังก์ชั่นLซึ่งแต่ละฟังก์ชั่นการทำงานในสองข้อโต้แย้ง จากนั้นจะใช้รายการฟังก์ชันตามลำดับเพื่อหาเรื่อง[r,n]โดยใช้การเรียกซ้ำจนกระทั่งรายการว่างเปล่าจากนั้นจะส่งคืนผลลัพธ์

ฟังก์ชั่นaใช้เวลาเป็นจำนวนมากและจำนวนของสำเนาn tมันสร้างความยาวของ tuples ทั้งหมด (t-1) จากรายการฟังก์ชัน{Plus, f, Times, g, Power, h, j}และส่งแต่ละ tuple ผ่าน function z จากนั้นส่งคืนรายการหมายเลขทั้งหมด 1 ถึง 10 ที่สร้างขึ้น

การดำเนินการเช่นการกลับมาa[2,3]{1, 2, 3, 6, 8}

ข้อ จำกัด

เนื่องจากมีการใช้รายการฟังก์ชั่นตามลำดับโดยใช้จำนวนสำเนาหนึ่งชุดในแต่ละครั้งจึงอาจพลาดบางชุดค่าผสม ตัวอย่างเช่นเมื่อใช้งานบนสี่ twos มันจะพลาด 22/22 = 1 เนื่องจากไม่สามารถประเมินรายการฟังก์ชันที่ไม่เป็นระเบียบได้ แน่นอน 2/2 * 2/2 = 1 ครอบคลุมกรณีนี้

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