Java, 1887 1866 bytes
Try in on Ideone
Saved 21 bytes due to unneeded "public" headers (Thanks to @Bálint!)
Not exactly a golfing challenge, but hey, why not?
I feel Java might actually be the best language for this challenge because no esolang could handle this, and many others don't have as good list manipulation (although Java's takes way more bytes).
Golfed:
import java.util.*;public class A{public static void main(String[]args){System.out.print((new P()).b(Integer.parseInt((new Scanner(System.in)).next())).s());}}class P{S p;public S b(int w){p=new S(w);int j=-1,k=-1,f=(w%2)*2,t,y,x;for(x=0;x<w/2-2+w%2;x++){t=r();y=r();if(j==t|k==y|t==y){x--;continue;}g(t,true,2);g(y,false,2-f);f=0;j=t;k=y;}while(1>0){t=r();y=r();if(w<4&t<1&y<1)continue;if(j==t|k==y|t==y|j==y){x--;continue;}g(t,true,3);g(y,false,3+(w<4?0:(w%2)*2));break;}return p;}void g(int w,boolean b,int h){if(w<1)p.u(h,b);else if(w<2)p.r(h,b);else p.l(h,b);}int r(){return (int)(Math.random()*3);}}class S{List<List<Character>>q,a;int h,s,u,o,e,r,b,t,g,n,m,x,y;public S(int d){s=d;h=s+s%2-1;u=h;o=h;b=s>3?(int)(Math.random()*3*s)+1:0;q=new ArrayList<List<Character>>();a=new ArrayList<List<Character>>();for(x=0;x<h;x++){q.add(new ArrayList<Character>());a.add(new ArrayList<Character>());}i(0,q);i(0,a);e=1;r=1;t=0;g=0;n=0;m=0;}public String s(){String p="";for(x=0;x<e+b+r;x++)p+=x>t+(s<4?1:0)&x<e+b+g?'_':' ';p+="\n";for(y=0;y<h;y++){for(x=0;x<e;x++)p+=y>h-2&x>n?'_':q.get(y).get(x);for(x=0;x<b;x++)p+=y>h-2?'_':' ';for(x=0;x<r;x++)p+=y>h-2&x<m-1?'_':a.get(y).get(x);p+="\n";}return p;}void i(int i,List<List<Character>>z){for(List<Character>l:z)l.add(i,' ');if(z==q){e++;if(i<=t)t++;if(i<=n)n++;}else{r++;if(i<=g)g++;if(i<=m)m++;}}void u(int v,boolean i){if(i){u-=v;for(y=0;y<v;)q.get(u+y++).set(t,'|');}else{o-=v;for(y=0;y<v;)a.get(o+y++).set(g,'|');}}void l(int v, boolean i){if(i){x=v-t;while(x-->0)i(0,q);t=x>0?0:t-v;u-=v;for(y=0;y<v;)q.get(y+u).set(t+y++,'\\');}else{x=v-g;while(x-->0)i(0,a);g=x>0?0:g-v;o-=v;for(y=0;y<v;)a.get(y+o).set(g+y++,'\\');}}void r(int v,boolean i){if(i){t+=v;y=t;while(e<=y)i(e,q);t=y-1;u-=v;for(y=0;y<v;)q.get(u+y).set(t-y++,'/');}else{g+=v;y=g;while(r<=y)i(r,a);g=v<1?g:y-1;o-=v;for(y=0;y<v;)a.get(o+y).set(g-y++,'/');}}}
Must be in file called A.java
(for obvious reasons). To run:
- In the terminal, type
javac A.java
- Then, if it gives you no errors, type
java A
- Finally, type the number of sides. This program actually supports side lengths up to 65536
As you can see in the example output below, the corners tend to be more open, and the sides not as smooth, as compared to the polygons in the examples. Also, it cannot produce a square, but still follows the official guidelines. If there are any problems I can change the answer to fix them.
Sample output:
3
/ |
/ |
/___|
4
____
/ \
/ \
/________\
5
_________
/ |
/ |
/ |
\ |
\ _________|
6
____________
| \
| \
| \
/ |
/_______________ |
7
_____________________
\ /
\ /
\ /
| /
| /
\ \
\ _____________\
8
_______________
\ /
\ /
\ /
| \
| \
/ |
/____________ |
9
__________
\ /
\ /
\ /
| /
| /
/ \
/ \
| |
|_____ |
10
____
/ \
/ \
/ \
| /
| /
\ |
\ |
/ \
/________\
EDIT: Finally! the ungolfed code is here! It's a bit long, but you probably already guessed that...
I will get to the explanation soon.
import java.util.*;
public class ASCII_Polygon_Driver
{
public static void main(String[] args)
{
System.out.print(P.b(Integer.parseInt((new Scanner(System.in)).next())));
}
}
class P
{
static S p;
public static S b(int w)
{
p = new S(w);
int l1=-1,l2=-1,f=(w%2)*2,r1,r2,x;
for(x=0;x<w/2-2+w%2;x++)
{
r1=r();
r2=r();
if(l1==r1){x--;continue;}
if(l2==r2){x--;continue;}
if(r1==r2){x--;continue;}
g(r1,true,2);
g(r2,false,2-f);
f=0;
l1=r1;
l2=r2;
}
while(true)
{
r1=r();
r2=r();
if(w<4&r1<1&r2<1)continue;
if(l1==r1|l2==r2|r1==r2|l1==r2){x--;continue;}
g(r1,true,3);
g(r2,false,3+(w<4?0:(w%2)*2));
break;
}
return p;
}
static void g(int w,boolean b,int h)
{
if(w<1)p.goUp(h,b);
else if(w<2)p.goRight(h,b);
else p.goLeft(h,b);
}
static int r()
{
return (int)(Math.random()*3);
}
}
class S
{
public List<List<Character>> area1;
public List<List<Character>> area2;
private int wid1;
private int wid2;
private int spcb;
public int hght;
private int top1;
private int top2;
private int bot1;
private int bot2;
private int mid1;
private int mid2;
public int sides;
private int x;
private int y;
public int y1;
public int y2;
public S(int numSides)
{
sides = numSides;
hght = sides+sides%2-1;
y1=hght;
y2=hght;
spcb = sides>3?(int)(Math.random()*3*sides)+1:0;
area1 = new ArrayList<List<Character>>();
area2 = new ArrayList<List<Character>>();
for(x=0;x<hght;x++)
{
area1.add(new ArrayList<Character>());
area2.add(new ArrayList<Character>());
}
insertCollum1(0);
insertCollum2(0);
wid1 = 1;
wid2 = 1;
top1 = 0;
top2 = 0;
bot1 = 0;
bot2 = 0;
}
public String toString()
{
String out ="";
for(x=0; x<wid1+spcb+wid2; x++)
{
out+=x>top1+1&x<wid1+spcb+top2?'_':' ';
}
out+="\n";
for(y=0; y<hght; y++)
{
for(x=0; x<wid1; x++)out+=y>hght-2&x>bot1?'_':area1.get(y).get(x);
for(x=0; x<spcb; x++)out+=y>hght-2?'_':' ';
for(x=0; x<wid2; x++)out+=y>hght-2&x<bot2-1?'_':area2.get(y).get(x);
out+="\n";
}
return out;
}
private void insertCollum1(int index)
{
for(List<Character> line : area1)
{
line.add(index,' ');
}
wid1++;
if(index<=top1)top1++;
if(index<=bot1)bot1++;
}
private void insertCollum2(int index)
{
for(List<Character> line : area2)
{
line.add(index,' ');
}
wid2++;
if(index<=top2)top2++;
if(index<=bot2)bot2++;
}
/*private void setChar1(int x, int y, char character, List<List<Character>> which)
{
which.get(y).set(x,character);
}*/
public void goUp(int howMany, boolean is1)
{
if(is1)
{
y1-=howMany;
for(y=0;y<howMany;)
{
area1.get(y1+y++).set(top1,'|');
}
}
else
{
y2-=howMany;
for(y=0;y<howMany;)
{
area2.get(y2+y++).set(top2,'|');
}
}
}
public void goLeft(int howMany, boolean is1)
{
if(is1)
{
x = howMany-top1;
while(x-->0)insertCollum1(0);
top1 = Math.max(0,top1-howMany);
y1-=howMany;
for(y=0;y<howMany;)
{
area1.get(y+y1).set(top1+y++,'\\');
}
}
else
{
x = howMany-top2;
while(x-->0)insertCollum2(0);
top2 = Math.max(0,top2-howMany);
y2-=howMany;
for(y=0;y<howMany;)
{
area2.get(y+y2).set(top2+y++,'\\');
}
}
}
public void goRight(int howMany,boolean is1)
{
if(is1)
{
top1+=howMany;
y=top1;
while(wid1<=y)insertCollum1(wid1);
top1=y-1;
y1-=howMany;
for(y=0;y<howMany;)
{
area1.get(y1+y).set(top1-y++,'/');
}
}
else
{
top2+=howMany;
y=top2;
while(wid2<=y)insertCollum2(wid2);
top2=howMany<1?top2:y-1;
y2-=howMany;
for(y=0;y<howMany;)
{
area2.get(y2+y).set(top2-y++,'/');
}
}
}
}
For your square and hourglass, you have the top overhanging the sides, but for the parallelogram and hexagon the top is "inside" the sides. Is that intentional? Can submissions choose either style, as fits their design? – AdmBorkBork – 2016-03-25T19:37:35.223
@TimmyD Those are just examples. Submissions can choose any style they want, as long as the submissions meet the guidelines given. – R. Kap – 2016-03-25T19:38:52.747
I think you mean hexagon, not pentagon for your n = 6 example. – DoctorHeckle – 2016-03-25T19:39:11.953
@DoctorHeckle Yes, you're right. I meant hexagon. – R. Kap – 2016-03-25T19:39:37.487
Can the sides overlap themselves? – Blue – 2016-03-26T02:03:07.370
@Blue Actually, now that I think about it, yes they can. Like I said in my post, they can be any style as long as the program follows the guidelines given. – R. Kap – 2016-03-26T03:33:57.560
Can we take # of program runs from input? Would make testing on online interpreters easier (as persistent data requires file io) – CalculatorFeline – 2016-03-26T03:42:25.857
@CatsAreFluffy For testing you can do whatever you want, as long as in the final version of the code, the input is a specific number of sides in the range
3 => 10
including 3 and 10. With that said, I wish you good luck! :) – R. Kap – 2016-03-26T03:49:02.927Can I have an example of a 9-sided ASCII polygon? – CalculatorFeline – 2016-03-26T03:52:08.570
@CatsAreFluffy Okay. Please look at the edit. – R. Kap – 2016-03-26T04:14:02.160
@R.Kap That last example isn't ascii. – Conor O'Brien – 2016-05-17T20:37:22.243
@CᴏɴᴏʀO'Bʀɪᴇɴ Now it should be. :) – R. Kap – 2016-05-17T20:48:01.710
Can I print a filled polygon instead of a wireframe? If I can, then I may be able to do it eith resterization. – Bálint – 2016-05-19T20:05:09.903
@Bálint Yeah, sure, that's fine, as long as I can distinguish between different sides. – R. Kap – 2016-05-19T20:06:38.197