Đã đến lúc làm toán


14

Giới thiệu

Đây là một trong những câu đố toán học yêu thích của tôi.

Cho một chữ số (nói 3) và số lần sử dụng chữ số đó (nói 5), tạo ra 10 biểu thức dẫn đến 1, 2, 3, 4, 5, 6, 7, 8, 9 và 10 chỉ bằng +, -, ×,, ^ và (root) (dấu ngoặc được phép hoạt động nhóm).

Ví dụ:

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

Lưu ý rằng tất cả các cách trên đều sử dụng năm 3 và các phép toán và kết quả là 5. Bạn cũng có thể sử dụng số 3 trước để biểu thị một khối lập phương. Tương tự với việc sử dụng 4 trước để biểu thị một gốc thứ tư.

Cũng lưu ý rằng hai 3 có thể được sử dụng để tạo thành 33 hoặc ba 3 có thể được sử dụng để tạo thành 333 và vv.

Thử thách

  • Bạn sẽ được cung cấp hai số (cả hai từ 1 đến 5) dưới dạng đối số hàm, STDIN hoặc đối số dòng lệnh.
  • Số đầu tiên biểu thị chữ số nào sẽ sử dụng và số thứ hai biểu thị số lần chữ số đó được sử dụng trong biểu thức.
  • Chương trình của bạn sẽ xuất ra một mảng có kích thước 10 (hoặc 10 số được phân tách bằng dấu cách) trong đó mỗi phần tử biểu thị cho dù một biểu thức toán học (chỉ sử dụng các toán tử được phép) dẫn đến (index + 1)số có thể hay không sử dụng giá trị trung thực / giả.

Ví dụ: nếu đầu vào là

1 3

Sau đó, đầu ra nên được

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

bởi vì chỉ có 1, 2, 3 và 10 có thể được biểu thị bằng ba 1.

Ghi bàn

  • Đây là một để độ dài mã tối thiểu tính bằng byte sẽ thắng.

Tặng kem

In-em-all [−50]

Trừ 50 từ điểm số của bạn nếu các thành phần mảng đầu ra bằng tổng số kết hợp hợp lý để lấy (index + 1)giá trị thay vì giá trị trung thực hoặc giả.

Ví dụ: nếu chỉ có 3 kết hợp có thể có của năm 3 kết quả là 5, thì mục thứ 4 của mảng đầu ra phải là 3.

Toán cực đoan [−100]

Trừ 100 từ điểm của bạn nếu các phần tử mảng đầu ra chứa ít nhất một trong các biểu thức thực tế dẫn đến (index + 1)giá trị.

Ví dụ, nếu sử dụng năm 3, mảng đầu ra của 4 thứ entry có thể là (3^3 + 3)/(3 + 3), (33 - 3)/(3 + 3)hoặc3 + 3/3 + 3/3

Quá mức [−200]

Trừ 200 từ điểm của bạn nếu các thành phần mảng đầu ra chứa tất cả các kết hợp có thể (cách nhau bởi |). Phần thưởng này được thêm vào đầu phần thưởng Extreme Maths , do đó bạn nhận được tổng cộng −300.

Ví dụ: nếu sử dụng năm 3 giây, phần tử thứ 4 của mảng đầu ra phải là(3^3 + 3)/(3 + 3)|(33 - 3)/(3 + 3)|3 + 3/3 + 3/3

Lưu ý: Bất kỳ hai biểu thức để đạt được cùng một kết quả nên khác nhau về mặt logic với một cách tiếp cận khác nhau trong cả hai biểu thức.

Chẳng hạn, để có được 5 bằng cách sử dụng năm 3, 3 + 3/3 + 3/3giống như 3/3 + 3 + 3/3hoặc 3/3 + 3/3 + 3bởi vì cách tiếp cận tương tự được thực hiện cho mỗi cách tiếp cận. (3^3 + 3)/(3 + 3)(33 - 3)/(3 + 3)khác nhau, vì 30 trong tử số đạt được thông qua các cách tiếp cận khác nhau.

CẬP NHẬT : Sau khi đi qua tất cả các câu trả lời, người ta thấy rằng tất cả các câu trả lời đều có sự không hoàn hảo do các trường hợp cạnh của unary -và. Vì vậy, thiếu những trường hợp cạnh đó được coi là ổn khi có đầy đủ các câu trả lời.

Đây là một câu hỏi khó, nhưng là một câu hỏi khá thú vị.

Chúc bạn chơi golf vui vẻ!


1
Tôi xin lỗi, điều này có thể là ngu ngốc, nhưng làm thế nào để bạn có được 10 chỉ với ba 1giây?
FryAmTheEggman

3
@FryAmTheEggman 11-1
Trình tối ưu hóa

1
À, vậy là tôi chết lặng: p
FryAmTheEggman

4
Đó là một quy tắc rất mơ hồ. Tôi có thể quyết định rằng căn bậc hai của 1, căn bậc hai của căn bậc hai của 1, v.v ... là tất cả các cách tiếp cận khác nhau và tôi có vô số câu trả lời. Là a + b khác với b + a? Là (-a) * (-b) khác với b * a?
frageum

2
Tôi biết điều này, nhưng tôi không thể biểu thị 4 ^ (4 ^ (4 ^ (4 ^ 4))) ở bất kỳ định dạng số thông thường nào - lưu trữ 4 ^ (4 ^ (4 ^ 4)) vì một số nguyên đã cần nhiều bit hơn hơn là có các nguyên tử trong vũ trụ). Vì vậy, trừ khi tôi sử dụng hệ thống đại số máy tính có khả năng xử lý những con số như vậy (nếu có tồn tại), tôi cần coi chúng là những trường hợp đặc biệt. Tuy nhiên, điều này gần như chắc chắn đòi hỏi nhiều nhân vật hơn tôi giành được bởi quá mức cần thiết. Do đó, những giải thưởng này là vô nghĩa trừ khi bạn phần nào loại trừ nhiều căn bậc hai.
Wrzlprmft

Câu trả lời:


1

Python 3 (không hoàn hảo), 449 - 300 = 149

Chịu đựng tất cả những thiếu sót giống như giải pháp của KSab : không có toán tử đơn nguyên, được ngoặc đơn hoàn toàn, chứa các biểu thức tương đương như (1+1)+11+(1+1). Tôi đã loại bỏ các bản sao chính xác bằng cách chuyển kết quả cho set(). Đầu ra có thể xấu hơn một chút để tiết kiệm một vài byte, nhưng tôi thích nó theo cách này. Tôi cũng không làm rễ thứ n vì có vẻ như họ không mua cho bạn nhiều trong vấn đề này.

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 _]

Điều này sẽ mất vài phút để chạy nếu đối số thứ hai là 5. Kiểm tra bằng cách gọi 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 (không hoàn hảo) 493 474 - 300 = 174

Có một số lượng lớn các vấn đề với giải pháp này, đầu tiên là nó bỏ qua mọi số mũ quá lớn (bất kỳ số nào trong đó số mũ lớn hơn 100). Tôi thực sự không nghĩ rằng điều này loại bỏ bất kỳ khả năng nào cho đầu vào nhỏ hơn hoặc bằng 5, nhưng tôi không chắc chắn 100%.

Một điều nữa là nó không xem xét bất kỳ căn bậc hai đơn phương nào, vì nó sẽ trở nên phức tạp (bất kỳ giải pháp nào có bất kỳ số hạng nào bằng 0 hoặc 1 sẽ tạo ra vô số giải pháp). Nó cũng không xem xét bất kỳ phủ định đơn phương nào (biểu tượng '-') cho cùng một lý do, cũng như thực tế là tôi không thực sự chắc chắn nếu câu hỏi yêu cầu.

Tôi cũng đã xem xét tiêu chí nào sẽ quyết định xem hai biểu thức có tương đương nhau không, nhưng tôi không thể tìm ra cách xác định chặt chẽ nó theo cách tôi thấy là trực quan, vì vậy (ít nhất là bây giờ) tôi đã không thực hiện bất cứ điều gì như thế. Điều này không có nghĩa là nó đưa ra khá nhiều kết quả và nó cũng sử dụng dấu ngoặc đơn theo cách khá ngây thơ.

Bên cạnh đó, tôi nghĩ rằng điều này có thể bao gồm dòng mã dài nhất mà tôi đã viết, đặc biệt là trước khi nó được chơi hoàn toàn.

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í dụ: ('v' đại diện cho '√')

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

Tôi tìm thấy một vài điều bạn có thể làm để rút ngắn 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

Tôi xin lỗi, nhận xét đó trông rất tệ :( Dù sao, để giải thích: khi so sánh với 0, tôi đã cố gắng phủ nhận tuyên bố, sau đó trao đổi hậu quả. Tôi cũng tìm thấy một vài nơi để sử dụng |&thay vì orand. có thể được sử dụng để rút ngắn cuộc gọi cuối cùng đến F, nhưng cuộc gọi đó sẽ yêu cầu một số Demorgan và tôi đã hết thời gian, p
FryAmTheEggman

@FryAmTheEggman Ôi thật tuyệt, tôi đã cập nhật câu trả lời của mình với những gì bạn đã đăng và khi có thời gian tôi sẽ xem xét câu cuối cùng. Những điều kiện để kiểm tra tính hợp lệ của đầu vào đã trở nên nặng hơn một chút so với tôi dự kiến: /
KSab

+10 cho sự rực rỡ của lambdas lồng nhau và eval- tôi đã mất khá nhiều thời gian để tìm ra dòng thứ hai của bạn! Tôi nghĩ rằng tôi đã có bạn đánh bại trên "dòng đơn dài nhất", mặc dù. ;) Tôi đồng ý bỏ qua số mũ lớn; thực tế, tôi nghĩ rằng bất kỳ số mũ nào lớn hơn 9 sẽ không hữu ích (ngoại trừ là số không khi cơ sở là 1).
DLosc

@DLosc Vâng, một kịch bản bạn có thể có là một cái gì đó như thế 3 = 33 √ (3 ^ 33). Trên thực tế khi tôi viết điều này, tôi nhận ra rằng hai kết hợp (có lẽ là hai duy nhất?) Mà câu trả lời của tôi bỏ lỡ là 4 = (4^4) √ (4 ^ (4^4))và biểu thức tương đương với 5s. Phải thừa nhận rằng rễ cây dường như không thêm nhiều vấn đề, vì phần lớn trong số chúng được sử dụng như là không hoạt động trên 0 hoặc 1, không-op khi gốc là 1 hoặc chỉ để hủy bỏ một quyền lực.
KSab

3

Trăn 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)]")

Đây là một phiên bản khá vô căn cứ:

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

Để thử nghiệm, tôi khuyên bạn nên thay đổi (9)thành một cái gì đó nhỏ hơn, vì đây là số lượng nhiều căn bậc hai được tính đến, có ảnh hưởng rất lớn đến hiệu suất.

Cuối cùng, điều này khiến tôi băn khoăn, liệu phép trừ unary có thực sự cần thiết trong một số trường hợp


1
Tôi nghĩ bạn nói đúng về unary '-' có thể không thêm bất cứ điều gì (ít nhất là vào câu hỏi cơ bản mà không có tiền thưởng). Kịch bản không tầm thường duy nhất tôi có thể nghĩ sẽ là bất cứ điều gì giống như vậy 1 = 3^3 * 3^(-3), nhưng ngay cả khi xem xét những điều này, tôi nghi ngờ có bất kỳ con số nào mà đây là một giải pháp khả thi khi không có người khác.
KSab

1
Bạn có thể lưu 3 byte bằng cách sử dụng a**.5**%ithay vì a**(1/2**%i)tính toán nhiều căn bậc hai.
DLosc

@DLosc: Thật vậy, cảm ơn.
Wrzlprmft

Bạn có thể lưu sáu byte bằng cách giảm bốn không gian thụt vào một không gian.
Beta Decay

@BetaDecay: Tôi không bao giờ sử dụng thụt lề bốn không gian (shudder), tôi sử dụng các tab. Chỉ cần nhìn vào nguồn bài viết của tôi. Stack Exchange chỉ hiển thị chúng như bốn không gian.
Wrzlprmft

2

Mathematica - 246 ký tự (không yêu cầu tiền thưởng)

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&]

Giải trình

Hàm jnối hai số có chữ số.

Hàm zlấy kết quả r, số nvà danh sách các hàm L, mỗi hàm hoạt động trên hai đối số. Sau đó, nó áp dụng danh sách các hàm tuần tự cho các đối số [r,n]bằng cách sử dụng đệ quy, cho đến khi danh sách trống, sau đó nó trả về kết quả.

Chức năng acó một số nvà một số bản sao t. Nó tạo ra tất cả các bộ dữ liệu có độ dài (t-1) từ danh sách các hàm {Plus, f, Times, g, Power, h, j}và gửi từng bộ dữ liệu qua hàm z, sau đó trả về một danh sách tất cả các số từ 1 đến 10 đã được tạo.

Ví dụ thực hiện a[2,3]trở lại {1, 2, 3, 6, 8}.

Hạn chế

Bởi vì danh sách các hàm được áp dụng tuần tự, tiêu thụ một bản sao của số mỗi lần, nó có thể bỏ lỡ một số kết hợp. Ví dụ, khi hoạt động trên bốn twos, nó sẽ bỏ lỡ 22/22 = 1 do không thể đánh giá danh sách các chức năng không theo thứ tự. Tất nhiên, 2/2 * 2/2 = 1 bao gồm trường hợp này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.