Golf a Brain-Flak Integer


28

นัมเบอร์น่าเบื่อที่จะเป็นตัวแทนในBrain-Flak มีผู้ให้บริการ 8 ราย:

()      Evaluates to 1, but does not push anything on any stack
[]      Evaluates to an indeterminate value for the purposes of this question
{}      Removes the top of the stack and evaluates to it
<>      Switches to or back from the alternate stack and evaluates to zero
(foo)   Pushes the value of the expression foo to the stack and evaluates to it
[foo]   Evaluates to the negation of foo
{foo}   Evaluates the expression foo until the top of the stack is zero
<foo>   Evaluates to zero but executes foo anyway

fooอาจประกอบด้วยผู้ให้บริการหลายรายซึ่งในกรณีนี้ผู้ใช้จะได้รับการประเมินและสรุปผล ยกตัวอย่างเช่น(()())ผลัก2ไปที่กอง (และประเมิน2ด้วย)

เห็นได้ชัดว่า(()...())กลไกนี้ไม่มีประโยชน์ใน Code Golf เนื่องจากมีจำนวนมากที่ต้องใช้จำนวนn*2+2ไบต์แทน ความท้าทายของคุณคือการเขียนโปรแกรมหรือฟังก์ชั่นที่จะส่งออกเป็นไบต์น้อยที่สุดเท่าที่เป็นไปได้โปรแกรม Brain-Flak ที่จะส่งจำนวนเต็มบวกที่กำหนดnไปยังสแต็กที่ใช้งานอยู่ โปรแกรมนี้จะต้องไม่ตั้งสมมติฐานใด ๆ เกี่ยวกับเนื้อหาที่มีอยู่ของสแต็คดังนั้นจึงต้องไม่ปล่อยให้สแต็คแลกเปลี่ยนหรือเพิ่มหรือลบค่าเพิ่มเติมจากสแต็ค

แม้ว่าโปรแกรมหรือฟังก์ชั่นของคุณจะต้องสามารถคืนโปรแกรม Brain-Flak ที่ใช้งานได้สำหรับอินพุตทั้งหมดตั้งแต่ 1 ถึง 1,000,000 ผู้ชนะจะเป็นโปรแกรมหรือฟังก์ชั่นที่สร้างชุด Brain-Flak ที่เหมาะสมที่สุดสำหรับจำนวนเฉพาะ 1,061 หมายเลขระหว่าง 1,000 ถึง10,000 คุณควรสังเกตขนาดรวมของผลงานของคุณสำหรับอินพุต 1061 เหล่านั้นเป็นส่วนหนึ่งของการส่งของคุณ โปรแกรมหรือฟังก์ชั่นของคุณอาจยอมรับจำนวนเต็มและส่งกลับ (สตริง) โปรแกรม Brain-Flak ในรูปแบบ I / O ที่ยอมรับได้ตามปกติ ความสัมพันธ์จะถูกทำลายโดยใช้ขนาดของโปรแกรมหรือฟังก์ชั่นของคุณ


4
เช่นเดียวกับโน้ต: จำนวนของโปรแกรมที่ถูกต้องของความยาวคือ2n 4^n catalan(n)
Leun Nun

2
อืมฉันชอบความท้าทาย แต่ฉันคิดว่ามันน่าจะเป็นจำนวนเต็มไม่ทราบ มิฉะนั้นจำนวนเต็มโปรแกรมที่ได้รับคะแนนเมื่ออาจจะเดรัจฉานบังคับและเลขอื่น ๆ (()()()...())เพียงแค่ด้านซ้ายเป็น นอกจากนี้หากคุณใช้ตัวเลขเฉพาะนั่นอาจทำให้พลาดการปรับแต่งที่เหมาะสมสำหรับคอมโพสิต
DJMcMayhem

นอกจากนี้ทำไม[]ไม่ได้กำหนดไว้สำหรับความท้าทายนี้ ฉันคิดว่ามันแปลกที่จะใช้ตัวดำเนินการ 7 ใน 8 ตัว ไม่ว่าจะด้วยวิธีใดความท้าทายยอดเยี่ยมฉันรู้สึกเป็นเกียรติกับใครบางคนที่จะเขียนความท้าทายที่ได้แรงบันดาลใจจากภาษาของฉัน
DJMcMayhem

2
@DJMcMayhem ฉันต้องการให้คนอื่น ๆ สามารถคำนวณคะแนนของตัวเองได้ ตัวเลขสำคัญทั้งหมดที่เกี่ยวข้องนั้นเป็นหนึ่งในจำนวนมากกว่าจำนวนประกอบดังนั้นควรมีการเพิ่มประสิทธิภาพที่เหมาะสม นอกจากนี้ฉันไม่ต้องการให้คนพึ่งพาค่าเฉพาะ[]ในคำตอบของพวกเขา
Neil

1
@YetiCGN ขนาดของสคริปต์นับเป็นตัวแบ่งไทม์เท่านั้น
Neil

คำตอบ:


16

Python 2, 59394 59244 58534 58416 58394 58250

ตกลงนี่คือทางออกของฉัน

import re
import math

cache = {0:"<()>"}

def find(x,i,j):
    return i*((x**2+x)/2)+(j+1)*((x**2-x)/2)

def solve(x, i, j):
    a = (i + j + 1)/2.
    b = (i - j - 1)/2.
    c = -x
    return (-b + math.sqrt(b**2 - 4*a*c))/(2*a)

def size(i,j=0):
    return 4*(i+j)+14

def polynomials(n):
    upperBound = int(4*math.log(n,2))
    i = 0
    answers = []
    while size(i) < upperBound:
        for j in range(i):
            sol = int(solve(n, i-j, j)+.5)
            if find(sol, i-j, j) == n:
                answers.append((sol, i-j, j))
        i += 1
    return answers

def complement(character):
        dict = {"(":")","{":"}","<":">","[":"]",")":"(","}":"{",">":"<","]":"["}
        return dict[character]

def findMatch(snippet, index):
        increment = 1 if snippet[index] in "({<[" else -1
        stack = []
        if snippet[index] in "(){}<>[]":
                stack.append(snippet[index])
        while len(stack) > 0 and index + increment < len(snippet):
                index += increment
                if snippet[index] in "(){}<>[]":
                        if complement(snippet[index]) == stack[-1]:
                                stack = stack[:-1]
                        else:
                                stack.append(snippet[index])
        return index

def isPrime(n):
    return not [0 for x in range(2,int(n**.5)+1) if n%x==0] and n>1

def getPrimeFactors(n):
    return [x for x in range(2,n/2) if n%x==0 and isPrime(x)]

def divHardcode(n,m):
    assert n%m == 0
    assert m != 1
    assert n != 1
    binary = bin(m)[3:]
    return (binary.count("1")+len(binary))*"("+getBF(n/m)+")"*binary.count("1")+binary.replace("1","){}{}").replace("0","){}")

def isTriangular(n):
    #Triangles must be between sqrt(2n) and cbrt(2n)
    if n < 0: return isTriangular(-n)
    for x in range(int((2*n)**(1/3.)),int((2*n)**.5)+1):
        if (x**2+x) == 2*n:
            return True
    return False

def getTriangle(n):
    if n < 0: return -getTriangle(-n)
    #Triangles must be between sqrt(2n) and cbrt(2n)
    for x in range(int((2*n)**(1/3.)),int((2*n)**.5)+1):
        if (x**2+x) == 2*n:
            return x
    #If we don't find one we made a mistake
    assert False

def getSimpleBF(n):
    if n in cache:return cache[n]
    if n < 0:
        # There is room for better solutions here
        return "["+getSimpleBF(-n)+"]"
    elif n == 0:
        return ""
    elif n < 6:
        return "()"*n
    #Non-edge cases
    solutions = []
    factors = getPrimeFactors(n)
    if n >= 78 and isTriangular(n):
        solutions.append(
           min([push(getTriangle(n))+"{({}[()])}{}","<"+push(getTriangle(n)+1)+">{({}[()])}{}"],key=len)
        )
    polynomialSolutions = polynomials(n)
    for polynomial in polynomialSolutions:
        solutions.append("<%s>{%s({}[()])%s}{}"%(push(polynomial[0]),"({})"*polynomial[1],"({})"*polynomial[2]))
        #Mod 3 tricks
    if n % 3 == 2:
       solutions.append(("((%s)()){}{}")%getBF(n/3))
    elif n % 3 == 1:
       solutions.append(("((%s)()()){}{}")%getBF(n/3-1))
    #Basic solutions
    if isPrime(n):
        solutions.append(getSimpleBF(n-1) + "()")
    else:
        #TODO multithread
        solutions += map(lambda m:divHardcode(n,m),factors)
    return min(solutions,key=lambda x:len(unpack(x)))

def getBF(n):
    if n in cache: return cache[n]
    result = getSimpleBF(n)
    index = n - 1
    while index > n-(len(result)/2):
        score = getSimpleBF(index)+getSimpleBF(n-index)
        if len(score) < len(result):result = score
        index -= 1
    index = n + 1
    while index < n+(len(result)/2):
        score = getSimpleBF(index)+getSimpleBF(n-index)
        if len(score) < len(result):result = score
        index += 1
    cache[n] = result
    return result

def unpack(string):
    reMatch = re.match("\(*<",string)
    if reMatch:
        location =reMatch.span()
        return string[location[1]:findMatch(string,location[1]-1)] +string[:location[1]-1] + string[findMatch(string,location[1]-1)+1:]
    return string

def push(n):
    return unpack("("+getBF(n)+")")

def kolmo(string):
    code = push(ord(string[-1]))
    stringVector = map(ord,string)
    for x,y in zip(stringVector[-1:0:-1],stringVector[-2::-1]):
        code = "("+code+getBF(y-x)+")"
    code = code.replace("<()>)",")")
    return code

def kolmo(stringVector):
    code = push(stringVector[-1])
    for x,y in zip(stringVector[-1:0:-1],stringVector[-2::-1]):
        code = "("+code+getBF(y-x)+")"
    code = code.replace("<()>)",")")
    return code


if __name__ == "__main__":
    import primes
    sum = 0
    for prime in primes.nums:
        print push(prime)
        sum += len(push(prime))
    print sum

push(n)ฟังก์ชั่นที่เกี่ยวข้องคือ หากต้องการเรียกเพียงกดหมายเลขที่คุณต้องการแสดง

คำอธิบาย

การปรับให้เหมาะสมหลักที่กระทำโดยโปรแกรมคือการเข้ารหัสแบบฮาร์โค้ด แนวคิดของการเข้ารหัสฮาร์ดโค้ดนั้นค่อนข้างง่าย คุณกดตัวเลขแล้วป๊อปอัพและกดเพื่อสร้างค่าใหม่ ตัวอย่างเช่นการคูณสองคุณสามารถใช้รหัสต่อไปนี้((n){})โดยที่ n code ผลิตตัวเลขเฉพาะ สิ่งนี้ใช้ได้เพราะทั้งคู่(n)และ{}มีค่าเป็น n

ความคิดง่ายๆนี้สามารถทำให้ซับซ้อนขึ้นสำหรับจำนวนที่มากขึ้น Take เช่น 5 (((n)){}){}{}มันถูกค้นพบในขณะที่ที่ผ่านมาว่าวิธีที่ดีที่สุดที่จะคูณด้วยห้าคือ รหัสนี้ทำให้สำเนาสองชุดของ n คูณหนึ่งคูณ 4 และเพิ่มทั้งสอง ใช้กลยุทธ์เดียวกันฉันจะทำให้การคูณทุกครั้งขึ้นอยู่กับการเป็นตัวแทนไบนารีของตัวเลข ฉันจะไม่เข้าไปดูรายละเอียดว่ามันใช้งานได้อย่างไร แต่ฉันทำได้โดยตัดสิ่งแรกของการแทนเลขฐานสองและแทนที่ 0 ด้วย){}และ 1 ด้วย){}{}. จากนั้นตรวจสอบให้แน่ใจว่ามีการผลักจำนวนครั้งที่เหมาะสมและทำให้ยอดคงเหลือในวงเล็บทั้งหมดถูกต้อง (หากคุณต้องการทราบวิธีการทำสิ่งนี้คุณสามารถดูรหัสของฉัน) หากคุณต้องการทราบว่าทำไมงานนี้เพียงแค่ถามฉันในความคิดเห็น ฉันไม่คิดว่ามีใครอ่านการอัปเดตทั้งหมดในโพสต์ของฉันดังนั้นฉันจึงไม่ต้องอธิบาย

เมื่ออัลกอริทึมพยายามค้นหาฮาร์โค้ดการคูณมันจะพยายามหาตัวประกอบจำนวนเฉพาะทั้งหมด มันไม่สนใจปัจจัยประกอบเพราะ ณ จุดหนึ่งปัจจัยประกอบสามารถแสดงให้เห็นชัดเจนกว่าเสมอว่าเป็นปัจจัยสำคัญของตัวเองซึ่งไม่ทราบว่าสิ่งนี้ยังคงเป็นจริง

กลไกการประหยัดไบต์อื่น ๆ คือตัวค้นหาพหุนาม มีรูปแบบพหุนามหลายรูปแบบซึ่งง่ายต่อการแทนด้วยลูปที่ลดลง ชื่อพหุนามเหล่านี้รวมถึง แต่ไม่ จำกัด เฉพาะรูปหลายเหลี่ยม การปรับให้เหมาะสมนี้ค้นหาพหุนามที่พอดีกับแบบฟอร์มและสร้างรหัสที่ทำให้

เอาท์พุต

วางถัง


"ไม่ว่า n จะใหญ่กว่าหรือเล็กกว่า n + 1" ??
Sparr

@ อธิบายว่าการตีความnมีขนาดใหญ่หรือเล็กกว่าn+1
ตัวช่วยสร้างข้าวสาลี

คุณควรยกเลิกการรวมบรรทัดจากif n % 3 == 2: ถึงจุดสิ้นสุดของฟังก์ชันนั้นในระดับหนึ่ง
user202729

13

Brain-Flak, 64664

ลองออนไลน์!

นี่คือรหัสข้อเขียนของฉัน

({}<
 ((((()()()()()){}){}){}()) #41
>)
{
 (({})[()()()()()()])
 ([({}<(())>)](<>)){({}())<>}{}<>{}{}<>(({})){(<{}({}<>)>)}{}({}<>)
 {((< #IF
  {} 
  {({}[()]< #FOR
   ((((()()()()()){}){}){}()) #41
   (({})[()])                 #40
  >)}{}
 >))}{}
 (({}))
 #MOD2
 {(<
  ({}<(())>)({<({}[()]<>)><>(()[{}])<><({}<>)>}{}<({}<>)><>)<>({}<>)
  {((<{}({}< #IF
   {}
   (((()()()()())({})({})({}){})({})({})({}){})  #125
   (({})[()()])                                  #123
   ((((()()()()()){}){}){}())                    #41
   <>
   ((((()()()()()){}){}){})                      #40
   <>
   >)

  >))}{}{}
 >)}{}
 #MOD2 (number 2)
 (({}))
 ({}(())){({}[()]<>)<>(()[{}])<>({}<>)}{}
 (({})<([{}]{})>)
 {
  ({}[()]<<>
    ((((()()()()()){}){}){}) #40
    (({})())                 #41
   <>>)
 }{}
}{}
<>{({}<>)<>}<>((((()()()()()){}){}){})

คำอธิบาย

สิ่งนี้ใช้เพียงสองกฎ ณ ตอนนี้:

  • ถ้า n หารด้วยสองคืนได้ (n/2){}

  • ถ้า n หารด้วยสองไม่ได้ n-1()

นอกจากนี้ยังเข้ารหัสรหัสทั้งหมดที่เล็กกว่า 6


ดูเหมือนว่าการตรวจสอบการหารด้วยสามควรลดคะแนนลงเล็กน้อย
ASCII-only

@ ASCII- เพียงฉันใช้งานจริงเท่านั้นและเพิ่มจำนวนไบต์ ฉันกำลังหาวิธีที่จะใช้การหารแบบฉลาดขึ้นโดยสามคน
ข้าวสาลีตัวช่วยสร้าง

ตกลงโดยใช้ Brain-Flak เพื่อสร้างโปรแกรมที่สร้างหมายเลข Brain-Frak ดี
Draco18s

10

Perl, 59222 59156 58460 ตัวอักษร

  • n() (11322660 ตัวอักษร)
  • (n){}() (64664 ตัวอักษร)
  • ((n)){}{} (63610 ตัวอักษร)
  • ((n)()){}{} (63484 ตัวอักษร) - นี่เป็นการคำนวณแบบใหม่
  • (n){({}[()])}{} (60748 ตัวอักษร)
  • n[m] (62800 ตัวอักษร)
  • (n){m({}[l])}{} (58460 ตัวอักษร) - นี่คือการคำนวณแบบใหม่

n(n/l+1)/2+mn/lสูตรการคำนวณที่สุดท้ายคือ ฉันได้ลองคำนวณอื่น ๆ แล้ว แต่มันไม่มีประโยชน์อีกต่อไปสำหรับผลลัพธ์ที่ให้ โปรแกรมสร้างค่าทั้งหมดได้ถึง 9999 แต่จากนั้นจะแสดงรายการหมายเลขเฉพาะและความยาวรวม

@primes = (<list of the 4-digit prime numbers here>);
@numbers = ();
for ($i = 1; $i < 10000; $i++) {
  $numbers[$i] = "()" x $i; # default calculation
}
for ($i = 2; $i < 10000; $i++) {
  for ($j = 1; $j < 8; $j++) {
    &try($i, "$numbers[$i+$j]\[$numbers[$j]]");
  }
  &try($i + 1, "$numbers[$i]()");
  &try($i * 2, "($numbers[$i]){}");
  &try($i * 3, "(($numbers[$i])){}{}");
  &try($i * 3 + 2, "(($numbers[$i])()){}{}");
  for ($l = 1; $l * $l < $i; $l++) { 
    unless ($i % $l) { 
      for ($j = 0; ($k = (($i + $j + $j) * $i / $l + $i) / 2) < 10000; $j++) { 
        &try($k, "($numbers[$i]){$numbers[$j]({}[$numbers[$l]])}{}");
      } 
    } 
  } 
}
$len = 0;
foreach (@primes) {
  print "($numbers[$_])\n";
  $len += 2 + length $numbers[$_];
}
print "$len\n";
sub try {
  ($n, $s) = @_;
  $numbers[$n] = $s if (length($numbers[$n]) > length $s);
}

คุณสามารถให้ลิงค์ไปยังเอาต์พุตได้หรือไม่?
DJMcMayhem

@DJMcMayhem โอ๊ะโอฉันบังเอิญทำรายการของตัวเองโดยไม่ได้ตั้งใจทำให้ตัวละครของฉันไม่ถูกต้อง
Neil

@Linus ((X) ()) {} {} ผลัก X แล้วบวก 1 ผลักผลลัพธ์แล้วป๊อป X + 1 และ X รวม 3X + 2 ฉันคิดว่าฉันลองสูตรอื่น ๆ ใน Try It Online แต่ฉันสามารถตรวจสอบอีกครั้งหากคุณต้องการ
Neil

@Neil ความผิดพลาดของฉัน ... สิ่งเหล่านี้ดูดี แต่อะไรที่ทำให้คุณต้องเสียเวลา?
ไลนัส

1
@Neil ฉันจะได้รับ 58158 เมื่อฉันเพิ่ม&try($i * $i, "$numbers[$i]{({})({}[()])}{}");ซึ่งลงไปที่ 58032 เมื่อฉันยังเพิ่ม&try((3 * $i * $i - $i) / 2, "$numbers[$i]{({})({}[()])({})}{}");(ตัวเลขสแควร์ / ห้าเหลี่ยม) - มันมาจากที่นี่
ASCII เท่านั้น

5

Python, 59136 58676 ตัวอักษร

ฟังก์ชั่นการเล่นกอล์ฟจำนวน Brainflak:

m=11111
R=range(0,m)
R[1]="()"
R[2]="()()"
l=2
def a(v,r):
 if v>0 and v<m:
  if isinstance(R[v],int) or len(r)<len(R[v]):
   R[v]=r
   if v<R[0]:
    R[0]=v
def s(v,k):
 S=0
 while v>0:
  S+=v
  v-=k
 return S
p=lambda r:"("+r+")"
w=lambda r:"{({}["+r+"])}{}"
def q(r,v):
 for i in range(1,v):
  r="("+r+")"
 for i in range(1,v):
  r+="{}"
 return r
def e(r,v,k):
 for i in range(0,k):
  r=q(r,v)
 return r
while l<m:
 R[0]=l+1
 a(l*2,q(R[l],2)) 
 a(l*3,q(R[l],3))
 a(l*5,q(R[l],5))
 a(l*7,q(R[l],7))
 for i in range(1,l):
  a(l+i,R[l]+R[i])
  a(l-i,R[l]+"["+R[i]+"]")
  if l%i==0:
   t=s(l-i,i)
   a(s(l,i),p(R[l])+w(R[i]))
   a(l+2*t,p(R[l])+q(w(R[i]),2))
   a(l+4*t,p(R[l])+e(w(R[i]),2,2))
   a(l+8*t,p(R[l])+e(w(R[i]),2,3))
   a(l+16*t,p(R[l])+e(w(R[i]),2,4))
   a(l+32*t,p(R[l])+e(w(R[i]),2,5))
   a(l+64*t,p(R[l])+e(w(R[i]),2,6))
   a(l+128*t,p(R[l])+e(w(R[i]),2,7))
   a(l+3*t,p(R[l])+q(w(R[i]),3))
   a(l+9*t,p(R[l])+e(w(R[i]),3,2))
   a(l+27*t,p(R[l])+e(w(R[i]),3,3))
   a(l+5*t,p(R[l])+q(w(R[i]),5))
   a(l+6*t,p(R[l])+q(q(w(R[i]),3),2))
   a(l+10*t,p(R[l])+q(q(w(R[i]),5),2))
   a(l+15*t,p(R[l])+q(q(w(R[i]),5),3))
   a(l+12*t,p(R[l])+q(q(q(w(R[i]),3),2),2))
   a(l+18*t,p(R[l])+q(q(q(w(R[i]),3),3),2))
   a(l+20*t,p(R[l])+q(q(q(w(R[i]),5),2),2))
   a(l+24*t,p(R[l])+q(q(q(q(w(R[i]),3),2),2),2))
   a(l+36*t,p(R[l])+q(q(q(q(w(R[i]),3),3),2),2))
   a(l+40*t,p(R[l])+q(q(q(q(w(R[i]),5),2),2),2))
 l=R[0]
f=lambda v:p(R[v])

การวนซ้ำจำนวนเฉพาะ:

def isPrime(v):
 i=2
 while i*i<=v:
  if v%i==0:
   return False
  i+=1
 return True

for i in range(1000,10000):
 if isPrime(i):
  print f(i)

เอาท์พุท:

Pastebin

คำอธิบาย:

เราล่วงหน้าในรายการRของสมองสะเก็ดระเบิดเป็นตัวแทนการประเมินเพื่อจำนวนเต็มของแต่ละบุคคลมากกว่าขนาดใหญ่กว่าช่วงที่จำเป็น [1, ม. -1] เพื่อกำหนดฟังก์ชั่นของเราฉ การเป็นตัวแทนจะเกิดขึ้นจากการเป็นตัวแทนที่ไม่ได้ใช้ต่ำสุด (จัดทำดัชนีโดยl ) และสร้างการเป็นตัวแทนใหม่ ๆ จากมันโดยรักษาเพียงระยะสั้นที่สุด การเป็นตัวแทนที่ไม่ได้ใช้ต่ำสุดถือว่าเป็นหมายเลข 1 ถึงl ทั้งหมดที่ได้รับมอบหมายการเป็นตัวแทนและการรับรองเหล่านี้ได้ถูกใช้เพื่อสร้างหมายเลขใหม่แล้ว หากค่าน้อยกว่าlได้รับการเป็นตัวแทนที่สั้นกว่าเราจะต้องย้อนกลับไปและสร้างตัวเลขเริ่มต้นจากจุดนั้น ฟังก์ชั่นf สร้างโปรแกรมที่บันทึกหมายเลขลงในสแต็กโดยการเพิ่มวงเล็บ

ฉันไม่รู้ Brainflak ใด ๆ เมื่อฉันเริ่มต้นนี้และขอบคุณคำตอบของ Eamon Olive ที่ชี้ให้เห็นสูตรสำหรับตัวเลขสามเหลี่ยม ส่วนใหญ่ฉันสรุปการสรุปและไม่หยุดยั้งเกี่ยวกับการตรวจสอบจำนวนเงินและความแตกต่าง การเพิ่มจำนวนทวีคูณจำนวนมากมีผลดีมาก

สำหรับผู้ที่สนใจนี่คือรหัสรอยขีดข่วนที่ฉันใช้เพื่อดูว่าสูตรใดมีค่า

สูตรการเป็นตัวแทน:

  1. การคูณด้วยจำนวนเฉพาะ:
    (X){}
    ((X)){}{}
    ((((X)))){}{}{}{}
    ((((((X)))))){}{}{}{}{}{}
  2. นอกจากX + Y :
    XY
  3. การลบX - Y :
    X[Y]
  4. การรวมและรวมถึงXของการเพิ่มค่าY :
    (X){({}[Y])}{}
  5. ทวีคูณของผลรวมเป็นXของการเพิ่มY , บวกX :
    (X)({({}[Y])}{}){}
    (X)(({({}[Y])}{})){}{}
    (X)(({({}[Y])}{}){}){}
    ฯลฯ

ฉันคิดว่า 5 * ไม่เป็นประโยชน์ แต่ตอนนี้ฉันเห็นว่ามันช่วยได้ 10 อักขระในคำตอบของฉัน ฉันคิดว่าฉันลองใช้ข้อสรุปเหล่านั้น แต่ฉันจะตรวจสอบอีกครั้ง
Neil

ผลรวมของการเพิ่มขึ้นบวกทวีคูณช่วยฉันอีก 46 ไบต์และจากนั้นฉันต้องล้างและทำซ้ำสามครั้งเพื่อจับพวกเขาทั้งหมด
Neil

ปรากฎว่าถ้าฉันใช้การลบแล้วฉันจะไม่ใช้ 5 * อีกครั้ง
Neil

4

ลัวะ 5.3, 57522

จริง ๆ แล้วฉันเริ่มทำงานด้านหลังเมื่อคำถามถูกโพสต์ แต่ลืมไปจนถึงวันครบรอบ Brain-Flak

-- 64 gives all results through 10000 (should run in about 1 second)
-- 78 gives all results through 100000 (should run in about 20 seconds)
-- 90 gives all results through 1000000 (should run in about 200 seconds)
-- Note: Timings may not be accurate, as the are not updated every time new cases are added.

local k_max_len = 64
local k_limit = 10000

local pre = os.clock()

local function compute_multiplier_helper(prefix, suffix, m)
  if m == 2 then
    prefix[#prefix + 1] = "("
    suffix[#suffix + 1] = "){}"
  elseif m % 2 == 0 then
    prefix[#prefix + 1] = "("
    compute_multiplier_helper(prefix, suffix, m // 2)
    suffix[#suffix + 1] = "){}"
  else
    suffix[#suffix + 1] = ")"
    compute_multiplier_helper(prefix, suffix, m - 1)
    prefix[#prefix + 1] = "("
    suffix[#suffix + 1] = "{}"
  end
end

local function compute_multiplier(m)
  local prefix = {}
  local suffix = {}
  compute_multiplier_helper(prefix, suffix, m)
  return table.concat(prefix), table.concat(suffix)
end

local multipliers = {}
for m = 2, k_limit do
  -- Including all factors, not just primes.
  -- This did improve a few numbers, although none in the ppcg test set.
  local prefix, suffix = compute_multiplier(m)
  local mult = {prefix = prefix, suffix = suffix, m = m, cost = #prefix + #suffix}
  table.insert(multipliers, mult)
end
table.sort(multipliers, function(a, b) return a.cost < b.cost end)

local poly_multipliers = {}
poly_multipliers[1] = {m = 1, s = "({})", l = 4}
for m = 2, k_limit do
  local prefix, suffix = compute_multiplier(m)
  local s = prefix .. "({})" .. suffix
  assert(#s <= 4 * m)
  poly_multipliers[m] = {m = m, s = s, l = #s}
end
poly_multipliers[k_limit + 1] = {m = 0, s = "", l = 0}

table.sort(poly_multipliers, function(a, b) return a.l < b.l end)

local pcache = {}
local plen_cache = {}

local function register_push(prefix, suffix, value, pvalue)
  if value > 1500000 or value < -1500000 then return end
  local old_res = pcache[value]
  if old_res == nil then
    local res = {prefix = prefix, suffix = suffix, value = value, pvalue = pvalue}
    pcache[value] = res
    local length = #prefix + #suffix
    local lcache = plen_cache[length]
    if lcache == nil then
      lcache = {}
      plen_cache[length] = lcache
    end
    lcache[#lcache + 1] = res
  end
end

local function get_pushes(length)
  return ipairs(plen_cache[length] or {})
end

register_push("", "()", 1, 0)
register_push("", "<()>", 0, 0)

local function triangle(n)
  return (n * (n + 1)) // 2
end

local function process(length)
  -- basic
  for _, res in get_pushes(length - 2) do
    register_push(res.prefix, res.suffix .. "()", res.value + 1, res.pvalue)
    register_push(res.prefix, "[" .. res.suffix .. "]", -res.value, res.pvalue)
  end

  -- multiplication by constant (precomputed)
  for _, mult in ipairs(multipliers) do
    local cost = mult.cost
    if length - cost >= 4 then
      local m, prefix, suffix = mult.m, mult.prefix, mult.suffix
      for _, pus in get_pushes(length - cost) do
        local name = prefix .. pus.suffix .. suffix
        register_push(pus.prefix, name, pus.value * m, pus.pvalue)
      end
    else
      break
    end
  end

  -- residue 2 mod3 trick (Neil)
  -- ((n)()){}{}
  --  (n)        -- push n
  -- (   ())     -- push n + 1
  --        {}{} -- (n + 1) + (n + 1) + n
  if length - 10 >= 2 then
    for _, res in get_pushes(length - 10) do
      local name = "((" .. res.suffix .. ")()){}{}"
      register_push(res.prefix, name, 3 * res.value + 2, res.pvalue)
    end
  end

  -- residue 1 mod3 trick (Wheat Wizard)
  -- ((n)()()){}{}
  --  (n)          -- push n
  -- (   ()())     -- push n + 2
  --          {}{} -- (n + 2) + (n + 2) + n
  -- not useful, but fast...
  if length - 12 >= 2 then
    for _, res in get_pushes(length - 12) do
      local name = "((" .. res.suffix .. ")()()){}{}"
      register_push(res.prefix, name, 3 * res.value + 4, res.pvalue)
    end
  end

  -- residue 2 mod5 trick (tehtmi)
  -- (((n)){}()){}{}
  --   (n)           -- push n
  --  (   )          -- push n
  -- (     {}())     -- push 2n + 1
  --            {}{} -- (2n + 1) + (2n + 1) + n
  -- [[
  if length - 14 >= 2 then
    for _, res in get_pushes(length - 14) do
      local name = "(((" .. res.suffix .. ")){}()){}{}"
      register_push(res.prefix, name, 5 * res.value + 2, res.pvalue)
    end
  end
  -- ]]

  -- residue 4 mod5 trick (tehtmi)
  -- (((n)()){}){}{}
  --   (n)           -- push n
  --  (   ())        -- push n + 1
  -- (       {})     -- push 2n + 2
  --            {}{} -- (2n + 2) + (2n + 2) + n
  -- [[
  if length - 14 >= 2 then
    for _, res in get_pushes(length - 14) do
      local name = "(((" .. res.suffix .. ")()){}){}{}"
      register_push(res.prefix, name, 5 * res.value + 4, res.pvalue)
    end
  end
  -- ]]

  -- residue 6 mod7 trick (tehtmi)
  -- ((((n)())){}{}){}{}
  --    (n)              -- push n
  --   (   ())           -- push n + 1
  --  (       )          -- push n + 1
  -- (         {}{})     -- push 3n + 3
  --                {}{} -- (3n + 3) + (3n + 3) + n
  -- [[
  if length - 18 >= 2 then
    for _, res in get_pushes(length - 18) do
      local name = "((((" .. res.suffix .. ")())){}{}){}{}"
      register_push(res.prefix, name, 7 * res.value + 6, res.pvalue)
    end
  end
  --]]

  -- residue 4 mod7 trick (tehtmi)
  -- ((((n))()){}{}){}{}
  --    (n)              -- push n
  --   (   )             -- push n
  --  (     ())          -- push n + 1
  -- (         {}{})     -- push 3n + 2
  --                {}{} -- (3n + 2) + (3n + 2) + n
  -- [[
  if length - 18 >= 2 then
    for _, res in get_pushes(length - 18) do
      local name = "((((" .. res.suffix .. "))()){}{}){}{}"
      register_push(res.prefix, name, 7 * res.value + 4, res.pvalue)
    end
  end
  --]]

  -- residue 2 mod7 trick (tehtmi)
  -- ((((n))){}{}()){}{}
  --    (n)              -- push n
  --   (   )             -- push n
  --  (     )            -- push n
  -- (       {}{}())     -- push 3n + 1
  --                {}{} -- (3n + 1) + (3n + 1) + n
  -- [[
  if length - 18 >= 2 then
    for _, res in get_pushes(length - 18) do
      local name = "((((" .. res.suffix .. "))){}{}()){}{}"
      register_push(res.prefix, name, 7 * res.value + 2, res.pvalue)
    end
  end
  --]]

  -- triangle numbers (?)
  --(n){({}[()])}{}
  --(n)              -- push n
  --   {        }    -- sum and repeat
  --    (      )     -- push
  --     {}[()]      -- top - 1
  --             {}  -- pop 0
  if length - 14 >= 2 then
    for _, res in get_pushes(length - 14) do
      if res.value > 0 then
        local code = "{({}[()])}{}"
        register_push(res.prefix .. "(" .. res.suffix .. ")", code, triangle(res.value - 1), res.pvalue + res.value)
        register_push(res.prefix, "(" .. res.suffix .. ")" .. code, triangle(res.value), res.pvalue)
        register_push("", res.prefix .. "(" .. res.suffix .. ")" .. code, triangle(res.value) + res.pvalue, 0)
      end
    end
  end

  -- negative triangle numbers (tehtmi)
  --(n){({}())}{}
  --(n)            -- push n
  --   {      }    -- sum and repeat
  --    (    )     -- push
  --     {}()      -- top + 1
  --           {}  -- pop 0
  if length - 12 >= 2 then
    for _, res in get_pushes(length - 12) do
      if res.value < 0 then
        local code = "{({}())}{}"
        register_push(res.prefix .. "(" .. res.suffix .. ")", code, -triangle(-res.value - 1), res.pvalue + res.value)
        register_push(res.prefix, "(" .. res.suffix .. ")" .. code, -triangle(-res.value), res.pvalue)
        register_push("", res.prefix .. "(" .. res.suffix .. ")" .. code, -triangle(-res.value) + res.pvalue, 0)
      end
    end
  end

  -- cubic (tehtmi)
  -- (n){(({}[()])){({}[()])}{}}{}
  -- (n^3-3*n^2+8*n-6)/6
  -- (-6 + n*(8 + n*(-3 + n)))/6
  --[[ superceded by negative cubic because 
       it is the same cost of -ncubic(-n)
  if length - 28 >= 2 then
    for _, res in get_pushes(length - 28) do
      if res.value > 0 then
        local code = "{(({}[()])){({}[()])}{}}{}"
        local v = res.value + 1
        v = (-6 + v*(8 + v*(-3 + v)))//6
        register_push(res.prefix .. "(" .. res.suffix .. ")", code, v - res.value, res.pvalue + res.value)
        register_push(res.prefix, "(" .. res.suffix .. ")" .. code, v, res.pvalue)
        register_push("", res.prefix .. "(" .. res.suffix .. ")" .. code, v + res.pvalue, 0)
      end
    end
  end
  --]]

  -- negative cubic (tehtmi)
  -- (n){(({}())){({}())}{}}{}
  -- (n^3-3*n^2+8*n-6)/6
  -- (-6 + n*(8 + n*(-3 + n)))/6
  -- [[
  if length - 24 >= 2 then
    for _, res in get_pushes(length - 24) do
      if res.value < 0 then
        local code = "{(({}())){({}())}{}}{}"
        local v = -res.value + 1
        v = (-6 + v*(8 + v*(-3 + v)))//6
        v = -v
        register_push(res.prefix .. "(" .. res.suffix .. ")", code, v - res.value, res.pvalue + res.value)
        register_push(res.prefix, "(" .. res.suffix .. ")" .. code, v, res.pvalue)
        register_push("", res.prefix .. "(" .. res.suffix .. ")" .. code, v + res.pvalue, 0)
      end
    end
  end
  --]]

  -- polynomial (Wheat Wizard, modified by tehtmi)
  -- <(n)>{A({}[()])B}{} where A, B are ({})({})({})... repeated a, b times
  -- <(n)>                -- push n (without adding)
  --      {          }    -- repeat until top is zero
  --       A              -- top * a
  --        ({}[()])      -- top = top - 1; += top - 1
  --                B     -- (top - 1) * b
  --                  {}  -- pop 0
  -- triangular numbers are with a = b = 0
  -- from B and base:
  -- (n - 1) * (B + 1) * (n - 2) * (B + 1) * ...
  -- (B + 1) * (1 + ... + n - 1)
  -- (B + 1) * n * (n - 1) / 2
  -- from A:
  -- n * A + (n - 1) * A + ...
  -- A * (1 + ... n)
  -- A * (n + 1) * n / 2
  -- total: (B + 1) * n * (n - 1) / 2 + A * (n + 1) * n / 2
  --        [(A + B + 1) * n^2 + (A - B - 1) * n] / 2
  -- S := 4 * (A + B)
  -- [[
  if length - 18 >= 2 then
    for S = 4, length - 14, 4 do
      for _, res in get_pushes(length - 14 - S) do
        if res.value > 0 then
          for _, A in ipairs(poly_multipliers) do
            if A.l > S then
              break
            end
            for _, B in ipairs(poly_multipliers) do
              if A.l + B.l < S then
                -- continue
              elseif A.l + B.l > S then
                break
              else
                local a = A.m
                local b = B.m

                local logic = "{" .. A.s .. "({}[()])" .. B.s .. "}{}"
                local v = res.value
                v = ((a + b + 1) * v * v + (a - b - 1) * v) // 2
                register_push(res.prefix .. "(" .. res.suffix .. ")", logic, v, res.pvalue + res.value)
                register_push(res.prefix, "(" .. res.suffix .. ")" .. logic, v + res.value, res.pvalue)
                register_push("", res.prefix .. "(" .. res.suffix .. ")" .. logic, v + res.value + res.pvalue, 0)
              end
            end
          end
        end
      end
    end
  end
  --]]

  -- negative polynomial (tehtmi)
  -- <(n)>{A({}())B}{}
  -- [[
  if length - 16 >= 2 then
    for S = 4, length - 12, 4 do
      for _, res in get_pushes(length - 12 - S) do
        if res.value < 0 then
          for _, A in ipairs(poly_multipliers) do
            if A.l > S then
              break
            end
            for _, B in ipairs(poly_multipliers) do
              if A.l + B.l < S then
                -- continue
              elseif A.l + B.l > S then
                break
              else
                local a = A.m
                local b = B.m

                local logic = "{" .. A.s .. "({}())" .. B.s .. "}{}"
                local v = -res.value
                v = ((a + b + 1) * v * v + (a - b - 1) * v) // -2

                register_push(res.prefix .. "(" .. res.suffix .. ")", logic, v, res.pvalue + res.value)
                register_push(res.prefix, "(" .. res.suffix .. ")" .. logic, v + res.value, res.pvalue)
                register_push("", res.prefix .. "(" .. res.suffix .. ")" .. logic, v + res.value + res.pvalue, 0)
              end
            end
          end
        end
      end
    end
  end
  --]]

  -- addition
  -- [[
  if length >= 4 then
    for part1 = 4, length // 2, 2 do
      for _, res1 in get_pushes(part1) do
        for _, res2 in get_pushes(length - part1) do
          register_push(res2.prefix .. res1.prefix, res1.suffix .. res2.suffix, res1.value + res2.value, res1.pvalue + res2.pvalue)
        end
      end
    end
  end
  --]]

  -- pseudo-exponentiation (tehtmi)
  -- (n)<>(m){({}[()])<>(({}){})<>}{}<>{}
  -- (n)<>(m)                             -- push n and m on opposite stacks
  --         {                    }       -- sum and repeat
  --          ({}[()])                    -- top(m) - 1
  --                  <>(({}){})<>        -- n = 2*n; += n
  --                               {}     -- pop 0
  --                                 <>   -- swap to result
  --                                   {} -- pop and add n
  -- [[
  if length - 34 >= 4 then
    local subl = length - 34
    for part1 = 2, subl - 2, 2 do
      for _, res2 in get_pushes(part1) do
        local b = res2.value
        if b > 0 and b < 55 then -- overflow could be a problem, so bound...
          for _, res1 in get_pushes(subl - part1) do
            -- 2n + 4n + 8n + ... + (2^m)*n + 2^m * n
            -- n( 2 + 4 + 8 + .. 2^m + 2^m)
            -- n( 3 * 2^m - 2 )
            local a = res1.value
            local body = "(" .. res1.suffix .. ")<>" .. res2.prefix .. "(" .. res2.suffix .. "){({}[()])<>(({}){})<>}{}<>{}"
            local v = a * (3 * (1 << b) - 2) + b * (b - 1) // 2 + a + b + res2.pvalue
            register_push(res1.prefix, body, v, res1.pvalue)
            register_push("", res1.prefix .. body, v + res1.pvalue, 0)
          end
        end
      end
    end
  end
  --]]
end

--print(os.clock(), "seconds (startup)")

local start = os.clock()
for i = 2, k_max_len - 2, 2 do
  --print(i)
  process(i)
end

plen_cache = nil

local final = {}
for i = 1, k_limit do
  if pcache[i] ~= nil then
    final[i] = pcache[i].prefix .. "(" .. pcache[i].suffix .. ")"
  end
end

pcache = nil

-- hard coded to 10000 for ppcg test
local sieve = {}
for i = 1, 10000 do sieve[i] = true end
for i = 2, 10000 do
  for j = i * i, 10000, i do
    sieve[j] = false
  end
end

--print(os.clock() - start, "seconds (calculation)")

--local bf = require("execute2")

local count = 0
local sum = 0
local sum2 = 0
local maxlen = 0
local pcount = 0
for i = 1, k_limit do
  local res = final[i]
  final[i] = nil
  --print(i, #res, res)
  --local ev = res and bf.eval1(bf.compile(res)) or -1; assert( res == nil or ev == i, string.format("Failed %d %s %d", i, res or "", ev))
  if sieve[i] and i > 1000 then
    sum = #res + sum
    pcount = pcount + 1
  end
  if res then
    sum2 = #res + sum2
    maxlen = math.max(maxlen, #res)
    count = count + 1
  end
end
print("sum", sum)
--print("coverage", count / k_limit, "missing", k_limit - count)
--print("sum2", sum2)
--print("maxlen", maxlen)
assert(pcount == 1061)

แนวคิดคล้ายกับคำตอบอื่น ๆ ที่ใช้ฟังก์ชั่นที่เป็นประโยชน์ที่รู้จักกันในการสร้างจำนวนมากขึ้นจากการเป็นตัวแทนที่ดีของตัวเลขง่าย

สิ่งหนึ่งที่แตกต่างคือแทนที่จะแก้ปัญหาย่อยในแง่ของจำนวนที่น้อยกว่าฉันกำลังแก้ปัญหาย่อยในแง่ของตัวเลขที่มีการแทนสั้นกว่า ฉันคิดว่านี่เป็นสิ่งที่ทำให้การใช้ประโยชน์จากตัวเลขติดลบดีขึ้นรวมถึงการจัดการกับกรณีที่มีจำนวนที่น้อยกว่าแสดงในรูปของจำนวนที่มากขึ้น

นอกจากนี้พยายามค้นหาตัวเลขทั้งหมดที่สามารถแสดงในขนาดที่แน่นอนแทนที่จะพยายามแสดงหมายเลขเฉพาะโดยเร็วที่สุดที่เป็นจริงการคำนวณบางอย่างง่ายขึ้น แทนที่จะใช้สูตรย้อนกลับเพื่อดูว่าสามารถใช้กับตัวเลขได้หรือไม่สามารถใช้สูตรต่อไปและนำไปใช้กับทุกหมายเลขได้

ความแตกต่างอีกอย่างก็คือโซลูชันที่ทราบจะถูกจัดเก็บไว้ในสองส่วน - (ส่วนเสริม) "คำนำหน้า" และ "คำต่อท้าย" (เหมือน infix) การประเมินมูลค่าของคำนำหน้าคาดว่าจะถูกละเว้นเมื่อคำนวณจำนวนที่กำหนด - คำนำหน้าเพียงแค่มีรหัสที่ตั้งค่าคำต่อท้ายให้ทำงาน prefix(suffix)ดังนั้นให้คำนำหน้าและคำต่อท้ายจำนวนที่สอดคล้องกันสามารถผลักลงบนสแต็คที่มี

การแยกนี้โดยทั่วไปจะแก้ปัญหาเดียวกับunpackฟังก์ชั่นในคำตอบของ Wheat Wizard แทนที่จะห่อรหัสด้วย<...>เพื่อยกเลิกในภายหลังเท่านั้นรหัสดังกล่าวจะถูกเพิ่มไปยังคำนำหน้า

ในบางกรณีคำนำหน้าจริง ๆ แล้วได้รับการประเมิน (ส่วนใหญ่สำหรับการดำเนินการหลอก - exponentiation) ดังนั้นการประเมินค่าจะถูกเก็บไว้ อย่างไรก็ตามสิ่งนี้ไม่ได้ทำให้เกิดปัญหาใหญ่นักเนื่องจากตัวสร้างไม่ได้พยายามสร้างตัวเลขเฉพาะ ดูเหมือนว่าในทางทฤษฎีหมายความว่าอาจมีโค้ดสองชิ้นที่มีความยาวเท่ากันและสร้างหมายเลขเดียวกันที่จะไม่ซ้ำซ้อนในแคชเนื่องจากมีการประเมินมูลค่าคำนำหน้าแตกต่างกัน ฉันไม่ได้สนใจเรื่องนี้เพราะดูเหมือนจะไม่สำคัญ (อย่างน้อยในโดเมนนี้)

ฉันคิดว่ามันจะง่ายต่อการลดจำนวนไบต์ลงเพียงแค่เพิ่มเคสเพิ่มเติม แต่ฉันมีเพียงพอแล้ว

ฉันวิ่งไปที่ 1000000 แต่ทำแค่การตรวจสุขภาพจิตสูงสุดถึง 100,000

Pastebin ของการส่งออกในช่วงเวลาที่กำหนด


ทำอะไรk_limitและk_max_lenทำอย่างไร ฉันไม่แน่ใจว่าฉันเข้าใจส่วนหัว
ข้าวสาลีตัวช่วยสร้าง

1
แทนที่จะพยายามที่จะคำนวณตัวเลขโดยเฉพาะอย่างยิ่งผมคำนวณประโยชน์ (เช่นการให้ตัวเลขที่ไม่มากเกินไปขนาดใหญ่ที่สั้นกว่าโปรแกรมพบอื่น ๆ ) โปรแกรมขึ้นอยู่กับความยาวบาง k_max_len- สามารถตรวจสอบได้อย่างง่ายดายว่าพบหมายเลขทั้งหมดที่คุณขอหลังการประมวลผลแต่ละความยาว แต่มันมีประโยชน์สำหรับฉันที่จะสามารถผูกความยาวสูงสุดในระหว่างการทดสอบเพื่อให้โปรแกรมทำงานได้เร็วขึ้น (การประมวลผลความยาวที่ใหญ่กว่าอาจช้ามาก) k_limitโดยทั่วไปคือพารามิเตอร์อินพุต - มันจะส่งออกโปรแกรมสำหรับตัวเลขที่สูงถึงนี้ - โดยถือว่าk_max_lenมีขนาดใหญ่พอที่จะค้นหาได้
tehtmi

4

ทับทิม 60246 ไบต์

$brain_flak = Hash.new{|h, k|
    a = []
    a.push "()"*k
    if k > 1
        if k > 10
            # Triangle Numbers:
            n = (Math.sqrt(1+8*k).to_i-1)/2
            if (n*n+n)/2 == k
                a.push "("+h[n]+"){({}[()])}{}" 
                a.push  h[n+n]+")({({}[()])}{}"
            end
        end
        (k**0.51).to_i.downto(2){|i|
            # multiplication:
            if k%i==0
                a.push "("*(i-1) + h[k/i] + ")"*(i-1)+"{}"*(i-1)

            end
        }
        (k/2).downto(1){|i|
            # Addition
            a.push h[k-i] + h[i]
        }
    end

    h[k] = a.min_by{|x|x.length}
}
$brain_flak[0] = "<><>"

def get_code_for (i)
  "(#{$brain_flak[i]})"
end

ฉันใช้แฮช ฉันค้นหากอล์ฟที่ดีที่สุดตามจำนวนที่กำหนดและใช้สนามที่เล็กกว่าเพื่อหาสนามที่ใหญ่กว่า

แฮ็กแบบวนซ้ำนั้นสนุกมาก!


2

Python, 64014 ตัวอักษร

ฉันไม่รู้อะไรเกี่ยวกับสมองก่อนหน้าความท้าทายนี้และเล่นกับมันเพียงเล็กน้อยบนไทรทันไลน์ดังนั้นอาจมีทางลัดที่ชัดเจนที่ฉันพลาดไป นี่เป็นวิธีการแก้ปัญหาที่ค่อนข้างน่าเบื่อเพียงแค่แยกสัญญาณเข้าx=x/2+x%2หรือx=x/3+x%3ใดก็ตามที่สั้นกว่า

k=lambda x:"(("+o(x/3)+")){}{}"+(x%3)*"()"if x>3else"()"*x
m=lambda x:"("+o(x/2)+"){}"+(x%2)*"()"if x>6else"()"*x
o=lambda x:min(k(x),m(x),key=len)
b=lambda x:"("+o(x)+")"

เรียกว่าเป็นเช่นนั้น: b(42)

ส่งออกบน pastebin


1

Lua 64664 ไบต์

โปรแกรมพิมพ์ความยาวทั้งหมดของโปรแกรมและโปรแกรมสำหรับรุ่นที่ 203 (มีบรรทัดที่คุณสามารถเปลี่ยนเพื่อเปลี่ยนรูปแบบที่พิมพ์หรือยกเลิกการใส่เครื่องหมายบรรทัดเพื่อพิมพ์โปรแกรมทั้งหมด)

ตอนนี้การเพิ่มประสิทธิภาพเพียงอย่างเดียวคือ x = 2 * n + 1

หวังว่าฉันจะมีเวลาเพิ่มการเพิ่มประสิทธิภาพบางอย่างเพื่อลดคะแนน

local primeS = [[<INSERT PRIMES HERE>]]

local primes = {}

for num in primeS:gmatch("%d+") do
    table.insert(primes, num+0)
end

local progs = {}
progs[0] = ""
progs[1] = "()"
progs[2] = "()()"

local function half(n)
    if progs[n] then return progs[n] end
    local p = ""
    local div = math.floor(n/2)
    local rem = n%2 == 1 and "()" or ""
    return "("..progs[div].."){}"..rem
end

for i = 3, 10000 do

    local bin = half(i)

    progs[i] = progs[i-1] .. "()"

    if #bin < #progs[i] then
        progs[i] = bin
    end

    if i % 1000 == 0 then
        print(i)
    end

end

local n = 203 -- This is the program it outputs
print(n..", ("..progs[203]..")")

local len = 0
for i,v in ipairs(primes) do
    len = len + #progs[v] + 2
    --print(v.." ("..progs[v]..")\n")
end
print("Total len: "..len)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.