Evitare voci duplicate utilizzando una modifica del segno


14

Questo aneddoto contiene il seguente intrigante scambio:

"Bene, Fred", interruppe Avi. "Quindi come cambieresti per evitare voci duplicate?"

"Oh, cambia quello lì in uno negativo."

Mentre questa affermazione non è precisa nel contesto, mi chiedo se ci sia un codice plausibile per il quale ha senso.

La tua sfida è scrivere codice (un programma, una funzione, qualunque cosa) che soddisfi questi criteri:

  1. Unisce due elenchi di input in uno, mantenendo i duplicati. [modifica: puoi eventualmente supporre che siano numeri interi e / o che gli elenchi stessi siano univoci. Non puoi supporre che gli interi siano positivi (l'unica risposta che fa questo è il nonno).]
  2. Un "1" letterale appare da qualche parte nel codice. Se lo cambi in letterale "-1", il codice fa la stessa cosa ma rimuove i duplicati.
  3. Il codice non si ramifica semplicemente da 1 / -1. Non stiamo cercando if (1 < 1) removeDuplicates()o [do_nothing, merge_with_dups, merge_without_dups][1].call(), per esempio.

L'input e l'output possono essere in qualsiasi formato ragionevole tu scelga. Un esempio potrebbe essere

[1,2],[2,3]->[1,2,2,3]prima che il segno cambi, e [1,2,3]dopo.

Questo è un concorso di popolarità. Non è il golf del codice , a meno che tu non voglia metterti in mostra. Accetterò la risposta più votata tra circa due settimane.


Qual è l'input - solo numeri interi? Positivo e / o negativo? Se gli elenchi di input contengono duplicati, devono essere rimossi nel -1caso?
— Ripristina Monica

1
Dovremmo supporre che gli elenchi di input siano ordinati e non contengano duplicati stessi?
— ugoren,

Il mio primo pensiero quando ho visto che sul DailyWTF era che dovevano definire "unire". Anche questa domanda ha bisogno di una sua definizione.
— Peter Taylor,

"Lo chiamano Boris il Bullet Dodger" "Perché lo chiamano così?" "... Perché schiva i proiettili, Avi". Qualche fan di Snatch su CodeGolf?
— Bojangles,

Risposte:


11

JavaScript

Prendi un algoritmo convenzionale e scrivilo con 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;
}

Questo codice contiene esattamente un letterale 1. Se viene modificato in -1, i duplicati verranno rimossi. Può essere utilizzato su qualsiasi valore comparabile.


5

22/23 APL

Richiede l'inserimento dello schermo tramite ← ⎕ e restituisce un elenco unito ordinato con o, se il primo è impostato in negativo, senza duplicati.

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

I contatori di byte devono tenere presente che i caratteri APL a byte singolo sono stati convertiti in UTF8 per essere visualizzati correttamente su questo sito.


In che modo -1 cambia tutto?
— Johannes Kuhn,

@Johannes Kuhn Nell'esempio precedente il codice 0, -2 = / v restituisce il vettore 0 0 ¯1 0 con ¯1 che indica la posizione di una voce duplicata. Testare questo vettore su 1 e ¯1 produce 0 0 0 0 o 0 0 1 0 invertendo gli elementi booleani si ottiene 1 1 1 1 o 1 1 0 1. Questi vettori vengono utilizzati per selezionare gli elementi appropriati dal vettore unito.
— Graham,

4

k (18)

Dovrebbe funzionare per qualsiasi tipo di elenco valido

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

Esempio:

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

3

Pitone

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

2

bash

Nello spirito del contesto, questo programma rimuove i duplicati se aggiungi un segno meno prima della minuscola lsulla greplinea. Se aggiungi un segno meno prima della maiuscola Inella riga precedente o prima della cifra 1nella riga successiva, il programma non si comporta in modo diverso.

I file di input contengono un numero intero per riga (questa è la consueta rappresentazione di elenchi come file di testo). Devono essere passati come due argomenti. L'elenco risultante viene scritto nell'output 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

Sentiti libero di usare questo programma come esempio del tuo miglior codice in un'intervista. Tutto ciò che chiedo è che tu non dica che è il mio miglior codice.


1

Tcl

Nello spirito della citazione

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

Se è un duplicato, moltiplicalo per (-) 1, dopodiché filtra i valori negativi.


Questa risposta è stata scritta in questo modo prima che la domanda cambi. Nello spirito della citazione, preferisco ancora rendere le voci negative.
— Johannes Kuhn,

-1

Sono principiante in PHP, non so se sia corretto

$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);

7
Non sembra che questo risponda effettivamente alla sfida: non vedo un 1 letterale da nessuna parte nel tuo codice.
— Riking
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.