数学Metagolf疯狂!


12

Mathemania规格:

Mathemania的每个代码都以数字开头2。从中2,您可以执行以下操作:

  • e:求幂。此命令的默认值是平方。
  • f:阶乘。该命令的默认值是在数字(using f on 2 = 2! = 2)上使用单阶乘。
  • r: 根。该命令的默认值是将数字平方根。
  • c:天花板功能。
  • l:发言权功能。

要在Mathemania中生成数字,您必须将这些命令串在一起,这些命令在number上从左到右执行2

例子:

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

efr命令可以通过额外Mathemania命令(这也与开始被改变2为“碱基”号)通过将括号中的改变的功能后,并把它里面的Mathemania命令以生成不同的求幂,阶乘和根。

例如,要对数字求立方而不是对数字求平方,可以将命令放在3after,e如下所示:

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

注意:出于我们的目的,阶乘命令(f2以单个阶乘开始。因此,如果这样做f(efrrc),它将被评估为双阶乘而不是三阶乘。

对于n-阶乘(例如,双阶乘= 2阶乘,三阶乘= 3阶乘等),基数乘以n小于它的数字,然后n小于该数字,依此类推,直到最终数字不能为减去n而不变成0负数。

例如:

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)

有关更多信息,请参见此处

您可以将其插入任何地方,Mathemania会将其视为单个函数:

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

您还可以将它们嵌套在一起:

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

有关Mathemania代码的解释器,请单击此处(欢呼,@ BradGilbertb2gills!)

任务:

您的任务是创建一个程序,当给定正整数n作为输入时,将生成Mathemania程序,该程序在执行时将返回n

但是,您生成的Mathemania程序必须尽可能小(滚动),并且最终分数取决于样本中生成的Mathemania程序中字节数的总和,即10,000to 的整数10,100。最低分获胜。

规则和规格:

  • 您的程序必须为任何正整数输出有效的Mathemania程序,但只会测试10,000和之间的数字10,100
  • 不允许输出不产生整数的Mathemania程序。如果这样做,您的程序将被取消资格。
  • 对于命令ef并且r,这些功能内部的Mathemania代码(例如e(efrrc),其中,efrrc是在函数内部的代码)的计算结果必须以上的正整数2。如果您的程序不遵循此规则,则它也将被取消资格。
  • 您的程序必须在现代笔记本电脑上最多30分钟内返回101个测试整数之一的Mathemania程序。
  • 您的程序每次运行时必须为任何整数返回相同的解决方案。例如,当给定一个程序输入5efrc输出时,每次给定输入时,它都必须输出5
  • 您可能没有为任何正整数硬编码任何解决方案。
  • 为了使输出中的高尔夫运动潜力最大化,您的程序应该能够处理任意大的整数。这不是必须的,但是如果您的语言不支持的话,也很幸运。

这是,所以最低分获胜!



@ BradGilbertb2gills哇,谢谢!我将在挑战中添加一个链接。
clismique '16

ef例如,如果输入是,是否允许代码“跳过”并仅在ef操作之前输出结果?
devRicher 2016年

@devRicher如果您是指程序“ ef”事先经过硬编码,那么根据当前规则,可以执行该操作,因为“ ef”不在10,000到10,100的范围内。我不确定那不是您的意思,并且我可能会更改规则,因为硬编码使质询方式太容易了,IMO。
clismique 2016年

1
在过去的几个小时中,我一直在为应对这一挑战编写程序。我想我有运行的代码,但是我不能完全正确地对其进行测试,因为阶乘生成的一些数字绝对是巨大的,而Python(我有程序和解释器的地方)不能取其平方根。我目前还不确定该程序如何处理。附带一提,我本来是误读并认为所有101个测试用例都必须在时限内完成,这几乎是不可能的。任何人似乎都更合理。
notjagan

Answers:


1

Python 3.5,分数为??

到目前为止,我还没有所有101个输入的输出,但是一旦我为所有测试用例运行程序,我就会更新分数。

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)

此外,由于数量庞大,我无法验证某些测试用例的输出,因此@ BradGilbertb2gills的在线解释器超时。希望所有输出都能正常工作。


我有在Python 2(可能3)的解释应该能够处理任意精度这里。将其复制并粘贴到您的IDE中以运行它。
clismique

什么是一些输出,以便我可能对其进行优化。
布拉德·吉尔伯特b2gills
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.