Hãy viết một Công cụ khai thác


14

Lý lịch

Công cụ khai thác được sử dụng, thông thường, khi phục vụ JavaScript cho Trình duyệt web của bạn. Nó thường được sử dụng để giảm số lượng byte phải gửi. Tiết kiệm băng thông là hữu ích vì lý do rõ ràng. Một số người sử dụng obfuscaters (điều đó cố tình làm cho mã khó đọc hơn), tôi không nói về những điều đó.

Chúng tôi sẽ thu nhỏ Python 2

Tôi đã tranh luận về việc có nên sử dụng JavaScript hay Python cho trải nghiệm rút gọn hay không và tôi đã quyết định về Python vì hai lý do: vấn đề khoảng trắng và tôi nghĩ rằng điều đó sẽ thêm một vấn đề năng động thú vị. Ngoài ra, sử dụng Python 2.7 sẽ cung cấp một động lực khác, chẳng hạn như loại bỏ không cần thiết ()trong quá trình in (tức là print("Hello world")so với print"Hello world"). Cá nhân tôi sẽ thích mở nó với bất kỳ ngôn ngữ nào, nhưng đối với một số ngôn ngữ, quá trình này sẽ không có ý nghĩa nhiều. Và, ngôn ngữ nào bạn quyết định giảm thiểu sẽ ảnh hưởng trực tiếp đến điểm số của bạn (và nếu ngôn ngữ thậm chí có thể được rút gọn).

Thông số kỹ thuật

Mục tiêu của bạn là chỉ sửa đổi mã theo cách không thay đổi chức năng của nó. Tất nhiên, bạn có thể thay đổi tên biến (trong chương trình rút gọn của mình) miễn là nó không ảnh hưởng đến đầu ra (theo dõi phạm vi ). Mặc dù tôi đang cung cấp cho bạn một chương trình cụ thể, vui lòng không tối ưu hóa cho trường hợp thử nghiệm vì tất cả các sơ hở tiêu chuẩn đều bị cấm.

Điểm : độ dài của chương trình sau khi bạn thu nhỏ nó.

Đầu vào : Bất kỳ chương trình Python 2.7 nào (không có lỗi)

Đầu ra : Một phiên bản rút gọn.

Mặc dù mã của bạn có thể chứa được tất cả đầu vào Python 2.7 hợp lệ, nhưng cần phải kiểm tra tập lệnh của bạn dựa vào thứ gì đó để chứng minh tính hiệu quả của nó.

Nhấn vào đây để xem chương trình ví dụ.

Làm cho vấn đề dễ tiếp cận hơn

Vui lòng sử dụng hoặc sửa đổi bất kỳ mã nào được tìm thấy trong giải pháp của tôi (được liệt kê dưới đây). Tôi đã làm điều này để giúp bạn bắt đầu với trích dẫn xử lý trích dẫn cơ bản; tuy nhiên, bạn có thể mở rộng nó sang thụt lề, v.v.

Ví dụ các cách để thu nhỏ Python

Tất cả khoảng trắng có thể được thay thế bằng số tiền tối thiểu có thể (Tôi thừa nhận rằng trong Python bạn có thể thực hiện một số nội dung phức tạp bằng các tab , nhưng tôi sẽ để bạn quyết định có thực hiện hay không).

Thí dụ

Sau đây là

def print_a_range(a):
    for i in range(a):
        print(i)

Có thể là:

def print_a_range(a):
 for i in range(a):
  print(i)

Về mặt kỹ thuật, nếu chỉ có một dòng trong một vòng lặp, bạn có thể nén nó nhiều hơn:

def print_a_range(a):
 for i in range(a):print(i)  #Note, you can also remove the `()` here.

Tuy nhiên, có một cách khác để bạn có thể thu nhỏ khoảng trắng trong Python:

Sau đây là

print ([a * 2 for a in range(20) if a % 2 == 0])

Có thể là:

print([a*2for a in range(20)if a%2==0])

Lưu ý rằng không cần khoảng cách giữa 2for. Biến, chức năng và từ khóa không thể bắt đầu bằng một số. Vì vậy, trình thông dịch Python vẫn ổn <num><keyword>, không có khoảng trắng. Bạn cũng nên lưu ý rằng không phải có khoảng cách giữa )if.

Lưu ý, bạn không được thay đổi đầu ra của chương trình! Vì thế:

print"f(x)=x*2 is a great equation!"

Câu lệnh in ở trên phải giữ nguyên vì loại bỏ khoảng trắng giữa 2issẽ sửa đổi đầu ra.



Sidenote: không có chương trình nào có thể xuất ra tương đương ngắn nhất so với bất kỳ chương trình nhập liệu tùy ý nào, theo cuộc thảo luận này
Leaky Nun

Có làm được một số công cụ python minifier đã . Tôi không nghĩ câu hỏi này có thể nhận được giải pháp tốt hơn các công cụ đã thoát.
tsh

Là thay đổi '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'thành '1'*100cho phép? Yêu cầu làm như hành vi là như nhau?
l4m2

Câu trả lời:


2

Điểm số Python 2.7, 2013

Chương trình này có thể được sử dụng làm tài liệu tham khảo và bạn được phép lấy đoạn mã sau và sửa đổi nó và sau đó đăng nó trong các giải pháp của riêng bạn.

Nhìn nhận lại, có lẽ tôi cũng nên sử dụng regex cho việc xử lý trích dẫn, nhưng tôi nghĩ ở trạng thái hiện tại của nó có thể đủ để khiến mọi người bắt đầu gặp vấn đề.

Tại sao tôi chọn Python 2.7: Tôi nghĩ sẽ dễ dàng hơn để kiểm tra xem liệu tôi có làm chương trình bị sập thông qua exectừ khóa không.

Mã này nhận chương trình như in.txt.

Tôi hình dung ít nhất tôi nên làm cho trái bóng lăn cho bất cứ ai muốn tham gia bằng cách viết một trình phân tích cú pháp trích dẫn (điều đó cũng xảy ra để xử lý các bình luận) và một ví dụ ngắn gọn về cách regex, khi kết hợp với trình phân tích cú pháp trích dẫn có thể thực sự thay đổi trò chơi về sự phức tạp của vấn đề này.

Lưu ý: vẫn còn nhiều chỗ để cải tiến trong công cụ khai thác này. Giống như bạn có thể chơi xung quanh với thụt lề, tên biến và xóa dấu ngoặc đơn khi chúng đang được sử dụng từ khóa của tôi, như printhoặc yield.

import re

with open("in.txt","r") as fi:
    code = fi.read()

class QuoteHandler():
    def __init__(self):
        pass
    def loadCode(self,code):
        quoteFlag = False
        currentQuoteChar = ""
        ignoreNext = False
        inEndLineComment=False
        startLocation = 0

        self.reAddStrings = []

        outStr = ""

        for i, character in enumerate(code):
            if ignoreNext:
                ignoreNext = False
            elif inEndLineComment:
                if character in "\r\n":
                    inEndLineComment=False
            elif character == "#" and not quoteFlag:
                inEndLineComment = True
            elif character in "'\"" and (currentQuoteChar == character or not quoteFlag):
                if quoteFlag:
                    self.reAddStrings.append(code[startLocation+1:i])
                else:
                    currentQuoteChar = character
                    startLocation = i
                quoteFlag = not quoteFlag
            elif character == "\\":
                ignoreNext = True

            if not inEndLineComment and not quoteFlag:
                outStr+=character                
        return outStr

    def find_all_locations(self,substr,code):
        return [m.start() for m in re.finditer(substr, code)]

    def unloadCode(self,code):
        temp = self.reAddStrings[::-1]
        for i, location in enumerate(list(self.find_all_locations('"',code))[::-1]):
            code = code[:location] + "\"" + temp[i] + code[location:]
        return code

def applyRegexes(code):#\w here?
    operatorRegexCleaner = ["([\d\/*\-\"=,'+{}:[\](\)])","[ \t]+","(\w)"]
    regexes = [
        [''.join(operatorRegexCleaner),r"\1\2"],
        [''.join(operatorRegexCleaner[::-1]),r"\1\2"],#removes whitespace between operators
        ["\n\s*\n","\n"]#removes empty lines
    ]
    for regex in regexes:
        code = re.sub(regex[0],regex[1],code)
    return code

qh = QuoteHandler()
code = qh.loadCode(code)
code = applyRegexes(code)
code = qh.unloadCode(code)
print(code)
exec(code)

Đầu ra của chương trình:

def factor(factor_number):
    for n in range(2,factor_number):
        if factor_number % n==0:    
            yield(n)
def gcd(a,b):
    """Calculate the Greatest Common Divisor of a and b.

    Unless b==0, the result will have the same sign as b (so that when
    b is divided by it, the result comes out positive).
    """
    while b:
         a,b=b,a%b 
    return a
class Apricot:
    def __init__(self):
        self.mold=False
    def get(self):
        return self.mold
    def update(self):
        self.mold=not self.mold
    def blue(self):return5
def tell_me_about_these_numbers(*a):
    print("%d is the first number!" % a[0])
    print("{} / 3 is {}".format(a[0],a[0]/3.))
    myFavorate=Apricot()
    for number in a:
        print list(factor(number))
        myFavorate.update()
    print[gcd(a,b)for a,b in zip(a[:-1],a[1:])]
    print(myFavorate.get())
tell_me_about_these_numbers(5,6,9,45,200)
print"Let's play with scope!"
a,b=10,9
def randomFunction(a):
    print(a)
randomFunction(b)
print(a)
for a in range(100):
    b+=a
print(a)
print(b)
li=[]
for i in range(10):
 li.append(i*2)
print(li)
print([i*2for i in range(10)])
a=c=b=d=e=f=g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=y=z=5
print(a)
a-=1
print(a)
g=10
print(str(10**g+5)[::-1])
def blue_fish(a):
    def blue_fish(a):
        def blue_fish(a):
            return a
        a+=1
        return blue_fish(a)
    a-=1
    return blue_fish(a)
print(blue_fish(10))
def blue_fish(a):
    if a==0:
        return"0"
    return"1" +blue_fish(a-1)
print(blue_fish(5))
blue_fish=lambda a,b,c:a*b*c
print(blue_fish(1,2,3))
blue_fish=lambda*a:reduce(lambda a,b:a*b,a)
print(blue_fish(1,2,3))
print(max([[6,1],[5,2],[4,3],[3,4],[2,5],[1,6]],key=lambda a:a[1]))
print(zip(*[[1],[2],[3],[4],[5]]))
print"Now let's test to see if you handle quotes correctly:"
print"test \'many diffent\' \"types of \" quotes, even with \' \" trailing quotes"
print"""

Multi line quotes are great too!

"""
a=""" ::
one more multi-line quote won't hurt
"""
print a
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.