|
Speed Challenge 13: The Polygon Split
Last post 05-15-2007 8:20 AM by omega0. 9 replies.
-
05-09-2007 3:04 PM
|
|
-
Faxmachinen


- Joined on 03-19-2007
- Posts 199
|
Speed Challenge 13: The Polygon Split
Sorry for the delay. Anyhow, let's get cracking:
This time we're going to write a program that splits any surface into three- and four-sided polygons. The program should take a sequence of 2D coordinates as input, which should be linked together in a loop to define the surface. For simplicity's sake you may assume that the loop doesn't cross itself. The program can then split it any way it sees fit, as long as the end result consists only of three- and four-sided convex polygons. Obviously, the fewer polygons the better.
How you choose to present the result is up to you, but it shouldn't be too hard to understand. You can also snag some bonus points with fancy ASCII or OpenGL graphics here.
rpar PROTON all
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 199
|
Re: Speed Challenge 13: The Polygon Split
I'll give you 12 hours as of this post. In the mean time, here's a simple solution that doesn't account for concave surfaces:
# polysplit.py
input_ = raw_input("Please enter the vertex coords in the format \"x,y\".\n")
coords = []
while input_:
for xy in input_.split():
coords.append(map(lambda x: int(x), xy.split(',')))
input_ = raw_input()
# Calculate which vertexes to link
splits = []
for i in range(2,len(coords)):
splitindex = 2;
while 1:
if i % splitindex:
break
splits.append((i - splitindex, i))
splitindex *= 2;
print "Splits:"
for line in splits:
print "%d,%d -> %d,%d" % tuple(coords[line[0]] + coords[line[1]])
rpar PROTON all
|
|
-
-
Autonuke


- Joined on 11-07-2006
- Posts 50
|
Re: Speed Challenge 13: The Polygon Split
# poly.py
def spdp(p1, p2, p3): """ return signum of perp dot product of edges p1..p2 and p2..p3 """ x1, y1 = p1 x2, y2 = p2 x3, y3 = p3 pdp = (y1 - y2)*(x3 - x2) + (x2 - x1)*(y3 - y2) if pdp < 0: return -1 if pdp > 0: return 1 return 0 def isstrictlyconvex(pgon): N = len(pgon) if N < 3: return False signum1 = spdp(pgon[0], pgon[1], pgon[2]) if signum1 == 0: return False if N == 3: return True for i in range(1, N): signum = spdp(pgon[i], pgon[(i + 1) % N], pgon[(i + 2) % N]) if signum != signum1: return False return True input_ = raw_input('Enter vertices: ').split() pgon = [] try: for pair in input_: x, y = pair.split(',') pgon.append((int(x), int(y))) except ValueError: print "No, no, no. You're supposed to enter the vertices as comma'ed pairs of integers." print "The pairs should be separated by whitespace. Example: -1,0 0,2 1,0 0,-2" else: if not isstrictlyconvex(pgon): print "What you supplied is not a (strictly) convex polygon." print "Maybe Faxmachinen has a better solution for you?" elif len(pgon) < 5: print "That's optimal as it is." else: x0, y0 = pgon[0] for i, (x, y) in enumerate(pgon[3:-1:2]): print '%d. Draw a line from %d,%d to %d,%d.' % (i + 1, x0, y0, x, y) print "That's it, well done!"
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 199
|
Re: Speed Challenge 13: The Polygon Split
Good work. Speed Challenge 14 is all yours, Autonuke.
rpar PROTON all
|
|
-
-
Autonuke


- Joined on 11-07-2006
- Posts 50
|
Speed Challenge 14: The New Ook!?
You're lucky: in this challenge, you have the chance to dream up your very own programming language. But, before you go overboard to create the language that makes Python look ugly, you also have to write a program that can 1) translate programs in your new language into brainfuck, and 2) translate brainfuck programs into your new language. For example, I've just invented BabyTalk. It is as trivially isomorphic (well, nearly) with brainfuck as Ook! is. Here's an example: Ma! Ma? Ma. Ma. Ma. Ma! Ma? Ma? Ma? Ma? Ma ma ma ma ma. Ma ma ma ma. Ma? Ma. Ma. Ma. Ma! Ma? Ma! Ma ma ma ma. Ma. Ma! Ma? Ma! Ma? Ma! Ma! Ma? Ma! Ma? Ma ma ma ma? Ma. Ma. Ma! Ma ma ma ma. Ma! Ma ma ma? Ma ma ma! Ma ma ma! Ma ma ma? Ma ma! Ma ma ma ma ma ma! Ma ma ma ma. Ma? Ma! Ma ma ma ma ma ma ma ma! Ma ma ma ma? Ma! Ma ma ma ma ma ma ma ma. Ma? Ma? Ma! Ma? Ma! Ma? Ma. Ma ma ma ma ma ma ma ma! Ma ma ma ma ma ma ma ma? Ma. Ma! Ma? Ma ma ma ma ma ma ma ma. Ma ma ma ma? Ma. Ma! Ma ma ma ma ma ma ma ma? Ma ma ma! Ma ma ma. Ma. Ma! Ma? Ma? Ma? Ma! Ma. Ma! Ma! Ma. Ma! Ma? Ma. Ma. Ma! Ma ma ma ma ma ma ma ma! Ma ma ma ma. Ma ma ma ma ma ma ma ma! Ma! Ma? Ma. Ma ma ma ma ma ma ma ma! Ma ma? Ma ma? Ma ma! Ma ma? Ma ma? Ma ma? Ma ma ma ma ma ma ma ma. Ma ma. Ma ma. Ma ma! Ma ma! Ma ma! Ma ma! Ma ma? Ma ma? Ma ma ma ma ma ma ma ma! Ma ma ma ma? Ma. Ma ma ma ma ma ma ma ma? Ma ma ma ma? Ma ma ma ma ma ma ma ma. (The above prints 'Hello World!', a reasonable thing for a baby to say. Full stops, exclamation marks and question marks are interchangeable, to give the programmer that extra bit of poetic freedom.) The deadline is 24 hours from this post.
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 199
|
Re: Speed Challenge 14: The New Ook!?
Evil pyramid schemes included: # pdcompiler.py
# MUAHAHA!
def opValue(script):
if script and script[0] == "two":
script.pop(0)
if script and script[0] == "three":
script.pop(0)
if script and script[0] == "four":
script.pop(0)
return 8
return 4
return 2
return 1
def popTo(token, script):
while script.pop(0) != token:
if not script:
print 'Error: Expected "%s", found EOF instead.' % token
return False
return True
# Open files and read
fname = raw_input("Please enter the Puppet Dance file to compile.\n")
infile = open(fname, 'r')
outfile = open(fname + '.b', 'w')
script = infile.read().lower().split()
infile.close()
# Compile
output = []
token_num = 0
error = False
while script:
token = script.pop(0)
token_num += 1
# Wishing Python had switch() right about now
if token == "\o":
if not popTo("o/", script):
error = True
break
elif token == "o/":
print 'Warning: Unexpected "o/" at token %d.' % token_num
elif token == "one":
opValue(script) # Do nothing
elif token == "up":
output.append("+" * opValue(script))
elif token == "down":
output.append("-" * opValue(script))
elif token == "left":
output.append("<" * opValue(script))
elif token == "right":
output.append(">" * opValue(script))
elif token == "go":
output.append("[")
elif token == "repeat":
output.append("]")
elif token == "jump":
output.append(",>" * opValue(script))
elif token == "spin":
output.append(".>" * opValue(script))
elif token == "two" or token == "three" or token == "four":
print 'Error: Did not expect "%s" at %d.' % (token, token_num)
error = True
break
else:
print 'Error: Unknown token "%s" at %d.' % (token, token_num)
error = True
break
if not error:
# Optimize a little
outstr = "".join(output).replace("><", "").replace("<>", "")
# Write to output file
outfile.write(outstr)
print 'Compiled successfully to "%s.b"' % fname---------------------------- # pddecomp.py
def repeat_count(element, array, index):
result = 0
while index < len(array) and array[index] == element:
result += 1
index += 1
return result
# Okay beating a dead horse here
def multiop(num, op):
result = []
while num > 0:
result.append(op)
if num > 1:
result.append("two")
if num > 3:
result.append("three")
if num > 7:
result.append("four")
num -= 8
else:
num -= 4
else:
num -= 2
else:
num -= 1
return result
# Open files and read
fname = raw_input("Please enter the brainfuck file to decompile.\n")
infile = open(fname, 'r')
outfile = open(fname + '.pd', 'w')
data = infile.read()
infile.close()
output = []
i = 0
while i < len(data):
ch = data[i]
rc = repeat_count(ch, data, i)
if ch == '>':
output += multiop(rc, "right")
i += rc
elif ch == '<':
output += multiop(rc, "left")
i += rc
elif ch == '+':
output += multiop(rc, "up")
i += rc
elif ch == '-':
output += multiop(rc, "down")
i += rc
elif ch == ',':
output += multiop(rc, "jump")
i += rc
elif ch == '.':
output += multiop(rc, "spin")
i += rc
elif ch == '[':
output.append("go")
i += 1
elif ch == ']':
output.append("repeat")
i += 1
outfile.write(" ".join(output))
outfile.close()
print "Done."---------------------------- \o hello.pd
Hello World in Puppet Dance o/
Right one two three \o Note the cosmetic no-op o/
Up two three four
Go
Down left up two three four up
Right one two repeat
Right two three
Up two three four up two
Go
Down left one two
Up two three four up two left
Up two three four up two left
Up two three four up two left
Up two three four up two left
Right two three right repeat
Right one two three
Up two three
Go
Down left up two three four
Right one two repeat
Right one two three
Up two three up
Go
Down left
Up two three four
Up two three four
Up one two
Right one two repeat
Right two three
Up two three four up two
Go
Down left one two
Up two three four up two left
Up two three four up two left
Up two three four up two left
Up two three four up two left
Right two three right repeat
Left one two three
Left up two three four
Left up two three four up two three up two
Left up two three four up two up
Left up two left
Left up two three four up two up
Left up two three four
Left up two three four
Left up left one two
Go
Spin one two three repeat
rpar PROTON all
|
|
-
-
omega0


- Joined on 04-26-2007
- Posts 57
|
Re: Speed Challenge 14: The New Ook!?
Behold the horror of switch: the language with nothing but switch-case statements...
to_switch.c
#include
#include
#include
void parse_bf( int, int, int, char* );
void indent( const char * );
void indent_output( int );
void fwd( int* );
void rwd( int* );
char code[2000];
char output[1000];
int id = 0;
int main( int argc, char **argv )
{
FILE * f;
int c;
int numi = 0;
int numo = 0;
int i = 0;
char data[1000] = {0};
if( argc != 2 )
{
printf("Usage: %s filename\n", argv[0] );
exit(0);
}
f = fopen( argv[1], "r" );
while( !feof(f) )
{
c = getc( f );
code[i] = c;
if( c == '.' ) numo++;
i++;
}
fclose(f);
code[i] = 0;
if( numo == 0 )
{
exit(0); // if there's no output, no need for any code
}
parse_bf( 0, 0, 0, data );
}
void parse_bf( int ip, int dp, int op, char *data )
{
char *newdata = malloc( 1000 );
char c;
char s[20];
memcpy( newdata, data, 1000 ); // new copy of the data space
for(;code[ip];ip++) // continue until end of code
{
switch(code[ip]) // normal brain fuck operators
{
case '+' :
newdata[dp]++;
break;
case '-' :
newdata[dp]--;
break;
case '>' :
dp = (dp+1) % 1000;
break;
case '<' :
dp--;
if( dp<0 ) dp+=1000;
break;
case '[' :
if( newdata[dp] == 0 )
fwd(&ip); // branch foward
break;
case ']' :
if( newdata[dp] != 0 )
rwd(&ip); // branch backward
break;
case '.' :
output[op] = newdata[dp]; // add to output buffer
op++;
break;
case ',' :
indent("switch {"); // possible change in execution here
id++;
// limited to kb chars
for(c=0x20;c<0x7F;c++) // try all input chars
{
sprintf(s,"case %d",c);
indent(s);
newdata[dp] = c;
id++;
parse_bf( ip+1, dp, op, newdata );
indent("break");
id--;
}
id--;
indent("}");
free(newdata);
return;
}
}
indent_output(op); // print output
free(newdata); // clean up
}
void indent( const char *s ) // pretty up output
{
int i;
for(i=0;i<id;i++)
printf("\t");
printf("%s\n",s );
}
void indent_output( int lim )
{
int i,j;
for(i=0;i<lim;i++)
{
for(j=0;j<id;j++)
printf("\t");
printf("putc");
printf(" %d\n", output[i] );
}
}
void fwd( int *p )
{
int cnt;
int q;
for(q=*p+1,cnt=1; cnt > 0; q++ )
{
if( code[q] == ']' )
cnt--;
if( code[q] == '[' )
cnt++;
}
*p = q;
}
void rwd( int *p )
{
int cnt;
int q;
for(q=*p-1,cnt=1; cnt > 0; q-- )
{
if( code[q] == '[' )
cnt--;
if( code[q] == ']' )
cnt++;
}
*p = q;
}
from_switch.pl
open( FILE, " )
{
$line = $_;
if( $line =~ /putc (\d+)/ )
{
$char = $1;
print ">"; # get a clean cell
for($i=0;$i<$char;$i++)
{
print "+"; # generate the character
}
print ".[-]<\n"; # output and clear cell
}
elsif( $line =~ /switch/ )
{
print ",>\n"; # read in char
}
elsif( $line =~ /case (\d+)/ )
{
$num = $1;
print "<[->+>+<<]>>[-<<+>>]<\n"; # copy input to next cell
for($i=0;$i<$num;$i++)
{
print "-"; # will be zero if eqal
}
print "\n>+<[>-<[-]]>[-\n" # branch if not equal
}
elsif( $line =~ /break/ )
{
print "]<\n"; # end branch
}
}
Switch behaves as follows:
switch-case-break works similar to C, but switch uses the next char from stdin as its condition. putc outputs the following number as a char
For example, Hello World is implemented via this switch code:
putc 72
putc 101
putc 108
putc 108
putc 111
putc 32
putc 87
putc 111
putc 114
putc 108
putc 100
putc 33
putc 10
(Just in case I missed an < to escape, the source files are also: http://omega0.xepher.net/stuff/to_switch.c http://omega0.xepher.net/stuff/from_switch.pl )
|
|
-
-
Faxmachinen


- Joined on 03-19-2007
- Posts 199
|
Re: Speed Challenge 14: The New Ook!?
I almost forgot the documentation:
Puppet Dance - A brief reference
Overview: --------- The Puppet Dance compiler converts Puppet Dance code into brainfuck code. As such, brainfuck conditions apply. Standard brainfuck intitializes a 30.000 array of single-byte cells, and places the cell pointer in the first cell.
Puppet Dance separates statements by whitespace. Spaces, tabs and newlines all count as whitespace.
Reference: ----------
\o [<comment>] o/ A comment block starts with "\o" and ends with "o/". Comments can span multiple lines.
one[ two[ three[ four]]] No-op.
up[ two[ three[ four]]] Increase current cell by (2^n) where n is number of optional parameters.
down[ two[ three[ four]]] Decrease current cell by (2^n).
left[ two[ three[ four]]] Move cell pointer back (2^n).
right[ two[ three[ four]]] Move cell pointer forwards (2^n).
go <...> repeat Loops <...> until the cell pointed to at the start of the loop is 0. Note that if the cell starts out 0, the loop is never executed.
jump[ two[ three[ four]]] Inserts (2^n) characters from the input stream to the current pointer location. The pointer moves forwards (2^n).
spin[ two[ three[ four]]] Writes (2^n) characters from the current pointer location to the output stream. The pointer moves forwards (2^n).
rpar PROTON all
|
|
-
-
Autonuke


- Joined on 11-07-2006
- Posts 50
|
Re: Speed Challenge 14: The New Ook!?
Thank you both for your submissions.
Faxmachinen: Puppet Dance has much to recommend it - the cosmetic no-op, the comment markers and the pyramid scheme. I also like how easy it is to re-use code, e.g. to entertain a children's birthday party.
omega0: now that's purely evil. I especially like how you emulate a brainfuck program in order to compile it. Your turn.
|
|
-
Page 1 of 1 (10 items)
|
|
|