| Bytes | Lang | Time | Link |
|---|---|---|---|
| 417 | Python3 | 241019T145637Z | Ajax1234 |
| 173 | Befunge | 161206T231342Z | James Ho |
| 178 | JavaScript ES6 | 161204T190920Z | Neil |
| 241 | Python 2 | 161205T105825Z | TFeld |
| 025 | Pyth | 161204T054309Z | Maltysen |
Python3, 417 bytes
from itertools import*
E=enumerate
def f(w):
C=0
D={i:(C:=C+1)if'|'==a else 0 for i,a in E(w[0])}
B=[[*i]for i in zip(*w[::-1])]
for I,j in E(B):
for a,b in groupby(E(j),key=lambda x:x[1].lower()):
if'x'==a:
u=[*b];v=sum([-1,1][t=='X']for _,t in u)
for A,_ in u:B[I][A]=' '
if v:B[I][u[-1][0]]=v
return'\n'.join(f'{D[i-1]} {D[i+1]} '+['L','R'][a==1]for j in zip(*B) for i,a in E(j)if a in[1,-1])
Befunge, 173 bytes
Input is read from stdin in the exact format given in the challenge description, although it's crucial that every line be the correct length and the final line must include a newline (i.e. not just EOF at the end of that line).
$1>>05p~$~:55+-#v_
$_^#`"N":+1g50$<>:2+3%1-05g6g+0v>!#:v#
vg50-1*2p51:-1_^#:<*2!!-*84p6g5<
+#,.#$"R"\#\-#+5<^g51$_:0`6*\25g\v@_:#!.#:1#,
>+::25p6g\48*\6p48 *-:!^!:--1*2`0:<
The basic idea for this solution is that we have an "array" keeping track of the twist counts for each wire. So every time we encounter a twist in one direction we increment the count for the associated wire, while a twist in the other direction will decrement the count.
At the same time as we process the twist for a particular wire, we also look at the twist count for the wires to the left and right of it. If either of them are non-zero, we need to "flush" those twists onto the stack, since it will no longer be possible for them to be unravelled by later twists in the opposite direction.
After the last line of input, the input stream returns EOF repeatedly, and these EOF characters are interpreted as twists in every wire, at least for the purposes of flushing. This forces the program to flush any outstanding counts in the array, but it will not generate any new twist counts.
Once we've finished processing the input, all the commands for untangling the wires will now be on the stack. This means we can simply pop them off in reverse order to output the instructions needed to untangle the wires from the bottom up.
JavaScript (ES6), 178 bytes
f=([t,...a],r=[])=>a[0]?t.replace(/x/gi,(c,i)=>(c=c<'x'?'R':'L',i=++i/2,r.reduce((f,[j,,d],n)=>f||i<j+2&&j<i+2&&(j-i|c==d||r.splice(n,1)&&2),0)<2?r=[[i,i+1,c],...r]:r))&&f(a,r):r
Takes input as an array of strings representing lines and returns an array of arrays of values e.g. [[2, 3, "R"], [3, 4, "L"], [1, 2, "R"]]. The reverse ordering helps with the eliminations.
Python 2, 244 241 bytes
m=[]
for l in input():
for i in range(len(l)):
c=l[i];a=i/2+1;L,R=[a,a+1,'LR'[c>'v']],[a,a+1,'RL'[c>'v']];x=m.index(L)if L in m else-1;M=zip(*m[:x+1])
if c in'xX':
if x>=0and(a in M[1]or a+1in M[0])<1:del m[x]
else:m=[R]+m
print m
Takes input as list of strings
Example:
Input: ['| | | |', ' X | |', '| | x ', '| X |', ' x | |']
Output: [[1, 2, 'L'], [2, 3, 'R'], [3, 4, 'L'], [1, 2, 'R']]
Edit: Fixed for case:
Input: ['| | |', ' X |', ' X |', ' x |', '| X', ' X |', ' x |', ' x |', '| | |']
Output: [[1, 2, 'L'], [2, 3, 'R'], [1, 2, 'R']]
Pyth - 26 25 bytes
Very straightforward, maybe I can golf the filtering.
fhhT_m+hB/xrdZ\x2@"RL"}\x