# Stitch a hitomezashi pattern

## Challenge

Given two binary vectors (containing two consistent values of your choice) of length $$\n\$$ and $$\m\$$, output a corresponding hitomezashi stitching pattern.

You are to fill the following pattern, where $$\n\$$ is the number of A-columns and $$\m\$$ is the number of B-rows:

 A A A A A
B+B+B+B+B+B
A A A A A
B+B+B+B+B+B
A A A A A


Here A can be one of | and  (space), and B can be one of - and  (space). The rows and columns alternate between these two values. The binary vectors indicate, whether to start in the "on" (|/-) or "off" ( ) position for each row or column.

You may be interested in a recent Numberphile video on that topic.

## Rules

• $$\n,m \geqslant 1\$$
• There are $$\ n \times m \$$ +s.
• You may take input in any consistent order (rows first or columns first) and following any direction (right-to-left and top-to-bottom or reversed or mixed).
• Output in any reasonable format, including one of: single string with newlines, list of lines, matrix of characters. Output as char codes is allowed only if your language doesn't support strings natively.
• Trailing whitespace is optional.

## Test cases

Input: 0 1 0 1, 0 1 1
Working out:

 0 1 0 1
0+?+?+?+?
? ? ? ?
1+?+?+?+?
? ? ? ?
1+?+?+?+?
? ? ? ?


Output:

   |   |
+-+ +-+
|   |
-+ +-+ +-
|   |
-+ +-+ +-
|   |


Input: 0, 0
Output:


+-
|


Input: 1, 1
Output:

 |
-+



Input: 1 0 1 0 1, 1 0 1 0 1 0 1
Output:

 |   |   |
-+ +-+ +-+
|   |
+-+ +-+ +-
|   |   |
-+ +-+ +-+
|   |
+-+ +-+ +-
|   |   |
-+ +-+ +-+
|   |
+-+ +-+ +-
|   |   |
-+ +-+ +-+
|   |

• "binary vectors indicate whether to start in the on or off position", and the lengths of the vectors give the number of rows & columns... so do the elements in each vector other than the first element have any function? Dec 17, 2021 at 14:15
• @DominicvanEssen the first vector (length n) indicates how do n columns start, the second - how do m rows start. I provided a working out for the first test case - hope it clarifies a little. Dec 17, 2021 at 14:17
• Got it (and now I see that this was implicit from test case 1). Suggest adding the clause '...for each row or column' at the end of paragraph 3 of the description. Dec 17, 2021 at 14:22
• @DominicvanEssen, thanks! Added. Dec 17, 2021 at 14:25

# Charcoal, 29 bytes

Ｆ²«Ｐ⭆§θ¬ι⪫¶¶⪫Ｅ⊕Ｌ§θι§ -⁺μκ+‖Ｔ↙


Try it online! Link is to verbose version of code. Takes input as an array of two binary vectors. Explanation:

Ｆ²«


Loop over rows and then columns.

Ｐ⭆§θ¬ι⪫¶¶⪫Ｅ⊕Ｌ§θι§ -⁺μκ+


For each row, build up the line of -s or spaces and +s according to the initial value from the binary vector. Double-space the rows out and output the whole string without moving the cursor.

‖Ｔ↙


Reflect the entire diagram around its main diagonal. On the first pass this moves the rows to the columns, allowing the columns to be printed where the rows were, while on the second pass the rows and columns are restored to their correct placement. Additionally, the -s and |s are swapped as part of the reflection.

# Jelly, 27 bytes

JŻḂ+ż⁸Fð"2,4^'/ị“+ - |  +”Y


Try it online!

Takes input like [[0,1,0,1],[0,1,1]].

Helper function: left input is a bit array, right input is a number

JŻḂ       Alternate [0,1,0,1,…] one longer than the bit array
ż⁸F   Interleave with the array:  [n, a0, n+1, a1, n, a2, n+1]

Main function: input is two bit arrays [A, B]

ð"2,4                  [helper(A, 2), helper(B, 4)]
^'/               Make a XOR table
ị“+ - |  +”Y   Index into “+ - |  +” and join by newlines.


For example, for the input [[0,1,0,1],[0,1,1]] this computes

 ^ │ 2 0 3 1 2 0 3 1 2
──┼───────────────────
4 │ 6 4 7 5 6 4 7 5 6
0 │ 2 0 3 1 2 0 3 1 2
5 │ 7 5 6 4 7 5 6 4 7
1 │ 3 1 2 0 3 1 2 0 3
4 │ 6 4 7 5 6 4 7 5 6
1 │ 3 1 2 0 3 1 2 0 3
5 │ 7 5 6 4 7 5 6 4 7


And then translates {0, 1} → +, 3 → -, 5 → |, and everything else to spaces.

# APL (Dyalog Unicode), 69 66 62 58 54 bytes

Function that takes two binary vectors as left and right argument. Assumes index origin 0.

{' -|+'[↑,⍉↑(,/¯2↑¨2×↑≠\(⊂⍺),!⍵)({∊⍺3⍵}/⍉↑≠\(⊂⍵),!⍺)]}


Try it online!

Commented (outdated):

{∊⍺'+'⍵}/' -'[⍉↑≠\(⊂⍵),!⍺] ⍝ Generate the B-rows
!⍺  ⍝ A list of n 1's (factorial of 0 and 1 is 1)
(⊂⍵),    ⍝ prepend the right (second) input vector
⍉↑≠\         ⍝ the tranpose of ≠ (XOR) scan
⍝   this gives a binary mask of where to place dashes
' -'[           ] ⍝ index with the mask into the string ' -' to get a character matrix
{∊⍺'+'⍵}/                  ⍝ for each row, insert plus's

,/¯2↑¨' |'[↑≠\(⊂⍺),!⍵] ⍝ Generate the A-rows
' |'[↑≠\(⊂⍺),!⍵] ⍝ Same as above, but with inputs swapped and not transposed
¯2↑¨                 ⍝ Prepend a space to each character in the matrix (this results in a nested matrix)
,/                     ⍝ Join each row into a single string

↑,⍉↑                       ⍝ Interleave the two lists of rows to get a single character matrix


# Python 3.8 (pre-release), 121 116 bytes

lambda h,v,i=0:[print(((i:=~i)<2>l)*((l*"-+"+len(h)*" +-+")[:len(h)*2+1]+"\n"),*["| "[k^i]for k in h])for l in[2]+v]


Try it online!

Uses Pythons space separated output of print for the vertical lines.

Thanks for @pxeger for noticing that the flag toggle (i:=~i) and first line check (2>l) can be combined, by using a numerical flag.

By using 0 and -1 instead of 0 and 1 for the flag, a further byte can be saved.

• 117 bytes by toggling a flag instead of reversing, and then combining that into the l<2 comparison Dec 17, 2021 at 23:19

# JavaScript (ES6), 95 bytes

Expects (a)(b). Returns a matrix of characters.

a=>b=>[...b+11].map((_,y)=>[...a+11].map((_,x)=>' |-+'[x*y%2*3|a[~-x/2]+y/2&1|b[~-y/2]*2+x&2]))


Try it online!

### Cell types

   01234    Cell types:
0 .|.|.      crossing (+)        : x odd and y odd ⇔ x * y % 2 == 1
1 -+-+-      vertical link (|)   : x odd and y even
2 .|.|.      horizontal link (-) : x even and y odd
3 -+-+-      empty (.)           : x even and y even
4 .|.|.


### Commented

a =>                  // a[] = horizontal vector
b =>                  // b[] = vertical vector
[...b + 11]           // coerce b[] to a string and append 2 more characters,
// which gives b.length * 2 + 1 characters
// e.g. [0,1,0] -> "0,1,011"
.map((_, y) =>        // for each entry at position y:
[...a + 11]         //   do the same thing with a[]
.map((_, x) =>      //   for each entry at position x:
' |-+'[           //     character lookup:
x * y % 2 * 3 | //       force a '+' if both x and y are odd
a[~-x / 2]      //       attempt to get a[(x - 1) / 2],
//       which is undefined if x is even
+ y / 2         //       add y / 2 (resulting in NaN if x is even)
& 1 |           //       bitwise AND with 1 to get either " " or "|"
b[~-y / 2] * 2  //       attempt to get b[(y - 1) / 2] * 2,
//       which is NaN if y is even
+ x             //       add x (still NaN if y is even)
& 2             //       bitwise AND with 2 to get either " " or "-"
]                 //     end of character lookup
)                   //   end of inner map()
)                     // end of outer map()


# 05AB1E, 37 33 bytes

"+ - |  +"Iε1ÝyĆ∍N>o+s.ι}sδ^<èJ»


-4 bytes by porting @Lynn's Jelly answer.

Original 37 byter:

v„|-NèðìyD_øIN_èg>δ∍N_iø}è„ +Nèý}.ι.c


Input as pair $$\[n,m]\$$, where both $$\n\$$ and $$\m\$$ are lists of 0s/1s.

Taking the input in the order $$\[m,n]\$$ instead would result in the same byte-count:

v„-|NèðìyD_øIN_èg>δ∍Niø}è„+ Nèý}s.ι.c


Explanation:

v                    # Loop y over the (implicit) input-pair:
„|-                 #  Push String "|-"
Nè               #  Use the 0-based loop-index to index into it
ðì             #  Prepend a space
y            #  Push the current input-list
D_          #  Duplicate it, and invert each 0↔1
ø         #  Zip the two lists, creating pairs
#  (all 0s are now [0,1] and all 1s are now [1,0])
I        #  Push the input-pair again
N_      #  Push the inverted loop-index
è     #  Use it to index into the input-pair
g    #  Pop and push its length
>   #  Increase this length by 1
δ  #  Loop over the list of [0,1] and [1,0] pairs:
∍ #   Extend each pair to the length+1 of the opposite list
N_i }               #  If this is the second input-pair:
ø                #   Zip/transpose it; swapping rows/columns
è              #  Index each value into the " |" or " -" we created earlier
„ +           #  Push string " +"
Nè         #  Index the loop-index into it
ý        #  Join the list of characters with this as delimiter
}.ι                  # After the loop, interleave both lists of lines on the stack
.c                # Join this list by newlines, and center each line
# (after which the result is output implicitly)


# R, 184164162136134 129 bytes

Edit: -28 bytes (!) thanks to pajonk, and -2 bytes thanks to Giuseppe

function(n,m,?=length){x=array(" ",c(?n,?m)*2+1)
x[2*1:?n,p<-!0:1][c(n,!n)]="-";x=t(x)
x[2*1:?m,p][c(m,!m)]="|"
x[!p,!p]="+"
x}


Try it online!

• Looks like this solution may struggle when one input is of length 1 and second more than 1. Or is it just weird formatting on mobile? Dec 20, 2021 at 5:40
• @pajonk - Thanks for spotting. The solution was Ok, but I mistakenly used ncol instead of nrow when calling write to prettily format the output. TIO link is fixed now. Dec 20, 2021 at 8:55
• -2 bytes by taking input as TRUE/FALSE. Dec 20, 2021 at 9:48
• @pajonk - Ah, yes, thanks. That's much more satisfying: I hated the double-!`s. Dec 20, 2021 at 10:09
• Some rearrangements for 136 bytes. And no, I don't have my answer to this challenge :) Dec 20, 2021 at 14:51