Xuất ra một biểu thức chứng minh cơ sở


21

Lý lịch

Trong một số tương lai có thể, thế giới sẽ chuyển đổi các hệ thống số của họ từ số thập phân (cơ số 10 hoặc b10) sang một số cơ sở khác (nhị phân b2, bát phân b8, thập lục phân b16hoặc thậm chí là đơn nguyên b1, trong trường hợp chúng ta bị lừa!). Do đó, để chuẩn bị cho sự kiện thay đổi thế giới có thể xảy ra này, bạn quyết định chứng minh cơ sở tất cả các chương trình của mình. Điều này có thể được thực hiện bằng cách chỉ sử dụng các số ít 01s kết hợp với các toán tử để thay thế các hằng số hiện có.

Tuy nhiên, chỉ có một vấn đề: Bạn có rất nhiều chương trình để thay đổi và việc chuyển đổi thủ công từng số thành biểu thức sẽ mất vài tuần! Do đó, bạn quyết định viết chương trình (hoặc hàm) để quyết định cho bạn biểu thức nào sẽ thay thế mỗi số.

Đầu vào

Đầu vào sẽ là một số nguyên dương. Mã của bạn phải có khả năng xử lý bất kỳ số nguyên nào lên tới 1000.

(Nếu mã của bạn hỗ trợ số thập phân và / hoặc đầu vào âm, hãy xem Ghi điểm bên dưới.)

Đầu ra

Mã của bạn phải xuất một biểu thức đánh giá đầu vào bằng ít nhất một ngôn ngữ. Đây có thể là bất kỳ ngôn ngữ nào; nó không phải giống với chương trình hoặc hàm của bạn được viết. Ngoài ra, biểu thức này không cần phải là một chương trình hoặc hàm đầy đủ.

Để rõ ràng, đầu ra có thể chứa bất kỳ thao tác nào sau đây:

  • Tăng giảm
  • thêm / tổng
  • trừ / phủ định
  • nhân / nhân đôi (chỉ khi nó không liên quan trực tiếp đến số 2!)
  • chia / modulo
  • số mũ / logarit
  • hình vuông / sqrt (một lần nữa, chỉ khi những thứ này không liên quan trực tiếp đến số 2!)
  • hoạt động bitwise (bOR, bAND, bNOT, bXOR, bit-shift)
  • thiết lập / nhận biến
  • thao tác ngăn xếp

Bạn không thể sử dụng eval()hoặc bất kỳ chức năng tương tự trong đầu ra. Bạn cũng không được sử dụng trong đầu ra bất kỳ chức năng nào thực hiện (các) hành động khác với các chức năng được đề cập ở trên.

Ồ, và một điều nữa: vì chúng tôi muốn đầu ra có giá trị trong càng nhiều cơ sở càng tốt, nên các hằng số duy nhất có thể chứa 01. Các số như 10(mười) không được phép, trừ khi ngôn ngữ diễn giải nó là a 1và a 0. Việc sử dụng các chuỗi để chứa số cũng không được phép, cũng như sử dụng các ký tự như của CJam A- K(đại diện cho 10- 20).

Các trường hợp thử nghiệm

(Tất cả các kết quả đầu ra là JavaScript, nhưng có thể hoạt động bằng các ngôn ngữ khác.)

Đầu vào 1:

2

Đầu ra có thể 1:

1+1

Đầu vào 2:

13

Đầu ra có thể 2:

(a=1+1+1)*a+a+1

Đầu vào 3:

60

Đầu ra có thể 3:

(b=(a=1+1+1+1)*a)*a-a

Đầu vào 4:

777

Đầu ra có thể 4:

(c=(b=((a=1+1+1+1)*a-a+1)*a)*a+b)+c+c-a+1

Đầu vào 5:

1000

Đầu ra có thể 5:

Math.pow((a=1+1+1)*a+1,a)

Chấm điểm

Mục tiêu của thử thách này là rút ngắn sản lượng mã của bạn càng nhiều càng tốt. Điểm của bạn sẽ được tính theo cách này:

  • Điểm cơ bản: Tổng số byte trung bình của tất cả các đầu ra cho các số nguyên từ 1 đến 1000.

  • Điểm thập phân: Nếu mã của bạn hỗ trợ ít nhất 3 vị trí thập phân, thì đây là số byte trung bình của tất cả các đầu ra của chuỗi số bắt đầu từ 0.001và kết thúc tại 1000, tăng theo 1.001từng thời điểm. 0.001, 1.002, 2.003...998.999, 1000.000Sau đó lấy 50% số điểm này.

  • Điểm âm: Nếu mã của bạn hỗ trợ các số âm và bằng 0, thì đây là số byte trung bình của các đầu ra của tất cả các số nguyên từ -1000đến 0. Sau đó lấy 10% số điểm này.

(Cách dễ nhất để tính toán những thứ này có thể là một vòng lặp với chương trình / chức năng của bạn bên trong.)

Điểm cuối cùng của bạn là trung bình của bất kỳ công thức nào được áp dụng ở trên.

Nếu đầu ra không xác định (nghĩa là hơi ngẫu nhiên; nhiều lần chạy với cùng một đầu vào tạo ra nhiều đầu ra duy nhất), thì điểm cho mỗi đầu vào được xác định bởi đầu ra lớn nhất trong mười lần chạy trên CPU của tôi.

Ngoài ra, vì bạn không biết dữ liệu máy tính sẽ quý giá như thế nào trong tương lai, số byte của mã trình tạo của bạn phải nhỏ hơn 512 byte.

Điểm thấp nhất trong hai tuần (vào ngày 30 tháng 9) sẽ được tuyên bố là người chiến thắng. Xin chúc mừng người chiến thắng của bạn, @ThomasKwa !


Bảng xếp hạng

Để đảm bảo câu trả lời của bạn hiển thị chính xác, vui lòng bắt đầu với tiêu đề này:

# Language name/Other language name, X points

Trong trường hợp Xlà số điểm của câu trả lời của bạn. Thí dụ:

# CJam/Pyth, 25.38 points

Nếu bạn có bất kỳ câu hỏi hoặc đề nghị, xin vui lòng cho tôi biết. Chúc may mắn!


Tôi có thể sử dụng các biến giữ 0hoặc 1theo mặc định không?
Dennis

@Dennis Tôi không thấy có vấn đề gì với điều đó, vì vậy hãy tiếp tục!
Sản phẩm ETH

Tôi giả sử tôi không thể thực hiện chuyển đổi cơ sở giữa cơ sở 2 và cơ sở mặc định.
Màu xanh

@muddyfish Không, không cho phép chuyển đổi cơ sở trong đầu ra.
Sản xuất ETH

Tôi đoán chúng ta cũng không được phép sử dụng một cái gì đó như thế Integer.parseInt("1000", 1+1+1+1+1+1+1+1+1+1)nào? Tôi khá chắc chắn parseIntchỉ sử dụng các hoạt động được phép ;-)
Paŭlo Ebermann

Câu trả lời:


10

Mã máy Python / Zilog Z80, 11.653 11.488

import math,numpy as np
def R(n):
    if n==0:return []
    if n<0:return -R(-n)
    e=int(math.log(n,2))
    if n >= 5/3 * 2**e:
        return np.append(2**(e+1),-R(2**(e+1)-n))
    return np.append(2**e,R(n-2**e))

def strR(n):
    b = R(n)
    s = ""
    if n==0:return s
    e=max(abs(b))
    while e:
        if e in b:s+="#"
        elif -e in b:s+="+"
        s+=")"
        e//=2
    return s[:-1]

Tiền thưởng: Số âm.

Giả sử rằng hlcặp thanh ghi ban đầu giữ 0 và trả về kết quả tronghl .

Chỉ có ba hướng dẫn này được sử dụng:

ASCII   Hex    Instruction
--------------------------
#       23     inc hl
)       29     add hl,hl
+       2B     dec hl

Chúng tôi sử dụng một sửa đổi nhỏ của đại diện nhị phân cân bằng trọng lượng tối thiểu BBR2 . Vì BBR2 giảm thiểu trọng số (số chữ số khác 0), nhưng chúng tôi muốn giảm thiểu trọng số cộng với số lần dịch chuyển bit, chúng tôi thay đổi hằng số trong thuật toán từ 3/2sang5/3 .

Để tính điểm và xác minh, sử dụng mã này:

def verify(n):
v = 0
for c in strR(n):
    if c=="#":v += 1
    elif c=="+":v -= 1
    else: v *= 2
return v==n

print(0.5*(sum([len(strR(n)) for n in range(1,1001)])/1000 + \
           sum([len(strR(n)) for n in range(-1000,1)])/1001 * 0.9))

print(all([verify(n) for n in range(-1000,1001)]))

Ví dụ đầu ra:

strR(486)
         '#)))))+)+))+)'

Hoặc trong lắp ráp:

inc hl \ add hl,hl \ add hl,hl \ add hl,hl \ add hl,hl \ add hl,hl \ dec hl \ add hl,hl \ dec hl \ add hl,hl \ add hl,hl \ dec hl \ add hl,hl

Các chương trình ví dụ khác:

-256  +))))))))
-255  +))))))))#
-254  +)))))))#)
-253  +)))))))#)#
-252  +))))))#))
-251  +))))))#))#
-250  +))))))#)#)
-249  +)))))#)))+
-248  +)))))#)))
-247  +)))))#)))#
-246  +)))))#))#)
-245  +)))))#))#)#
-244  +)))))#)#))
-243  +)))))#)#))#
-242  +))))#)))+)
-241  +))))#))))+

  -5  +))+
  -4  +))
  -3  +)+
  -2  +)
  -1  +
   0  
   1  #
   2  #)
   3  #)#
   4  #))
   5  #))#

Tối ưu hóa có thể: Các quy tắc OP cho phép inc hvà các dec hhướng dẫn, trực tiếp thay đổi byte trên hl, là bất hợp pháp, sla hvà không có giấy tờ sl1 h(bit trái dịch chuyển 1 trên hca đó trong một 01tương ứng) được cho phép. sla hsl1 hlà hai byte mỗi, nhưng đôi khi chúng có thể rút ngắn đầu ra.


Rất đẹp, thấp nhất cho đến nay! Tôi đoán đây là một ví dụ trong đó mã máy tinh khiết có ích. ;)
Sản phẩm ETH

2
+1 điều này có lẽ là vô địch. Ngoài ra đối với thiên tài sử dụng mã máy (trên cpu với bộ hướng dẫn phần lớn 8 bit và một số thanh ghi 16 bit.)
Level River St

Thật kỳ lạ khi +dịch sang dec. Tôi tiếp tục đọc các ví dụ tiêu cực sai.
Sản xuất ETH

9

CJam / CJam, 143.263 42.713 28.899 23.901 21.903 20.468

ri
[
    ['X\2b1>e`{~{"1)*)"*}{_({(')*1\"m<"}{"1)*"*}?}?}/]s
    "X1)*"/"1)"*
    "1)1)*"/"1)))"*
    "X1)m<"/"1)))"*
    _"1)"/("1):Y"+\'Y*+
]
{,}$0=

Không có tiền thưởng áp dụng.

Dùng thử trực tuyến: chạy mẫu | máy tính điểm | xác minh

Ví dụ chạy

   1 X
   2 1)
   3 1))
   4 1)))
   5 1))))
   6 1))1)*
   7 1))1)*)
   8 X1))m<
   9 1)))1)*)
  10 1))))1)*
  11 1))))1)*)
  12 1))1)m<
  13 1))1)*1)*)
  14 1))1)*)1)*
  15 1))1)*)1)*)
  16 X1)))m<
  17 X1))m<1)*)
  18 1)))1)*)1)*
  19 1)))1)*)1)*)
  20 1))))1)m<
 981 1):Y)Y*)Y*)Y*Y*)Y*Y*)Y*Y*)
 982 1):Y)Y*)Y*)Y*Y*)Y*Y*)Y*)Y*
 983 1):Y)Y*)Y*)Y*Y*)Y*Y*)Y*)Y*)
 984 1):Y)Y*)Y*)Y*Y*)Y*)Y)m<
 985 1):Y)Y*)Y*)Y*Y*)Y*)Ym<Y*)
 986 1):Y)Y*)Y*)Y*Y*)Y*)Y*Y*)Y*
 987 1):Y)Y*)Y*)Y*Y*)Y*)Y*Y*)Y*)
 988 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Ym<
 989 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Y*Y*)
 990 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Y*)Y*
 991 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Y*)Y*)
 992 1):Y)Y*)Y*)Y*)Y)))m<
 993 1):Y)Y*)Y*)Y*)Y))m<Y*)
 994 1):Y)Y*)Y*)Y*)Y)m<Y*)Y*
 995 1):Y)Y*)Y*)Y*)Y)m<Y*)Y*)
 996 1):Y)Y*)Y*)Y*)Ym<Y*)Ym<
 997 1):Y)Y*)Y*)Y*)Ym<Y*)Y*Y*)
 998 1):Y)Y*)Y*)Y*)Ym<Y*)Y*)Y*
 999 1):Y)Y*)Y*)Y*)Ym<Y*)Y*)Y*)
1000 1):Y)Y*)Y*)Y*)Y*Y*)Y)m<

Lời của tôi, thật nhanh! Các liên kết không hoạt động trong Firefox, mặc dù.
Sản phẩm ETH

Vì đây không phải là mã golf, tôi thay thế %bằng một biểu thức dài hơn. Các liên kết nên làm việc bây giờ.
Dennis

Đầu vào 34 cho 1. Trên đó đầu vào nào hoạt động tốt hơn
Kishan Kumar

2
@KishanKumar Việc xác minh kiểm tra tất cả 1000 đầu vào có thể. Kết quả 1 chỉ ra rằng sự so sánh đã thành công.
Dennis

Bạn có thể thêm một số ví dụ đầu ra?
Paŭlo Ebermann

3

ß / BrainFuck, 34.201 điểm

nguồn ß (194B):

E='++[------>+<]>++'°\c[1]<0°{E&='.'µA=ß"-ß°°c[1]),'')µE&='+++'°/B=1°(A[0]°\A[B]='.'°{µE&='--.++'°]E&=ß~A'+',A[B])&'.'&ß~A'-',A[B])°}°)°'ß"&E,'+-')+ß"&E,'-+')>0µE=ß"'ß"'E,'-+',''),'+-','')°!€E)

Nếu ai đó quan tâm, tôi sẽ thêm một lời giải thích. Đầu ra BF đã được tối ưu hóa khá nhiều, nhưng tôi đoán tôi có thể sử dụng mã 318B còn lại để thực hiện

  • tối ưu hóa vòng lặp lồng nhau,
  • nhiều phím tắt tràn 8 bit,
  • điều hành va chạm loại bỏ .

Mẫu:

Chạy trong cửa sổ:

$ sharps encode.ss 42
++[------>+<]>+++++++++.--.--

$ sharps encode.ss -42
++[------>+<]>++.+++++++.--.--

$ sharps encode.ss 1.427
++[------>+<]>++++++.---.++++++.--.+++++.-------

$ sharps encode.ss -946.427
++[------>+<]>++.++++++++++++.-----.++.--------.++++++.--.+++++.-------

Chạy trong linux:

$ WINEDEBUG=-all wine sharps source.ss -4.72
++[------>+<]>++.+++++++.------.+++++++++.-----.--

Xác thực trong trình thông dịch BF trực tuyến .

Điểm số:

  1. Trung bình cơ sở = 37.495 .
  2. Trung bình thập phân = 60.959 * 0.5 = ~30.48 .
  3. Tiêu cực avg. = 38.4765234765235 * 0.9 = ~34.629
  4. Trung bình trên, điểm cuối cùng = (37.495 + 30.48 + 34.629)/3 = 34.201.

1
Tôi luôn muốn thấy những ngôn ngữ mới mà mọi người đã tạo ra. :) Cảm ơn vì sự cố điểm số! Tôi muốn đặt thêm phần thưởng cho phần thập phân, vì vậy tôi đã thay đổi mức khấu trừ từ 40% thành 50%.
Sản phẩm ETH

@ETHproductions Vâng, tôi sẽ thử thiết lập một trình thông dịch trực tuyến cho việc này. Có khoảng 435 toán tử trừu tượng cao, có thể xác định thêm 9,9k ;-). Tôi đã sửa chữa tính toán (hy vọng).
mınxomaτ

3

Ruby / Ruby, 29.77885

31.873 * 0.9 (âm) 30.872 (dương).

Chiến lược cơ bản là biểu diễn cơ sở 3 đối xứng ("ternary cân bằng"), tức là khi các chữ số -1,0,1thay vì0,1,2

#function
f=->n{m=n  
  a='0' 
  7.times{|i|
    r=m%3;r-=r/2*3
    m=(m-r)/3
    #produce expression: replace 0 with (0*x+-1)
    #only add 0*x if there are higher base 3 digits to follow.
    #only add (..+-1) if the current base 3 digit is nonzero. 
    a.sub!('0',['','(','('][r]+(m.abs>0?'0*x':'')+['','+1)','-1)'][r])
  }
  #tidy up expression
  a.sub!('(-1)*','-')          #remove internal (-1)*
  a.sub!('(+1)*','')           #remove internal (+1)*
  a[-1]==')' && a=a[1..-2]     #remove unnecessary global brackets
  a.sub!('x','(x=1+1+1)')      #find the first x and define it as 1+1+1=3
  #special cases for small numbers 
  n.abs<8 && a=n==0?'0':['','1'+'+1'*(n-1).abs,'-1'*n.abs][n<=>0] 
  a 
}

#call like this
(1..1000).each{|p|
b=f.call(p)
puts b

Đây là đầu ra từ 0 đến 40 trước khi dọn dẹp

(+1)
((+1)*x-1)
(+1)*x
((+1)*x+1)
(((+1)*x-1)*x-1)
((+1)*x-1)*x
(((+1)*x-1)*x+1)
((+1)*x*x-1)
(+1)*x*x
((+1)*x*x+1)
(((+1)*x+1)*x-1)
((+1)*x+1)*x
(((+1)*x+1)*x+1)
((((+1)*x-1)*x-1)*x-1)
(((+1)*x-1)*x-1)*x
((((+1)*x-1)*x-1)*x+1)
(((+1)*x-1)*x*x-1)
((+1)*x-1)*x*x
(((+1)*x-1)*x*x+1)
((((+1)*x-1)*x+1)*x-1)
(((+1)*x-1)*x+1)*x
((((+1)*x-1)*x+1)*x+1)
(((+1)*x*x-1)*x-1)
((+1)*x*x-1)*x
(((+1)*x*x-1)*x+1)
((+1)*x*x*x-1)
(+1)*x*x*x
((+1)*x*x*x+1)
(((+1)*x*x+1)*x-1)
((+1)*x*x+1)*x
(((+1)*x*x+1)*x+1)
((((+1)*x+1)*x-1)*x-1)
(((+1)*x+1)*x-1)*x
((((+1)*x+1)*x-1)*x+1)
(((+1)*x+1)*x*x-1)
((+1)*x+1)*x*x
(((+1)*x+1)*x*x+1)
((((+1)*x+1)*x+1)*x-1)
(((+1)*x+1)*x+1)*x
((((+1)*x+1)*x+1)*x+1)

Và sau khi dọn dẹp

0
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
(x=1+1+1)*x-1
(x=1+1+1)*x
(x=1+1+1)*x+1
((x=1+1+1)+1)*x-1
((x=1+1+1)+1)*x
((x=1+1+1)+1)*x+1
(((x=1+1+1)-1)*x-1)*x-1
(((x=1+1+1)-1)*x-1)*x
(((x=1+1+1)-1)*x-1)*x+1
((x=1+1+1)-1)*x*x-1
((x=1+1+1)-1)*x*x
((x=1+1+1)-1)*x*x+1
(((x=1+1+1)-1)*x+1)*x-1
(((x=1+1+1)-1)*x+1)*x
(((x=1+1+1)-1)*x+1)*x+1
((x=1+1+1)*x-1)*x-1
((x=1+1+1)*x-1)*x
((x=1+1+1)*x-1)*x+1
(x=1+1+1)*x*x-1
(x=1+1+1)*x*x
(x=1+1+1)*x*x+1
((x=1+1+1)*x+1)*x-1
((x=1+1+1)*x+1)*x
((x=1+1+1)*x+1)*x+1
(((x=1+1+1)+1)*x-1)*x-1
(((x=1+1+1)+1)*x-1)*x
(((x=1+1+1)+1)*x-1)*x+1
((x=1+1+1)+1)*x*x-1
((x=1+1+1)+1)*x*x
((x=1+1+1)+1)*x*x+1
(((x=1+1+1)+1)*x+1)*x-1
(((x=1+1+1)+1)*x+1)*x
(((x=1+1+1)+1)*x+1)*x+1

Tôi tin rằng nó được gọi là "ternary cân bằng".
lirtosiast

@ThomasKwa đã chỉnh sửa, cảm ơn
Level River St

3

Ceylon / Ceylon, 49,86 40,95 điểm

Phiên bản thứ ba sử dụng Ceylon 1.2 cho trình tạo và 509 byte mã:

import ceylon.language{S=String,I=Integer,e=expand}S q(I n)=>n==0then"0"else(n<0then"-"+p(-n,"-")else p(n,"+"));variable Map<[I,S],S>c=map{};S p(I n,S s){S v=c[[n,s]]else(n<8then s.join([1].repeat(n)))else(let(a="+-".replace(s,""))e(e{for(x in 2..8)let(l=(n^(1.0/x)).integer){for(r in l:2)if(r>1)let(w=r^x){if(w-n<n)"("+p(r,"+")+")^("+p(x,"+")+")"+(w<n then s+p(n-w,s)else(n<w then a+p(w-n,a)else""))}}}).reduce<S>((x,y)=>x.size<y.size then x else y))else"";c=[n,s]in c then c else map{[n,s]->v,*c};return v;}

Nó giảm xuống còn 35,22 điểm, nhưng tôi sẽ không đặt nó trong dòng tiêu đề vì Celyon 1.2 chỉ được xuất bản vào ngày 29 tháng 10. Tôi không nghĩ rằng tôi có thể thực hiện thuật toán này trong Ceylon 1.1 ở kích thước này.). Thêm chi tiết ở dưới đó, ở đây tôi sẽ mô tả phiên bản thứ hai. (Phiên bản đầu tiên có thể được nhìn thấy trong lịch sử - nó chỉ hỗ trợ các số dương, nhưng phù hợp với 256 byte.)

Phiên bản thứ hai

Bây giờ là phiên bản thứ hai, hỗ trợ các số nguyên âm (và 0), và thường tạo ra đầu ra ngắn hơn một chút bằng cách sử dụng thêm -. (Phiên bản này thực sự sử dụng độ dài cho phép, phiên bản đầu tiên đã cố gắng ở dưới 256 byte thay vì 512.)

String proof(Integer n) {
    if (n == 0) { return "0"; }
    if (n < 0) { return "-" + p(-n, "-"); }
    return p(n, "+");
}
String p(Integer n, String sign) {
    if (n < 9) {
        return sign.join([1].repeat(n));
    }
    value anti = (sign == "+") then "-" else "+";
    value root = ((n^0.5) + 0.5).integer;
    return "(" + p(root, "+") + ")^(1+1)" +
       ( (root^2 < n) then sign + p(n - root^2, sign) else
         ((n < root^2) then anti + p(root^2 - n, anti) else ""));
}

Mã có độ dài 487, vì vậy vẫn còn một số không gian để tối ưu hóa hơn sau này. (Ngoài ra còn có rất nhiều dự trữ dưới dạng khoảng trắng và tên biến dài.)

Điểm số:

Total positive: 42652
Average positive:42.652
Total negative: 43653
Average negative: 43.60939060939061
With bonus:39.24845154845155
Overall score: 40.95022577422577

Một số kết quả đầu ra mẫu:

   27:  21: (1+1+1+1+1)^(1+1)+1+1
   28:  23: (1+1+1+1+1)^(1+1)+1+1+1
   29:  25: (1+1+1+1+1)^(1+1)+1+1+1+1
   30:  27: (1+1+1+1+1)^(1+1)+1+1+1+1+1
   31:  29: (1+1+1+1+1+1)^(1+1)-1-1-1-1-1
   32:  27: (1+1+1+1+1+1)^(1+1)-1-1-1-1
   33:  25: (1+1+1+1+1+1)^(1+1)-1-1-1
   34:  23: (1+1+1+1+1+1)^(1+1)-1-1

  -27:  22: -(1+1+1+1+1)^(1+1)-1-1
  -28:  24: -(1+1+1+1+1)^(1+1)-1-1-1
  -29:  26: -(1+1+1+1+1)^(1+1)-1-1-1-1
  -30:  28: -(1+1+1+1+1)^(1+1)-1-1-1-1-1
  -31:  30: -(1+1+1+1+1+1)^(1+1)+1+1+1+1+1
  -32:  28: -(1+1+1+1+1+1)^(1+1)+1+1+1+1
  -33:  26: -(1+1+1+1+1+1)^(1+1)+1+1+1
  -34:  24: -(1+1+1+1+1+1)^(1+1)+1+1


  993:  65: ((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
  994:  63: ((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
  995:  61: ((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
  996:  59: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1-1-1
  997:  57: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1-1
  998:  55: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1
  999:  53: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)
 1000:  55: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)+1

 -993:  66: -((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
 -994:  64: -((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
 -995:  62: -((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
 -996:  60: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1+1+1
 -997:  58: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1+1
 -998:  56: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1
 -999:  54: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)
-1000:  56: -((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:   3: 1+1
    3:   5: 1+1+1
    4:   7: 1+1+1+1
    5:   9: 1+1+1+1+1
    6:  11: 1+1+1+1+1+1
    7:  13: 1+1+1+1+1+1+1
    8:  15: 1+1+1+1+1+1+1+1
    9:  13: (1+1+1)^(1+1)
   10:  15: (1+1+1)^(1+1)+1

    0:   1: 0
   -1:   2: -1
   -2:   4: -1-1
   -3:   6: -1-1-1
   -4:   8: -1-1-1-1
   -5:  10: -1-1-1-1-1
   -6:  12: -1-1-1-1-1-1
   -7:  14: -1-1-1-1-1-1-1
   -8:  16: -1-1-1-1-1-1-1-1
   -9:  14: -(1+1+1)^(1+1)
  -10:  16: -(1+1+1)^(1+1)-1

Như bạn có thể thấy, những cái tiêu cực luôn -dài hơn một byte (hàng đầu ) so với những cái tích cực tương ứng.

Ý tưởng cơ bản giống như chương trình trước: tìm một hình vuông gần số mục tiêu của chúng tôi và đại diện cho gốc của nó và phần còn lại theo cách đệ quy. Nhưng bây giờ chúng tôi cho phép hình vuông của chúng tôi cũng lớn hơn số mục tiêu, sau đó làm cho phần còn lại âm. (Có +0.5thể thay đổi thành một hằng số khác để điều chỉnh thuật toán, nhưng có vẻ như tôi đã đạt được mức tối ưu ở đây - cả 0,4 và 0,6 đều cho kết quả tồi tệ hơn.)

Để làm cho các giá trị âm trở thành âm (và mặt khác có cùng cấu trúc với các giá trị dương, chúng ta chuyển toán tử signcho hàm đệ quy p- đó là "+"hoặc"-" . Chúng ta có thể sử dụng nó cho hàm nối trong các trường hợp tầm thường (ví dụ n <9) đối với phần còn lại nếu nó dương tính và sử dụng dấu ngược lại cho phần còn lại nếu nó âm tính.

Các proofxử lý chức năng là dấu hiệu ban đầu (với một trường hợp đặc biệt cho 0), các pchức năng thực hiện công việc thực tế, với đệ quy.

Phiên bản thứ ba, cho Ceylon 1.2

import ceylon.language { S=String, I=Integer,e=expand }

// output a base-proof Ceylon expression for an integer
// (i.e. using only 0 and 1 as digits).
//
// Question: http://codegolf.stackexchange.com/q/58084/2338
// My Answer:  http://codegolf.stackexchange.com/a/58122/2338
//
// The goal is to produce an expression as short as possible, with
// the code staying under 512 bytes in length.
//
// This approach is to represent a positive integer as a square
// of a positive integer plus some remainder (where the remainder
// can be negative), and for negative integers replace the + on the
// outer level by -.

S q(I n) =>
        n == 0 then "0"
        else (n < 0 then "-" + p(-n, "-")
            else p(n, "+"));

// cache for values of p
variable Map<[I, S],S> c = map { };

// Transforms a positive number into a base-proof term, using
// the given sign for the summation on the outer level.
S p(I n, S s) {
    S v =
    // look into the cache
            c[[n, s]] else (
        // hard-code small numbers
        n < 8 then s.join([1].repeat(n)))
            else
    // do the complicated stuff
    (let (a = "+-".replace(s,""))
            e(e {
                    for (x in 2..8) // try these exponents
                        let (l = (n ^ (1.0 / x)).integer) // \[ sqrt[exp]{n} \] in LaTeX
                            { for (r in l:2) // lowerRoot, lowerRoot + 1
                                    if (r > 1)
                                        let (w = r ^ x)
                                            { if (w-n < n) // avoid recursion to larger or same number
                                                    // format the string as  r^x + (n-w)
                                                    "(" + p(r, "+") + ")^(" + p(x, "+") + ")" +
                                                            (w < n then s + p(n - w, s)
                                                                else (n < w then a + p(w - n, a)
                                                                    else ""))
                                            } } })
            // and now find the shortest formatted string
                .reduce<S>((x, y) => x.size < y.size then x else y))
    // this should never happen, but we can't tell the compiler
    // that at least some of the iterables are non-empty due to the if clause.
            else "";

    // this builds a new cache in each step – quite wasteful,
    // as this also happens when the value was found in the cache,
    // but we don't have more characters remaining.
    //// c = map { [n, s] -> v, *c };
    ///better way:
     c = [n,s] in c then c else map{[n,s]->v, *c}; 
    return v;
}

Phiên bản được đánh gôn (nghĩa là bình luận và khoảng trắng bị xóa) được đăng ở trên cùng, với chính xác 509 byte mã.

Điều này sử dụng nguyên tắc cơ bản giống như phiên bản thứ hai, nhưng thay vì chỉ là hình vuông, nó cũng cố gắng sử dụng số lũy thừa cao hơn (thử số mũ từ 2 đến 8) và sử dụng kết quả ngắn nhất. Nó cũng lưu trữ kết quả, vì nếu không, điều này sẽ chậm đến mức không thể chấp nhận được đối với các số lớn hơn với nhiều cuộc gọi đệ quy.

Ghi điểm:

Total positive: 36622
Average positive: 36.622
Total negative: 37623
Average negative: 37.58541458541458
With bonus:33.826873126873124
Overall score: 35.22443656343656

Cấu trúc thụt lề lớn ở giữa là ba cách hiểu lặp lại lồng nhau, hai bên trong bên trong một biểu thức let. Chúng sau đó không được kiểm tra bằng cách sử dụng hàm mở rộng hai lần và reducehàm tìm thấy chuỗi ngắn nhất trong số các chuỗi đó.

Tôi đã gửi một yêu cầu tính năng để có thể thực hiện điều này trong một lần hiểu.

Bên trong sự hiểu biết, chúng tôi đang xây dựng một chuỗi từ gốc r, số mũ xvà phần còn lại ( n-whoặc w-n).

Các letbiểu hiện và các mapchức năng mới trong Ceylon 1.2. mapcó thể đã được thay thế bằng HashMap(cần thêm nhiều ký tự để nhập, mặc dù có thể sẽ nhanh hơn nữa, vì tôi sẽ không xây dựng bản đồ mới cho mỗi mục nhập mới). Các letbiểu thức như let (w = r ^ x)có thể đã được thay thế bằng cách sử dụng một ifmệnh đề như if(exists w = true then r ^ x)(và sau đó tôi sẽ không cần hai expandcuộc gọi), nhưng điều này vẫn sẽ dài hơn một chút, không phù hợp với 511 byte được phép.

Ở đây, các đầu ra mẫu tương ứng với các đầu ra được chọn ở trên, tất cả chúng ngoại trừ các số thực sự nhỏ đều ngắn hơn:

   27:  15: (1+1+1)^(1+1+1)
   28:  17: (1+1+1)^(1+1+1)+1
   29:  19: (1+1+1)^(1+1+1)+1+1
   30:  21: (1+1)^(1+1+1+1+1)-1-1
   31:  19: (1+1)^(1+1+1+1+1)-1
   32:  17: (1+1)^(1+1+1+1+1)
   33:  19: (1+1)^(1+1+1+1+1)+1
   34:  21: (1+1)^(1+1+1+1+1)+1+1

  -27:  16: -(1+1+1)^(1+1+1)
  -28:  18: -(1+1+1)^(1+1+1)-1
  -29:  20: -(1+1+1)^(1+1+1)-1-1
  -30:  22: -(1+1)^(1+1+1+1+1)+1+1
  -31:  20: -(1+1)^(1+1+1+1+1)+1
  -32:  18: -(1+1)^(1+1+1+1+1)
  -33:  20: -(1+1)^(1+1+1+1+1)-1
  -34:  22: -(1+1)^(1+1+1+1+1)-1-1

  993:  39: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1-1-1-1
  994:  37: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1-1-1
  995:  35: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1-1
  996:  33: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1
  997:  31: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1
  998:  29: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1
  999:  27: ((1+1+1)^(1+1)+1)^(1+1+1)-1
 1000:  25: ((1+1+1)^(1+1)+1)^(1+1+1)

 -993:  40: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1+1+1+1
 -994:  38: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1+1+1
 -995:  36: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1+1
 -996:  34: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1
 -997:  32: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1
 -998:  30: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1
 -999:  28: -((1+1+1)^(1+1)+1)^(1+1+1)+1
-1000:  26: -((1+1+1)^(1+1)+1)^(1+1+1)

    1:   1: 1
    2:   3: 1+1
    3:   5: 1+1+1
    4:   7: 1+1+1+1
    5:   9: 1+1+1+1+1
    6:  11: 1+1+1+1+1+1
    7:  13: 1+1+1+1+1+1+1
    8:  13: (1+1)^(1+1+1)
    9:  13: (1+1+1)^(1+1)
   10:  15: (1+1+1)^(1+1)+1

    0:   1: 0
   -1:   2: -1
   -2:   4: -1-1
   -3:   6: -1-1-1
   -4:   8: -1-1-1-1
   -5:  10: -1-1-1-1-1
   -6:  12: -1-1-1-1-1-1
   -7:  14: -1-1-1-1-1-1-1
   -8:  14: -(1+1)^(1+1+1)
   -9:  14: -(1+1+1)^(1+1)
  -10:  16: -(1+1+1)^(1+1)-1

Ví dụ: bây giờ chúng ta có 1000 = (3 ^ 2 + 1) ^ 3, thay vì 1000 = (6 ^ 2-4) ^ 2-5 ^ 2 + 1.


Tôi đã nhớ sai chương trình hạn chế là 256 byte ... trong 512 khá nhiều có thể được thực hiện. Sẽ thử điều đó sau.
Paŭlo Ebermann

Không, nó nói less than 512. Sou bạn có thể sử dụng tối đa. trong số 511 byte;)
mınxomaτ

Làm thế nào tôi chưa bao giờ nghe nói về ngôn ngữ này?!? : O Nhưng nghiêm túc, giải thích tuyệt vời! Tôi thích hiểu các kỹ thuật mà người khác sử dụng trong câu trả lời của họ. +1
Sản phẩm ETH

@ETHproductions Tôi cũng chỉ đọc về nó khoảng hai tuần trước tại đây trên trang web, và bắt đầu thích nó. Vì vậy, để hiểu rõ hơn về nó, tôi cố gắng trả lời các câu hỏi ở đây bằng Ceylon.
Paŭlo Ebermann

2

Ruby / dc, 20.296 18.414 16.968

Lập trình năng động! Xác định danh sách các hàm, được cung cấp một lệnh dc, trả về một biểu thức mới và giá trị số của biểu thức đó. Sau đó, bắt đầu với tiền đề 1, nó xây dựng một danh sách tất cả các giá trị có thể tiếp cận lên đến và bao gồm cả giá trị mong muốn.

chỉnh sửa:

Đã thêm một hàm cho n-1 và làm cho nó chạy thuật toán qua nhiều lần. Có vẻ như cần 7 đường chuyền để ổn định. Phải rút ngắn một số tên biến để ở trong 512 byte.

chỉnh sửa 2:

Đã thêm các hàm cho n (n-1) , n (n + 1)n ^ 3 khi tôi ở đó. Rút ngắn mã thêm một số, hạ cánh chính xác 512 byte.

N = gets.to_i

fns = [
  ->(n,s){[n-1,   s+'1-']},
  ->(n,s){[n+1,   s+'1+']},
  ->(n,s){[n*2,   s+'d+']},
  ->(n,s){[n*3,   s+'dd++']},
  ->(n,s){[n*~-n, s+'d1-*']},
  ->(n,s){[n*n,   s+'d*']},
  ->(n,s){[n*-~n, s+'d1+*']},
  ->(n,s){[n*n*n, s+'dd**']},
]

lst = []*(N+1)
lst[0..2] = %w[0 1 1d+]

loop do
  prev = lst.dup

  (1..N).each do |n|
    fns.each do |f|
      m,s = f[n, lst[n]]
      lst[m] = s if m <= N && (lst[m].nil? || lst[m].size > s.size)
    end
  end

  break if lst == prev
end

puts lst[N]

Số được tạo:

Đầu ra bao gồm hoàn toàn năm ký tự khác nhau: 1đẩy giá trị 1 trên ngăn xếp; dnhân đôi đỉnh của ngăn xếp; +, -* bật hai giá trị hàng đầu và lần lượt đẩy tổng, hiệu và sản phẩm của chúng. Mỗi biểu thức được tạo chỉ thêm một giá trị vào ngăn xếp sau khi thực hiện.

   1: 1
   2: 1d+
   3: 1dd++
   4: 1d+d+
   5: 1d+d+1+
   6: 1d+dd++
   7: 1d+dd++1+
   8: 1d+dd**
   9: 1dd++d*
  10: 1d+d+1+d+
  11: 1d+d+1+d+1+
  12: 1dd++d1+*
  13: 1dd++d1+*1+
  14: 1d+dd++1+d+
  15: 1d+d+d*1-
  16: 1d+d+d*
  17: 1d+d+d*1+
  18: 1dd++d*d+
  19: 1dd++d*d+1+
  20: 1d+d+d1+*
  21: 1d+d+d1+*1+
  22: 1d+d+1+d+1+d+
  23: 1d+dd**dd++1-
  24: 1d+dd**dd++
  25: 1d+d+1+d*

...

 989: 1d+d+d*d+d1-*1-1-1-
 990: 1d+d+d*d+d1-*1-1-
 991: 1d+d+d*d+d1-*1-
 992: 1d+d+d*d+d1-*
 993: 1d+d+d*d+d1-*1+
 994: 1d+d+d*d+d1-*1+1+
 995: 1d+d+d*d+d1-*1+1+1+
 996: 1d+d+1+dd**d+1-d+d+
 997: 1d+d+1+d+dd**1-1-1-
 998: 1d+d+1+d+dd**1-1-
 999: 1d+d+1+d+dd**1-
1000: 1d+d+1+d+dd**

1
Khá tốt, đánh bại mọi thứ trừ mã máy z80 cho đến nay (ngay cả Dennis 'CJam!). Bạn có nghĩ rằng bạn có thể thêm một -toán tử trong khi vẫn ở trong số byte không?
Sản xuất ETH

@ETHproductions Thế nào? ;) Bây giờ cũng không khó để thêm số âm.
daniero

0

Python 2.6, 78.069 - 66.265 điểm

Gửi câu trả lời của tôi cho giá trị của nó (không nhiều trong trường hợp này ... nhưng chứng minh rõ ràng rằng đối với thử thách này, không đủ để nghĩ đơn giản là kết hợp đầu ra dưới dạng tổng của các giá trị thay đổi bit; khi tính đến việc không có chữ số bên ngoài 0 hoặc 1 có thể xuất hiện ở đầu ra). Tôi có thể quay lại sau với một cách tạo đầu ra khác.

Bản thân mã không quá dài (176 ký tự):

def f(a):return'+'.join(('(1<<%s)'%['0','+'.join('1'*x)][x>0]).replace('(1<<0)','1')for x in[i for i,e in enumerate(bin(a)[::-1][:-2])if int(e)])
print"".join(f(int(input())))

Nó tạo ra đầu ra chính xác nhưng dài dòng:

17
1+(1<<1+1+1+1)

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

Đoạn trích tính điểm:

def f(a):return'+'.join(('(1<<%s)'%['0','+'.join('1'*x)][x>0]).replace('(1<<0)','1')for x in[i for i,e in enumerate(bin(a)[::-1][:-2])if int(e)])
print sum(len("".join(f(i)))for i in range(1000))
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.