Unikaj powielania wpisów za pomocą zmiany znaku

14

Ta anegdota zawiera następującą intrygującą wymianę:

„W porządku Fred”, przerwał Avi. „W takim razie jak byś to zmienił, aby uniknąć powielania wpisów?

„Och, po prostu zmień ten tam na negatywny”.

Chociaż twierdzenie to nie jest dokładne w kontekście, zastanawiam się, czy istnieje jakiś wiarygodny kod, dla którego ma to sens.

Twoim wyzwaniem jest napisanie kodu (programu, funkcji, cokolwiek), który spełnia te kryteria:

  1. Łączy dwie listy wejściowe w jedną, zachowując duplikaty. [edytuj: Możesz opcjonalnie założyć, że są to liczby całkowite i / lub same listy są unikalne. Nie można zakładać, że liczby całkowite są dodatnie (jedna odpowiedź, która to robi, jest dziadkiem).]
  2. Dosłownie „1” pojawia się gdzieś w kodzie. Jeśli zmienisz to na dosłowne „-1”, kod robi to samo, ale usuwa duplikaty.
  3. Kod nie rozgałęzia się po prostu 1 / -1. Nie szukasz if (1 < 1) removeDuplicates()lub [do_nothing, merge_with_dups, merge_without_dups][1].call(), na przykład.

Dane wejściowe i wyjściowe mogą być w dowolnym rozsądnym formacie, który wybierzesz. Jednym z przykładów może być

[1,2],[2,3]->[1,2,2,3]przed zmianą znaku i [1,2,3]po.

To konkurs popularności. To nie jest golf golfowy , chyba że chcesz się pochwalić. Przyjmuję najwyżej głosowaną odpowiedź za około dwa tygodnie.

histocrat
źródło
Jakie są dane wejściowe - tylko liczby całkowite? Pozytywny i / lub negatywny? Jeśli listy wejściowe zawierają duplikaty, czy należy je usunąć w -1skrzynce?
Przywróć Monikę
1
Czy należy założyć, że listy wejściowe są posortowane i nie zawierają samych duplikatów?
ugoren
Pierwszą myślą, jaką zobaczyłem na DailyWTF, było to, że musieli zdefiniować „scalenie”. To pytanie wymaga również jego definicji.
Peter Taylor,
„Nazywają go Boris the Bullet Dodger” „Dlaczego tak go nazywają?” „... Ponieważ unika pocisków, Avi”. Jacyś fani Snatch na CodeGolf?
Bojangles,

Odpowiedzi:

11

JavaScript

Weź konwencjonalny algorytm i napisz go z błędem:

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;
}

Ten kod zawiera dokładnie jeden literał 1. Jeśli zostanie zmieniony na -1, duplikaty zostaną usunięte. Może być stosowany na dowolnych porównywalnych wartościach.

Kevin Reid
źródło
5

APL 22/23

Monituje o wprowadzenie ekranu za pomocą ← ⎕ i zwraca uporządkowaną scaloną listę z lub, jeśli wiodąca jest ustawiona na ujemną, bez duplikatów.

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

Liczniki bajtów należy pamiętać, że jednobajtowe znaki APL zostały przekonwertowane na UTF8, aby poprawnie renderować na tej stronie.

Graham
źródło
Jak -1 zmienia wszystko?
Johannes Kuhn
@Johannes Kuhn W powyższym przykładzie kod 0, -2 = / v daje wektor 0 0 ¯ 1 0, gdzie indicating1 wskazuje pozycję zduplikowanego wpisu. Testowanie tego wektora na 1 i ¯1 daje 0 0 0 0 lub 0 0 1 0 odwrócenie elementów boolowskich daje 1 1 1 1 lub 1 1 0 1. Wektory te są używane do wyboru odpowiednich elementów ze scalonego wektora.
Graham
4

k (18)

Powinien działać dla każdego prawidłowego typu listy

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

Przykład:

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
źródło
3

Pyton

def merge(a, b):
    return a + [i for i in b if i not in a*- 1]
dansalmo
źródło
2

Grzmotnąć

W duchu kontekstu ten program usuwa duplikaty, jeśli dodasz znak minus przed małymi literami lw grepwierszu. Jeśli dodasz znak minus przed dużymi literami Iw poprzednim wierszu lub przed cyfrą 1w następnym wierszu, program nie będzie zachowywać się inaczej.

Pliki wejściowe zawierają jedną liczbę całkowitą w wierszu (jest to zwykle reprezentacja list jako plików tekstowych). Należy je podać jako dwa argumenty. Powstała lista jest zapisywana w standardowym 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

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

Możesz użyć tego programu jako przykładu najlepszego kodu w wywiadzie. Proszę tylko, żebyś nie powiedział, że to mój najlepszy kod.

Gilles „SO- przestań być zły”
źródło
1

Tcl

W duchu cytatu

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

Jeśli jest to duplikat, pomnóż go przez (-) 1, a następnie odfiltruj wartości ujemne.

Johannes Kuhn
źródło
Ta odpowiedź została napisana w ten sposób, zanim pytanie uległo zmianie. W duchu cytatu nadal wolę, aby wpisy były negatywne.
Johannes Kuhn
-1

Jestem początkującym w PHP Nie wiem, czy to poprawne

$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
źródło
7
Nie wygląda na to, że tak naprawdę stanowi wyzwanie - nie widzę dosłownie 1 w twoim kodzie.
Riking