Évitez les entrées en double en utilisant un changement de signe

14

Cette anecdote contient l'échange intrigant suivant:

"Très bien, Fred," interrompit Avi. "Alors comment changeriez-vous cela pour éviter les entrées en double?"

"Oh, change juste celui-là en négatif."

Bien que cette affirmation ne soit pas exacte dans son contexte, je me demande s'il existe un code plausible pour lequel cela a du sens.

Votre défi est d'écrire du code (un programme, une fonction, peu importe) qui correspond à ces critères:

  1. Fusionne deux listes d'entrée en une seule, en conservant les doublons. [edit: Vous pouvez éventuellement supposer qu'il s'agit d'entiers et / ou que les listes elles-mêmes sont uniques. Vous ne pouvez pas supposer que les nombres entiers sont positifs (la seule réponse qui fait cela est privilégiée).]
  2. Un "1" littéral apparaît quelque part dans le code. Si vous changez cela en un littéral "-1", le code fait la même chose mais supprime les doublons.
  3. Le code ne dérive pas simplement du 1 / -1. Nous ne recherchons pas if (1 < 1) removeDuplicates()ou [do_nothing, merge_with_dups, merge_without_dups][1].call(), par exemple.

L'entrée et la sortie peuvent être dans n'importe quel format raisonnable que vous choisissez. Un exemple pourrait être

[1,2],[2,3]->[1,2,2,3]avant le changement de signe, et [1,2,3]après.

Il s'agit d'un concours de popularité. Ce n'est pas du golf de code , sauf si vous voulez vous montrer. J'accepte la réponse la plus votée dans environ deux semaines.

histocrate
la source
Quels sont les entiers en entrée uniquement? Positif et / ou négatif? Si les listes d'entrée contiennent des doublons, doivent-elles être supprimées dans le -1cas?
Rétablir Monica
1
Faut-il supposer que les listes d'entrée sont triées et ne contiennent pas de doublons elles-mêmes?
ugoren
Ma première pensée quand j'ai vu que sur le DailyWTF était qu'ils devaient définir "fusionner". Cette question doit également être définie.
Peter Taylor
"Ils l'appellent Boris le Bullet Dodger" "Pourquoi l'appellent-ils ainsi?" "... Parce qu'il esquive les balles, Avi". Des fans de Snatch sur CodeGolf?
Bojangles

Réponses:

11

Javascript

Prenez un algorithme conventionnel et écrivez-le avec un 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;
}

Ce code contient exactement un littéral 1. S'il est modifié en -1, les doublons seront supprimés. Il peut être utilisé sur toutes les valeurs comparables.

Kevin Reid
la source
5

APL 22/23

Invite à saisir l'écran via ← ⎕ et renvoie une liste fusionnée ordonnée avec ou, si la première est définie négative, sans doublons.

(~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

Compteurs d'octets veuillez noter que les caractères APL à un octet ont été convertis en UTF8 pour un rendu correct sur ce site.

Graham
la source
Comment le -1 change-t-il tout?
Johannes Kuhn
@Johannes Kuhn Pour l'exemple ci-dessus, le code 0, -2 = / v donne le vecteur 0 0 ¯1 0 avec ¯1 indiquant la position d'une entrée en double. Le test de ce vecteur contre 1 et ¯1 donne 0 0 0 0 ou 0 0 1 0 inversant les éléments booléens donne 1 1 1 1 ou 1 1 0 1. Ces vecteurs sont utilisés pour sélectionner les éléments appropriés dans le vecteur fusionné.
Graham
4

k (18)

Devrait fonctionner pour tout type de liste valide

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

Exemple:

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
skeevey
la source
3

Python

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

Frapper

Dans l'esprit du contexte, ce programme supprime les doublons si vous ajoutez un signe moins avant les minuscules lsur la grepligne. Si vous ajoutez un signe moins avant la majuscule Ide la ligne précédente ou avant le chiffre 1de la ligne suivante, le programme ne se comporte pas différemment.

Les fichiers d'entrée contiennent un entier par ligne (c'est la représentation habituelle des listes sous forme de fichiers texte). Ils doivent être passés comme deux arguments. La liste résultante est écrite en sortie standard.

# 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

while read num
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

N'hésitez pas à utiliser ce programme comme exemple de votre meilleur code dans une interview. Tout ce que je demande, c'est que vous ne dites pas que c'est mon meilleur code.

Gilles 'SO- arrête d'être méchant'
la source
1

Tcl

Dans l'esprit de la citation

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

S'il s'agit d'un doublon, multipliez-le par (-) 1, après quoi filtrer les valeurs négatives.

Johannes Kuhn
la source
Cette réponse a été écrite de cette façon avant que la question ne change. Dans l'esprit de la citation, je préfère toujours rendre les entrées négatives.
Johannes Kuhn
-1

Je suis débutant en PHP, je ne sais pas si c'est 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);
Sasori
la source
7
Il ne semble pas que cela réponde réellement au défi - je ne vois pas de littéral 1 n'importe où dans votre code.
Riking