Toán Metagolf Mania!


12

Thông số kỹ thuật Mathemania:

Mỗi đoạn mã Mathemania bắt đầu bằng số 2. Từ 2, bạn có thể thực hiện các thao tác sau:

  • e: Lũy thừa. Mặc định của lệnh này là bình phương số.
  • f: Yếu tố. Mặc định của lệnh này đang sử dụng giai thừa duy nhất trên số ( using f on 2 = 2! = 2).
  • r: Nguồn gốc. Mặc định của lệnh này là căn bậc hai số.
  • c: Chức năng trần.
  • l: Chức năng sàn.

Để tạo một số trong Mathemania, bạn phải xâu chuỗi các lệnh này, được thực hiện từ trái sang phải trên số đó 2.

Ví dụ:

ef = (2^2)! = 4! = 24
rl = floor(sqrt(2)) = floor(1.4...) = 1
er = sqrt(2^2) = sqrt(4) = 2
efrrc = ceil(sqrt(sqrt((2^2)!)))
      = ceil(sqrt(sqrt(24)))
      = ceil(sqrt(4.89...))
      = ceil(2.21...)
      = 3

Các e, frcác lệnh có thể được thay đổi bởi lệnh Mathemania thêm (mà cũng bắt đầu với 2là "cơ sở" số của nó) để tạo exponentiations khác nhau, giai thừa và rễ bằng cách đặt dấu ngoặc sau khi các chức năng thay đổi và đặt các lệnh Mathemania bên trong nó.

Ví dụ: để lập phương cho một số thay vì bình phương nó, bạn có thể đặt lệnh 3sau khi ethích như vậy:

e(efrrc) -> cube a number, "efrrc" = 3

LƯU Ý: với mục đích của chúng tôi, lệnh giai thừa ( f) bắt đầu bằng 2một giai thừa. Vì vậy, nếu bạn làm f(efrrc), điều đó sẽ được đánh giá thành một nhân tử kép, không phải là một nhân tố ba.

Đối với n-factorials (ví dụ: nhân đôi kép = 2 nhân tử, nhân tử ba = 3 nhân tố, v.v.), số cơ sở được nhân với số nnhỏ hơn số đó và nít hơn số đó, cho đến khi số cuối cùng không thể bị trừ bởi nkhông trở thành 0hoặc tiêu cực.

Ví dụ:

7!! = 7 * 5 * 3 * 1 = 105 (repeatedly subtract 2, 1 is the last term as
                           1 - 2 = -1, which is negative)
9!!! = 9 * 6 * 3 = 162 (repeatedly subtract 3, 3 is the last term as
                        3 - 3 = 0, which is 0)

Để biết thêm thông tin, xem tại đây .

Bạn có thể chèn nó vào bất cứ đâu và nó sẽ được Mathemania coi là một hàm duy nhất:

e(efrrc)rc = ceil(sqrt(2^3))
           = ceil(2.82...)
           = 3

Bạn cũng được phép lồng những thứ này vào trong nhau:

e(e(e)) = e(4th power)
        = (2^4)th power
        = 16th power

Đối với một thông dịch viên của mã Mathemania, bấm vào đây (chúc mừng, @ BradGilbertb2gills!)

Bài tập:

Nhiệm vụ của bạn là tạo ra một chương trình, khi được cung cấp một số nguyên dương nlàm đầu vào, sẽ tạo ra một chương trình Mathemania mà khi được thực thi sẽ trả về n.

Tuy nhiên, các chương trình Mathemania mà bạn tạo phải càng nhỏ (golfed) càng tốt, và điểm số cuối cùng của bạn được xác định bởi tổng số byte trong các chương trình Mathemania tạo của mẫu, đó là những số nguyên 10,000để 10,100. Điểm thấp nhất sẽ thắng.

Quy tắc và thông số kỹ thuật:

  • Chương trình của bạn phải xuất ra một chương trình Mathemania hợp lệ cho bất kỳ số nguyên dương nào, nhưng chỉ các số giữa 10,00010,100sẽ được kiểm tra.
  • Bạn không được phép xuất các chương trình Mathemania không dẫn đến số nguyên. Nếu bạn làm như vậy, chương trình của bạn bị loại.
  • Đối với các lệnh e, fr, mã Mathemania bên trong những chức năng (ví dụ e(efrrc), nơi efrrclà mã bên trong hàm) phải đánh giá một số nguyên dương trên 2. Nếu chương trình của bạn không tuân theo quy tắc này, nó cũng bị loại.
  • Chương trình của bạn phải trả lại chương trình Mathemania cho bất kỳ một trong 101 số nguyên kiểm tra nào trong tối đa 30 phút trên máy tính xách tay hiện đại.
  • Chương trình của bạn phải trả về cùng một giải pháp cho bất kỳ số nguyên nào mỗi khi nó được chạy. Ví dụ, khi một chương trình được cung cấp một đầu vào 5và nó xuất ra efrc, nó phải xuất ra mỗi khi đầu vào 5được đưa ra.
  • Bạn không thể mã hóa bất kỳ giải pháp nào cho bất kỳ số nguyên dương nào.
  • Để tối đa hóa tiềm năng chơi gôn trong đầu ra của bạn, chương trình của bạn sẽ có thể xử lý các số nguyên lớn tùy ý. Đó không phải là một yêu cầu, mặc dù may mắn nếu ngôn ngữ của bạn không hỗ trợ điều này.

Đây là , vì vậy điểm số thấp nhất sẽ thắng!


2
Tôi đã viết một người đánh giá cho ngôn ngữ này trong Perl 6 trên TIO Nexus.
Brad Gilbert b2gills

@ BradGilbertb2gills Wow, cảm ơn! Tôi sẽ đặt một liên kết trong thử thách.
clismique

Nếu đầu vào là efví dụ, mã có được phép "bỏ qua" không và chỉ xuất kết quả trước khi efthao tác?
devR Rich

@devR Rich Nếu bạn muốn nói rằng chương trình "ef" được mã hóa cứng trước đó, thì theo các quy tắc hiện hành, có, bạn được phép làm điều đó, bởi vì "ef" không nằm trong phạm vi từ 10.000 đến 10.100. Tôi không chắc đó là ý của bạn, và tôi có thể thay đổi các quy tắc bởi vì mã hóa cứng khiến cho thử thách trở nên quá dễ dàng, IMO.
clismique

1
Tôi đã viết một chương trình cho thử thách này trong vài giờ qua. Tôi nghĩ rằng tôi có mã làm việc, nhưng tôi không thể kiểm tra chính xác nó một cách chính xác bởi vì một số số được tạo bởi các giai thừa là rất lớn và Python (nơi tôi có chương trình và trình thông dịch của tôi) không thể lấy căn bậc hai của chúng. Tôi không chắc chắn phải làm gì với chương trình tại thời điểm này. Bên cạnh đó, ban đầu tôi đã đọc sai và nghĩ rằng TẤT CẢ 101 trường hợp thử nghiệm phải phù hợp trong giới hạn thời gian, điều này dường như là không thể. Bất kỳ một có vẻ hợp lý hơn rất nhiều.
notjagan

Câu trả lời:


1

Python 3.5, Điểm của ??

Cho đến bây giờ tôi không có đầu ra cho tất cả 101 đầu vào, nhưng một khi tôi chạy chương trình cho tất cả các trường hợp thử nghiệm, tôi sẽ cập nhật với điểm số của mình.

from math import *

memoized = {}
same = {}

def _(mathmania, n):
    memoized[n] = mathmania
    return mathmania

def is_prime(n):
    if n == 2:
        return True
    if n % 2 == 0 or n <= 1:
        return False
    for divisor in range(3, int(sqrt(n)) + 1, 2):
        if n % divisor == 0:
            return False
    return True

def pair_key(pair):
    low, high = pair
    diff = high - low
    if diff == 0:
        return 100
    low_done, high_done, diff_done = low in memoized, high in memoized, diff in memoized
    if high_done and memoized[high] == None or low_done and memoized[low] == None:
        return -1
    return (high_done + diff_done + (diff + 1 == low)) * 33 + low / high

def major_pairs(n):
    for i in range(n, int(sqrt(n)), -1):
        d = n / i
        if i - d < d - 1:
            break
        if d == int(d):
            yield (int(d), i)

def fact_key(pair):
    i, f = pair
    if i in memoized:
        if memoized[i] == None:
            return -1
        return 1
    return i / f

def near_fact(n, level):
    s = 4
    if n in same:
        s = same[n]
    for i in range(s, n ** 2 ** level):
        f = factorial(i)
        if f > (n - 1) ** 2 ** level:
            if f < (n + 1) ** 2 ** level:
                same[n] = i
                yield (i, f)
            else:
                return

def generate_mathmania(n):
    if n in memoized and memoized[n] != None:
        return memoized[n]
    memoized[n] = None
    binx = log(n, 2)
    if binx == int(binx):
        if binx == 2:
            return _("e", n)
        if binx == 1:
            return _("er", n)
        if binx == 0:
            return _("rl", n)
        return _("e(" + generate_mathmania(int(binx)) + ")", n)
    sq = sqrt(n)
    if sq == int(sq):
        return _(generate_mathmania(int(sq)) + "e", n)
    low, high = max(major_pairs(n), key=pair_key)
    if pair_key((low, high)) == -1:
        level = 1
        while True:
            try:
                i, f = max(near_fact(n, level), key=fact_key)
            except:
                level += 1
                continue
            if fact_key((i, f)) == -1:
                return _(generate_mathmania((n - 1) ** 2 + 1) + "rc", n)
            if f == n ** 2 ** level:
                return _(generate_mathmania(i) + "f" + "r" * level, n)
            if f < n ** 2 ** level:
                return _(generate_mathmania(i) + "f" + "r" * level + "c", n)
            return _(generate_mathmania(i) + "f" + "r" * level + "l", n)
    if low != 1:
        if low == high:
            return _(generate_mathmania(low) + "e", n)
        if high - low == 1:
            return _(generate_mathmania(high) + "f", n)
        return _(generate_mathmania(high) + "f(" + generate_mathmania(high - low + 1) + ")", n)
    good = None
    for i in range(n ** 2 - 1, (n - 1) ** 2, -1):
        if i in memoized:
            return _(generate_mathmania(i) + "rc", n)
        if not is_prime(i):
            good = i
    if good:
        return _(generate_mathmania(good) + "rc", n)
    for i in range((n + 1) ** 2 - 1, n ** 2, -1):
        if i in memoized:
            return _(generate_mathmania(i) + "rl", n)
        if not is_prime(i):
            good = i
    if good:
        return _(generate_mathmania(good) + "rl", n)
    return _(generate_mathmania((n - 1) ** 2 + 1), n)

Ngoài ra, tôi không thể xác minh kết quả đầu ra của một số trường hợp thử nghiệm mà tôi đã thử do kích thước số tuyệt đối và tại thời điểm đó, phiên dịch trực tuyến của @ BradGilbertb2gills đã hết thời gian. Hy vọng tất cả các đầu ra làm việc.


Tôi có một trình thông dịch trong Python 2 (có thể là 3) để có thể xử lý độ chính xác tùy ý ở đây . Sao chép và dán nó vào IDE của bạn để chạy nó.
clismique

Một số kết quả đầu ra là gì để tôi có thể tối ưu hóa nó.
Brad Gilbert b2gills
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.