축소기를 작성합시다


14

배경

축소 기는 일반적으로 웹 브라우저에 JavaScript를 제공 할 때 사용됩니다. 일반적으로 전송해야하는 바이트 수를 줄이는 데 사용됩니다. 대역폭 절약은 명백한 이유로 유용합니다. 어떤 사람들은 의도적으로 코드를 읽기 어렵게 만드는 난독 화를 사용합니다.

우리는 파이썬 2를 축소 할 것입니다

나는 축소 경험에 JavaScript 또는 Python을 사용할지 여부에 대해 토론하고 있었고 두 가지 이유로 파이썬을 결정했습니다. 공백 문제와 흥미로운 동적 문제를 추가 할 것이라고 생각합니다. 또한 Python 2.7을 사용 ()하면 인쇄 중에 불필요한 제거 (예 : print("Hello world")vs. print"Hello world") 와 같은 또 다른 동적 요소가 제공됩니다 . 개인적으로 언어를 공개하는 것을 선호했지만 일부 언어의 경우이 프로세스가 적합하지 않습니다. 그리고 어떤 언어를 축소하기로 결정했는지는 점수에 직접 영향을 미칩니다 (언어를 축소 할 수있는 경우).

명세서

목표는 어쨌든 코드의 기능을 변경하지 않는 방식으로 만 코드를 수정하는 것입니다. 물론 출력에 영향을 미치지 않는 범위 내에서 변수 이름을 축소 프로그램 내에서 변경할 수 있습니다 ( 범위 추적 ). 특정 프로그램을 제공하고 있지만 모든 표준 허점 이 금지되어 있으므로 테스트 사례에 맞게 최적화하지 마십시오 .

점수 : 프로그램을 축소 한 후의 길이입니다.

입력 : 모든 Python 2.7 프로그램 (오류가 포함되지 않음)

출력 : 축소 버전입니다.

코드가 유효한 모든 Python 2.7 입력을 수용 할 수 있어야하지만 효과를 입증하기 위해 스크립트를 테스트해야합니다.

예제 프로그램을 보려면 여기클릭하십시오 .

더 접근하기 쉬운 문제 만들기

내 솔루션 내부에있는 코드를 자유롭게 사용하거나 수정하십시오 (아래 참조). 나는 당신이 견적 기본 견적 처리를 시작하기 위해 이것을했다; 그러나 들여 쓰기 등으로 확장 할 수 있습니다.

파이썬을 축소하는 예제 방법

모든 공백은 가능한 최소량으로 대체 할 수 있습니다 (Python 에서는 tab으로 까다로운 작업을 수행 할 수 있음을 인정 하지만 구현 여부를 결정하기 위해 귀하에게 맡길 것입니다).

다음과 같은:

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

될 수 있습니다 :

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

기술적으로 루프 안에 한 줄만 있으면 더 압축 할 수 있습니다.

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

그러나 파이썬에서 공백을 최소화 할 수있는 또 다른 방법이 있습니다.

다음과 같은:

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

될 수 있습니다 :

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

2와 사이에 공백이 필요하지 않습니다 for. 변수, 함수 및 키워드 숫자로 시작할 수 없습니다 . 따라서 파이썬 인터프리터는 <num><keyword>공간이 없어도 괜찮습니다 . )와 사이에 공백이 없어도 if됩니다.

프로그램의 출력을 변경해서는 안됩니다! 그래서:

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

위의 인쇄 문 사이의 공간을 제거하기 때문에 동일하게 유지해야 2하고 is출력을 수정하는 것입니다.



(!) 참고 : 어떤 프로그램이 없음을 출력 할 수 최단 당 임의의 입력 프로그램 당량 이 논의
리키 수녀

이미 파이썬 축소 도구 있습니다. 나는이 질문이 이미 종료 된 도구보다 더 나은 해결책을 얻을 수 있다고 생각하지 않습니다.
tsh December

변화 '1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111''1'*100허용? 동작이 동일하므로해야합니까?
l4m2

답변:


2

파이썬 2.7, 2013 점수

이 프로그램은 참조 용으로 사용할 수 있으며 다음 코드를 가져 와서 수정 한 다음 자체 솔루션에 게시 할 수 있습니다.

가늠자에 따르면, 인용 처리에도 정규 표현식을 사용해야했을 수도 있지만 현재 상태에서는 사람들을 문제에 빠뜨리기 시작하는 것으로 충분할 것이라고 생각합니다.

Python 2.7을 선택한 이유 : exec키워드 를 통해 프로그램이 충돌하는지 테스트하는 것이 더 쉬울 것이라고 생각했습니다 .

이 코드는 다음과 같이 프로그램을 수행 in.txt합니다.

나는 인용 파서를 작성하여 참여하고 싶은 사람을 위해 볼 롤링을 얻어야한다고 생각했다. 이 문제의 복잡성.

참고 : 이 축소기에는 여전히 개선의 여지가 충분합니다. 그들은처럼, 내 키워드를 사용하는 때 당신은 들여 쓰기, 변수 이름, 괄호를 제거 함께 놀러 수처럼 printyield.

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)

프로그램 출력 :

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.