Draw An ASCII Double Helix

55

4

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.

Calvin's Hobbies

Posted 2015-05-11T03:46:02.003

Reputation: 84 000

9Brilliant Question! – Joshpbarron – 2015-05-11T09:11:06.073

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 – 2015-05-11T13:31:11.480

1print "." Zoom in to see helix. *nodnod* – David Richerby – 2015-05-11T20:05:20.150

@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 – 2015-05-11T20:15:32.980

Answers

16

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

Optimizer

Posted 2015-05-11T03:46:02.003

Reputation: 25 836

10

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.

More readable

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'
)  

edc65

Posted 2015-05-11T03:46:02.003

Reputation: 31 086

1And i thought I'm good with JS ... what is n=>( doing? I've never seen nor used that operator before. – Y U NO WORK – 2015-05-12T10:53:57.833

@YUNOWORK it's an ES6 feature for creating a function, It's still available only on FireFox. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

– edc65 – 2015-05-12T11:01:22.337

That's some cool stuff, should look into ES6 too soon. Thanks for clarifying! – Y U NO WORK – 2015-05-12T11:10:30.837

8

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.

isaacg

Posted 2015-05-11T03:46:02.003

Reputation: 39 268

6

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.

grc

Posted 2015-05-11T03:46:02.003

Reputation: 18 565

1Nice work. One thing: it should be a capital letter "O" rather than the number 0. – Alex A. – 2015-05-11T14:11:32.157

@AlexA. Thanks - I completely missed that. – grc – 2015-05-11T14:54:13.647

5

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);}}

britboy3456

Posted 2015-05-11T03:46:02.003

Reputation: 51

5Welcome 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 – 2015-05-11T19:12:51.360

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 – 2015-05-12T01:38:08.150

+1 for Java. You can get rid of the sc variable since it is only called once. Shaves off 14 bytes. – topher – 2015-05-12T16:51:22.057

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 – 2018-01-29T09:33:20.730

1

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 – 2018-01-29T09:34:18.397

5

Haskell, 156 bytes

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>

Willem Van Onsem

Posted 2015-05-11T03:46:02.003

Reputation: 181

2You can write 1<2 or something like that instead of True, and save a byte. – marinus – 2015-05-12T11:59:52.550

@marinus: updated, many thanks. – Willem Van Onsem – 2015-05-12T12:01:06.983

4

C#, 242 241 238 230 222 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;
}

James Thorpe

Posted 2015-05-11T03:46:02.003

Reputation: 161

3

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.

Mattermonkey

Posted 2015-05-11T03:46:02.003

Reputation: 71

3

C# 199 197 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.

Vincent Ripoll

Posted 2015-05-11T03:46:02.003

Reputation: 31

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 – 2015-05-12T15:47:47.447

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 – 2015-05-12T15:48:55.527

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 – 2015-05-12T16:03:47.577

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 – 2015-05-12T16:04:45.153

Since your version didn't use any var, I didn't want to get an undue advantage. :) – Vincent Ripoll – 2015-05-12T16:06:40.817

haha - I couldn't use it for my strings, as I was initialising them at the same time - you can't use var when you do that (you wouldn't be able to do it for a and b here) – James Thorpe – 2015-05-12T16:07:51.100

Fine, here you go, "var". – Vincent Ripoll – 2015-05-12T16:09:40.227

2

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

Alex A.

Posted 2015-05-11T03:46:02.003

Reputation: 23 761

2

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

OrangeHat

Posted 2015-05-11T03:46:02.003

Reputation: 31

2

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.

nutki

Posted 2015-05-11T03:46:02.003

Reputation: 3 634

This is really sweet. You can save two more bytes by replacing /^0/?O:etc with $_?etc:O – alexander-brett – 2015-05-12T15:48:52.443

@alexander-brett this would require no EOL on input, because "0\n" evaluates to true. – nutki – 2015-05-12T15:53:40.157

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 – 2015-05-12T16:02:41.323

@alexander-brett, this produces backslashes in the center line for positive numbers, which is incorrect, right? – nutki – 2015-05-12T16:07:47.817

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 – 2015-05-12T16:09:31.307

2

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")))))))

Alan Third

Posted 2015-05-11T03:46:02.003

Reputation: 147

2

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.

Marco13

Posted 2015-05-11T03:46:02.003

Reputation: 1 131

2

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");}}

Olivia Trewin

Posted 2015-05-11T03:46:02.003

Reputation: 351

1

Canvas, 33 32 30 bytes

 /¶O:╴⤢╷\ /¶ \×+;↔+──╴0<?↷}╴‽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

dzaima

Posted 2015-05-11T03:46:02.003

Reputation: 19 048

1

Charcoal, 28 24 22 bytes

↙OF↔θ/¶\¶ \¶↗‖BO¿›N⁰⟲T

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.

F↔θ/¶\¶ \¶

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

Move back over the last \.

‖B

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.

¿›N⁰⟲T

If the input was positive then rotate the canvas.

Neil

Posted 2015-05-11T03:46:02.003

Reputation: 95 035

1

Groovy, 142 134 129 125 120 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!

dbramwell

Posted 2015-05-11T03:46:02.003

Reputation: 201

1

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.

Tim

Posted 2015-05-11T03:46:02.003

Reputation: 2 789

1

Perl, 193 197 187 180 166 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'

alexander-brett

Posted 2015-05-11T03:46:02.003

Reputation: 1 485

Is it conventional that -M5.10.0 does not contribute to your byte count? say is handy for code golf … – xebtl – 2015-05-12T08:22:21.870

@TheSuitIsBlackNot said that it was (in the top comment http://codegolf.stackexchange.com/a/49762/19039 on) - I assume it's because it's a language version.

– alexander-brett – 2015-05-12T09:07:35.103

1

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 ")
}

Flounderer

Posted 2015-05-11T03:46:02.003

Reputation: 596

1

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;

kuldeep.kamboj

Posted 2015-05-11T03:46:02.003

Reputation: 625

1

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);}}

Angelo Tricarico

Posted 2015-05-11T03:46:02.003

Reputation: 141

1

C++ 269 262 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);}

Chris.Wilson

Posted 2015-05-11T03:46:02.003

Reputation: 111

0

C (gcc), 161 160 bytes

Now more compliant than ever! Thanks to @EriktheOutgolfer for making it so.

#define g(n)for(i=n;i--;)printf(
i;f(n){if(n<0){puts(" O");g(-n)"/ \\\n\\ /\n%2c\n",i?92:79);}else{g(n)" /\\");g(1)"\nO"+!n);g(n)i?"  /":"  O\n");g(n)" \\/");}}

Try it online!

gastropner

Posted 2015-05-11T03:46:02.003

Reputation: 3 264

You can save a byte by making the Os uppercase. However, I think this answer is invalid (There should never be any leading space that aren't part of the specified pattern.)

– Erik the Outgolfer – 2018-01-21T16:37:13.320

@EriktheOutgolfer Ah, yes. Not sure why I added unnecessary spaces there. Also, thanks for pointing out the Os are capital, since I completely missed that. – gastropner – 2018-01-21T20:31:36.690

0

J, 67 59 55 51 bytes

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

Try it online!

FrownyFrog

Posted 2015-05-11T03:46:02.003

Reputation: 3 112

0

SOGL V0.12, 37 bytes

 O¶/”▓:.θH{"⌠λ5⁸‘▓+};↕№+╬⁷.0>?I↔}.‽ O

Try it Here!

dzaima

Posted 2015-05-11T03:46:02.003

Reputation: 19 048

0

Ruby, 118 138 bytes

->i{print i<0?" O ":" /\\"*i+"\n"*(1-0**i),i<0?("\n/ \\\n\\ /\n \\"*-i)[0..-3]:i==0&&"O"||"O "+" / "*(i-1)+" O\n",i<0?" O ":" \\/"*i+"\n"}

Basically a if-else statement on all the 3 parts of the helixes :)

Try it online!

Any tips to get it even smaller would be greatly appericated!

Edit: Silly me forgot to remove all the parantheses, and didnt see the requirement of "O" if 0

Håvard Nygård

Posted 2015-05-11T03:46:02.003

Reputation: 341

0

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

Question Marks

Posted 2015-05-11T03:46:02.003

Reputation: 171

0

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.

Caek

Posted 2015-05-11T03:46:02.003

Reputation: 111

0

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);
 }

Some notes about the approach:

  • 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.

Reto Koradi

Posted 2015-05-11T03:46:02.003

Reputation: 4 870

0

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!

CJ Dennis

Posted 2015-05-11T03:46:02.003

Reputation: 4 104

0

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";

mk8374876

Posted 2015-05-11T03:46:02.003

Reputation: 21