You are not logged in.

#1 2010-05-10 19:32:02

Chimera
Member
From: Run Level 7
Registered: 2010-03-28
Posts: 43

obfuscated python

Anyone here played floodit?
I wrote it in Python, with the explicit goal of keeping it as short as possible, at the cost of readability.
I'm just wondering if anyone can find a way to shorten this code further, for fun.              cool

import fltk, random
colors, path=[fltk.FL_BLACK, fltk.FL_RED, fltk.FL_BLUE, fltk.FL_GREEN, fltk.FL_WHITE, fltk.FL_YELLOW], []
def flip(x, y, color):
    if "%d %d" %(x, y) in path: return 
    path.append("%d %d" %(x, y))
    [flip(nx, ny, color) for nx, ny in [[x+1, y], [x-1, y], [x, y+1], [x, y-1]] if 0<=nx<15 and 0<=ny<15 and grid[nx][ny].color()==grid[x][y].color()]
    grid[x][y].color(color)
    grid[x][y].redraw()
    path.pop()
    if all([grid[r][c].color()==grid[r][c-1].color() for r in range(15) for c in range(15)]): fltk.fl_message("You win!")
app=fltk.Fl_Window(425, 475, "Flood-It")
app.begin()
grid=[[fltk.Fl_Box(fltk.FL_FLAT_BOX, x*25+25, y*25+75, 25, 25, "") for x in xrange(15)] for y in xrange(15)]
[square.color(random.choice(colors)) for row in grid for square in row]
[button.callback(lambda button: flip(0,0, button.color())) or button.color(colors.pop()) for button in [fltk.Fl_Button((x%3*25)+25, (x/3*25)+15, 25, 25) for x in xrange(6)]]
app.show()
fltk.Fl.run()

btw: This code does not keep track of how many turns you have played

Offline

#2 2010-05-11 17:20:28

AlecSchueler
Member
Registered: 2009-05-30
Posts: 22

Re: obfuscated python

I'm sure that with a complete rewrite there's a lot that can be removed from this. I really enjoy obfuscating python, so I hope to take a look at it at the weekend, but for now you can cut out about 200 characters with a couple of small changes:

from fltk import *;c,p,t,f,z,a,r=[56,88,216,63,255,95],[],25,15,0,Fl_Window(425,475,"Flood-It"),__import__('random')
def w(x,y,color):
 if(x,y)in p or p.append((x,y)):return
 [flip(e,f,color)for e,f in[[x+1,y],[x-1,y],[x,y+1],[x,y-1]]if 0<=e<f and 0<=f<f and g[e][f].color()==g[x][y].color()];g[x][y].color(color);g[x][y].redraw();p.pop()
 if all([g[r][c].color()==g[r][c-1].color()for r in range(f)for c in range(f)]):fl_message("You win!")
g=[[Fl_Box(1,x*t+t,y*t+t,t,t,"")for x in range(f)] for y in range(f)];a.begin();[square.color(r.choice(c))for row in g for square in row];[b.callback(lambda b:w(0,0,b.color()))or b.color(c.pop())for b in[Fl_Button((x%3*t)+t,(x/3*t)+f,t,t)for x in range(6)]];a.show();Fl.run()

EDIT: noticed a few more redundancies -- now down ~270 characters

Last edited by AlecSchueler (2010-05-11 17:38:57)

Offline

#3 2010-05-11 17:32:48

keenerd
Package Maintainer (PM)
Registered: 2007-02-22
Posts: 647
Website

Re: obfuscated python

How does replacing newlines with semicolons help size?  It is one byte either way.  The single biggest savings would be from replacing the "button" variable with just "b".  Some more savings by using product(range(15), repeat=2) instead of nested list comprehensions.  Use "import fltk as f, random as r".

It might be better to store the grid not as a 2D list, but as a dictionary with (x,y) tuples as keys and the data as values.

Last edited by keenerd (2010-05-11 17:35:17)

Offline

#4 2010-05-11 17:43:03

AlecSchueler
Member
Registered: 2009-05-30
Posts: 22

Re: obfuscated python

keenerd wrote:

How does replacing newlines with semicolons help size?

Some people count display size as well as the size in bytes. It also makes it harder to read, which I took as an additional goal implicitly stated by the topic title.


keenard wrote:

The single biggest savings would be from replacing the "button" variable with just "b".

You beat me to it. I was just revisiting the thread to make this change.

keenerd wrote:

Use "import fltk as f, random as r"

I tried this, but `from fltk import *` was shorter. That was actually before I replaced a lot of stuff with the literal values though, so that may not be the case now. I'll try it again shortly.

Last edited by AlecSchueler (2010-05-11 17:47:10)

Offline

#5 2010-05-11 17:45:47

AlecSchueler
Member
Registered: 2009-05-30
Posts: 22

Re: obfuscated python

It cuts out a single byte

import fltk as F,random as r;c,p,t,f,z,a=[56,88,216,63,255,95],[],25,15,0,F.Fl_Window(425,475,"Flood-It")
def w(x,y,color):
 if(x,y)in p or p.append((x,y)):return
 [flip(e,f,color)for e,f in[[x+1,y],[x-1,y],[x,y+1],[x,y-1]]if 0<=e<f and 0<=f<f and g[e][f].color()==g[x][y].color()];g[x][y].color(color);g[x][y].redraw();p.pop()
 if all([g[r][c].color()==g[r][c-1].color()for r in range(f)for c in range(f)]):F.fl_message("You win!")
g=[[F.Fl_Box(1,x*t+t,y*t+t,t,t,"")for x in xrange(f)] for y in xrange(f)];a.begin();[square.color(r.choice(c))for row in g for square in row];[button.callback(lambda b:w(0,0,b.color()))or button.color(c.pop())for button in[F.Fl_Button((x%3*t)+t,(x/3*t)+f,t,t)for x in xrange(6)]];a.show();F.Fl.run()

Offline

#6 2010-05-11 18:33:52

keenerd
Package Maintainer (PM)
Registered: 2007-02-22
Posts: 647
Website

Re: obfuscated python

Too lazy to super crunch it.  Itertools might have been a wash.  Setattr(c) was also futile.  But using a dict of tuples helped quite a bit!  I am annoyed with the offset calculations, there must be a better way.  Untested.

import fltk as F, random as r, itertools as i
cs,pa=[56,88,216,63,255,95],[]
def f(p, c):
    if p in pa or min(p) < 0 or max(p)>15: return
    pa.append(p)
    [f(p2,c) for p2 in [(p[0]+o[0], p[1]+o[1]) for o in [(1,0),(-1,0),(0,1),(0,-1)]] and g[p2].c()==g[p].c()]
    g[p].c(c)
    g[p].redraw()
    pa.pop()
    if all(g[(0,0)].c() == v.c() for v in g.values()): F.fl_message("You win!")
a=F.Fl_Window(425, 475, "Flood-It")
a.begin()
g=dict((x,y),F.Fl_Box(1, x*25+25, y*25+75, 25, 25, "") for x,y in i.product(range(15), repeat=2))
[s.__setattr__('c', s.color) for s in g.values()]
[s.c(r.choice(cs)) for s in g.values()]
[b.callback(lambda b: f((0,0), b.color())) or b.color(cs.pop()) for b in [F.Fl_Button((x%3*25)+25, (x/3*25)+15, 25, 25) for x in xrange(6)]]
a.show()
F.Fl.run()

Decoder ring:
cs colors
c color
F fltk
r random
i itertools
pa path
f flip
g grid
s square
a app
b button
o offset
p point

Last edited by keenerd (2010-05-11 18:48:42)

Offline

#7 2010-05-12 01:36:30

Chimera
Member
From: Run Level 7
Registered: 2010-03-28
Posts: 43

Re: obfuscated python

lol, this is awesome
I actually only had lines in mind, but I was considering counting characters. I definitely wouldn't use newlines though, even though it helps obfuscation--they're like pseudo-cheating

Interesting that so "clean" a language doesn't have to be, though. Come to think of it, my code looks relatively clean compared to some of the other implementations here...

Offline

Board footer

Powered by FluxBB