ASCII Art of the Day #1 - Double Knot

47

10

Write a full program or a function that takes a positive integer N as input via STDIN/command line/ARGV or function arguments and prints an ASCII double knot corresponding to the N to STDOUT.

The ASCII double knot looks like this:

  __  __  __  __  __  __
 /  \/  \/  \/  \/  \/  \
| /\/ /\/ /\/ /\/ /\/ /\ |
| \/ /\/ /\/ /\/ /\/ /\/ |
 \ \/\ \/\ \/\ \/\ \/\ \/
 /\ \/\ \/\ \/\ \/\ \/\ \
| /\/ /\/ /\/ /\/ /\/ /\ |
| \/ /\/ /\/ /\/ /\/ /\/ |
 \__/\__/\__/\__/\__/\__/

The above is for N = 6

Here are a few more double knots for other values of N:

If N = 1, the output double knot looks like:

  __
 /  \
| /\ |
| \/ |
 \ \/
 /\ \
| /\ |
| \/ |
 \__/

For N = 2, its

  __  __ 
 /  \/  \
| /\/ /\ |
| \/ /\/ |
 \ \/\ \/
 /\ \/\ \
| /\/ /\ |
| \/ /\/ |
 \__/\__/

For N = 3, its

  __  __  __ 
 /  \/  \/  \
| /\/ /\/ /\ |
| \/ /\/ /\/ |
 \ \/\ \/\ \/
 /\ \/\ \/\ \
| /\/ /\/ /\ |
| \/ /\/ /\/ |
 \__/\__/\__/

and similarly, the pattern continues and any larger value of N.

Details:

  • The input is always a positive integer greater than 0.
  • Trailing newline is optional
  • There should either be no trailing spaces in each line, or enough trailing spaces such that each row's length is 4*N + 2.
  • There should never be any leading space that aren't part of the specified pattern.

This is , so shortest code in bytes wins.


Series Leaderboard

I am converting this into a series of ASCII art challenges and thus adding a leader board for the series (snippet by Martin). To make sure that your answers show up, please start every answer with a headline, using the following Markdown template:

# Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

# Ruby, <s>104</s> <s>101</s> 96 bytes

/* Configuration */

var QUESTION_IDs = [50484, 50521, 50625, 51123, 51222]; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!.FjwQBrX2KXuFkv6p2lChi_RjzM19";

/* App */

var answers = [], page = 1, currentQ = -1;

function answersUrl(index) {
  return "http://api.stackexchange.com/2.2/questions/" +  QUESTION_IDs.join(";") + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}


function getAnswers() {
  $.ajax({
    url: answersUrl(page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      if (data.has_more) getAnswers();
      else process();
    }
  });
}

getAnswers();

var SIZE_REG = /\d+(?=[^\d&]*(?:&lt;(?:s&gt;((?!&gt;).)*&lt;\/s&gt;|((?!&gt;).)+&gt;)[^\d&]*)*$)/;
var NUMBER_REG = /\d+/;
var LANGUAGE_REG = /^#*\s*([^\n,]+)(?=,)/;//

function shouldHaveHeading(a) {
  var pass = false;
  var lines = a.body_markdown.split("\n");
  try {
    pass |= /^#/.test(a.body_markdown);
    pass |= ["-", "="]
              .indexOf(lines[1][0]) > -1;
    pass &= LANGUAGE_REG.test(a.body_markdown);
  } catch (ex) {}
  return pass;
}

function shouldHaveScore(a) {
  var pass = false;
  try {
    pass |= SIZE_REG.test(a.body_markdown.split("\n")[0]);
  } catch (ex) {}
  if (!pass) console.log(a);
  return pass;
}

function getAuthorName(a) {
  return a.owner.display_name;
}

function getAuthorId(a) {
  return a.owner.user_id;
}

function process() {
  answers = answers.filter(shouldHaveScore)
                   .filter(shouldHaveHeading);
  answers.sort(function (a, b) {
    var aB = +(a.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0],
        bB = +(b.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0];
    return aB - bB
  });

  var users = {};
  answers.forEach(function (a) {
    var headline = a.body_markdown.split("\n")[0];
    var question = QUESTION_IDs.indexOf(a.question_id);
    var size = parseInt((headline.match(SIZE_REG)||[0])[0]);
    var language = headline.match(LANGUAGE_REG)[1];
    var user = getAuthorName(a);
    var userId = getAuthorId(a);
    if (!users[userId]) users[userId] = {name: user, nAnswer: 0, answers: []};
    if (!users[userId].answers[question]) {
      users[userId].answers[question] = {size: Infinity};
      users[userId].nAnswer++;
    }
    if (users[userId].answers[question].size > size) {
      users[userId].answers[question] = {size: size, link: a.share_link}
    }
  });
  
  
  var sortedUsers = [];
  for (var userId in users)
    if (users.hasOwnProperty(userId)) {
      var user = users[userId];
      user.score = 0;
      user.completedAll = true;
      for (var i = 0; i < QUESTION_IDs.length; ++i) {
        if (user.answers[i])
          user.score += user.answers[i].size;
        else
          user.completedAll = false;
      }
      sortedUsers.push(user);
    }  
  
  sortedUsers.sort(function (a, b) {
    if (a.nAnswer > b.nAnswer) return -1;
    if (b.nAnswer > a.nAnswer) return 1;
    return a.score - b.score;
  });
  
  var place = 1;
  for (var i = 0; i < sortedUsers.length; ++i) {
    var user = sortedUsers[i];
    var row = '<tr><td>'+ place++ +'.</td><td>'+user.name+'</td>';
    for (var j = 0; j < QUESTION_IDs.length; ++j) {
      var answer = user.answers[j];
      if (answer)
        row += '<td><a href="'+answer.link+'">'+answer.size+'</a></td>';
      else
        row += '<td class="missing"></td>';
    }
    row += '<td></td>';
    if (user.completedAll)
      row += '<td class="total">'+user.score+'</td>';
    else
      row += '<td class="total missing">'+user.score+'</td>';
    row += '</tr>';
    $("#users").append(row);
  }
}
body { text-align: left !important}

#leaderboard {
  width: 500px; 
}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}

td.total {
  font-weight: bold;
  text-align: right;
}

td.missing {
  background: #bbbbbb;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="leaderboard">
  <h2>Leaderboard</h2>
  <p>
    Missing scores are shown as grey cells. A grey total indicates that the user has not participated in all challenges and is not eligible for the overall victory yet.
  </p>
  <table class="_user-list">
    <thead>
      <tr><td></td><td>User</td>
        <td><a href="https://codegolf.stackexchange.com/q/50484/31414">#1</a></td>
        <td><a href="https://codegolf.stackexchange.com/q/50521/31414">#2</a></td>
        <td><a href="https://codegolf.stackexchange.com/q/50625/31414">#3</a></td>
        <td><a href="https://codegolf.stackexchange.com/q/51123/31414">#4</a></td>
        <td><a href="https://codegolf.stackexchange.com/q/51222/31414">#5</a></td>
        <td></td><td>Total</td>
      </tr>
    </thead>
    <tbody id="users">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

Series so far

1. Double Knot

2. Flow Snakes

3. Chinese Shrines

4. Zodiac Signs

5. Random Diamond Tilings

Optimizer

Posted 2015-05-19T22:26:07.140

Reputation: 25 836

1Why is the right edge different for N=3? – aditsu quit because SE is EVIL – 2015-05-24T09:17:29.253

@aditsu Haha. 4 days, 3K views, 11 answers and you are the first person to notice it :D . Fixed! – Optimizer – 2015-05-24T09:18:39.930

Answers

12

CJam, 55 bytes

I got nerd sniped pretty badly by this... anyway, I finally came up with 55 bytes of ISO 8859-1:

"²îå<63Åhbغ¢dräOä[æTZ"246b5b"|_ \/"f=9/4/~2/\ri*2>*zN*

or this alternative:

"ô/Ht]õDz1M;í,D¯Tmä$:r"246b5b"_/\ |"f=9/2/~+ri*2>\++zN*

Initially I tried to do it in plain ASCII, but only got it down to 58 bytes:

"C]VA~`+-WIt*n_I?FanSEo*b"128b5b"_/|\ "f=9/4/~2/\ri*2>*zN*

and again, an alternative:

"1,*Ap7c?UvI$yQHqHqs~=}n"153b5b"_ /|\\"f=9/2/~+ri*2>\++zN*

Explanation:

The idea is to encode the unique parts (left edge, right edge and middle pattern) in a convenient way, repeat the middle part as needed, and put them together. The code ended up being similar in many ways to Dennis's answer; I didn't try to copy him, but I tried many different approaches (including exploiting more symmetries and repetitions) and this is what worked best.

I put the left and right edges together like this:

    
 /\ 
|  |
|  |
 \/ 
 /\ 
|  |
|  |
 \/ 

The middle pattern has 4 columns, but they are repeated N-0.5 times, i.e. one repetition is cut in half. For convenience, I used this pattern:

  __
\/  
/ /\
 /\/
/\ \
\/\ 
/ /\
 /\/
/\__

and removed the first half of the first repetition.

So I joined the parts and encoded them in transposed form, as it's easier to work with them that way. The first and third program encode this string:

 \/ /\/ /
 / /\/ /\
_ /\ \/\_
_ \/\ \/_
  ||  || 
 /  \/  \
 \  /\  /
  ||  || 

(without newlines), which is the transposition of the middle + edges. The second and fourth program (the "alternatives") encode this string:

  ||  || 
 /  \/  \
 \  /\  /
  ||  || 
 \/ /\/ /
 / /\/ /\
_ /\ \/\_
_ \/\ \/_

again, without newlines, and this is the transposition of edges + middle.

Here's how this common part of the code works:

"…"        encoded string (constructed via the reverse process,
           using a suitable base that gives valid characters)
246b       convert the string to an integer, treating each character as a digit
           in base 246 (or other bases in the ASCII versions)
5b         convert the number to base 5, obtaining 72 digits from 0 to 4,
           representing the 5 different characters we have
"|_ \/"f=  convert the digits to their corresponding characters
           (each program uses a different assignment order)
9/         split the resulting strings into 8 strings of 9 characters
           if viewed as lines, they look exactly like the 2 patterns shown above

After this, the implementation differs slightly. In the first and third program we have:

4/     split the lines into groups of 4 - the middle part and the edges
~      dump the two 4-line parts onto the stack
2/     split the second part (the edges) into 2 groups of 2 lines
       (left edge and right edge)
\      swap the edges with the middle part
ri*    read the input, convert to integer (N) and repeat the middle part N times
2>     remove the first 2 lines (first half of first repetition)
*      join the 2 edges using the repeated middle part as a separator
z      transpose the result back to the desired form
N*     join with newlines

In the second and fourth (alternative) programs, we have:

2/     split the lines into groups of 2
       (left edge, right edge, middle first half, middle 2nd half)
~      dump all the groups onto the stack
+      join the two middle halves into a single middle group of 4 lines
ri*    read the input, convert to integer (N) and repeat the middle part N times
2>     remove the first 2 lines (first half of first repetition)
\      swap the repeated middle with the right edge
+      concatenate the middle with the right edge
+      concatenate the left edge with the rest
z      transpose the result back to the desired form
N*     join with newlines

aditsu quit because SE is EVIL

Posted 2015-05-19T22:26:07.140

Reputation: 22 326

I'm not sure how long I tried to make the 1>W< shorter. Turns out that I only had to rotate the array before encoding it and use 2>... – Dennis – 2015-06-04T03:59:54.717

23

CJam, 103 92 83 69 66 57 bytes

"O5àäªÞáKZò,_÷%SJ«Ò"248b5b"/ \_|"f=9/4/~ri*1>W<+2m<zN*

Try it online in the CJam interpreter.

Idea

The pattern becomes a lot more obvious once we transpose rows with columns (padded to the right with spaces).

For input 3, for example, this gives:

  ||  || 
 /  \/  \
_ /\ \/\_
_ \/\ \/_
 \/ /\/ /
 / /\/ /\
_ /\ \/\_
_ \/\ \/_
 \/ /\/ /
 / /\/ /\
_ /\ \/\_
_ \/\ \/_
 \  /\  /
  ||  || 

The first two and last two rows are special, but the others repeat the same pattern over and over again.

Thus, for input N, all we have to do is repeat

 / /\/ /\
_ /\ \/\_
_ \/\ \/_
 \/ /\/ /

N times, replace the first row with

  ||  || 
 /  \/  \

the last row with

 \  /\  /
  ||  || 

and, finally, transpose rows with columns.

Code

"O5àäªÞáKZò,_÷%SJ«Ò"

248b  e# Convert the string (array of code points in base 248) to an integer.
5b    e# Convert the integer to the array of its digits in base 5.

      e# This pushes the following array:

      e# [ 1 2 1 1 0 2 1 1 0 1 1 4 4 1 1 4 4 1 1 1 4 4 1 1
      e#   4 4 1 1 0 1 1 2 0 1 1 2 1 0 1 0 2 0 1 0 2 3 1 0
      e#   2 1 2 0 2 3 3 1 2 0 2 1 2 0 3 1 2 0 1 0 2 0 1 0 ]

"/ \_"

f=    e# Retrieve the chars that correspond to the indexes in the array.

      e# This pushes the following string:

      e# " \  /\  /  ||  ||   ||  ||  /  \/  \ / /\/ /\_ /\ \/\__ \/\ \/_ \/ /\/ /"

9/4/~ e# Divide into groups of 4 strings of length 9.

      e# This pushes the following arrays:

      e# [ " \  /\  /"   "  ||  || "   "  ||  || "   " /  \/  \" ]
      e# [ " / /\/ /\"   "_ /\ \/\_"   "_ \/\ \/_"   " \/ /\/ /" ]

ri    e# Read an integer from STDIN.
*     e# Repeat the last array that many times.
1>W<  e# Remove the first and last string from the array.
+     e# Concatenate both arrays.
2m<   e# Rotate the concatenated arrays two elements to the left.
z     e# Zip the array of strings (transpose rows with columns).
N*    e# Join the strings of the array, separating by linefeeds.

Dennis

Posted 2015-05-19T22:26:07.140

Reputation: 196 637

12

Javascript (ES7 Draft), 169 163 160 158 bytes

Edit: -6 by using a template string to eliminate some repetition from the pattern string.

Edit: -3 by switching from slice(0,-2) to slice(2) by rearranging the pattern string.

Edit: -2 by looping through b instead of a and reducing the a string to 4 with a modulo.

F=N=>[(a='  ||'[i%4])+b[i]+`  __0\\/ ${c=' 0/ /\\0 /\\/0/\\'} \\0\\/\\${c}__`.split(0)[i].repeat(N).slice(2)+(b+b)[9-i]+a for(i in b=' /  \\/  \\')].join(`
`)
<input id="stdin" value="4" />
<button onclick="stdout.innerHTML=F(stdin.value)">Run</button><br />
<pre id="stdout"></pre>

Commented:

F=N=>[ // define function F, start array comprehension to generate each line
    (a = '  ||'[i % 4]) + // first character of the line, store copy in a
    b[i] + // second character of each line
        `  __0\\/ ${c=' 0/ /\\0 /\\/0/\\'} \\0\\/\\${c}__`. 
        // list of patterns for each line delimited by 0's
        // results in string: '  __0\/  0/ /\0 /\/0/\ \0\/\ 0/ /\0 /\/0/\__'
        split(0)[i]. // split by 0, get index at i
        repeat(N). // repeat N times
        slice(2) + // chop off the first 2 characters
    (b + b)[9 - i] + // get opposite of second character, b+b to get a space at index 9
    a // repeat first character (a)
    for(i in b = ' /  \\/  \\') // runs for each index in character map b
].join(` // join resulting array with newlines
`)

nderscore

Posted 2015-05-19T22:26:07.140

Reputation: 4 912

I think you can replace the string before .split(0) with ('__ 0 '+(r='\\/0/\\/ 0\\/ /0 ')+r+'0\\/ /0__/\\'). – flawr – 2015-05-20T17:45:10.853

@flawr I was able to condense it down even further using a similar method :) – nderscore – 2015-05-20T17:54:59.540

If you pass 0 on it, you will see an 8. – Ismael Miguel – 2015-05-20T18:30:52.007

What do those \` and the${...}` exactly do? – flawr – 2015-05-20T20:09:05.720

@flawr The backtick syntax declares a [template string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings). Anything inside${}` is evaluated as a javascript expression. – nderscore – 2015-05-20T20:21:38.483

9

Perl, 134 129

print s/...\K.{4}/$&x~-"@ARGV"/er=~y!iolp!| /\\!r,$/for
map/i/?$_.oi:"o$_$_".o,o__o,loop,@x=(iolplolp,ioplolpl),popl,lpop,@x,p__l

Takes a command line parameter:

$ perl ~/knot.pl 3
  __  __  __  
 /  \/  \/  \ 
| /\/ /\/ /\ |
| \/ /\/ /\/ |
 \ \/\ \/\ \/ 
 /\ \/\ \/\ \ 
| /\/ /\/ /\ |
| \/ /\/ /\/ |
 \__/\__/\__/ 

nutki

Posted 2015-05-19T22:26:07.140

Reputation: 3 634

8

JavaScript (ES6), 165 166

Knot elements:

  • 2 top rows, based on ' __' and '/ \' repeated
  • 2 outer rows, based on '/\/ ' repeated and enclosed in '| ... |'
  • 2 inner rows, based on '\/\ ' repeated and enclosed in '.../' and '/...\'
  • the same 2 outer rows above
  • 1 bottom row based on '\__/' repeated

Ungolfed

K=r=>
{
  R = x => x.repeat(r);
  S = d => R(elem).slice(d,d-2); // use global 'elem' that must be assigned before the call
  elem = '/\\/ '
  outer = '\n| ' + S(0) + ' |\n| ' + S(1) + ' |\n '
  elem = '\\ \\/'
  inner = '\\' + S(1) + '/\n /' + S(0) + '\\'
  return R('  __') + '\n ' + R('/  \\') + outer
  + inner + outer + R('\\__/')
}

Golfed

K=r=>(S=d=>(R=e=>e.repeat(r))(e).slice(d,d-2),o=`
| ${S(0,e='/\\/ ')} |
| ${S(1)} |
 `,R('  __')+`
 ${R('/  \\')+o}\\${S(1,e='\\ \\/')}/
 /${S(0)}\\${o}`+R('\\__/'))

// TEST

function go() {
  O.innerHTML=K(I.value)
}

go()
<input id=I value=5><button onclick='go()'>-></button><br>
<pre id=O></pre>

edc65

Posted 2015-05-19T22:26:07.140

Reputation: 31 086

2Try passing 0 to it and you will get a 4-legged spider. – Ismael Miguel – 2015-05-20T18:29:51.183

8

C++ , 1530 639 479

This looked like a fun challenge I deviated from the brief a little.

#include "stdafx.h"
#include <iostream>
#include <sstream>
using namespace std;
string a=" __ ",b="/  \\",c=" /\\",d="/\\/ ",f="\\ \\/",g="/\\\ \\",r="\\__/",o="",e=o,j="|";
string q(int n,string r,string x="",string m=" ",string t=" "){string z=o;for(int i=0;i<n;i++){z+=r;if(i!=n-1)z+=x;}return m+z+t+"\n";}
int main(){int x,y;cin>>x;cin>>y;e+=q(x,a)+q(x,b);for(int i=0;i<y;i++){e+=q(x,c,"/",j," |")+q(x-1,d,o,"| \\/ ",j);if(i!=y-1){e+=q(x,f)+q(x,g);}}e+=q(x,r);cout<<e;}

Im not sure how to measure bytes of the size of my application but I will try figure it out and update my answer.

My app could be smaller but it loops in both the x and y, and I kinda like that :D

Spaceman

Posted 2015-05-19T22:26:07.140

Reputation: 251

1Welcome to PPCG! Your score is the size of your source code, which is 1530 bytes as it is. You can start saving bytes by removing comments and whitespace, and shorten variable and function names. – Dennis – 2015-05-21T04:05:45.293

Wowzor thats bigger then the rest haha i will work on getting it down :D – Spaceman – 2015-05-21T04:19:18.573

6

Python 2, 156 151 147 141 139

edit 1: edited to use input() instead of a function.

edit 2: used str.join and added to var c to remove some redundant characters.

edit 3: removed some unnecessary string escape sequences.

edit 4: used ~-n instead of a=n-1

This was good fun to program, my first code golf!

n=input()
a='/\/ '*~-n
b='\ '+'\/\ '*~-n+'\\'
c='\n| '+a+'/\ |\n| \/ '+a+'|'
print'\n '.join(('  __'*n,'/  \\'*n+c,b+'/','/'+b+c,'\__/'*n))

save it in an external text editor as n.py in order to remove last newline character in order to reduce file size by 1 byte, run the module, and input your number.

micsthepick

Posted 2015-05-19T22:26:07.140

Reputation: 421

If you allow for entering the number right after the programs execution statement, then I can further strip it down to 151 bytes – micsthepick – 2015-05-20T09:56:11.347

Usually input () is considered okay when reading from STDIN. – seequ – 2015-05-20T16:12:23.467

I see you've saved a=n-1 to save on writing *(n-1) twice, but you do *~-n.

– xnor – 2015-05-21T06:06:57.640

still same amount of characters either way, because I use the value twice, but good tip. – micsthepick – 2015-05-21T06:37:47.577

You can save some bytes on the way python handles backslashes in strings, you don't always need to encode them. See http://stackoverflow.com/a/16973452/3351622

– Matty – 2015-05-22T09:31:00.657

@micsthepick I think it does save chars: b='/\/ '*~-n;c='\ '+'\/\ '*~-n+'\\' – xnor – 2015-05-26T09:40:10.797

I see. I took the amount it would cost to implement your solution, 2*3 = 6 characters for each use of 'a', and I took that from the cost of the definition - 6, but I didn't take into account that it also takes two characters to use the variable. – micsthepick – 2015-05-26T09:49:14.240

5

Python 2, 139 133 129 bytes

n=input()
for i in range(9):w=' ?|'[i&2];s=' / /\/ /\_ /\ \/\__ \/\ \/_ \/ /\/ /'[i::9]*n;s=(s,' %s '%s[1:-1])[i%4>1];print w+s+w

This one just builds and prints line by line.

Here's the code in ungolfed form:

n=int(input())
# The list with all the knot pieces
l= [' __ ',
    '/  \\',
    ' /\/',
    '/\/ ',
    '\ \/',
    '/\ \\',
    ' /\/',
    '/\/ ',
    '\__/']
# The first and last columns
w = '  ||  || '
# Loop for each row
for i in range(9):
    # Exception for the first and last character in the knot (in some rows)
    s = l[i]*n
    if i % 4 > 1:
        s = ' ' + s[1:-1] + ' '
    # Print the knot for this row
    print(w[i] + s + w[i])

Edit: I changed the language to python 2, to be compatible with my answer for #3 (and it also saves 6 more bytes)

Matty

Posted 2015-05-19T22:26:07.140

Reputation: 471

I believe w=(3*' ||')[i] -> w=' |'[i&2] and ' '+s[1:-1]+' ' -> ' %s '%s[1:-1] work (the first one is a string with two spaces then a pipe, but SE's acting up) – Sp3000 – 2015-05-25T06:45:40.003

@Sp3000 Thanks! That first one is pretty smart. I should have thought of ' ||'[i%4], but this is even shorter (also with two spaces). – Matty – 2015-05-25T11:13:53.420

3

C, 159 bytes

j,k;f(n){char*t="7>771I;M6CMI93;IIB;;MI1M;M6CMI93;IIB;>MI";for(n*=4;t[j/2];++k,k%=n+3,j+=k-n?k%n<3||k%4-2?1:-3:3)putchar("\n _|/\\"[(t[j/2]-48)/(j%2?1:6)%6]);}

With whitespace, and some other readability improvements:

#include <stdio.h>

int j, k;

void f(int n) {
    char *t = "7>771I;M6CMI93;IIB;;MI1M;M6CMI93;IIB;>MI", *m = "\n _|/\\";
    for (n *= 4; t[j / 2];
         ++k,
         k %= n + 3,
         j += k - n ? k % n < 3 || k % 4 - 2 ? 1 : -3 : 3)
        putchar(m[(t[j / 2] - 48) / (j % 2 ? 1 : 6 ) % 6]);
}

This is primarily template based. The template t contains all 9 possible columns of the output, meaning that it encodes 9 * 9 = 81 characters, or 80 without the trailing newline.

Since there are only 6 different characters in the pattern (including newline characters), I packaged pairs of them into one template character, which means that the template can be stored in 40 characters. There are then 6 * 6 = 36 possible pairs of characters, which are encoded as ASCII characters 48 to 73. The translation back to the original character is given by the small lookup table m.

The rest of the logic is mainly to repeat the pattern n times, which means jumping back 4 characters in the template, while emitting the start and end parts of each row correctly.

Reto Koradi

Posted 2015-05-19T22:26:07.140

Reputation: 4 870

2

PHP 5.5.3, 488, 466

<?php 
function k($n){$r=array_fill(0,9,'');for($i=0;$i<$n;$i++){$r[0].=($i==0)?"  __ ":" __ ";$r[1].=($i==0)?" /  \\":"/  \\";$r[2].=($i==0)?"| /\\/":(($i==$n-1)?" /\\ |":" /\\/");$r[3].=($i==0)?"| \/ ":(($i==$n-1)?"/\/ |":"/\/ ");$r[4].=($i==0)?" \\ ":(($i==$n-1)?"\\/\\ \\/":"\\/\\ ");$r[5].=($i==0)?" /\\ ":(($i==$n-1)?"\\/\\ \\":"\\/\\ ");$r[6]=$r[2];$r[7]=$r[3];$r[8].=($i==0)? " \__/":"\__/";}foreach($r as $o){if(strlen($o)-2 !== 4*$n)$o.=" ";echo $o."\n";}}

Med

Posted 2015-05-19T22:26:07.140

Reputation: 121

You can save some chars by removing some unnecessary whitespace around operators, for example around the = and .= ones. – ProgramFOX – 2015-05-21T16:03:54.527

Thx I edited the answer – Med – 2015-05-21T16:12:15.803

2

Prolog (SWI), 285 bytes

a(N):-b(N,"  ||  || "," /  \\/  \\","_ /\\ \\/\\_","_ \\/\\ \\/_"," \\/ /\\/ /"," / /\\/ /\\"," \\  /\\  /"). b(N,[A|G],[B|H],[C|I],[D|J],[E|K],[F|L],[Y|Z]):-c(N,[Y,A],[E,F,C,D],T),writef([A,B,C,D|T]),nl,b(N,G,H,I,J,K,L,Z). c(1,L,_,L):-!. c(N,L,X,O):-M is N-1,c(M,L,X,T),append(X,T,O).

(With whitespace):

a(N):-
    b(N,
    "  ||  || ", 
    " /  \\/  \\", 
    "_ /\\ \\/\\_", 
    "_ \\/\\ \\/_", 
    " \\/ /\\/ /", 
    " / /\\/ /\\", 
    " \\  /\\  /").

b(N,[A|G],[B|H],[C|I],[D|J],[E|K],[F|L],[Y|Z]):-
    c(N,[Y,A],[E,F,C,D],T),
    writef([A,B,C,D|T]),
    nl,
    b(N,G,H,I,J,K,L,Z).

c(1,L,_,L):-!.
c(N,L,X,O):-
    M is N - 1,
    c(M,L,X,T),
    append(X,T,O).

I tried a few ways of chopping the strings, but none seemed to beat this naive columns method.

Paul Butcher

Posted 2015-05-19T22:26:07.140

Reputation: 221

2

JavaScript (ES6), 158 154 148 137 bytes

n=>`    __
 /\\/ - \\/
 /\\/\\-__/`.replace(/-/g,` \\
| / /\\ |
|  /\\/ |
 \\/\\`).replace(/(..)(....)/g,(_,l,m)=>l+m.repeat(n).slice(2))

Edit: Saved 11 bytes thanks to @Bálint.

Neil

Posted 2015-05-19T22:26:07.140

Reputation: 95 035

@Bálint But /(..)(.{4})/g is 13 bytes, the same as /(..)(....)/g... – Neil – 2016-05-11T21:17:38.843

@Bálint I actually realised that my previous 4-byte saving allowed me to do that, but I was away from the computer at the time. – Neil – 2016-05-11T21:19:12.873

@Bálint Nice! I had looked into avoiding the repeated \/\ segment but I hadn't thought to check for a longer repeated substring. – Neil – 2016-05-12T09:07:27.710

1

PowerShell, 228 207 181 133 bytes

%{"  "+"__  "*$_;" "+"/  \"*$_;$b="|"+" /\/"*$_+"`b |";$b;$c="| "+"\/ /"*$_+"`b|";$c;" "+"\ \/"*$_;" "+"/\ \"*$_;$b;$c;" "+"\__/"*$_}

Reminder - PowerShell doesn't wait on stdin automatically. You have to pipe something in, e.g. 3|%{...}

Nacht - Reinstate Monica

Posted 2015-05-19T22:26:07.140

Reputation: 481

1

Java, 339 330 bytes

class D{int n,i;public static void main(String[]a){new D(new Integer(a[0]));}D(int k){n=k;r("  __");p("\n ");r("/  \\");c();r("\\ \\/");p("\n ");r("/\\ \\");c();r("\\__/");}void c(){p("\n|");--n;r(" /\\/");p(" /\\ |\n| \\/");r(" /\\/");++n;p(" |\n ");}void p(String s){System.out.print(s);}void r(String s){for(i=n;i>0;--i)p(s);}}

My first solution had so many "static" keywords in it that it was shorter to make the methods and attributes non-static and run the code in the constructor.

ECS

Posted 2015-05-19T22:26:07.140

Reputation: 361

0

SmileBASIC, 149 bytes

INPUT N?"  __"*N
A$="| / /\ |
B$="|  /\/ |
K" /\/  \
K A$K B$K" \/\ \/
K" /\/\ \
K A$K B$K" \/\__/
DEF K A?SUBST$(A,2,4,MID$(MID$(A,2,4)*N,2,N*9))END

Each string contains the pattern AACCBBDD which is expanded to form AABB(CCBB)*DD The CCBB part is repeated N times, then the first 2 characters are removed. (It was shorter to remove characters from the start than from the end)

12Me21

Posted 2015-05-19T22:26:07.140

Reputation: 6 110