Mathe Metagolf Mania!

12

Mathemania Specs:

Jeder Mathemania-Code beginnt mit der Nummer 2. Von der 2aus können Sie folgende Operationen ausführen:

  • e: Potenzierung. Die Standardeinstellung dieses Befehls ist das Quadrieren der Zahl.
  • f: Factorial. In der Standardeinstellung dieses Befehls wird die einfache Fakultät für die Zahl ( using f on 2 = 2! = 2) verwendet.
  • r: Wurzel. Die Standardeinstellung dieses Befehls ist das Quadratwurzeln der Zahl.
  • c: Deckenfunktion.
  • l: Bodenfunktion.

Um eine Zahl in Mathemania zu generieren, müssen Sie diese Befehle, die von links nach rechts für die Zahl ausgeführt werden, aneinanderreihen 2.

Beispiele:

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

Die Befehle e, fund rkönnen durch zusätzliche Mathemania-Befehle geändert werden (die ebenfalls 2als "Basis" -Zahl beginnen ), um unterschiedliche Exponentiale, Fakultäten und Wurzeln zu erzeugen, indem nach der geänderten Funktion eckige Klammern gesetzt und die Mathemania-Befehle darin eingefügt werden.

Um beispielsweise eine Zahl zu würfeln, anstatt sie zu quadrieren, können Sie den Befehl für 3after folgendermaßen eeingeben:

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

HINWEIS: Für unseren Zweck fbeginnt der Fakultätsbefehl ( ) mit 2einer einzelnen Fakultät. Wenn Sie dies tun f(efrrc), wird dies zu einer doppelten Fakultät und nicht zu einer dreifachen Fakultät gewertet.

Für n-Faktoren (z. B. doppelte Fakultäten = 2-Fakultäten, dreifache Fakultäten = 3-Fakultäten usw.) wird die Basiszahl mit der Zahl multipliziert, die nkleiner als sie und nkleiner als diese ist, und so weiter, bis die endgültige Zahl nicht mehr sein kann subtrahiert von nohne zu werden 0oder negativ.

Beispielsweise:

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)

Weitere Informationen finden Sie hier .

Sie können es überall einfügen und es wird von Mathemania als einzelne Funktion behandelt:

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

Sie dürfen diese auch ineinander verschachteln:

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

Klicken Sie hier , um einen Interpret des Mathemania-Codes zu erhalten (Prost, @ BradGilbertb2gills!)

Aufgabe:

Ihre Aufgabe ist es, ein Programm zu erstellen, das bei einer positiven Ganzzahl nals Eingabe ein Mathemania-Programm generiert, das bei Ausführung zurückgibt n.

Die von Ihnen generierten Mathemania-Programme müssen jedoch so klein (golfen) wie möglich sein, und Ihre endgültige Punktzahl wird durch die Summe der Anzahl der Bytes in den generierten Mathemania-Programmen des Beispiels bestimmt, die die ganzen Zahlen 10,000sind 10,100. Die niedrigste Punktzahl gewinnt.

Regeln und Spezifikationen:

  • Ihr Programm muss ein gültiges Mathemania-Programm für eine positive ganze Zahl ausgeben, es werden jedoch nur die Zahlen zwischen 10,000und 10,100getestet.
  • Sie dürfen keine Mathemania-Programme ausgeben, die keine Ganzzahl ergeben. Wenn Sie dies tun, wird Ihr Programm disqualifiziert.
  • Für die Befehle e, fund rdie Mathe Code innerhalb dieser Funktionen ( zum Beispiel e(efrrc), wo der efrrcder Code innerhalb der Funktion ist) , muss auf eine positive Ganzzahl über bewerten 2. Wenn Ihr Programm dieser Regel nicht entspricht, wird es ebenfalls disqualifiziert.
  • Ihr Programm muss ein Mathemania-Programm für eine der 101 Test-Ganzzahlen in höchstens 30 Minuten auf einem modernen Laptop zurückgeben.
  • Ihr Programm muss jedes Mal, wenn es ausgeführt wird, dieselbe Lösung für eine beliebige Ganzzahl zurückgeben. Wenn ein Programm beispielsweise eine Eingabe erhält 5und ausgibt efrc, muss es diese jedes Mal ausgeben, wenn die Eingabe 5erfolgt.
  • Sie dürfen keine Lösungen für eine positive ganze Zahl hartcodieren.
  • Um das Golfpotential in Ihrer Ausgabe vollständig zu maximieren, sollte Ihr Programm in der Lage sein, beliebig große ganze Zahlen zu verarbeiten. Es ist keine Voraussetzung, aber viel Glück, wenn Ihre Sprache dies nicht unterstützt.

Dies ist , also gewinnt die niedrigste Punktzahl!

Clismique
quelle
2
Ich habe einen Evaluator für diese Sprache in Perl 6 auf TIO Nexus geschrieben.
Brad Gilbert b2gills
@ BradGilbertb2gills Wow, danke! Ich werde einen Link in die Herausforderung setzen.
Clismique
Wenn die Eingabe efzum Beispiel ist, darf der Code "überspringen" und nur das Ergebnis vor der efOperation ausgeben ?
DevRicher
@devRicher Wenn Sie meinen, dass das Programm "ef" im Voraus fest programmiert ist, dann dürfen Sie dies nach den aktuellen Regeln tun, da "ef" nicht im Bereich von 10.000 bis 10.100 liegt. Ich bin mir aber nicht sicher, ob Sie das gemeint haben, und ich könnte die Regeln ändern, weil die Herausforderung durch Hardcoding viel zu einfach wird, IMO.
Clismique
1
Ich habe in den letzten Stunden ein Programm für diese Herausforderung geschrieben. Ich glaube, ich habe funktionierenden Code, aber ich kann ihn nicht genau testen, weil einige der von Fakultäten generierten Zahlen absolut riesig sind und Python (wo ich mein Programm und meinen Interpreter habe) ihre Quadratwurzel nicht ziehen kann. Ich bin nicht ganz sicher, was ich mit dem Programm an dieser Stelle anfangen soll. Nebenbei bemerkt, ich habe ursprünglich ALLE 101 Testfälle falsch gelesen und dachte, sie müssten innerhalb des Zeitlimits passen, was so gut wie unmöglich schien. Jeder scheint viel vernünftiger.
Notjagan

Antworten:

1

Python 3.5, Ergebnis von ??

Ab jetzt habe ich nicht die Ausgabe für alle 101 Eingaben, aber sobald ich das Programm für alle Testfälle ausgeführt habe, werde ich mit meiner Punktzahl aktualisieren.

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)

Darüber hinaus konnte ich die Ausgabe einiger der von mir getesteten Testfälle aufgrund der bloßen Zahlengröße nicht überprüfen, und zu diesem Zeitpunkt ist das Zeitlimit für den Online-Interpreter von @ BradGilbertb2gills abgelaufen. Hoffentlich funktionieren alle Ausgänge.

notjagan
quelle
Ich habe einen Interpreter in Python 2 (möglicherweise 3), der hier mit willkürlicher Präzision umgehen kann . Kopieren Sie es und fügen Sie es in Ihre IDE ein, um es auszuführen.
Clismique
Was waren einige der Ausgaben, damit ich es eventuell optimieren konnte.
Brad Gilbert b2gills