Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Imagine a rectangular grid of | characters represents the taut strings on a loom (the warp) that other threads (the weft), which we will represent as -, can be woven around.

Here is the unwoven warp of a 7×4 loom:

|||||||
|||||||
|||||||
|||||||

There are a number of ways the weft can be woven into the warp, the simplest being the plain weave.

In the first row of a plain weave the weft starts above the first warp string, goes below the second string, then above the third string, then below the fourth, and so on.

The second weft row is identical to the first but offset to the right by one warp string, so it starts under then goes over, and so on.

On our 7×4 loom the plain weave looks like this:

-|-|-|-
|-|-|-|
-|-|-|-
|-|-|-|

We can describe the plain weave by saying that the weft goes over the warp 1 time, then under 1 time, and each subsequent row is shifted 1 string to the right.

A generalized weave can be described by having the weft go over the warp v times, then under u times, with each subsequent row shifted by s strings to the right. (All values are integers, s may be 0 or negative, u and v must be non-negative.)

A 7×4 loom with v = 1, u = 2, s = 2, a type of twill weave:

-||-||-
||-||-|
|-||-||
-||-||-

Challenge

Your task is to write the shortest program (in bytes) that produces a woven pattern of bars and dashes given v, u, s, the width and height of the loom, and the initial shift.

The initial shift is the number of strings the first row in the weft is shifted to the right (0 in the examples above). Each subsequent row is shifted by s more strings.

Your program should take in these 6 numbers in some easy to use format (stdin, a function call, etc.) and output the woven grid of bars and rectangles to stdout. You may assume all input is valid. (All values are integers, width and height must be positive, initial shift may be anything.)

Examples

width = 5, height = 4, initial shift = 0, v = 1, u = 3, s = -2:

-|||-
||-||
-|||-
||-||

width = 5, height = 4, initial shift = 3, v = 1, u = 3, s = -2:

|||-|
|-|||
|||-|
|-|||

width = 5, height = 4, initial shift = 1, v = 1, u = 1, s = 0:

|-|-|
|-|-|
|-|-|
|-|-|

width = 5, height = 4, initial shift = 0, v = 1, u = 0, s = 0:

-----
-----
-----
-----

Notes

  • The pattern always starts with the weft over the warp at the top left corner of the grid (unless initially shifted).
  • All the weft threads come in from the left. They do not spiral like this.
  • u + v is not necessarily a multiple of the grid width.
  • u and v may not both be 0
share|improve this question

4 Answers 4

up vote 5 down vote accepted

Ruby, 72 bytes

w,h,v,u,s,i=$*.map &:to_i;h.times{puts ((?-*v+?|*u)*w)[-i%(u+v),w];i+=s}

Not a lot to say about this. I build one repetition of - and |, repeat it w times (just to be sure), and the I slice out the appropriate section for each line.

share|improve this answer
    
When u+v==1, is w times enough? –  edc65 Jul 25 at 19:32
    
@edc65 yes, because of the %(u+v). In this case I'm only ever starting at index 0, so I've got w characters left in the string. –  Martin Büttner Jul 25 at 19:41

JavaScript (ES 6) 128

F=(w,h,i,v,u,s)=>{for(x=('-'[R='repeat'](v)+'|'[R](u))[R](w*h),l=v+u,i=-i%l+l,s=-s%l+l;h--;i+=s)console.log(x.substr(i,w)+'\n')}

Test

F(11,8,2,5,3,-2)

||-----|||-
-----|||---
---|||-----
-|||-----||
||-----|||-
-----|||---
---|||-----
-|||-----||
share|improve this answer

Python, 92 bytes

w,h,i,v,u,s=eval(A)
x=('|'*u+'-'*v)*w
while h:print(x[-i:]+x[:-i])[-w:];x=x[-s:]+x[:-s];h-=1

Hmm... So tempted to learn ruby now.

Input by assigning a string variable in this format: "width, height, initial shift, v, u, s".
Paste before the program:

A="80,80,0,2,2,-9"
share|improve this answer
1  
I believe it should be while h. I'm getting an extra row. –  Calvin's Hobbies Jul 25 at 19:24
1  
You should use the any input format system - make the input values comma separated, and eval it. –  isaacg Jul 25 at 20:33
    
Thanks both python frequenters for tips! –  bitpwner Jul 25 at 21:11

"It's more comfortable than it looks." "It would have to be." -- Gia and Eidon (No one's going to get this reference. Hint: "Weave Mat")

So I've been working on and off on this for about five hours now, and I give up. I have no idea how to get this code to work. It keeps going backwards after the first row, and then gets entirely wrong (7 4 0 2 2 1).

Here's the simpler version you can read more easily. All I do is retrieve input, make the template array, and then print within the loops.

#include<stdio.h>
int w,h,t,v,u,s,i,j,l,f;
int main(){
    scanf("%d %d %d %d %d %d",&w,&h,&t,&v,&u,&s);
    l=v+u;char g[l];g[l]='\0';f=0;
    while(u--){g[v+u]='|';}while(v--){g[v]='-';}
    for(i=0;i<h;i++){
        for(j=0;j<w;j++){
            printf("%c",g[abs(t+f+j)%l]); // THIS is the line that needs help.
        }
        printf("\n");
        f-=s;
    }
}

And here's the compacted version, 257 bytes. I'm sure it can be squashed a bit more.

#include<stdio.h>
int w,h,t,v,u,s,i,j,l,f;int main(){scanf("%d %d %d %d %d %d",&w,&h,&t,&v,&u,&s);l=v+u;char g[l];g[l]='\0';f=0;while(u--){g[v+u]='|';}while(v--){g[v]='-';}for(i=0;i<h;i++){for(j=0;j<w;j++){printf("%c",g[abs(t+f+j)%l]);}printf("\n");f-=s;}}

You can easily test it here: http://www.compileonline.com/compile_c_online.php using "7 4 0 1 1 1" in the STDIN Input box at the bottom. Start editing the numbers, and you'll see the problems.

Sorry I couldn't come up with a working solution; I'm hating myself for this. I've spent too much time to not upload it to have someone else fix.

I've been using this printf for a while to further separate the top row (easy) to the rest of them (the problem rows): printf("%c",g[i?abs(t+f+j)%l:abs(t+j)%l]);

share|improve this answer
    
for(i=0;i++<h;)? Same trick for the second for-loop? It saves just one char per loop though. –  11684 Jul 25 at 21:26
    
I did try that a few times, but that makes the numbers off, and I couldn't find a way to use them. –  Ness Jul 28 at 12:59
    
Strange. Other way around? ++i? That's just a shot in the dark though. –  11684 Jul 28 at 13:29
    
Nope; that would increment before the number is even used for the comparison and you'd end up with h-1 iterations. The problem with using a ++ at all in the second section of the for loop declaration is that i is incremented before you even use it within the loop. Dealing with the off-number may require a -1 somewhere in the math, and that makes the shortcut not worth it. Unless this is doable without that -1. I still can't figure it out. –  Ness Jul 28 at 13:36
    
Of course! facepalm. –  11684 Jul 28 at 13:36

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.