Gluttonous Colluding Numbers
J, 12 bytes
-1 thanks to FrownyFrog!
[/:OR\@e.-e.
Try it online!
For 6 4 3 1 2 3 0
and 0 2 4
:
[/:OR\@e.-e.
OR OR …
\ each prefix of …
@e. the bitmask of friends, or:
OR\@e. after the first friend? (0 1 1 1 1 1 1)
e. the bitmask of friends (0 1 0 0 1 0 1)
- minus (0 0 1 1 0 1 0)
[/: (stable) sort the people based on the list
(6 4 3 1 2 3 0)
05AB1E, 9 8 bytes
ΣåDi©}®‹
-1 byte thanks to @ovs.
Try it online or verify all test cases.
Explanation:
Σ # (Stable) sort the first (implicit) input-list by:
å # Check that the current item is in the second (implicit) input-list
# (1 if truthy; 0 if falsey)
Di } # Duplicate it, pop this copy, and if it's 1:
© # Store 1 in variable `®` (without popping) (variable `®` is -1 by default)
®‹ # Check that the duplicated check is smaller than `®`
# (1 if truthy; 0 if falsey)
Here the same TIOs with map instead of sort-by, so you can see any leading non-friends become 0
, all friends become 0
as well, and any non-friends after the first friend become 1
:
Try it online or verify all test cases.
R, 49 47 45 42 bytes
Edit: -2 bytes, and then -3 more bytes, thanks to Giuseppe
function(l,f)l[order(cummax(p<-l%in%f)-p)]
Try it online!
Commented:
function(l,f` # function with arguments:
# l = line
# f = friends
p=l%in%f) # define p as TRUE at positions of friends in the line
l[order # now output l, in the order of (lowest>highest):
-( # minus (so now highest>lowest)
p # 1 for each friend
+2*!cumsum(p) # +2 for anyone ahead of the first friend
))] # (so, in the end, anyone ahead of all friends gets -2,
# the friends get -1,
# and anyone else behind the first friend gets zero).
Previous approach: R, 67 59 54 bytes
Edit: -8 bytes thanks to Giuseppe, then -5 more bytes thanks to Robin Ryder
function(l,f,p=which(l%in%f))c(l[z<-c(1:p-1,p)],l[-z])
Try it online!