Targeted duplicate removal

In this challenge, you are given a number and a list. Your task is to remove from the list all occurrences of the given number except the first (leftmost) one, and output the resulting list. The other elements of the list should be left intact.

• The number will be a positive integer below 1000, and the list will only contain positive integers below 1000.
• The list is not guaranteed to contain any occurrences of the given number. It may even be empty. In these cases you should output the list as-is.
• Input and output formats are flexible within reason. You can output by modifying the list in place.
• The lowest byte count wins.

Test cases

5 [] -> []
5 [5] -> [5]
5 [5,5] -> [5]
10 [5,5] -> [5,5]
10 [5,5,10,10,5,5,10,10] -> [5,5,10,5,5]
2 [1,2,3,1,2,3,1,2,3] -> [1,2,3,1,3,1,3]
7 [9,8,7,6,5] -> [9,8,7,6,5]
7 [7,7,7,7,7,7,7,3,7,7,7,7,7,7,3,7,1,7,3] -> [7,3,3,1,3]
432 [432,567,100,432,100] -> [432,567,100,100]

• Are we allowed to take the length of the input list as one of the inputs? – user96495 Oct 12 at 9:02
• @2x-1 No, unless you can't compute it from the list in your language. – Zgarb Oct 12 at 9:15

Husk, 5 4 bytes

• Saved 1 byte thanks to Razetime

• Saved 2 bytes thanks to Jo King

üoEė


Try it online!

Thanks to Razetime for suggesting ü and Jo King for letting me know I could leave the superscript arguments out, saving me 2 bytes. It removes duplicates with a custom predicate that makes sure both arguments are equal to the number to be removed.

Explanation:

üoEė
ü     Remove duplicates by binary function (implicit second argument)
o    Compose 2 functions
ė  Make a list of 3 elements (first element is implicitly added)
E   Are they all equal?

• Ë= can just be E – Razetime Oct 12 at 17:16
• @Razetime Nice, thanks! – user Oct 12 at 17:23

R, 30 bytes

function(l,d)unique(l,l[l!=d])


Try it online!

unique() has the signature unique(x,incomparables = FALSE,...); this sets incomparables to the elements that aren't equal to d, so only d is uniquified.

JavaScript (ES6),  32  30 bytes

Expects (x)(list).

x=>a=>a.filter(v=>v^x||a[a=0])


Try it online!

How?

All values v that are not equal to x are preserved thanks to v^x. The first value that is equal to x is kept as well because a[0] is guaranteed to be a positive integer (except if a is empty, but then we don't enter the .filter() loop to begin with). For the next values that are equal to x, we have a = 0 and a[0] === undefined, so they are rejected. This test doesn't throw an error because Numbers are Objects, so it's legal to access the (non-existent) property '0' of 0.

Python 2, 50 bytes

l,n=input()
for x in l:
if~n-x:print x;n^=-(x==n)


Try it online!

Prints output one entry per line.

The idea is to store whether we have already encountered the entry-to-remove n in the sign of n rather than a separate Boolean variable. When we see a list entry that equals n, we negate n. To decide whether to print the current entry x, we check if it equals -n, which checks that it equals the original n and that we've already negated n due to an earlier match. Note that since n and list entries are positive, there's no way to get x==-n before n is negated.

Well, actually, instead of negating n, it's shorter to bit-complement it to ~n, which is -n-1. To do the conditional complementing, we note that we can convert [x,~x][b] to x^-b (as in this tip), using that bitwise xor ^ has x^0==x and x^-1==~x. So, we do n^=-(x==n).

a%(b:c)|a==b=b:filter(/=a)c|1<2=b:a%c
_%x=x


Try it online!

Ungolfed:

dedupl v (x:xs)
| x == v = x : filter (/= v) xs
| otherwise = x : dedupl v xs
dedupl _ [] = []


This version takes a (negative) predicate for input instead.

f%(b:c)|f b=b:f%c|1<2=b:filter f c
_%x=x


Try it online!

• Simple and elegant! How I didn't thought about that? How I messed up doing complicated stuffs when the solution was so obviously simple? Haskell journey is getting interesting day by day – AZTECCO Oct 13 at 21:40

C (gcc), 60 bytes

Saved 2 bytes thanks to ceilingcat!!!
Saved 2 bytes thanks to ErikF!!!

t;f(d,l)int*l;{for(t=0;*l;++l)*l==d&&t++||printf("%d ",*l);}


Try it online!

Inputs a number and a pointer to a null terminated array (as there's no way to know the length of an array passed into a function in C) and outputs the filtered array to stdout.

Explanation

f(d,                        // function taking the duplicate number d,
l)int*l;{               // a null terminated array of int l
for(                      // loop...
t=0;                  //   init test flag t to 0, this will mark the
//   1st (if any) occurance of d
*l;               // ...over the array elements
++l)          // bumping the array pointer each time
*l==d                 // if the array element isn't d...
&&t              //   or it's the 1st time seeing d
++           //   unmark t by making it non-zero
||printf("%d ",*l);   // ...then print that element
}

• If you use 0 as a sentinel, you don't need to take a length (61 bytes): Try it online! – ErikF Oct 12 at 20:40
• @ErikF Nice one - thanks! :-) – Noodle9 Oct 12 at 20:53

APL (Dyalog Unicode), 1815 10 bytes

Thanks to Adám for -8 bytes!!!

∊⊢⊆⍨≠∨<\⍤=


Try it online!

Example inputs: left argument 3, right argument 1 2 3 4 3 4.

= does element-wise not-equal comparison. => 0 0 1 0 1 0
<\ Scans with less-than. This keeps just the first 1, all other places are 0. => 0 0 1 0 0 0
≠∨ does element-wise OR with the ≠ mask. => 1 1 1 1 0 1.
⊢⊆ partitions the input based on the vector, including positions with positive integers. => (1 2 3 4) (4) ∊ flattens the nested array. => 1 2 3 4 4

• -3: ∊⊢⊆⍨≠∨¯1↓1,⌊\⍤≠ Try it online! – Adám Oct 12 at 10:05
• @Adam thanks a lot! – ovs Oct 12 at 10:27
• -5: ¯1↓1,⌊\⍤≠<\⍤= Try it online! – Adám Oct 14 at 11:12

Japt, 10 7 bytes

kÈ¶V©T°


Try it

-3 bytes thanks to caffeine!

kÈ¶V©T°     :Implicit input of array U and integer V
k           :Remove the elements in U that return true
È          :When passed through the following function
¶V        :Is equal to V?
T°     :Postfix increment T (initially 0)


05AB1E, 6 bytes

Ê0X.;Ï


Integer as first input, list as second input.

Explanation:

Ê      # Check for each value in the second (implicit) input-list whether it's NOT equal
# to the first (implicit) input-integer (1 if NOT equal; 0 if equal)
0X.;  # Replace the first 0 with a 1
Ï # And only keep the values in the (implicit) input-list at the truthy (1) indices
# (after which the result is output implicitly)


Jelly,  6  5 bytes

-1 thanks to Sisyphus's suggestion to use Ẇ in place of W€

Ẇi¦⁹ḟ


A full program accepting the list and the value which prints the Jelly representation of a list with all but the first occurrence of the value removed (empty lists print nothing, lists with one element print that element).

Try it online! Or see the test-suite.

How?

Ẇi¦⁹ḟ - Link: list, A; value V
¦   - sparse application...
i ⁹  - ...to indices: first occurrence of V in A  ([0] if no V found)
W     - ...action: all non-empty sublists (since ¦ zips, the element, z, at any
given index of A will be [z])
ḟ - filter discard occurrence of V (leaves the [z] as is)
- implicit print


I thought ḟẹḊ¥¦ would work for 5, but it fails with a divide by zero error with [5,5] and 5.

• I think Ẇi¦⁹ḟ works for 5. – Sisyphus Oct 16 at 4:19
• @Sisyphus Nice, it will, since the first n entries of the results of Ẇ for a length n list are the wrapped elements of that list. – Jonathan Allan Oct 17 at 15:20

Wolfram Language (Mathematica), 26 bytes

#2/.(a=#)/;a++>#:>(##&[])&


Try it online!

Takes advantage of the fact that the pattern (a=#) to be matched is only evaluated once, at the very start. Then, the condition a++># is only evaluated each time the pattern is matched - so a will have been incremented on subsequent matches.

Bash + sed, 49 bytes

sed "s/\b$1\b/_/;s/\b$1\b \?//g;s/_/$1/"<<<${*:2}


Try it online!

Takes the first argument as the duplicate and the rest as the array.

APL (Dyalog Unicode), 9 bytes (SBCS)

Translation of Galen Ivanov's J solution.

Anonymous tacit infix function, taking number as left argument and list as right argument (though argument order can be switched by changing the ⊢s into ⊣s).

∊⊢⊆⍨≠∨∘≠⊢


Try it online!

⊢ on the right argument

∘≠ apply nub-sieve (Boolean list with Trues where unique elements occur first), then:

…∨ element-wise OR that with:

≠ Boolean list with Trues where elements in the list are different from the number

⊆⍨ corresponding to runs of Trues in that, extract runs in:

⊢ the list

∊ϵnlist (flatten)

Python 3, 62 bytes

f=lambda n,l:l.count(n)>1and f(l.pop(~l[::-1].index(n)),l)or l


Try it online!

This function will recursively pop the last instance of the given value until no more than one instance is present. Then it returns the list.

or, for the same byte count

lambda n,l:[j for i,j in enumerate(l)if j!=n or i==l.index(n)]


Try it online!

This is just a simple filter.

05AB1E, 8 bytes

ʒÊD¾ms_½


Try it online!

Commented:

ʒ          # filter the first input on ...
Ê         #   not equal to the second input (n)?
D        #   duplicate this value
¾       #   push the counter variable initially 0
m      #   power (value != n)**(counter)
#   this is only 0 if value==n and counter is positive
s     #   swap to (value != n)
_    #   negate this
½   #   increment the counter variable if this is truthy (value == n)


Perl 5, 36 bytes

sub{$n=pop;$i=0;grep$n-$_||!$i++,@_}  Try it online! Pop last input value from @_ into$n. The remaining @_ is the input list. Filter (grep) @_ for the values that either isn't equal to $n ($n-$_ is truthy when$n and current list value $_ is different) or is the first equal to$n since !$i++ is truthy for the first and not for the rest. • There's no need for the $i=0; part, unless you're using the sub multiple times. Which you shouldn't as this is code golf. – Abigail Oct 12 at 21:31

J, 15 10 bytes

-5 bytes thanks to xash!

]#~=<:~:@]


Try it online!

J, 15 bytes

[#~~:+i.@#@[=i.


Try it online!

• @xash Really nice, thanks! +. could be >. :) – Galen Ivanov Oct 12 at 13:23
• Ah, with that kind of logic it's 10 bytes :-) – xash Oct 12 at 13:31
• @xash That's great, thanks again! – Galen Ivanov Oct 12 at 13:35

APL+WIN, 19 bytes

Prompts for vector followed by element to be removed:

((v≠n)+<\v=n←⎕)/v←⎕


Try it online! Thanks to Dyalog Classic

Husk, 13 12 bytes

F+ṀΓ·:f≠⁰↕≠⁰


Try it online!

user's answer.(-3 bytes, then -1 byte.)

Husk, 16 bytes

J²fI§e←of≠²→↕≠²⁰


Try it online!

Can probably be shortened with Γ.

There may be an extremely short solution with ü as well.user's answer

+2 bytes after supporting numbers not in the list.

• The 5-byter doesn't work on test cases 5 and 6. – Zgarb Oct 12 at 15:02
• @user once arguments are used explicitly, they can't be removed. – Razetime Oct 12 at 16:43
• @user You don't need to apologize to me for posting your own answer :) – Razetime Oct 12 at 17:14

C# (Visual C# Interactive Compiler), 42 bytes

a=>b=>a.Where((x,i)=>x!=b|i==a.IndexOf(b))


Try it online!

• -1 byte with is operator sorcery. – the default. Oct 13 at 13:57
• @thedefault. That is very impressive, I would've never gotten there, you don't want to post that yourself? – LiefdeWen Oct 13 at 14:08

Scala, 6261 58 bytes

a=>s=>{val(c,d)=s splitAt s.indexOf(a)+1;c++d.filter(a!=)}


Try it online!

• Thanks to Galen for -1 character
• Thanks to user for -3 characters

f n=foldl(\a x->if x==n&&xelema then a else a++[x])[]


Try it online!

• Previous answer was complicated and not so good so I decided to try a more expressive approach inspired by @Caagr98 answer, mine is still longer but I feel better now =)

# Previous 72 bytes
g b n(h:t)
|h/=n=h:g b n t
|b>0=g 1n t
|1>0=h:g 1n t
g b n _=[]
f=g 0


Try it online!

• Thank you @user ! Anyway this is a mess, compared to codegolf.stackexchange.com/a/212430/84844 mine is not only longer, it's not elegant and and less readable. I think Caagr98 answer is exactly as expressive as Haskell is meant to be – AZTECCO Oct 13 at 21:32

Javascript 117 113 bytes

function x(i,j){var d=false;var o=[];for(x in i){if(i[x]==j){d?0:o.push(j),d=true;}else{o.push(i[x]);}}return o;}


Usage:

x(input array,number);

returns output array;

Try it online!

• It's a good practice to hose your programs on tio so people can check: Try it online! – Razetime Oct 19 at 3:44
• Thanks, @Razetime – TheCoderPro Oct 19 at 3:47
• You can get this to 62 bytes, I think. Probably a lot more with filter and more golfing tricks, but I don't know JS that well – user Oct 21 at 15:00

Red, 46 bytes

func[n b][try[replace/all find/tail b n n[]]b]


Try it online!

Charcoal, 12 bytes

ＩΦη∨⁻ιθ⁼κ⌕ηι


Try it online! Link is to verbose version of code. Explanation:

  η             Input list
Φ              Filtered where
ι          Current element
⁻           Subtract (i.e. does not equal)
θ         Input integer
∨            Logical Or
κ       Current index
⁼        Equals
⌕      First index of
ι    Current element in
η     Input list
Ｉ               Cast to string
Implicitly print


The last character could also be θ of course since the two variables are equal at that point.

Python 2, 55 52 bytes

Thanks to xnor for -3 bytes!

Output is newline-separated.

n,l=input()
x=1
for d in l:
if x|d-n:print d;x*=d-n


Try it online!

• It looks like it's shorter to just write d-n in place of w. – xnor Oct 12 at 9:51
• @xnor It is indeed. I initially had d!=n and it was the same length, but I forgot to check again. Thanks a lot! – ovs Oct 12 at 10:00

K (Kona), 21 bytes

{y@&(~x=y)+(!#y)=y?x}


Try it online!

Stacked, 28 bytes

[@y:0@b[b\y=:b+@b*¬]"!keep]


Try it online!

Explanation

[@y:0@b[b\y=:b+@b*¬]"!keep]
[                         ]   anonymous function (expects 2 args)
@y                           save top as y
0@b                       initialize b = 0
:   [           ]"!        for each element E in the input array:
b\                      save the current value of b for later computation
y= b+@b               b = max(b, y == E)
b y=:    *¬             not both (old b) and (y == E) are true
for y != E, and for the first y == E, this is 1, else 0
this generates a mask of 1s and 0s
keep    keep only the elements in the input which correspond to a 1



51 bytes: [@y()@z{e:[z e push][z y∈¬*]$!e y=ifelse}map@.z] 41 bytes: [@y::inits[:y index\#'1-=]map\y neq+keep] 36 bytes: [@y:0@b[b\:y=b\max@b y=*¬]map keep] 33 bytes: [@y:0@b[b\:y=b+@b y=*¬]map keep] PHP 63 Bytes Number provided in$n, list provided in $a, $p=explode($n,$a,2);echo$p[0].$n.str_replace("$n,", '',$p[1]);


Ungolfed:

$p = explode($n,$a,2); echo$p[0].$n.str_replace("$n,", '', $p[1]);  e.g. $n=432;
$a="[432,567,100,432,100]";$p = explode($n,$a,2);
echo $p[0].$n.str_replace("$n,", '',$p[1]);


(I'm unsure if it's ok not to count the input into the bytes, or the opening '<?php' for that matter...)

Wolfram Language (Mathematica), 50 bytes

Insert[DeleteCases@##,#2,#&@@Position@##]~Check~#&


Try it online!