12
\$\begingroup\$

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
\$\endgroup\$

6 Answers 6

5
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ When u+v==1, is w times enough? \$\endgroup\$
    – edc65
    Jul 25, 2014 at 19:32
  • \$\begingroup\$ @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. \$\endgroup\$ Jul 25, 2014 at 19:41
3
\$\begingroup\$

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)

||-----|||-
-----|||---
---|||-----
-|||-----||
||-----|||-
-----|||---
---|||-----
-|||-----||
\$\endgroup\$
2
\$\begingroup\$

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"
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I believe it should be while h. I'm getting an extra row. \$\endgroup\$ Jul 25, 2014 at 19:24
  • 1
    \$\begingroup\$ You should use the any input format system - make the input values comma separated, and eval it. \$\endgroup\$
    – isaacg
    Jul 25, 2014 at 20:33
1
\$\begingroup\$

JavaScript (ES6), 111 bytes

A slightly different ES6 approach, using the functional Array.from.

f takes arguments (w,h,i,v,u,s) and returns a string. Newlines added to code and literal newline in string replaced by \n for clarity; neither reflected in byte count.

f=(w,h,i,v,u,s)=>(A=Array).from(A(h),(_,j)=>A.from(A(w),
(_,k)=>(j*((x=v+u)-s)+x+k-i)%x<v?'-':'|').join``).join`\n`

Usage

console.log(f(5,4,0,1,3,-2)) /*

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

*/

Ungolfed version with explanation

I saved some bytes by creating an alias for Array, which is not reflected in the ungolfed version.

// take input and create an array of length h (height):
f = (w,h,i,v,u,s) => Array.from( Array(h),

    // in each row position j, create an array of length w (width):
    (_,j) => Array.from( Array(w), 

        // in each cell, place - or | depending on the pattern (i,v,u,s)
        // and current position (j,k):
        (_,k) => ( j * ( ( x = v + u ) - s ) + x + k - i ) % x < v ? '-' : '|'

    // turn each row into a string:
    ).join``

// join rows with newlines:
).join`\n`
\$\endgroup\$
0
\$\begingroup\$

C, 357 bytes

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

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

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

\$\endgroup\$
5
  • \$\begingroup\$ for(i=0;i++<h;)? Same trick for the second for-loop? It saves just one char per loop though. \$\endgroup\$
    – 11684
    Jul 25, 2014 at 21:26
  • \$\begingroup\$ I did try that a few times, but that makes the numbers off, and I couldn't find a way to use them. \$\endgroup\$
    – Ness
    Jul 28, 2014 at 12:59
  • \$\begingroup\$ Strange. Other way around? ++i? That's just a shot in the dark though. \$\endgroup\$
    – 11684
    Jul 28, 2014 at 13:29
  • \$\begingroup\$ 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. \$\endgroup\$
    – Ness
    Jul 28, 2014 at 13:36
  • \$\begingroup\$ Of course! facepalm. \$\endgroup\$
    – 11684
    Jul 28, 2014 at 13:36
0
\$\begingroup\$

Haskell, 126 bytes

f w h i v u s=putStr.unlines$take h$take w<$>(iterate(drop(mod s(u+v)))$drop(mod(-i)(u+v)).cycle$('-'<$[1..v])++('|'<$[1..u]))
\$\endgroup\$
1
  • 1
    \$\begingroup\$ A trivial golf would be to change f w h i v u s for (w?h)i v u s. An infix function \$\endgroup\$
    – H.PWiz
    Apr 3, 2018 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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