« Pythonの構文木を見る |Main| 日記 »

« Pythonの構文木を見る | Python | キミならどう書く 2.0 - ROUND 3 - »

Just Another Python Hacker, その3

Python リファレンスマニュアルを読んでいて、単項演算子は-, +の他に~(ビット否定)もあることを知ったのでそれを導入して西尾泰和の日記(2006-02-02)を改良してみました。

>>> print''.join([chr(x) for x in 7^77,-~7*7^77,-77^-~7*~7,77^7*7-~7,7*7&~-7*7,7
^77-7,~-777/7,777/7,77^7*7-~7,7^777/7,7777/77,~7*7^7-77,7*7&~-7*7,~7&7+77,7^7*7+
77,77^7*7-~7,7^777/7,777/7,~-777/7,7*7&~-7*7,~7&77,-777/~7,-7777/~77,7-7777/~77,
7777/77,~7*7^7-77,~-7^~-7*7])
Just Another Python Hacker,

80文字改行で、1行くらい短くなりましたね。なお見やすくするために80文字で改行しているので実行してみる人は改行を取り除いてくださいね。

この他に括弧をつける機能も入れてみたのですけど、括弧はコストが高いみたいでちっとも使われませんでした。


__ ちょっと行数は短くなったけども、7だらけなのは変わらないので見栄えは大して変わらず、ちょっと面白くないので0と1のバージョンを作ってみました。

>>> print''.join([chr(x) for x in -~0111,100|10+11,10^11*11,100|10+10,-0101/~1,0
101,110,111,100|10+10,~11^-100,101,1+111-~1,-0101/~1,10*010,11*11,100|10+10,~11^
-100,111,110,-0101/~1,0110,~1%~-100,~-100,10|~-100,101,1+111-~1,11*~1*~1])
Just Another Python Hacker,

今のところこれが一番短いですね。0と1から10進数と8進数の両方を作れるからでしょう。

>>> print''.join([chr(x) for x in 7^77,77^070,~-77^077,700/~-7,7*7&7*70,7^70,770
/7,777/7,700/~-7,7^777/7,707/7,77^077,7*7&7*70,70+70/7,70^077,700/~-7,7^777/7,77
7/7,770/7,7*7&7*70,~7&77,-777/~7,~-700/7,7+700/7,707/7,77^077,700&70700])
Just Another Python Hacker,

0と7の方がわずかに短いですね。でも0/1版は最初の項がマイナスで始まるからinの後のスペースを詰めることが出来てやっぱり同じですね…。


__

>>> print''.join([chr(x) for x in -~0111,100|10+11,10^11*11,100|10+10,-0101/~1,0
101,110,111,100|10+10,~11^-100,101,1+111-~1,-0101/~1,10*010,11*11,100|10+10,~11^
-100,111,110,-0101/~1,0110,~1%~-100,~-100,10|~-100,101,1+111-~1,11*~1*~1])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in -222/~2,20|202/2,22^202/2,20|200/2,2*020,0202/
2,220/2,222/2,20|200/2,2-~202/2,202/2,0202-020,2*020,2*2*20,20+202/2,20|200/2,2-
~202/2,222/2,220/2,2*020,0220/2,~2+200/2,~-200/2,~2+220/2,202/2,0202-020,22*2])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in 3^0333/3,-3-~3*30,3-~333/3,~3-~3*30,~-33,0303/
3,330/3,333/3,~3-~3*30,3+303/3,303/3,3+333/3,~-33,330/3-30,30*3-~30,~3-~3*30,3+3
03/3,333/3,330/3,~-33,3*030,333^300,33*3,330/3-3,303/3,3+333/3,33+33/3])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in 044^440/4,~-4*~-40,4+444/4,4*40-44,040,0404/4,
440/4,444/4,4*40-44,4+400/4,404/4,4+440/4,040,40+40,4*40-~-40,4*40-44,4+400/4,44
4/4,440/4,040,0440/4,4^404/4,~-400/4,4^444/4,404/4,4+440/4,44])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in 55^5*5*5,5-~555/5,5+55+55,5+555/5,50&050,0505/
5,55+55,555/5,5+555/5,55+~-50,505/5,5+55+~-55,50&050,55+5*5,-5&5*5*5,5+555/5,55+
~-50,555/5,55+55,50&050,0550/5,5^50+50,50+~-50,5^55+55,505/5,5+55+~-55,~-055])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in 66|6+66,6+666/6,066-~60,66^066,~6&6*6,~-66,660
/6,666/6,66^066,6^660/6,606/6,66|060,~6&6*6,66^6+6+6,60-~60,66^066,6^660/6,666/6
,660/6,~6&6*6,66+6,6*6-~60,~-600/6,6+606/6,606/6,66|060,60&6060])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in 7^77,77^070,~-77^077,700/~-7,7*7&7*70,7^70,770
/7,777/7,700/~-7,7^777/7,707/7,77^077,7*7&7*70,70+70/7,70^077,700/~-7,7^777/7,77
7/7,770/7,7*7&7*70,~7&77,-777/~7,~-700/7,7+700/7,707/7,77^077,700&70700])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in 8*8+80/8,80|808/8,808/~-8,80|800/8,8+8+8+8,8*8
-~0,880/8,888/8,80|800/8,8|8+88,808/8,800/~-8,8+8+8+8,80,88|8-~88,80|800/8,8|8+8
8,888/8,880/8,8+8+8+8,80-8,88-~8,88+88/8,8-888/~8,808/8,800/~-8,-88/~-~0])
Just Another Python Hacker,

>>> print''.join([chr(x) for x in 90&-9-9,9+99+9,99|9+9,99+9+~-9,99&9000,99&9*9,
990/9,999/9,99+9+~-9,99^99/9,909/9,~99^-9-9,99&9000,~9%90,9|9+9^99,99+9+~-9,99^9
9/9,999/9,990/9,99&9000,9*~-9,~-~-99,99,9|99,909/9,~99^-9-9,9+99&9-90])
Just Another Python Hacker,

4が一番短いですね。そしてやっぱりどれも括弧は使わないですね。コストが高いんでしょう。

DIGIT = 1
OPERATORS = "%/&|^*+-"
PREFIX = "-~0" + str(DIGIT)
SUFFIX = "0" + str(DIGIT)
caches = [{}, {DIGIT: str(DIGIT), 0: "0"}]
numLetters = {}
QUERY = [ord(x) for x in "Just Another Python Hacker,"]
query = QUERY
 
def evalEq(eq):
    try:
        v = eval(eq)
        if not(numLetters.has_key(v)):
            numLetters[v] = level
            result[v] = eq
    except:
        pass


for level in range(2, 100):
    result = {}
    
    for a in caches[level - 1].values():
        for prefix in PREFIX:
            evalEq(prefix + a)
        for suffix in SUFFIX:
            evalEq(a + suffix)

    for i in range(1, level - 1):
        j = level - i - 1
        for a in caches[i].values():
            for b in caches[j].values():
                for f in OPERATORS:
                    eq = a + f + b
                    evalEq(eq)

    for i in range(1, level - 3):
        j = (level - 3) - i
        for a in caches[i].values():
            for b in caches[j].values():
                for f in OPERATORS:
                    eq = "%s%s(%s)" % (a, f, b)
                    evalEq(eq)
                    eq = "(%s)%s%s" % (a, f, b)
                    evalEq(eq)

    for i in range(1, level - 5):
        j = (level - 5) - i
        for a in caches[i].values():
            for b in caches[j].values():
                for f in OPERATORS:
                    eq = "(%s)%s(%s)" % (a, f, b)
                    evalEq(eq)

 
    query = [q for q in query if not(q in result)]
    caches.append(result)
    if query == []: break
    print level
 

print "print''.join([chr(x) for x in " + ",".join(
    [caches[numLetters[x]][x] for x in QUERY]) + "])"

トラックバック(Trackback)

Trackback URL: http://www.nishiohirokazu.org/mt/mt-tb.cgi/243

ご意見・ご感想をお送りください(フィードバック)

(フィードバックはメールで送信され、基本的に表示されませんが、内容によっては公開させていただくこともございます。ご了承ください。Your comment doesn't appear the page immediately. If the comment has value to other people, it will be put on the page or subsequent entries. Thank you.)

上の情報は、いずれも未記入でかまいません。 All of above questions are optional.