# Draw An ASCII Double Helix

Write a program that takes in an integer N via stdin or the command line.

If N is 0, the single letter O must be printed to stdout.

If N is positive, this horizontal ASCII art double helix, drawn N segments wide, must be printed.

If N is 1, the output is:

 /\
O  O
\/


If N is 2, the output is:

 /\ /\
O  /  O
\/ \/


If N is 3, the output is:

 /\ /\ /\
O  /  /  O
\/ \/ \/


If N is 4, the output is:

 /\ /\ /\ /\
O  /  /  /  O
\/ \/ \/ \/


The pattern continues in the exact same way for larger N. Note that forward slash (/) must be used in all places the helixes cross, except for the O ends.

If N is negative, this vertical ASCII art double helix, drawn -N segments tall, must be printed.

If N is -1, the output is:

 O
/ \
\ /
O


If N is -2, the output is:

 O
/ \
\ /
\
/ \
\ /
O


If N is -3, the output is:

 O
/ \
\ /
\
/ \
\ /
\
/ \
\ /
O


If N is -4, the output is:

 O
/ \
\ /
\
/ \
\ /
\
/ \
\ /
\
/ \
\ /
O


The pattern continues in the exact same way for smaller N. Note that backward slashes (\) must be used in all places the helixes cross, except for the O ends.

Details

• Instead of a program, you may write a function that takes N as an integer and prints the result normally or returns it as a string.
• The output for any N may optionally contain a trailing newline.
• Any line of output for any N may optionally contain 4 or fewer trailing spaces.
• There should never be any leading space that aren't part of the specified pattern.
• The shortest code in bytes wins.
• Brilliant Question! – Joshpbarron May 11 '15 at 9:11
• it seems to me that for n=0, it might be convenient to print <spc>O<spc>  or \nO\n. Is unnecesary leading whitespace allowed? – Level River St May 11 '15 at 13:31
• print "." Zoom in to see helix. *nodnod* – David Richerby May 11 '15 at 20:05
• @steveverrill That may have been helpful but there are so many answers now I don't want to change the rule. I've clarified that leading spaces not part of the pattern are not allowed. – Calvin's Hobbies May 11 '15 at 20:15

# CJam, 56 55 53 52 50 bytes

S'O:Ori:X0>"\/"=" / \\\ / "+Xz*1>O]s3/X"z"<~N*X\O?


Look at that size! The main culprits are N = 0 special case and the \ instead of / in the vertical helix.

Here is how it works:

S'O:O                                  e# Put a space on stack. Now put char O on stack
e# and assign it to variable O. This is not really
e# helping in golfing as using 'O everywhere is
e# same number of bytes
ri:X                              e# Read input as in integer and store it in X
0>"\/"=                       e# If X is greater than 0, choose /, otherwise \
" / \\\ / "            e# Put this string on stack
+           e# Append to chosen \ or /
Xz*        e# Repeat it abs(X) times
1>                                     e# Remove the first character from repeated string
O]                                   e# Put char O on stack, wrap everything in an array
e# and convert it to string.
3/                                 e# Split the string into parts of length 3
X"z"<~                           e# If X is positive, transpose the array to get a
e# horizontal helix, otherwise it would be vertical
N*                         e# Join the parts with newline
X\O?                     e# If X was 0, then pick char O instead of this
e# final joined string.


The code is divided into three parts:

• The part X0>"\/"=" / \\\ / "+ gives either "/ / \\\ / " or "\ / \\\ / " which is crucial as the helix is simply made up of alternate "/ \" and "\ /" joined by either " / " or " \ ". For instance, if you consider input to be 2, then your final repeated string would be "/ / \\ / / / \\ / " (without escaping). This obviously has extra / at the beginning and an extra space at the ending.
• Second part is to correct the above string with additional things and split. For an input 2, the desired final string without newlines would be " O / \\\ / / / \\\ / O", but after the above point, we only have "/ / \\\ / / / \\\ / ". So we remove the first character, add a space and 'O at the beginning and another 'O at the end. Then we finally split it into parts of 3
• Finally, we decide whether to transpose this split string for a vertical helix or not; Join the parts by newlines; And choose between this and a single character 'O (for input 0 case)

Try it online here

# JavaScript(ES6), 126 132 133

A=n=>(F=(f,j='')=>f+(j+f).repeat(n-1),n>0?F(' /\\')+
o${F(' ','/')}o +F(' \\/'):(n=-n)? o${F(
/ \\
\\ /
,' \\')} o:'o')

// Test
for(i=0;i<10;i++)
P.innerHTML = P.innerHTML + A(i)+'\n\n\n',
N.innerHTML = N.innerHTML + A(-i)+'\n\n\n'
pre {
font-size: 10px;
line-height: 9px;
}
<table>
<tr><th>Positive</th><th>Negative</th></tr>
<tr><td valign=top><pre id=P></pre></td><td><pre id=N></pre></td></tr>
</table>

Using templated string, newlines count.

A=n=>(
F=(f,j='')=>f+(j+f).repeat(n-1),
n > 0 ? F(' /\\') + '\no' + F('  ','/') + 'o\n'+F(' \\/')
: (n=-n) ? ' o' + F('\n/ \\\n\\ /\n',' \\')'+' o':'o'
)

• And i thought I'm good with JS ... what is n=>( doing? I've never seen nor used that operator before. – Y U NO WORK May 12 '15 at 10:53
• @YUNOWORK it's an ES6 feature for creating a function, It's still available only on FireFox. See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… – edc65 May 12 '15 at 11:01
• That's some cool stuff, should look into ES6 too soon. Thanks for clarifying! – Y U NO WORK May 12 '15 at 11:10

# Pyth, 52 bytes

M[Jj"/\\"*hGdjP*G+*2dH*2\O_J)?jb?gQ\/>Q0msdCg_Q\\Q\O


Demonstration.

Explanation:

The first section, M[Jj"/\\"*hGdjP*G+*2dH*2\O_J), defines a function, g, which takes two inputs. The first input, G, is the number of repetions to use. This is the absolute value of the input. The second input, H, is the character to place at the center of the spirals.

The function returns a 3 element list, which consists of the 3 lines of the positive spiral, and the 3 columns of the negative spiral.

The first element is defined by Jj"/\\"*hGd. *hGd is the string of G+1 spaces. j"/\\"*hGd joins that string with "/\" as the delimeter. The J at the beginning saves the resultant value for future use.

The second element is jP*G+*2dH*2\O. We start with +*2dH. This is two spaces followed by the input character. Then, we repeat that string G times with *G. Then, we remove its final character with P. Finally, we surround this string with two O characters, with j ... *2\O.

The third element is generated with _J. This is simply the reverse of the first line.

The latter section, ?jb?gQ\/>Q0msdCg_Q\\Q\O selects between three different posibilities, positive, negative and zero. The first if-then conditions on Q, the input. The second conditions on >Q0, whether the input is positive.

If Q is zero, \O, the character O, is printed.

If Q is nonzero, we join the result of the second ternary on newlines and print it, with jb. If Q is positive, the list joined and printed is gQ\/, g(Q,"/").

If Q is negative, the list joined and printed is msdCg_Q\\. We start with g_Q\\, which is g(-Q,"\"). Then we transpose the rows and columns with C. msd turns the resultant tuples of characters into strings, ready to be joined on newlines and printed.

## Python 2, 118

n=input()
a=[' O '[n==0:]]+['/ \\','\\ /','  /\\ '[n<0::2]]*abs(n)
a[-1]=a[0]
for x in[a,zip(*a)][n>0]:print''.join(x)


Creates the vertical double helix from a list of strings and transposes it to get the horizontal one. I'm sure it could be improved.

• Nice work. One thing: it should be a capital letter "O" rather than the number 0. – Alex A. May 11 '15 at 14:11
• @AlexA. Thanks - I completely missed that. – grc May 11 '15 at 14:54

# Java, 500 488 bytes

My first try, and unfortunately it is 10* longer than the current leader :(. Anyone have any tips (other than use a different language)?

import java.util.*;class t{public static void main(String[] args){Scanner sc=new Scanner(System.in);int n=Integer.parseInt(sc.nextLine());if(n>0){for(int i=0;i<n;i++)System.out.print(" /\\");o("");System.out.print('o');for(int i=0;i<n-1;i++)System.out.print("  /");o("  o");for(int i=0;i<n;i++)System.out.print(" \\/");}else if(n<0){o(" o ");for(int i=0;i<-n-1;i++){o("/ \\");o("\\ /");o(" \\ ");}o("/ \\");o("\\ /");o(" o ");}else o("o");}static void o(String s){System.out.println(s);}}

• Welcome to PPCG! It's not important that you're a factor 10 off a golfing language like CJam with Java. ;) The joy is in trying to beat answers in the same language, or languages of similar verbosity, and learning new quirks of your language. I'm not that familiar with golfing in Java, but you can certainly save some bytes with a shorter class name and consistently 1-letter variable names. Also, can't you just import System.* or something to save writing System each time? – Martin Ender May 11 '15 at 19:12
• Indeed he can, import static java.lang.System.*;, or he could save the standard output stream as a variable (though, I don't know if it'd save or hinder in this case, haven't checked). – bloo May 12 '15 at 1:38
• +1 for Java. You can get rid of the sc variable since it is only called once. Shaves off 14 bytes. – topher May 12 '15 at 16:51
• I know it's been almost three years, but quite a few things can be golfed: class M{public static void main(String[]a){int n=new Integer(new java.util.Scanner(System.in).next()),i=n;if(n>0){for(;i-->0;)o(" /\\");o("\no");for(i=n;i-->1;)o(" /");o(" o\n");for(i=0;i++<n;)o(" \\/");}else if(n<0){o(" o \n");for(i=0;i++<~n;)o("/ \\\n\\ /\n \\ \n");o("/ \\\n\\ /\n o \n");}else o("o\n");}static<T>void o(T s){System.out.print(s);}} (352 bytes) Try it online. – Kevin Cruijssen Jan 29 '18 at 9:33
• In addition, a function is allowed for this challenge, so it can be 251 bytes when using a Java 8+ lambda: n->{int i=n;if(n>0){for(;i-->0;)o(" /\\");o("\no");for(i=n;i-->1;)o(" /");o(" o\n");for(i=0;i++<n;)o(" \\/");}else if(n<0){o(" o \n");for(i=0;i++<~n;)o("/ \\\n\\ /\n \\ \n");o("/ \\\n\\ /\n o \n");}else o("o\n");};<T>void o(T s){System.out.print(s);} Try it online. – Kevin Cruijssen Jan 29 '18 at 9:34

h 0="O"
h n|n>0=' ':c n "/\\ "++"\nO"++c(n-1)"  /"++"  O\n "++c n "\\/ "
|0<1=" O\n/ \\\n"++c(-n-1)"\\ /\n \\\n/ \\\n"++"\\ /\n O"
c x=concat.replicate x


You can then write it as:

*Main> putStrLn $h 1 /\ O O \/ *Main> putStrLn$ h 0
O
*Main> putStrLn $h (-1) O / \ \ / O *Main> putStrLn$ h 3
/\ /\ /\
O  /  /  O
\/ \/ \/
*Main> putStrLn $h (-3) O / \ \ / \ / \ \ / \ / \ \ / O *Main>  • You can write 1<2 or something like that instead of True, and save a byte. – marinus May 12 '15 at 11:59 • @marinus: updated, many thanks. – Willem Van Onsem May 12 '15 at 12:01 # C#, 242241238230222 219 Bytes Spurred on by Martin's comment, here's my first attempt at something like this: string h(int n){int x=0;string p="",r=n==0?"O":p;if(n>0){for(;x++<n;){r+=" /\\";p+=" \\/";}r+="\nO ";for(;x-->2;)r+="/ ";r+="O\n"+p;}else if(n<0){r+=@" O / \ ";for(--x;x-->n;)r+=@"\ / \ / \ ";r+=@"\ / O";}return r;}  More readably: string h(int n) { int x = 0; string p = "", r = n==0 ? "O" : p; if (n > 0) { for (; x++ < n;) { r += " /\\"; p += " \\/"; } r += "\nO "; for (; x-- > 2;) r += "/ "; r += "O\n" + p; } else if(n<0) { r += @" O / \ "; for (--x; x-- > n;) r += @"\ / \ / \ "; r += @"\ / O"; } return r; }  # C# 199197 196 bytes string f(int n){var u=n<0;int m=u?-n:n;string a="",b=" O ";for(;m-->0;)b+="\n/ \\\n\\ /\n "+(m==0?"O ":u?"\\ ":"/ ");for(;++m<3;)a+=string.Concat(b.Split('\n').Select(s=>s[m]))+"\n";return u?b:a;}  Ungolfed version:  string f(int n) { var u = n < 0; int m = u ? -n : n; string a = "", b = " O "; for (; m-- > 0; ) b += "\n/ \\\n\\ /\n " + (m == 0 ? "O " : u ? "\\ " : "/ "); for (; ++m < 3;) a += string.Concat(b.Split('\n').Select(s => s[m])) + "\n"; return u ? b : a; }  The idea is to build the horizontal display from the vertical display by rendering the transposed matrix of characters. • Nice - I hadn't had a chance to try a transposition answer in C# yet. Note that you have the "\" and "/" the wrong way round for the crossovers, and you can save a few bytes by changing for(;m>0;--m) to for(;m-->0;) in both loops – James Thorpe May 12 '15 at 15:47 • This string: "\n/ \\\n\\ /\n " could also be shortened as per the methods in my answer - ie use @"...", where each "\\" becomes "\" and each "\n" becomes an actual newline – James Thorpe May 12 '15 at 15:48 • Right, I introduced the variable u to shorten the solution, but forgot to invert the test of the crossovers. Thanks for the idea of shortening the loop condition (though I can't shorten the second loop since m is then equal to 0 and I use it as index). For the newline trick, it doesn't work under windows because the b.Split('\n') should be changed to b.Split('\n','\r') which costs 5 characters and saves only 3. – Vincent Ripoll May 12 '15 at 16:03 • Ah fair enough - I guess I hadn't noticed because I wasn't splitting anything. I also just spotted you could switch bool u for var u for another whole byte :) – James Thorpe May 12 '15 at 16:04 • Since your version didn't use any var, I didn't want to get an undue advantage. :) – Vincent Ripoll May 12 '15 at 16:06 # Python 3, 118 bytes x=int(input()) print("O"if x==0else" /\\"*x+"\nO "+" / "*(x-1)+" O\n"+" \\/"*x if x>0else(" O"+"\n/ \\\n\\ /\n \\"*-x)[:-1]+"O")  My first ever code golf submission, so it may not be at all impressive. Just uses Python's ... if ... else ... ternary operator to separate the three scenarios. That gives a string made of repeating some smaller strings a certain number of times to print. # Julia, 229 bytes Oh man, this is way, way too big. It's the longest answer so far by a large margin. I could probably save a lot by returning the string rather than printing it, or by avoiding the matrix approach altogether. I'll experiment with that later. n->(if n==0 println("O")else m=abs(n);A=B=reshape(split(" / "*(n>0?"/":"\\")*" \\\\ /",""),(3,3));E=[" ";"O";" "];if m>1for i=2:m B=hcat(B,A)end end;B[:,1]=E;B=hcat(B,E);C=n>0?B:B';for i=1:size(C,1) println(join(C[i,:]))end end)  This creates a lambda function that takes a single integer and prints the appropriately formatted double helix. To call it, give it a name, e.g. f=n->(...). Ungolfed + explanation: function f(n) if n == 0 println("O") else m = abs(n) # Split the string into a 3x3 matrix with a slash on the left, # or a backslash for n < 0 A = B = reshape(split(" / " * (n > 0 ? "/" : "\\") * " \\\\ /", ""), (3, 3)) # We can get the O lines where needed by appending this E = [" "; "O"; " "] # Grow the helix by abs(n) if m > 1 for i = 2:m B = hcat(B, A) end end # Exchange the first column for E B[:,1] = E # Add E onto the right B = hcat(B, E) # If n is negative, we actually want the transpose C = n > 0 ? B : B' # Print the rows of C for i = 1:size(C, 1) println(join(C[i,:])) end end end  A couple examples: julia> f(1) /\ O O \/ julia> f(-2) O / \ \ / \ / \ \ / O  # Python 3, 135 bytes n=int(input());m=abs(n)-1;print({n:" O\n/ \\\n"+m*"\ /\n \\\n/ \\\n"+"\\ /\n O",m+1:n*" /\\"+"\nO"+" /"*m+" O\n"+" \/"*n,0:"O"}[n])  Try it online here # Perl, 91 97 Transposing proved to be too expensive in the end. #!perl -n print/-/?"\0\23"^" \\ / \\ \\ / "x-$_." O":-$_?" /\\"x$_.("*"^" / "x$_." O "." \\/"x$_):O


Previous solution:

#!perl -n
$".=""^"/ \\ / / \\ "x abs.O;print/-/?$"=~y!/\\!\\/!r:/^0/?O:map{($"=~/^.{$_}(.)/mg,$/)}2,1,0  Test me. • This is really sweet. You can save two more bytes by replacing /^0/?O:etc with $_?etc:O – alexander-brett May 12 '15 at 15:48
• @alexander-brett this would require no EOL on input, because "0\n" evaluates to true. – nutki May 12 '15 at 15:53
• You can probably get away with requiring no EOL on stdin :) also, you can save 4 with $".="\23"^"\\ / \\ \\ / "x abs."O ";print/-/?$":/^0/?O:map{reverse$/,$"=~/(.).{$_}$/mg}0..2 – alexander-brett May 12 '15 at 16:02
• @alexander-brett, this produces backslashes in the center line for positive numbers, which is incorrect, right? – nutki May 12 '15 at 16:07
• Oh man, that's what I get far playing fast and loose. You're absolutely right. Also, did I mention I really really like this array-transpose idea. – alexander-brett May 12 '15 at 16:09

# Scheme, 379 bytes

My first attempt at code golf and, unfortunately, one of the longest ones. :(

(define (h i) (define a string-append) (define (k n p q s e) (cond ((= i n) (p s (k (q n 1) p q s e))) ((= 0 n) e) (else (p ("\\ /" ,(if (> i 0) " / " " \\") "/ \\") (k (q n 1) p q s e))))) (if (= i 0) "O\n" (apply a (map (lambda (s) (a s "\n")) (if (> i 0) (k i (lambda (x y) (map a x y)) - '(" /" "O " " \\") '("\\" " O" "/")) (k i append + '(" O" "/ \\") '("\\ /" " O")))))))


Ungolfified:

(define (h i)
(define a string-append)

(define (k n p q s e)
(cond ((= i n) (p s (k (q n 1) p q s e)))
((= 0 n) e)
(else (p ("\\ /" ,(if (> i 0) " / " " \\") "/ \\")
(k (q n 1) p q s e)))))

(if (= i 0) "O\n"
(apply a (map (lambda (s) (a s "\n"))
(if (> i 0)
(k i (lambda (x y) (map a x y)) -
'(" /" "O " " \\")
'("\\" " O" "/"))
(k i append +
'(" O" "/ \\")
'("\\ /" " O")))))))


## Java, 282

My first approach, with particularly nice variable names:

class H{public static void main(String[]_){int N=Integer.parseInt(_[0]),í=N;String ì="/ \\\n\\ /\n",I=" o \n",i="",l=I;for(;í-->0;)i+=" /\\";i+="\no";for(í=N;í-->1;)i+="  /";i+="  o\n";for(í=N;í-->0;)i+=" \\/";for(í=1;í++<-N;)l+=ì+" \\ \n";System.out.println(N<0?l+ì+I:N>0?i:"o");}}


I have no idea why I am doing this. Must be some recreational thing.

## Java, 317

My first code golf attempt.

public class t{public static void main(String[]e){int n=Integer.parseInt(e[0]);String s=new String(new char[n==0?0:(n>0?n:-n)-1]),u="\0";System.out.print(n==0?"O":n>0?s.replace(u," /\\")+" /\\\nO"+s.replace(u,"  /")+"  O\n"+s.replace(u," \\/")+" \\/":" O \n/ \\\n"+s.replace(u,"\\ /\n \\ \n/ \\\n")+"\\ /\n O \n");}}


# Python 3, 165 bytes

x,a,b,c,d=int(input())-1,'\ /',' / ','/ \\','\ /\n \\\n/ \\\n'
print([[' O\n/ \\\n'+d*abs(x+2)+'\ /\n O',' /'+a*x+'\\\nO '+b*x+' O\n \\'+c*x+'/'],'OO'][x==-1][x>-1])


Try it online here.

# Perl, 193197187180166 163B

1 byte penalty for -n commandline switch. Run with echo 1|perl -M5.10.0 -n scratch.pl:

$_*=3;$s=($m=abs)==$_;$_?map{say if$_=join'',map{(map[/./g]," O ",(('/ \\', '\\ /',$s?' / ':' \\ ')x$m)[0..$m-2]," O")[$s?$_:$j][$s?$j:$_]}0..$m;$j++}0..$m:say'O'


With whitespace:

$_ *= 3;$s = ($m = abs) ==$_;
$_ ? map{ say if$_=join '', map {
( map[/./g],
" O ",
(('/ \\', '\\ /',$s?' / ':' \\ ') x$m)[0..$m-2], " O" )[$s ? $_ :$j][$s ?$j : $_] }0..$m;
$j++ } 0..$m
: say 'O'

• Is it conventional that -M5.10.0 does not contribute to your byte count? say is handy for code golf … – xebtl May 12 '15 at 8:22
• @TheSuitIsBlackNot said that it was (in the top comment codegolf.stackexchange.com/a/49762/19039 on) - I assume it's because it's a language version. – alexander-brett May 12 '15 at 9:07

# PHP, 341

$s='';$n=$argv[1];$l=PHP_EOL;if($n>0){for($i=0;$i<$n;$i++)$s.=" /\\";$s.=$l;for($i=0;$i<$n;$i++){if($i==0)$s.='o';if($i<$n-1)$s.=' /';if($i==$n-1)$s.='  o';}$s.=$l;for($i=0;$i<$n;$i++)$s.=" \\/";}else{$n=abs($n);for($i=0;$i<$n;$i++){if($i== 0)$s.=' o '.$l;$s.="/ \\".$l."\\ /".$l;if($i < $n-1)$s.=' \\ '.$l;if($i==$n-1)$s.=' o '.$l;}}echo$s;


Ungolfed version

$s = '';$n = $argv[1]; echo PHP_EOL; if($n > 0)
{
for($i=0;$i<$n;$i++)
{
$s.=" /\\"; }$s.=PHP_EOL;

for($i=0;$i<$n;$i++)
{
if($i==0) {$s.='o';
}
if($i <$n-1) {
$s.=' /'; } if($i == $n-1) {$s.='  o';
}
}
$s.=PHP_EOL; for($i=0;$i<$n;$i++) {$s.=" \\/";
}
} else
{
$n = abs($n);
for($i=0;$i<$n;$i++)
{
if($i == 0) {$s.=' o '.PHP_EOL;
}
$s.="/ \\".PHP_EOL."\\ /".PHP_EOL; if($i < $n-1) {$s.=' \\ '.PHP_EOL;
}
if( $i ==$n-1) {
$s.=' o '.PHP_EOL; } } } echo$s;


# JAVA 377 384 bytes

class F{public static void main(String[] a){int n=Integer.parseInt(a[0]);if(n>0){for(int i=0;i<n;i++)p(" /\\");p("\n");for(int i=0;i<n;i++){if(i==0)if(n>1)p("O  ");else p("O  O");else if(i==n-1)p("/  O");else p("/  ");}p("\n");for(int i=0;i<n;i++){p(" \\/");}}else{p(" O\n");for(int i=0;i<Math.abs(n);i++){p("/ \\\n\\ /\n O\n");}}}static void p(String s){System.out.print(s);}}


# C++ 269262 258

#include <string>
#include <iostream>
int main(){int i,j;std::cin>>i;std::string s,u,t;if(i>0){for(j=i;j;j--){s+=" /\\";t+="/  ";u+=" \\/";}t[0]='O';t+="O";s=s+'\n'+t+'\n'+u;}else{for(j=i;j;j++)s+=" \\\n/ \\\n\\ /\n";s[1]='O';s+=" O";}std::cout<<(i==0?"O":s);}


# R, 228 201

n=scan();z=cat;f=for;if(!n)z("O");if(n>0){f(i,1:n,z(" /\\"));z("\nO  ");if(n>1)f(i,2:n,z("/  "));z("O\n");f(i,1:n,z(" \\/"))};if(n<0){z(" O\n");f(i,-n:1,{z("/ \\\n\\ /\n ");if(i>1)z("\\\n")});z("O")}


My first attempt at code golf. I think it works but it is not subtle.

n=scan(); # enter number here
z=cat;
if(!n) z("O\n");
if(n>0){
z(" ");
for(i in 1:n) z("/\\ ");
z("\nO");
if(n>1){
for(i in 2:n) z("  /")
};
z("  O\n ");
for(i in 1:n) z("\\/ ")
};
if(n<0){
z(" O \n");
for(i in -n:1){
z("/ \\\n\\ /");
if(i>1) z("\n \\\n")
};
z("\n O ")
}


# Groovy, 142134129125120 118

a=args[0]as int;b="\n/ \\\n\\ /\n ";print!a?"O":a>0?" /\\"*a+"\nO  ${"/ "*(a-1)}O\n"+" \\/"*a:" O$b${"\\$b"*(1-a)}O"


Finally tied with python 2!

# Charcoal, 2824 22 bytes

↙OＦ↔θ/¶\¶ \¶↗‖ＢO¿›Ｎ⁰⟲Ｔ


Try it online! Link is to verbose version of code. Explanation:

↙O


Print the top O, and leave the cursor one space down and left.

Ｆ↔θ/¶\¶ \¶


Print the strings /, \ and  \ and repeat for the absolute number value of the input.

↗


Move back over the last \.

‖Ｂ


Reflect to create the right-hand side of the helix. I do this here because otherwise the ↗ would not parse unambiguously.

O


Overwrite the last \ with an O.

¿›Ｎ⁰⟲Ｔ


If the input was positive then rotate the canvas.

# Canvas, 3332 30 bytes

 /¶O：╴⤢╷\ /¶ \×＋；↔＋──╴０＜？↷｝╴‽O


Try it here!

Explanation:

 /¶O:                           push " /\¶O" twice
╴⤢╷                        push the absolute value of the input, -1
\ /¶ /×                 repeat "\ /¶ /" horizontally that many times
＋                append that horizontally to one of the first strings
;               and get the other, reverse it
↔+             and then append it to the result of above. Now the top part of the helix is done
──           vertically palindromize with no mirroring (works because of a misake - it just doesn't overlap smartly)
╴0<? }     if the input is less than 0
↷        rotate clockwise the whole thing
╴‽   if the input is falsy (aka 0)
O    push O; implicitly output the top of stack


## C++, 352

Not at all the shortest answer, but the first in C++ so far :)

#include <iostream>
int main(int argc, char* argv[]){int a=argv[0][0]-'0';if(a==0){printf("o");}else if(a>0){for(int i =0; i < a;i++){printf(" /\\");}printf("\no");for(int i=0;i<a-1;i++){printf("  /");}printf("  o\n");for(int i=0;i<a;i++){printf(" \\/");}}else{printf(" o\n/ \\\n\\ /\n");for(int i=0;i>a+1;i--){printf("/ \\\n\\ /\n");}printf(" o");};}


Here it is in C++ Shell with whitespace to test

# perl 156

$==pop;print$=>0?' /\\'x$=.$/:'',$=>0?'O'.' /'x$=."\bO
":'',$=>0?' \\/'x$=:'';print$=<0?" O":'';print" / \\ \\ / \\" for$=..-1;print$=<0?"\bO":!$=?"O":''


Pretty straight forward attempt, my second golf. I think newlines count as 1 byte right?

Now to figure out how to join all those ternaries together.. I have a lot of room for improvement with those :''; everywhere.

## C, 189 bytes

char*h="6Er66 e66Ee 6rE66",*v="6e6 E6r r6E 6r6 6e6",*z="e",*u;b,m,w,c,p;f(n){b=n<0;u=b?v:n?h:z;for(m=b?4:1,w=n*(b?-3:3);u[p];p+=++c%((w+2)*m)==w*m?m:p%(6*m)==m*4?-m*3:0)putchar(u[p++]-22);}


With whitespace and newlines:

char *h="6Er66 e66Ee 6rE66",
*v="6e6 E6r r6E 6r6 6e6",
*z="e",
*u;
b, m, w, c, p;
f(n) {
b = n < 0;
u = b ? v : n ? h : z;
for (m = b ? 4 : 1, w = n * (b ? - 3 : 3);
u[p];
p += ++c % ((w + 2) * m) == w * m ? m : p % (6 * m ) == m * 4 ? - m * 3 : 0)
putchar(u[p++] - 22);
}


• Stores the pattern in character arrays. They are shifted by 22 characters to avoid needing a bunch of backslashes to escape special characters.
• Uses separate patterns for horizontal, vertical, and zero. I initially considered using one single pattern, and just traversing it differently for positive and negative values. I didn't implement it, but I had a feeling that it would make the logic quite a bit more complicated. Particularly since the central slash has the opposite direction for the two cases. And the tables are not that large, so this seemed more promising.
• The code is mainly just index calculations, with logic to decide when it's done and when the pattern loops. Much of the math is there so that it works for both cases with their different dimensions and repetition rules.

# Perl, 184 bytes

$n=pop;$p=$n>0;$_=' \ /'x(1+abs$n*3);$n=$p?$n*4+1:3;$_=join' ',/.{$n}/g;$r=$p?'.':'.*
';s/($r$r)$r($r)/$1$2/g;$p and s/^\S|\S$/O/gm or s/^ \S $|(?<=^ )\S|\S$/O/g;y~\\/~/\\~if$p;print;  I thought this was going to be a lot shorter! There are probably some simple things I can do to save a few bytes. It's been five years since I've programmed seriously in Perl! # PHP, 155 $n=$argv[1];$r='str_repeat';$k="/ \\\n\\ /\n";echo$n>0?" /{$r('\ /',$n-1)}\\\nO{$r(' /',$n-1)}  O\n \\{$r('/ \\',$n-1)}/":" O\n{$r("$k \\\n",-$n-1)}$k O";


# J, 67 59 55 51 bytes

(<&0|:' O '(0},[)(3,~3*|)$' / \\'({~,7$[)0,*) ::'O'


Try it online!