# Avoid duplicate entries using a sign change

This anecdote contains the following intriguing exchange:

"Fine, Fred," Avi interrupted. "Then how would you change this to avoid duplicate entries?"

"Oh, just change that one there to a negative one."

While this claim is not accurate in context, I do wonder if there's some plausible code for which that makes sense.

Your challenge is to write code (a program, a function, whatever) that fits this criteria:

1. Merges two input lists into one, keeping duplicates. [edit: You can optionally assume that they are integers, and/or that the lists themselves are unique. You can't assume the integers are positive (the one answer that does this is grandfathered in).]
2. A literal "1" appears somewhere in the code. If you change this to a literal "-1", the code does the same thing but removing duplicates.
3. The code does not simply branch off of the 1/-1. We're not looking for if (1 < 1) removeDuplicates() or [do_nothing, merge_with_dups, merge_without_dups][1].call(), for example.

Input and output can be in any reasonable format you choose. One example might be

[1,2],[2,3]->[1,2,2,3] before the sign change, and [1,2,3] after.

This is a popularity contest. It is not code golf, unless you want to show off. I'll accept the highest-voted answer in about two weeks.

• What is the input - only integers? Positive and/or negative? If the input lists contain duplicates, should they be removed in the -1 case? – Reinstate Monica May 9 '13 at 14:37
• Should we assume the input lists are sorted and don't contain duplicates themselves? – ugoren May 9 '13 at 14:53
• My first thought when I saw that on the DailyWTF was that they needed to define "merge". This question also needs a definition thereof. – Peter Taylor May 9 '13 at 21:56
• "They call him Boris the Bullet Dodger" "Why do they call him that?" "... Because he dodges bullets, Avi". Any Snatch fans on CodeGolf? – Bojangles May 10 '13 at 5:50

### JavaScript

Take a conventional algorithm and write it with a bug:

function merge(a, b) {
var ai = 0, bi = 0, oi = 0;
var o = [];
while (ai < a.length && bi < b.length) {
var v = a[ai] < b[bi] ? a[ai++] : b[bi++];
if (v !== o[oi + 1]) {
o[oi++] = v;
}
}
while (ai < a.length) o[oi++] = a[ai++];
while (bi < b.length) o[oi++] = b[bi++];
return o;
}


This code contains exactly one literal 1. If it is changed to -1, then duplicates will be removed. It can be used on any comparable values.

## APL 22/23

Prompts for screen input via ←⎕ and returns an ordered merged list with or, if the leading one is set negative, without duplicates.

(~1=0,-2=/v)/v←v[⍋v←⎕]

⎕:
(1 2),(2 3)
1 2 2 3

(~¯1=0,-2=/v)/v←v[⍋v←⎕]

⎕:
(1 2),(2 3)
1 2 3


Byte counters please note that the single byte APL characters have been converted to UTF8 to render properly on this site.

• How does the -1 change everything? – Johannes Kuhn May 9 '13 at 19:25
• @Johannes Kuhn For the above example the code 0,-2=/v yields the vector 0 0 ¯1 0 with ¯1 indicating the position of a duplicate entry. Testing this vector against 1 and ¯1 yields 0 0 0 0 or 0 0 1 0 reversing the boolean elements gives 1 1 1 1 or 1 1 0 1. These vectors are used to select the appropriate elements from the merged vector. – Graham May 9 '13 at 19:38

# k (18)

Should work for any valid type of list

{(*1#(::;?:))@x,y}


Example:

k){(*-1#(::;?:))@x,y}[1 2 3 4;3 4 5 6]
1 2 3 4 5 6
k){(*1#(::;?:))@x,y}[1 2 3 4;3 4 5 6]
1 2 3 4 3 4 5 6


## Python

def merge(a, b):
return a + [i for i in b if i not in a*- 1]


## Bash

In the spirit of the context, this program removes the duplicates if you add a minus sign before the lowercase l on the grep line. If you add a minus sign before the uppercase I on the previous line, or before the digit 1 on the next line, the program doesn't behave differently.

The input files contain one integer per line (this is the usual representation of lists as text files). They must be passed as two arguments. The resulting list is written to standard ouptut.

# Create temp file for working
temp=$(mktemp -d) # Copy left and right file to merge into same cp$1 $temp/l cp$2 $temp/r cd$temp

do
# I remove the output
set grep -Lax -e $num l  <r> /dev/null if [$# != 1 ]
then echo $num >>r fi done <l cp r /dev/stdout cd rm -r$temp


Feel free to use this program as an example of your best code in an interview. All I ask is that you don't say that it's my best code.

## Tcl

In the spirit of the quote

foreach item $list1 { if {$item in $list2} {set item [expr {$item * 1}]}
lappend list2 $item } foreach item$list2 {
if {$item >= 0} {lappend result$item}
}


If it is a duplicate, multiply it with (-)1, after that filter out negative values.

• This answer was written that way before the question changed. In spirit of the quote, I still prefer making the entries negative. – Johannes Kuhn May 9 '13 at 19:28

I'm beginner in PHP I don't know if it's correct

$list1=explode(',',$_GET['list1']);
$list2=explode(',',$_GET['list2']);
$list_merged=array_merge($list1,$list2); print_r($list_merged);
$list_unique=array_unique($list_merged);
print_r(\$list_unique);

• It doesn't look like this actually answers the challenge - I don't see a literal 1 anywhere in your code. – Riking May 23 '13 at 14:29