Will you be my Weaver?

14

1

I've been recently playing through 'The Weaver' and I think it presents an interesting challenge for .

Premise:

The Weaver is a game wherein you are given a number of ribbons coming from 2 directions 90 degrees apart and your goal is to swap them at certain intersections to achieve a desired output.

   Like this:         This is a swap:         This isn't:

Like thisswapnot a swap

Input:

3 arrays:

  • Top ribbons (left to right)
  • Left ribbons (top to bottom)
  • The coordinates of the intersections to swap

Output:

2 arrays:

  • Bottom ribbons (left to right)
  • Right ribbons (top to bottom)

Examples:

I'll use the above image as the first example:

Input: [r, y, b], [r, y, b], [(0, 1), (2, 1), (2, 2)]

What happens:

   r   y   b
   r   y   b
r r r r•y y y y
   r   r   b
y y y y y y y y
   r   r   b
b b b b•r r•b b
   r   b   r
   r   b   r

Where represents a swap.

Output: [r, b, r], [y, y, b]


Input: [a, b, c], [d, e, f], [(0, 0), (2, 1)]

What happens:

   a   b   c
   a   b   c
d d•a a a a a a
   d   b   c
e e e e e e e e
   d   b   c
f f f f•b b b b
   d   f   c
   d   f   c

Output: [d, f, c], [a, e, b]


Input: [a, b], [a, b, c], [(0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 1)]

What happens:

   a   b
   a   b
a a a a•b b
   a   a
b b•a a•a a
   b   a
c c•b b•a a
   c   b
   c   b

Output: [c, b], [b, a, a]

Notes:

  • The examples show coordinates given as (row, column) though you may take them as (column, row).
  • The top row and left column may have ribbons of the same color
  • The board can be rectangular
  • All coordinates will be non-negative (>=0) (or strictly positive (>=1) if you choose 1-indexing)
  • Ignore any swaps that are outside the board
  • You may choose to work with letters ([a-zA-Z]), integers ([0-9]) or both
  • The ribbons in your output must match the ribbons in the input exactly (a -> a)
  • You may assume the list of swaps is sorted in any way you want, as long as it's consistent (if you do, please specify how it should be sorted)
  • You may take the swap coordinates as 0 or 1-indexed
  • Default loopholes are forbidden

More examples:

Input:
[b], [r], []
Output:
[b], [r]

Input:
[b], [r], [(0, 0)]
Output:
[r], [b]

Input:
[r, p, y], [r, y, p], [(0, 0), (1, 2), (2, 1), (3, 2)]
Output:
[r, p, y], [r, y, p]

Input:
[b, y, o, r],
[r, o, b, y],
[(0, 0), (2, 0), (3, 2)]
Output:
[b, y, y, r],
[b, o, r, o]

The last example relates to this case (if that makes it easier to visualize):

example

This is so the shortest answer in bytes for each language wins.

Asone Tuhid

Posted 2018-04-19T11:03:42.910

Reputation: 1 944

1Re "Ignore any swaps that are outside the board" - does that mean we cannot assume that all swap coordinates are on the board, and we need to filter them for validity (ignore the invalid ones), or does that mean that we can ignore the case of coordinates being outside of the board because the input will always be valid? – Bergi – 2018-04-19T21:05:01.827

@Bergi it means that the input may include swaps outside the board and you have to filter or ignore them. (The 3rd example includes such a swap) – Asone Tuhid – 2018-04-19T21:10:34.577

Oh. I think the challenge would have been more interesting if the swaps would only have had valid coordinates, but that we could not assume they were sorted in an order that fits our solution. – Bergi – 2018-04-19T21:13:21.827

@Bergi maybe, but if that was the challenge, most answers would simply sort the list (which is a boilerplate action just like filtering invalid coordinates). Personally, I think that filtering (or ignoring) invalid coordinates can be done more cleverly than sorting. – Asone Tuhid – 2018-04-19T21:18:41.843

Yeah, they're both boilerplate, so I would have expected both or neither. Depending on the language, sorting takes some cleverness or many bytes as well - and I would have loved to see clever algorithms that don't require a particular order :-) – Bergi – 2018-04-19T21:29:19.350

Regarding invalid coordinates, can they be negative (or 0 in 1-indexed solutions)? – Bergi – 2018-04-19T21:30:23.517

1@Bergi You're probably right, well, it's too late to change now. And no, all coordinates will be positive, I'll update the question. – Asone Tuhid – 2018-04-19T21:34:35.983

"positive" is the same as ">0". Maybe you meant this? – user202729 – 2018-04-20T01:19:18.733

@user202729 No, I mean positive (>=0) if you take. 0-indexed coordinates and (>0) otherwise. Or in other words, no coordinate will be above or left of the board. – Asone Tuhid – 2018-04-20T04:33:33.833

No, >=0 is non-negative. According to this.

– user202729 – 2018-04-20T05:13:03.457

Missing comma in first example input – Sunny Patel – 2018-04-20T14:02:00.877

1@AsoneTuhid If coords are (row,col), it makes more sense to i/o the left ribbons first and the top ribbons second. Is that allowed? – ngn – 2018-04-23T05:27:16.320

@ngn I'm leaning towards no. Would it significantly simplify your solution? – Asone Tuhid – 2018-04-23T05:44:35.167

@AsoneTuhid It would save some precious bytes. – ngn – 2018-04-23T05:49:39.093

@ngn Alright, it was probably an unnecessary restriction anyway. – Asone Tuhid – 2018-04-23T05:59:36.330

@AsoneTuhid Thank you! I think it makes more sense this way - axes come in a consistent order. – ngn – 2018-04-23T06:02:58.770

Answers

8

Python 3, 74 bytes

def g(a,b,l):
 for x,y in l:
  if x<len(a)and y<len(b):a[x],b[y]=b[y],a[x]

Try it online!

Requires l to be sorted in lexicographical order. a and b are lists of characters representing (left ribbon, top ribbon).

Returns by modifying the list a and b.

user202729

Posted 2018-04-19T11:03:42.910

Reputation: 14 620

3

Jelly, 37 35 30 bytes

ṙ"z0U1¦Zḟ€0ṙ"N}
<Ạ¥ÐfL€}⁹ṭṚç/Y

Try it online!

Dyadic program, take 0-indexing list of swap indices as left argument (sorted in reverse lexicographical order) and (left ribbon, top ribbon) as right argument. Returns (right ribbon, bottom ribbon).


Jelly is a tacit language. There is (almost) no variable to work with, so doing anything involves more than two variables at once is a mess.

The first link takes [l,t] as its left argument, [x,y] (0-indexing) as its right argument, and return [l,t] with l[x] and r[y] exchanged.

ṙ"z0U1¦Zḟ€0ṙ"N}
ṙ"               Zipwith rotate. Current value: `[l ṙ x, t ṙ y]`
                   (so l[x] and r[x] becomes l[0] and r[0] respectively)
  z0             Zip, fill with 0. Elements at corresponding (new) indices are
                   paired together, with 0 as the filler.
    U1¦          Reverse the pair at index `1` (first index).
       Zḟ€0      Zip again and filter out the `0`s, effectively undo the z0.
           ṙ"N}  Zipwith rotate by negative shift amount, reverse of `ṙ"`.

So basically "U1¦ under ṙ"z0".


The second link simply filter out OoB indices (<Ạ¥Ðf L€), append the second argument (⁹ṭ), reverse (), and reduce over ç (similar to Haskell's foldl)

user202729

Posted 2018-04-19T11:03:42.910

Reputation: 14 620

2

Python 2, 193 bytes

def f(t,l,s):
 m=[[x,y]for y in[0]+l for x in[0]+t];L=len(t)+1
 for i in range(len(m)):
  if i%L:m[i]=[m[i-L][0],m[i-1][1]][::[1,-1][(i/L,i%L)in s]]
 s=sum(m,[]);print s[2-L*2::2],s[4*L-1::2*L]

Try it online!

Takes 1-indexed swap coordinates

TFeld

Posted 2018-04-19T11:03:42.910

Reputation: 19 246

2

APL (Dyalog Classic), 31 30 bytes

{⊃{⌽@(0 1,¨⍺)⊢⍵}/(⍵∩,⍳≢¨⍺),⊂⍺}

Try it online!

The left argument is a pair of character vectors - left ribbons and top ribbons. The right argument is a vector of coordinate pairs - swap locations. Returns a pair of right ribbons and bottom ribbons. (Note that unlike in the examples, I use the order left-top and right-bottom for the ribbons in order to be consistent with the row-col axis order in the coordinates.)

Swaps must be sorted so that a swap to the upper-left of another comes before after it. If two swaps are to the lower-left/upper-right of each other, their order doesn't matter.

EDIT: saved one byte () by requiring reverse order of swaps in the input

ngn

Posted 2018-04-19T11:03:42.910

Reputation: 11 449

1

Javascript, 87 76 62 bytes

(c,r,s)=>{for([i,j]of s)if(r[i]&&c[j])[r[i],c[j]]=[c[j],r[i]]}

Try it online!

Same trivial algorithm as the Python 3 answer. Uses arrays as coordinate tuples. Requires ribbon colors to be designated by truthy values. Requires coordinates to be partially ordered so that x1,y1 comes before x2,y2 if either x1 < x2 && y1 = y2 or x1 = x2 && y1 < y2. Returns by modifying input arrays.

Bergi

Posted 2018-04-19T11:03:42.910

Reputation: 967

I'm pretty sure you can delete ;return[r,c] and call it a return by modification

– Asone Tuhid – 2018-04-19T22:35:54.207

if(r[i]&&c[j]) would save some more bytes. – Neil – 2018-04-19T23:44:31.233

I know that my condition is too strong, but your condition is self-contradictory. Consider x1=1,x2=2,y1=2,y2=1. Because x1<x2, (x1,y1) comes before (x2,y2); but because y2<y1, (x2,y2) comes before (x1,y1). I think "x1 < x2 and y1 < y2" suffices. – user202729 – 2018-04-20T01:25:40.490

@AsoneTuhid Hm, I think that's cheating. Modifying the input objects is not the same as output by reference parameters. – Bergi – 2018-04-20T10:33:27.753

@Neil Oh, I was thinking the colors could be integers including 0. That's not necessary of course. Thanks! – Bergi – 2018-04-20T10:36:28.830

@user202729 Oops, messed that up, I need an and indeed. (1,2) and (2,1) are not supposed to be related, they could be in either order. – Bergi – 2018-04-20T10:39:46.053

I think those <=s only need to be =s in that ordering condition. – Neil – 2018-04-20T10:41:18.077

1Q: "Does this mean that in languages that allow it, the seven characters for return can simply be replaced with an assignment?" A: "Yes, provided the changed value will then be accessible in the context that called the function.". Seems pretty clear to me. – Asone Tuhid – 2018-04-20T10:41:21.153

@Neil Yeah, that works as well (and conveys the idea better), the partial ordering is transitive anyway – Bergi – 2018-04-20T10:44:12.563

@AsoneTuhid JS is not a pass-by-reference language, and there would be no reference assignment instead of the return - there simply would be nothing. – Bergi – 2018-04-20T10:44:56.550

I think this counts as passing by reference and the assignment doesn't need to "replace" the return keyword. What's important is that the result(s) of executing the function can be accessed in the scope from which it was called. By the way, I think you can omit f= as the function doesn't need to refer to itself.

– Asone Tuhid – 2018-04-20T10:49:20.460

Your answer doesn't seem to work, please include a tio link – Asone Tuhid – 2018-04-20T11:49:05.513

@AsoneTuhid Fixed. I had confused myself whether r would mean "the colors in the top row" or "the start colors of the rows" :-/ – Bergi – 2018-04-20T13:35:39.097

0

Ruby, 56 54 bytes

->t,l,s{s.map{|i,j|a=t[j];t[j]&&=l[i]||a;a&&l[i]&&=a}}

Try it online!

A port of user202729's Python 3 answer with some ruby tricks

Coordinates have to be lexicographically sorted

Asone Tuhid

Posted 2018-04-19T11:03:42.910

Reputation: 1 944