Математика Метагольф Манія!


12

Математичні характеристики:

Кожен фрагмент коду Mathemania починається з числа 2. З цього 2пункту Ви можете виконати наступні операції:

  • e: Експоненція. За замовчуванням для цієї команди відбувається порівняння числа.
  • f: Факторський. За замовчуванням для цієї команди використовується єдиний фактор на число ( using f on 2 = 2! = 2).
  • r: Корінь. За замовчуванням цієї команди - це квадратне коріння числа.
  • c: Стельова функція.
  • l: Функція підлоги.

Щоб створити число в Mathemania, ви повинні з'єднати ці команди, які виконуються зліва направо на число 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

В e, fі rкоманди можуть бути змінені з допомогою додаткових команд Mathemania (які також починають з в 2якості «базового» номера) для створення різного зведення в ступені, факториалов і коренів, поміщаючи дужки після зміненої функції і розміщення команд Mathemania всередині нього.

Наприклад, для куба числа замість того, щоб складати його, ви можете поставити команду для 3після eподібного:

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

ПРИМІТКА. Для нашої мети командна команда ( f) починається з 2одного фактора. Отже, якщо ви це зробите 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 що ви породжує повинна бути як малі (golfed) , наскільки це можливо, і ваш підсумковий результат визначається сумою числа байт в згенерованих програмах Mathemania зразка, які є цілими числами 10,000в 10,100. Виграє найнижчий бал.

Правила та характеристики:

  • Ваша програма повинна вивести дійсну програму Mathemania для будь-якого додатного цілого числа, але тільки числа між 10,000і 10,100буде перевірена.
  • Вам заборонено виводити програми Mathemania, які не призводять до цілого числа. Якщо ви це зробите, вашу програму дискваліфікують.
  • Для команд e, fі r, код Mathemania всередині цих функцій (наприклад e(efrrc), коли efrrcце код всередині функції) повинен оцінювати з позитивним цілим числом вище 2. Якщо ваша програма не дотримується цього правила, вона також буде дискваліфікована.
  • Ваша програма повинна повернути програму Mathemania для будь-якого з 101 тестових чисел не пізніше 30 хвилин на сучасному ноутбуці.
  • Програма повинна повертати те саме рішення для будь-якого цілого числа кожного разу, коли воно запускається. Наприклад, коли програмі дається вхід 5і вона виводить efrc, вона повинна виводити щоразу, коли вводиться вхід 5.
  • Ви не можете жорстко кодувати будь-які рішення для будь-якого додатного цілого числа.
  • Для того, щоб максимально використати потенціал для гольфу у ваших результатах, ваша програма повинна мати можливість обробляти довільно великі цілі числа. Це не є вимогою, хоча удачі, якщо ваша мова цього не підтримує.

Це , тому найнижчий бал виграє!



@ BradGilbertb2gills Нічого собі, дякую! Я покладу посилання на виклик.
клісмік

Якщо вхід є, efнаприклад, чи дозволено код "пропустити" та просто вивести результат перед efоперацією?
devRicher

@devRicher Якщо ви маєте на увазі, що програма "ef" заздалегідь жорстко закодована, то, згідно з чинними правилами, так, вам це дозволяється, тому що "ef" не знаходиться в діапазоні від 10000 до 10000. Я не впевнений, що це саме ви мали на увазі, і я можу змінити правила, оскільки жорстке кодування дуже легко справляється з проблемою, IMO.
клісмік

1
Я писав програму для цього виклику протягом останніх кількох годин. Я думаю, що у мене є робочий код, але я не можу точно перевірити його належним чином, оскільки деякі числа, створені фабрикаціями, абсолютно величезні, і Python (де я маю свою програму та інтерпретатор) не може прийняти їх квадратний корінь. Я не зовсім впевнений, що робити з програмою на даний момент. Зі сторони, я спочатку неправильно читав і вважав, що ВСІ 101 тестові випадки повинні відповідати за певний строк, що здавалося майже неможливим. Будь-який здається набагато розумнішим.
notjagan

Відповіді:


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, щоб запустити його.
клісмік

Які були результати, щоб я міг оптимізувати його.
Бред Гілберт b2gills
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.