Matematik Metagolf Mania!


12

Mathemania Özellikleri:

Mathemania kodunun her parçası numarayla başlar 2. 'Den, 2aşağıdaki işlemleri yapabilirsiniz:

  • e: Üs. Bu komutun varsayılan değeri sayıyı kareleridir.
  • f: Faktöriyel. Bu komutun varsayılan değeri, sayıdaki ( using f on 2 = 2! = 2) tek faktöriyeli kullanmaktır .
  • r: Kök. Bu komutun varsayılan değeri sayının kare köküdür.
  • c: Tavan fonksiyonu.
  • l: Zemin fonksiyonu.

Mathemania'da bir sayı oluşturmak için, sayı üzerinde soldan sağa gerçekleştirilen bu komutları bir araya getirmelisiniz 2.

Örnekler:

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, fVe rkomutları (aynı zamanda ile başlamak ilave Mathemania komutları ile değiştirilebilir 2fonksiyonu değişmiş sonra parantez yerleştirilmesi ve içinde Mathemania komutları yerleştirerek, farklı üs alma, faktöriyel ve kökler üretmek için onun "temel" numarası).

Örneğin, bunun yerine o kare alma bir dizi küp için, sizin için komutu koyabilirsiniz 3sonra eşöyle:

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

NOT: amacımız için, faktöryel komut ( f) 2tek faktörlü olarak başlar . Yani bunu yaparsanız f(efrrc), üçlü faktöriyel değil, çift faktöriyeli değerlendirilir.

İçin n-factorials (örneğin çift faktöriyel = 2 faktörlü, üç faktör = 3 faktörlü vs.), baz numarası olan numara ile çarpılır naz bunun altında ve nve böylece nihai sayısı vermeye kadar üzerine, daha az daha nOlmadan 0veya negatif olmadan çıkarılır .

Örneğin:

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)

Daha fazla bilgi için buraya bakın .

Her yere yerleştirebilirsiniz ve Mathemania tarafından tek bir işlev olarak ele alınacaktır:

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

Bunları iç içe yerleştirmenize de izin verilir:

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

Mathemania kodunun bir tercümanı için buraya tıklayın (şerefe, @ BradGilbertb2gills!)

Görev:

Göreviniz ngirdi olarak pozitif bir tamsayı verildiğinde yürütüldüğünde geri dönen bir Mathemania programı oluşturan bir program oluşturmaktır n.

Ancak, üretmek Mathemania programları mümkün olduğunca (golfed) küçük olarak olmalı, ve son puan tam sayılardır numunenin oluşturulan Mathemania programlarda bayt sayısı toplamı ile belirlenir 10,000için 10,100. En düşük puan kazanır.

Kurallar ve teknik özellikler:

  • Programınız zorunluluk çıkışı herhangi bir pozitif tamsayı için geçerli bir Mathemania programı, ama sadece sayılar arasındaki 10,000ve 10,100test edilecektir.
  • Tamsayı ile sonuçlanmayan Mathemania programlarının çıktısını almanıza izin verilmez. Bunu yaparsanız, programınız diskalifiye edilir.
  • Komutlar için e, fve r, (örneğin, bu işlevleri içinde Mathemania kodu e(efrrc), efrrcişlev içinde kodudur) üzerinde pozitif bir tamsayı değerlendirmelidir 2. Programınız bu kurala uymuyorsa, diskalifiye edilir.
  • Programınız, modern bir dizüstü bilgisayarda en fazla 30 dakika içinde 101 test tamsayısının herhangi biri için bir Mathemania programı döndürmelidir.
  • Programınız her çalıştırıldığında herhangi bir tamsayı için aynı çözümü döndürmelidir. Örneğin, bir program bir girdi verildiğinde 5ve çıktılandığında efrc, her girdi 5verildiğinde çıktı alınmalıdır .
  • Pozitif tamsayı için herhangi bir çözümü kodlayamazsınız.
  • Çıktınızdaki golf potansiyelini en üst düzeye çıkarmak için, programınız keyfi olarak büyük tamsayıları işleyebilmelidir. Diliniz bunu desteklemiyorsa iyi şanslar olsa da, bu bir gereklilik değildir.

Bu , bu yüzden en düşük puan kazanır!


2
Bir yazdım bu dil için değerlendirici içinde Perl 6 TIO Nexus'taki.
Brad Gilbert b2gills

@ BradGilbertb2gills Vay canına, teşekkürler! Meydan okumaya bir link koyacağım.
clismique

Giriş eförneğin ise, kodun "atlama" ya izin vermesi ve sadece efişlemden önce sonucun çıktısını alması mümkün mü?
devRicher

@devRicher "ef" programının önceden sabit olarak kodlandığını kastediyorsanız, geçerli kurallar altında, evet, bunu yapmanıza izin verilir, çünkü "ef" 10.000 ila 10.100 aralığında değildir. Ne demek istediğinden emin değilim ve kuralları değiştirebilirim çünkü hardcoding zorluğu çok kolay hale getiriyor IMO.
clismique

1
Son birkaç saattir bu meydan okuma için bir program yazıyorum. Ben çalışma kodu var, ama tam olarak düzgün test edemiyorum çünkü faktöriyeliler tarafından üretilen bazı sayılar kesinlikle büyük ve Python (benim program ve yorumlayıcı var) kendi kare kök alamaz. Bu noktada programla ne yapacağımdan tam olarak emin değilim. Bir yan notta, aslında yanlış anladım ve ALL 101 test vakalarının, imkansız gibi görünen zaman sınırına uyması gerektiğini düşündüm. Herhangi biri çok daha makul görünüyor.
notjagan

Yanıtlar:


1

Python 3.5, Skoru ??

Şu an itibariyle, 101 girişin tümü için çıktı yok, ancak programı tüm test senaryoları için çalıştırdığımda puanımla güncelleyeceğim.

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)

Ayrıca, çok sayıda boyutu nedeniyle denediğim bazı test durumlarının çıktılarını doğrulayamadım ve bu noktada @ BradGilbertb2gills'in çevrimiçi yorumlayıcısı zaman aşımına uğradı. Umarım tüm çıktılar çalışır.


Python 2'de (muhtemelen 3) burada keyfi hassasiyetle başa çıkması gereken bir tercümanım var . Çalıştırmak için kopyalayıp IDE'nize yapıştırın.
clismique

Çıktıların bazıları nelerdi, böylece onu optimize edebildim.
Brad Gilbert b2gills
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.