+12  A: 

Perl, 235 211 225 211 207 196 179 177 175 168 160 156 146 chars

<>=~/-\d+/;for$y(@a=-$'..$'){print+(map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a),$/}


Perl using say feature, 161 149 139 chars

$ echo -n '<>=~/-\d+/;for$y(@a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}' | wc -c
139
$ perl -E '<>=~/-\d+/;for$y(@a=-$'"'"'..$'"'"'){say map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}'


Perl without trailing newline, 153 143 chars

<>=~/-\d+/;for$y(@a=-$'..$'){print$/,map$_|$y?!($t=8*($y>0)+atan2(-$y,$_)/atan2 1,1)&-$&/45==8|$t>=$`/45&$t<=-$&/45?qw(- / | \\)[$t%4]:$":o,@a}


Original version commented:

$_=<>;m/(\d+)-(\d+) (\d+)/;$e=$1/45;$f=$2/45; # parse angles and radius, angles are 0-8
for$y(-$3..$3){                               # loop for each row and col
    for$x(-$3..$3){
            $t=atan2(-$y,$x)/atan2 1,1;   # angle of this point
            $t+=8if($t<0);                # normalize negative angles
            @w=split//,"-/|\\"x2;         # array of ASCII symbols for enclosing lines
            $s.=!$x&&!$y?"o":$t==$e||$t==$f?$w[$t]:$t>$e&&$t<$f?"x":$";
            # if it's origin -> "o", if it's enclosing line, get symbol from array
            # if it's between enclosing angles "x", otherwise space
    }
    $s.=$/;
}
print$s;


EDIT 1: Inlined sub, relational and equality operators return 0 or 1.
EDIT 2: Added version with comments.
EDIT 3: Fixed enclosing line at 360º. Char count increased significantly.
EDIT 4: Added a shorter version, bending the rules.
EDIT 5: Smarter fix for the 360º enclosing line. Also, use a number as fill. Both things were obvious. Meh, I should sleep more :/
EDIT 6: Removed unneeded m from match operator. Removed some semicolons.
EDIT 7: Smarter regexp. Under 200 chars!
EDIT 8: Lots of small improvements:

  • Inner for loop -> map (1 char)
  • symbol array from split string -> qw (3 chars)
  • inlined symbol array (6 chars, together with the previous improvement 9 chars!)
  • Logical or -> bitwise or (1 char)
  • Regexp improvement (1 char)
  • Use arithmethic for testing negative angles, inspired by Jacob's answer (5 chars)


EDIT 9: A little reordering in the conditional operators saves 2 chars.
EDIT 10: Use barewords for characters.
EDIT 11: Moved print inside of loop, inspired by Lowjacker's answer.
EDIT 12: Added version using say.
EDIT 13: Reuse angles characters for fill character, as Gwell's answer does. Output isn't as nice as Gwell's though, that would require 5 additional chars :) Also, .. operator doen't need parentheses.
EDIT 14: Apply regex directly to <>. Assign range operator to a variable, as per Adrian's suggestion to bta's answer. Add version without the final newline. Updated say version.
EDIT 15: More inlining. map{block}@a -> map expr,@a.

ninjalj
I meant I do not draw correctly the enclosing line if it's at 360º.
ninjalj
Right, I had responded just before testing it; that's why my comment is removed. Good job getting it under 200! :)
Jon Purdy
+4  A: 

Ruby, 292 276 186 chars

x,y,r=gets.scan(/\d+/).map{|z|z.to_i};s=(-r..r);s.each{|a|s.each{|b|g=Math::atan2(-a,b)/Math::PI*180/1%360;print a|b==0?'o':g==x||g==y%360?'-/|\\'[g/45%4].chr: (x..y)===g ?'*':' '};puts}

Nicer-formatted version:

x, y, r = gets.scan(/\d+/).map{|z| z.to_i}
s = (-r..r)
s.each {|a|
    s.each {|b|
        g = (((Math::atan2(-a,b) / Math::PI) * 180) / 1) % 360
        print ((a | b) == 0) ? 'o' :
            (g == x || g == (y % 360)) ? '-/|\\'[(g / 45) % 4].chr :
                ((x..y) === g) ? '*' : ' '
    }
    puts
}

I'm sure someone out there who got more sleep than I did can condense this more...

Edit 1: Switched if statements in inner loop to nested ? : operator

Edit 2: Stored range to intermediate variable (thanks Adrian), used stdin instead of CLI params (thanks for the clarification Jon), eliminated array in favor of direct output, fixed bug where an ending angle of 360 wouldn't display a line, removed some un-needed parentheses, used division for rounding instead of .round, used modulo instead of conditional add

bta
Nice! Should probably accept parameters from standard input instead of `ARGV`, but I'm not picky.
Jon Purdy
You could save three characters by assigning `-r..r` to a variable.
Adrian
I definitely can't compete with lowjacker's answer. Some of those Ruby 1.9 changes are very useful here.
bta
You could also save characters if you changed `s=(-r..r)` to `s=-r..r`.
Adrian
+7  A: 

MATLAB, 188 chars :)

input '';[w x r]=strread(ans,'%d-%d%d');l='-/|\-/|\-';[X Y]=meshgrid(-r:r);T=atan2(-Y,X)/pi*180;T=T+(T<=0)*360;T(T>w&T<x)=-42;T(T==w)=-l(1+w/45);T(T==x)=-l(1+x/45);T(r+1,r+1)=-'o';char(-T)

Commented code:

%%# Get the string variable (enclose in quotes, e.g. '45-315 4')
input ''
%%# Extract angles and length
[w x r]=strread(ans,'%d-%d%d');
%%# Store characters
l='-/|\-/|\-';
%%# Create the grid
[X Y]=meshgrid(-r:r);
%%# Compute the angles in degrees
T=atan2(-Y,X)/pi*180;
%%# Get all the angles
T=T+(T<=0)*360;
%# Negative numbers indicate valid characters
%%# Add the characters
T(T>w&T<x)=-42;
T(T==w)=-l(1+w/45);
T(T==x)=-l(1+x/45);
%%# Add the origin
T(r+1,r+1)=-'o';
%%# Display
char(-T)
Jacob
Now I'm wondering why more golfs aren't done in MATLAB.
Jon Purdy
@Jon- I've wondered the same thing. Given how much space you save using MATLAB's vector operations, you'd think you would see it more often.
bta
@Bta/John: True, but Perl has an insane advantage with those chained ternary conditionals or whatever they're called --- it's like they're built for golf!
Jacob
If only the problem didn't require ASCII output, this could be cut down even more if a MATLAB `plot` would suffice.
bta
input evaluates the text you give it unless you specify a second parameter, 's'. So you need input '' s; But I think you should change T=T+(T<=0)*360 to T=mod(T,360), which would give you your two characters back :-)
SCFrench
@SCFrench: I think asking the user to add quotes to the input string is not unreasonable :)
Jacob
Any idea for condensing `T(T==w) ..`?
Jacob
@SCFrench: Also the `mod` idea is great but I need to set T(T==0) to 360 as well to solve the enclosing line problem when `Y=360` (or `x` in my code)
Jacob
I can accept quoting the input string. But unfortunately when I try your code with the 0-45 8 case, I don't see the bottom line of hyphens, I think because w is 0 but the corresponding values in T are 360. You might need to mod both w and T with 360 to get both cases to work.
SCFrench
I spent a long time last night looking for ways to condense your code further but I couldn't find anything else. You've got some pretty tight MATLAB code there.
SCFrench
I managed to save three chars: try `input '';[w x r]=strread(ans,'%d-%d%d');l='-/|\-/|\-';[X Y]=meshgrid(r:-1:-r,-r:r);T=180+atan2(Y,X)*180/pi;T(T>wT(T==w)=-l(1+w/45);T(T==x)=-l(1+x/45);T(r+1,r+1)=-'o';char(-T)` this would build the same matrix `T` (except the center value which doesn't really matter since its always replaced with 'o')
Amro
you can save one additional character if capital 'O' is used instead of small 'o': `T(r+1,r+1)=-79`
Amro
Couldn't help but try this myself. I trimmed a [MATLAB solution](http://stackoverflow.com/questions/3365487/code-golf-build-me-an-arc/3393560#3393560) down to 168 characters, and I still think I could get more.
gnovice
`input '';[w x r]=strread(ans,'%d-%d%d');` can become `[w x r]=strread(input(''),'%d-%d %d');` to save 2 characters.
Geoff
+2  A: 

Perl - 388 characters

Since it wouldn't be fair to pose a challenge I couldn't solve myself, here's a solution that uses string substitution instead of trigonometric functions, and making heavy use of your friendly neighbourhood Perl's ability to treat barewords as strings. It's necessarily a little long, but perhaps interesting for the sake of uniqueness:

($x,$y,$r)=split/\D/,<>;for(0..$r-1){$t=$r-1-$_;
$a.=L x$_.D.K x$t.C.J x$t.B.I x$_."\n";
$b.=M x$t.F.N x$_.G.O x$_.H.P x$t."\n"}
$_=$a.E x$r.o.A x$r."\n".$b;$x/=45;$y/=45;$S=' ';
sub A{$v=$_[0];$x==$v||$y==$v?$_[1]:$x<$v&&$y>$v?x:$S}
sub B{$x<=$_[0]&&$y>$_[0]?x:$S}
@a=!$x||$y==8?'-':$S;
push@a,map{A$_,'\\'.qw(- / | \\)[$_%4]}1..7;
push@a,!$x?x:$S,map{B$_}1..7;
eval"y/A-P/".(join'',@a)."/";print

All newlines are optional. It's fairly straightforward:

  • Grab user input.
  • Build the top ($a) and bottom ($b) parts of the pattern.
  • Build the complete pattern ($_).
  • Define a sub A to get the fill character for an angle.
  • Define a sub B to get the fill character for a region.
  • Build an array (@a) of substitution characters using A and B.
  • Perform the substitution and print the results.

The generated format looks like this, for R = 4:

DKKKCJJJB
LDKKCJJBI
LLDKCJBII
LLLDCBIII
EEEEoAAAA
MMMFGHPPP
MMFNGOHPP
MFNNGOOHP
FNNNGOOOH

Where A-H denote angles and I-P denote regions.

(Admittedly, this could probably be golfed further. The operations on @a gave me incorrect output when written as one list, presumably having something to do with how map plays with $_.)

Jon Purdy
+3  A: 

Ruby, 168 characters

Requires Ruby 1.9 to work

s,e,r=gets.scan(/\d+/).map &:to_i;s/=45;e/=45;G=-r..r;G.map{|y|G.map{|x|a=Math.atan2(-y,x)/Math::PI*4%8;print x|y!=0?a==s||a==e%8?'-/|\\'[a%4]:a<s||a>e ?' ':8:?o};puts}

Readable version:

start, _end, radius = gets.scan(/\d+/).map &:to_i
start /= 45
_end /= 45

(-radius..radius).each {|y|
    (-radius..radius).each {|x|
        angle = Math.atan2(-y, x)/Math::PI * 4 % 8
        print x|y != 0 ? angle==start || angle==_end%8 ? '-/|\\'[angle%4] : angle<start || angle>_end ? ' ' : 8 : ?o
    }
    puts
}
Lowjacker
+4  A: 

GNU BC, 339 chars

Gnu bc because of read(), else and logical operators.

scale=A
a=read()/45
b=read()/45
c=read()
for(y=c;y>=-c;y--){for(x=-c;x<=c;x++){if(x==0)if(y<0)t=-2else t=2else if(x>0)t=a(y/x)/a(1)else if(y<0)t=a(y/x)/a(1)-4else t=a(y/x)/a(1)+4
if(y<0)t+=8
if(x||y)if(t==a||t==b||t==b-8){scale=0;u=(t%4);scale=A;if(u==0)"-";if(u==1)"/";if(u==2)"|";if(u==3)"\"}else if(t>a&&t<b)"x"else" "else"o"};"
"}
quit
ninjalj
Nice! I would never have thought of using 'bc'.
bta
+10  A: 

Lua, 259 characters

Slightly abuses the non-whitespace character clause to produce a dazzling display and more importantly save strokes.

m=math i=io.read():gmatch("%d+")a=i()/45 b=i()/45 r=i()for y=r,-r,-1 do for x=-r,r do c=m.atan2(y,x)/m.pi*4 c=c<0 and c+8 or c k=1+m.modf(c+.5)io.write(x==0 and y==0 and'o'or c>=a and c<=b and('-/|\\-/|\\-'):sub(k,k)or c==0 and b==8 and'-'or' ')end print()end

Input: 45-360 4

\\\|||///
\\\|||// 
\\\\|//  
--\\|/   
----o----
--//|\\--
////|\\\\
///|||\\\
///|||\\\

Able to handle odd angles

Input: 15-75 8

           |/////
          |//////
          |//////
          |//////
          ///////
         |//////-
         ////--- 
         //-     
        o        








gwell
Very nice! I was waiting for someone to take advantage of that wording. The support for non-multiple-of-45-degree angles is great, too, though mine and perhaps others at least degrade gracefully.
Jon Purdy
+4  A: 

Mathematica 100 Chars

Out of competition because graphics are too perfect :)

  f[x_-y_ z_]:=Graphics@Table[
                 {EdgeForm@Red,Disk[{0,0},r,{x °,y °}],{r,z,1,-1}]
                 SetAttributes[f,HoldAll]

Invoke with f[30-70 5]

Result

alt text

alt text

Note

The SetAttributes[f, HoldAll];

is needed because the input

    f[a-b c] 

is otherwise interpreted as

    f[(a-b*c)]
belisarius
lol, "graphics too perfect" xD
Alessandro Stamatto
@Alessandro Stamatto That was for the sake of sane competition ... and before someone complains that there is no "o" at the vertex :) ... Auguri!
belisarius
Now show us the output in ASCII!
Gabe
@Gabe Lol ... I have the output here http://en.wikipedia.org/wiki/File:Diophantus-II-8-Fermat.jpg ... but it's too large for the margin of this site :)
belisarius
+6  A: 

MATLAB 7.8.0 (R2009a) - 168 163 162 characters

Starting from Jacob's answer and inspired by gwell's use of any non-whitespace character to fill the arc, I managed the following solution:

[w x r]=strread(input('','s'),'%d-%d%d');
l='o -/|\-/|\-';
X=meshgrid(-r:r);
T=atan2(-X',X)*180/pi;
T=T+(T<=-~w)*360;
T(T>x|T<w)=-1;
T(r+1,r+1)=-90;
disp(l(fix(3+T/45)))

And some test output:

>> arc
0-135 4
\||||////
 \|||///-
  \||//--
   \|/---
    o----

I could reduce it further to 156 characters by removing the call to disp, but this would add an extra ans = preceding the output (which might violate the output formatting rules).

Even still, I feel like there are some ways to reduce this further. ;)

gnovice
Damn. That is some tight MATLAB, sir. And rather readable, I might add.
Jon Purdy
@gnovice: A credit to the MATLAB community :)
Jacob
+1 156! Great job.
Geoff
`T=atan2(-X',X)*180/pi;T=T+(T<=-~w)*360;` can become `T=180*(atan2(-X',X)/pi+(X'>=0)*2);` to save 5 characters.
Geoff
@Geoff: That looks like it has definite promise. I'll have to try it out tomorrow.
gnovice
@gnovice: You could write the script as a function that is invoked f(w,x,r) to save a few characters from the first line.
Jonas
+1  A: 

C# - 325 319 chars

using System;class P{static void Main(){var s=Console.ReadLine().Split(' ');
var d=s[0].Split('-');int l=s[1][0]-48,x,y,r,a=int.Parse(d[0]),b=int.Parse(d[1]);
for(y=l;y>=-l;y--)for(x=-l;x<=l;)Console.Write((x==0&&y==0?'o':a<=(r=((int)
(Math.Atan2(y,x)*57.3)+360)%360)&&r<b||r==b%360?
@"-/|\"[r/45%4]:' ')+(x++==l?"\n":""));}}

Newlines not significant.

Sample input/output

45-180 8
\||||||||////////
\\|||||||///////
\\\||||||//////
\\\\|||||/////
\\\\\||||////
\\\\\\|||///
\\\\\\\||//
\\\\\\\\|/
--------o
135-360 5
\
\\
\\\
\\\\
\\\\\
-----o-----
----/|\\\\\
---//||\\\\
--///|||\\\
-////||||\\
/////|||||\
Anton Hansson
+1 for showing that anything can take as long to read as Perl if you just remove all the whitespace.
Stroboskop
Replacing `3.14*180` with the result is like saying `(3.14/180)`, that is, you should take `*(3.14/180)` instead.
Jon Purdy
Oh wow.. embarrassing. Now 6 chars shorter :-)
Anton Hansson
A: 

Java - 304 chars


class A{public static void main(String[]a){String[]b=a[0].split("-");int e=new Integer(b[1]),r=new Integer(a[1]),g,x,y=r;for(;y>=-r;y--)for(x=-r;x<=r;)System.out.print((x==0&y==0?'o':new Integer(b[0])<=(g=((int)(Math.atan2(y,x)*57.3)+360)%360)&g<e|g==e%360?"-/|\\".charAt(g/45%4):' ')+(x++<r?"":"\n"));}}

More readable version:

class A{
 public static void main(String[]a){
  String[]b=a[0].split("-");
  int e=new Integer(b[1]),r=new Integer(a[1]),g,x,y=r;
  for(;y>=-r;y--)for(x=-r;x<=r;)System.out.print((
   x==0&y==0
    ?'o'
    :new Integer(b[0])<=(g=((int)(Math.atan2(y,x)*57.3)+360)%360)&g<e|g==e%360
     ?"-/|\\".charAt(g/45%4)
     :' '
   )+(x++<r?"":"\n"));
 }
}
BalusC
A: 

C (902 byte)

This doesn't use trigonometric functions (like the original perl version), so it's quite ``bloated''. Anyway, here is my first code-golf submission:

#define V(r) (4*r*r+6*r+3)
#define F for(i=0;i<r;i++)
#define C ;break;case
#define U p-=2*r+2,
#define D p+=2*r+2,
#define R *++p=
#define L *--p=
#define H *p='|';
#define E else if
#define G(a) for(j=0;j<V(r)-1;j++)if(f[j]==i+'0')f[j]=a;
#define O(i) for(i=0;i<2*r+1;i++){
main(int i,char**v){char*p,f[V(8)];
int j,m,e,s,x,y,r;p=*++v;x=atoi(p);while(*p!=45)p++;
char*h="0123";y=atoi(p+1);r=atoi(*++v);
for(p=f+2*r+1;p<f+V(r);p+=2*r+2)*p=10;
*(p-2*r-2)=0;x=x?x/45:x;y/=45;s=0;e=2*r;m=r;p=f;O(i)O(j)
if(j>e)*p=h[0];E(j>m)*p=h[1];E(j>s)*p=h[2];else*p=h[3];p++;}
if(i+1==r){h="7654";m--;e--;}E(i==r){s--;}E(i>r){s--;e++;}
else{s++;e--;}p++;}for(p=f+V(r)/2-1,i=0;i<r;i++)*++p=48;
for(i=0;i<8;i++)if(i>=x&&i<y){G(64);}else G(32);
y=y==8?0:y;q:p=f+V(r)/2-1;*p='o';switch(x){
C 0:F R 45 C 1:F U R 47 C 2:F U H C 3:F U L 92
C 4:F L 45 C 5:F D L 47 C 6:F D H C 7:F D R 92;}
if(y!=8){x=y;y=8;goto q;}puts(f);}

also, the #defines look rather ugly, but they save about 200 bytes so I kept them in, anyway. It is valid ANSI C89/C90 and compiles with very few warnings (two about atoi and puts and two about crippled form of main).