Auto-meta-รหัสกอล์ฟ


13

คุณเบื่อความท้าทาย codegolf ทั้งหมด ดังนั้นคุณตัดสินใจที่จะเขียนโปรแกรมที่จะเขียนรหัส Python ให้คุณโดยอัตโนมัติ มี 3 กรณีทดสอบ:

print quickSort([0,7,3,-1,8,10,57,2])
def quickSort(arr):
    less = []
    pivotList = []
    more = []
    if len(arr) <= 1:
        return arr
    else:
        pivot = arr[0]
        for i in arr:
            if i < pivot:
                less.append(i)
            elif i > pivot:
                more.append(i)
            else:
                pivotList.append(i)
        less = quickSort(less)
        more = quickSort(more)
        return less + pivotList + more

for i in xrange(1, 101):
    if i % 15 == 0:
        print "FizzBuzz"
    elif i % 3 == 0:
        print "Fizz"
    elif i % 5 == 0:
        print "Buzz"
    else:
        print i

from sys import argv

def randomGenerator(seed=1):
    max_int32 = (1 << 31) - 1
    seed = seed & max_int32

    while True:
        seed = (seed * 214013 + 2531011) & max_int32
        yield seed >> 16

def deal(seed):
    nc = 52
    cards = range(nc - 1, -1, -1)
    rnd = randomGenerator(seed)
    for i, r in zip(range(nc), rnd):
        j = (nc - 1) - r % (nc - i)
        cards[i], cards[j] = cards[j], cards[i]
    return cards

def show(cards):
    l = ["A23456789TJQK"[c / 4] + "CDHS"[c % 4] for c in cards]
    for i in range(0, len(cards), 8):
        print " ", " ".join(l[i : i+8])

if __name__ == '__main__':
    seed = int(argv[1]) if len(argv) == 2 else 11982
    print "Hand", seed
    deck = deal(seed)
    show(deck)

กฎ:

  1. โปรแกรมของคุณต้องไม่กำหนดเป้าหมายรหัสที่ฉันโพสต์ไว้เป็นพิเศษและควรทำงานกับรหัส Python 2 ใด ๆ ฉันขอสงวนสิทธิ์ในการเปลี่ยนรหัสต้นฉบับที่ถูก codegolfed คุณอาจสันนิษฐานว่าไม่มีสตริงหลายบรรทัด (ดังนั้นคุณจึงไม่ได้สร้างตัวแยกวิเคราะห์เต็มรูปแบบ) และไม่มีการเรียกใช้ภาษาท้องถิ่น ()

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

  3. คุณสามารถใช้ STDIO หรือไฟล์เพื่อทำอินพุต / เอาต์พุตของซอร์สโค้ดของคุณ

คะแนนของคุณจะเป็นผลรวมของไบต์ของผลลัพธ์ของโปรแกรมของคุณ

(รหัสด้านบนถูกนำมาจากhttp://rosettacode.org/ภายใต้สัญญาอนุญาตเอกสารเสรีของ GNU 1.2 )


3
ดูเหมือนว่าจะคล้ายกับcodegolf.stackexchange.com/questions/3652/write-a-code-golfer/?????????????
KSab

3
นี่คือกรณีทดสอบโบนัสสำหรับคนที่จะลอง
Sp3000

4
รุ่นของคุณในการกำหนดว่าเอาต์พุต " [ทำงาน] ในลักษณะเดียวกันกับซอร์สโค้ดต้นฉบับ " คืออะไร เช่นสำหรับตัวอย่างที่สองฉันเชื่อว่าการลบif __name__ == '__main__':จะมีผลต่อพฤติกรรมในบริบทบางอย่าง แต่ไม่ใช่สำหรับคนอื่น ๆ อีกตัวอย่างหนึ่งถ้าข้อมูลที่ไม่ได้รับการทึกทักถือว่ามันอ่าน int จาก stdin และส่งข้อยกเว้นหนึ่งประเภทถ้าให้อย่างอื่นอินพุตของสนามกอล์ฟสามารถโยนข้อยกเว้นประเภทอื่นได้หรือไม่ถ้าไม่ใช่จำนวนเต็ม?
ปีเตอร์เทย์เลอร์

2
สิ่งที่เกี่ยวกับโปรแกรมเช่นนี้: random_long_variable=0;print locals()?
Justin

คำตอบ:


4

Python 2.7, 794

ฉันตั้งใจจะสร้าง minifier สำหรับ Python มาระยะหนึ่งแล้วนี่เป็นโอกาสที่ดีในการตรวจสอบปัญหา

โปรแกรมใช้การผสมผสานการวิเคราะห์นิพจน์ทั่วไปและการดำเนินการตัวแยกวิเคราะห์ Python ลดพื้นที่สีขาว ตัวแปรที่กำหนดโดยผู้ใช้จะถูกแทนที่ด้วยตัวแปรตัวอักษรตัวเดียว (ซึ่งไม่ได้ใช้งาน!) ในที่สุดwhile Trueคำสั่งจะถูกวางในอาหาร

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

ผล

228 t1.py
128 t2.py
438 t3.py
794 total

เอาท์พุต

def c(a):
 b=[]
 d=[]
 f=[]
 if len(a)<=1:
  return a
 else:
  e=a[0]
  for i in a:
   if i<e:
    b.append(i)
   elif i>e:
    f.append(i)
   else:
    d.append(i)
  b=c(b)
  f=c(f)
  return b+d+f
print c([0,7,3,-1,8,10,57,2])


for i in xrange(1,101):
 if i%15==0:
  print"FizzBuzz"
 elif i%3==0:
  print"Fizz"
 elif i%5==0:
  print"Buzz"
 else:
  print i


from sys import argv
def a(k=1):
 b=(1<<31)-1
 k=k&b
 while 1:
  k=(k*214013+2531011)&b
  yield k>>16
def d(k):
 f=52
 h=range(f-1,-1,-1)
 g=a(k)
 for i,r in zip(range(f),g):
  j=(f-1)-r%(f-i)
  h[i],h[j]=h[j],h[i]
 return h
def m(h):
 l=["A23456789TJQK"[c/4]+"CDHS"[c%4]for c in h]
 for i in range(0,len(h),8):
  print" "," ".join(l[i:i+8])
if __name__=='__main__':
 k=int(argv[1])if len(argv)==2 else 11982
 print"Hand",k
 e=d(k)
 m(e)

รหัส

import sys
import re
from tokenize import generate_tokens
from token import tok_name
from keyword import iskeyword

wr = sys.stdout.write

def pyparse(text):
    'Return [TYPE,TOKEN] pair list'
    # Use KEYWORD,NAME,NUMBER,OP,STRING,NL,NEWLINE,COMMENT,INDENT,DEDENT
    rawtokens = generate_tokens(text.readline)
    tokens = [[tok_name[n], t] for n,t,p1,p2,dx in rawtokens]
    for tpair in tokens:
        if tpair[0] == 'NAME' and iskeyword(tpair[1]):
            tpair[0] = 'KEYWORD'
    return tokens

def finduservars(filename):
    'Return a set of user variables that we can replace with a-zA-Z'
    varset = set()
    for line in open(filename):
        line = line.strip()
        match = re.match(r'def\s+(\w+)\s*\((.*)\)\s*:', line)
        if match:
            func, args = match.groups()
            varset.add(func)
            arglist = re.findall(r'(\w+|=)', args)
            for a in arglist:
                if a == '=':
                    break  # keyword args follow - too hard to parse
                varset.add(a)
            continue
        match = re.match(r'(\w+)\s*=.+', line)
        if match:
            assigned = match.group(1)
            varset.add(assigned)
            continue
    return set(v for v in list(varset) if len(v) > 1)

filename = sys.argv[1]
tokenlist = pyparse(open(filename))

# Build map for var->char conversion:
varset = finduservars(filename)
singles = [text for tok,text in tokenlist if tok=='NAME' and len(text)==1]
allvar = [chr(n) for n in range(97,123)+range(65,91)]
charvar = [c for c in allvar if c not in singles]
varreplaced = list(varset)[:len(charvar)]
varmap = dict((v, charvar.pop(0)) for v in varreplaced)

prev = 'NONE'
indent = ['']
output = []
add = output.append
for tok, text in tokenlist:
    if tok == 'NL':
        continue
    elif tok == 'INDENT':
        indent.append( text.replace('    ', ' ') )
        output[-1] = indent[-1]
    elif tok == 'DEDENT':
        indent.pop(-1)
        output[-1] = indent[-1]
    elif tok == 'NEWLINE':
        add(text)
        add(indent[-1])
    elif tok in 'KEYWORD,NAME,NUMBER':
        if prev in 'KEYWORD,NAME,NUMBER':
            add(' ')
        if tok == 'NAME':
            if output[-2] == 'while' and text == 'True':
                add('1') # common verbose idiom
            else:
                add(varmap.get(text, text))
        else:
            add(text)
    else:
        add(text)
    prev = tok

wr(''.join(output))

4

sed, 1074 (ลดลงจาก 1390)

คำตอบที่อ่อนโยนมาก ๆ ผลไม้แขวนต่ำเพื่อให้ได้ลูกบอลกลิ้ง:

/^$/d                  # Remove empty lines
/^[ <--TAB-->]*#/d     # Remove whole-line comments
s/    /<--TAB-->/g     # Replace 4 spaces with tabs
/^[^'"]*$/s/ *([|&:,<>=*/%+-]) */\1/g  # Remove spaces before/after operators

แทนที่<--TAB-->ด้วยTABอักขระจริง

ข้อบกพร่องที่เห็นได้ชัด:

  • เยื้องสันนิษฐานว่าเป็น 4 ช่องว่างในรหัสการป้อนข้อมูล

เนื่องจากเราสามารถสมมติว่าไม่มีสตริงหลายบรรทัดดังนั้นเราจึงตัดเฉพาะช่องว่างนำหน้า / ต่อท้ายจากโอเปอเรเตอร์หากไม่มี'หรือ"บนบรรทัดที่กำหนด นี้อาจจะดีขึ้น แต่<พึมพำบางอย่างเกี่ยวกับ sed regex เสมอโลภ>

ทดสอบดังนี้:

$ cat qs.py fizzbuzz.py cards.py | wc -c
1390
$ sed -rf pygolf.sed qs.py fizzbuzz.py cards.py | wc -c
1074
$ sed -rf pygolf.sed qs.py fizzbuzz.py cards.py | python
[-1, 0, 2, 3, 7, 8, 10, 57]
1
2
Fizz
...
98
Fizz
Buzz
Hand 11982
  AH AS 4H AC 2D 6S TS JS
  3D 3H QS QC 8S 7H AD KS
  KD 6H 5S 4D 9H JH 9S 3C
  JC 5D 5C 8C 9D TD KH 7C
  6C 2C TH QH 6D TC 4S 7S
  JD 7D 8H 9C 2H QD 4C 5H
  KC 8D 2S 3S
$ 

คุณไม่จำเป็นต้องตรวจสอบสตริงหลายบรรทัด แต่สองรายการสุดท้ายของคุณต้องได้รับการอัปเดตอย่างแน่นอน
Nathan Merrill

@NathanMerrill yup ผู้ดำเนินการชั้นนำ / พื้นที่ต่อท้ายตอนนี้ดีขึ้นเล็กน้อย แต่อันที่เยื้องนั้นจะยากกว่าการพูดคุยทั่วไป - และเป็นที่ที่ฉันได้รับผลกำไรประมาณ 2/3
บาดเจ็บทางดิจิตอล

3

Python 3.4, 1134

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

import subprocess
from sys import argv

progamtext = open(argv[1]).read()

if 'argv' in progamtext or 'input' in progamtext or 'open' in programtext:#Make sure the program always produces the same results.
    exit(0)

program = subprocess.Popen(['C:\Python27\python', argv[1]], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
program.wait()
erroroutput1 = str(program.stderr.read())
output1 = str(program.stdout.read())
program = subprocess.Popen(['C:\Python27\python', argv[1]], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
program.wait()
erroroutput2 = str(program.stderr.read())
output2 = str(program.stdout.read())
if erroroutput1 != erroroutput2 or output1 != output2:#Make sure the program always produces the same results.
    exit(0)

newprog = ''
if erroroutput1:
    newprog += "import sys\n" + "sys.stderr.write("+ erroroutput1 + ')'
    if output1:
        newprog += "\n"
if output1:
    newprog += 'print ' + output1

if len(newprog) > len(progamtext):
    exit(0)

open(argv[1],mode='w').write(newprog)

มันทำงานอย่างไร:

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

โปรแกรมของ Sp3000 ได้รับการปรับปรุง:

import sys
sys.stderr.write(b'')
print b'0.540377721372\r\n3\r\n1\r\n7\r\n99\r\nf\r\n[5, 5]\r\n53\r\n53\r\n53\r\n'

โปรแกรมโบนัสพิเศษของ Sp3000 ได้รับการปรับปรุง:

รุ่นที่ได้รับการปรับให้เหมาะสมจะปิดลงเพียง. 001%

import sys
sys.stderr.write(b'')
print b'B\r\n'

1
ฉันแน่ใจว่ามีผลกระทบภายนอกอื่น ๆ กว่าargv, inputและrandomซึ่งรหัสของคุณจะแตก ;)
Martin Ender

2
ฮะ บางทีฉันควรใส่บางอย่างที่ไม่ใช่ระดับ - print id(0)เป็นสิ่งที่ดี
Sp3000

@ มาร์ตินคงที่ (ส่วนใหญ่) :)
TheNumberOne


เฮ้ความคิดสร้างสรรค์มาก
นาธานเมอร์ริลล์
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.