| Bytes | Lang | Time | Link |
|---|---|---|---|
| 220 | Python3 | 250718T154858Z | Ajax1234 |
| 104 | Python 2 | 210319T043600Z | kops |
| 048 | Charcoal | 210318T232712Z | Neil |
| nan | J | 210318T011029Z | Jonah |
Python3, 220 bytes
def f(p):
d,n={},[]
for x,y,X,Y in p:
if X+Y:d[v]=d.get(v:=(x+X,y+Y),[])+[(x,y)]
else:n+=[(x,y)]
n+=[j for k in d for j in d[k]if len(d[k])>1]+[]
return[i if len(d[a])>1 or a in n else a for a in d for i in d[a]]
Python 2, 127 112 104 bytes
def f(l):r=map(sum,l);exec"r=[[p,x][r.count(p)>1or[x+d,-d]in l]for p,[x,d]in zip(r,l)];"*len(l);return r
Takes input as a list of pairs of complex numbers, outputs a list of complex numbers. Initially has everyone walk unless they would swap and then repeatedly sends back anyone who collided until there are no collisions left.
-8 bytes thanks to xnor!
Charcoal, 48 bytes
Wφ«≔⁰φFθ¿∧§κ¹∨№θ⟦Σκ±§κ¹⟧⊖№EθΣλΣκ«≔⊟κφ⊞κ⁰»»Eθ⭆¹Σι
Try it online! Link is to verbose version of code. Takes input as an array of pairs of complex numbers and outputs a list of complex numbers. Explanation:
Wφ«
Repeat while a flag value is non-zero.
≔⁰φ
Zero out the flag value.
Fθ
Loop over the people.
¿∧§κ¹
If they want to move, and...
∨№θ⟦Σκ±§κ¹⟧
... they would be swapping with the person at their destination, or...
⊖№EθΣλΣκ«
... another person would end up at the same destination, then:
≔⊟κφ
Set the flag value by removing that person's desired movement, and...
⊞κ⁰
Replace their movement with standing still.
»»Eθ⭆¹Σι
Print the final positions. (I've printed them on separate lines as that's what Charcoal's default output should be, although Charcoal doesn't know how to output complex numbers, so I've had to cheat slightly. I could extend that cheat and simply output the whole list as a Python array which would save two bytes.)
J, 60 58 50 47 bytes
[:+/(*1,:1-(1<1#.+/=/+/)+{.(~:*[=i.{_,~])+/)^:_
Takes input as a matrix of complex numbers -- starting positions in the 1st row, steps to walk in the 2nd row.
Passes all test cases including those suggested by tsh and the cycle of 4 suggested by xnor.
tldr how
We iteratively adjust the steps to be 0 for impossible moves (same destination (1<1#.+/=/+/) or + swaps {.(~:*[=i.{_,~])+/) until they reach a fixed point ^:_. Iteration is needed because some steps only become illegal after a walker changes from someone who will move to someone standing still. There's a chain reaction.
After that iteration, impossible steps will have been converted to 0, and legal steps will remain what they were.
Once that's done, we just add those steps to the starting positions [:+/.