Matematica Metagolf Mania!


12

Specifiche della Mathemania:

Ogni pezzo di codice Mathemania inizia con il numero 2. Da 2, è possibile eseguire le seguenti operazioni:

  • e: Esponenziazione. L'impostazione predefinita di questo comando è la quadratura del numero.
  • f: Fattoriale. L'impostazione predefinita di questo comando utilizza il singolo fattoriale sul numero ( using f on 2 = 2! = 2).
  • r: Radice. L'impostazione predefinita di questo comando è il rooting quadrato del numero.
  • c: Funzione soffitto.
  • l: Funzione Floor.

Per generare un numero in Mathemania, è necessario mettere insieme questi comandi, che vengono eseguiti da sinistra a destra sul numero 2.

Esempi:

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

I e, fei rcomandi possono essere modificati da comandi Mathemania supplementari (che si aprono anche via con 2il suo numero "base") per generare differenti exponentiations, fattoriali e radici mettendo parentesi dopo la funzione alterata e ponendo i comandi Mathemania suo interno.

Ad esempio, per cubare un numero invece di quadrarlo, puoi inserire il comando 3dopo in questo emodo:

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

NOTA: per i nostri scopi, il comando fattoriale ( f) inizia con 2un singolo fattoriale. Quindi, se lo fai f(efrrc), verrà valutato un doppio fattoriale, non un triplo fattoriale.

Per n-fattoriali (ad es. Doppi fattoriali = 2-fattoriali, tripli fattoriali = 3-fattoriali ecc.), Il numero di base viene moltiplicato per il numero che è ninferiore a esso, e ninferiore a quello, e così via fino a quando il numero finale non può essere sottratto da nsenza diventare 0o negativo.

Per esempio:

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)

Per ulteriori informazioni, vedere qui .

Puoi inserirlo ovunque e verrà trattato da Mathemania come una singola funzione:

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

Puoi anche nidificarli uno dentro l'altro:

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

Per un interprete del codice Mathemania, clicca qui (evviva, @ BradGilbertb2gills!)

Compito:

Il tuo compito è creare un programma che, quando viene dato un intero positivo ncome input, genera un programma Mathemania che, una volta eseguito, ritorna n.

Tuttavia, i programmi Mathemania che si genera deve essere il più piccolo (golfed) il più possibile, e il punteggio finale è determinato dalla somma del numero di byte nei programmi Mathemania generati del campione, che sono i numeri interi 10,000a 10,100. Vince il punteggio più basso.

Regole e specifiche:

  • Il tuo programma deve generare un programma Mathemania valido per qualsiasi numero intero positivo, ma verranno testati solo i numeri tra 10,000e 10,100.
  • Non è consentito produrre programmi Mathemania che non generano un numero intero. In tal caso, il programma verrà squalificato.
  • Per i comandi e, fe r, il codice Mathemania all'interno di quelle funzioni (ad esempio e(efrrc), dove il efrrcè il codice all'interno della funzione) deve restituire un intero positivo sopra 2. Se il tuo programma non segue questa regola, viene anche squalificato.
  • Il tuo programma deve restituire un programma Mathemania per uno dei 101 numeri interi di test in un massimo di 30 minuti su un laptop moderno.
  • Il programma deve restituire la stessa soluzione per qualsiasi numero intero ogni volta che viene eseguito. Ad esempio, quando un programma riceve un input 5e viene efrcemesso, deve emetterlo ogni volta che 5viene fornito l'input .
  • Non è possibile codificare alcuna soluzione per qualsiasi numero intero positivo.
  • Al fine di massimizzare completamente il potenziale di golf nel tuo output, il tuo programma dovrebbe essere in grado di gestire numeri arbitrariamente grandi. Non è un requisito, anche se buona fortuna se la tua lingua non lo supporta.

Questo è , quindi vince il punteggio più basso!


2
Ho scritto un valutatore per questa lingua in Perl 6 su TIO Nexus.
Brad Gilbert b2gills

@ BradGilbertb2gills Caspita, grazie! Metterò un link nella sfida.
clismique il

Se l'input è efad esempio, è permesso al codice di "saltare" e di emettere il risultato prima efdell'operazione?
devRicher,

@devRicher Se intendi che il programma "ef" è preventivamente codificato, quindi secondo le regole attuali, sì, ti è permesso farlo, perché "ef" non è compreso tra 10.000 e 10.100. Non sono sicuro che sia quello che volevi dire, e potrei cambiare le regole perché l'hardcoding rende la sfida troppo facile, IMO.
clismique,

1
Ho scritto un programma per questa sfida nelle ultime ore. Penso di avere un codice funzionante, ma non riesco esattamente a testarlo correttamente perché alcuni dei numeri generati dai fattoriali sono assolutamente enormi e Python (dove ho il mio programma e interprete) non può prendere la loro radice quadrata. Non sono sicuro di cosa fare con il programma a questo punto. Da un lato, inizialmente ho letto male e ho pensato che TUTTI i 101 casi di test dovessero adattarsi entro il limite di tempo, il che sembrava quasi impossibile. Qualcuno sembra molto più ragionevole.
notjagan,

Risposte:


1

Python 3.5, Punteggio di ??

Al momento non ho l'output per tutti i 101 input, ma una volta eseguito il programma per tutti i casi di test aggiornerò con il mio punteggio.

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)

Inoltre, non sono stato in grado di verificare i risultati di alcuni dei casi di test che ho provato a causa della mera dimensione del numero, e a quel punto l'interprete online di @ BradGilbertb2gills è scaduto. Speriamo che tutte le uscite funzionino.


Ho un interprete in Python 2 (forse 3) che dovrebbe essere in grado di gestire una precisione arbitraria qui . Copialo e incollalo nell'IDE per eseguirlo.
clismique,

Quali sono stati alcuni degli output in modo che io possa eventualmente ottimizzarli.
Brad Gilbert b2gills il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.