İşaret değişikliği kullanarak yinelenen girişlerden kaçının


14

Bu fıkra şu ilginç alışverişi içerir:

"Güzel Fred," diye araya girdi Avi. "Peki yinelenen girişleri önlemek için bunu nasıl değiştirirdiniz?"

"Ah, sadece bunu negatif olana değiştir."

Bu iddia bağlamda doğru olmasa da, bunun mantıklı olan bazı makul kodları olup olmadığını merak ediyorum.

Buradaki zorluk, bu kriterlere uyan kod (bir program, bir işlev, ne olursa olsun) yazmaktır:

  1. Kopyaları tutarak iki giriş listesini bir araya getirir. İsteğe bağlı olarak tamsayı olduklarını ve / veya listelerin kendilerinin benzersiz olduğunu varsayabilirsiniz. Tamsayıların pozitif olduğunu varsayamazsınız (bunu yapan tek cevap büyükbabadır).]
  2. Kodun bir yerinde değişmez "1" görünür. Bunu değişmez "-1" olarak değiştirirseniz, kod aynı şeyi yinelemeleri kaldırarak yapar.
  3. Kod sadece 1 / -1'den ayrılmaz. Örneğin, aramıyoruz if (1 < 1) removeDuplicates()veya [do_nothing, merge_with_dups, merge_without_dups][1].call().

Giriş ve çıkış seçtiğiniz herhangi bir makul biçimde olabilir. Bir örnek olabilir

[1,2],[2,3]->[1,2,2,3]işaret değişmeden önce ve [1,2,3]sonra.

Bu bir popülerlik yarışması. Gösteriş yapmak istemiyorsanız, kod golf değildir . Yaklaşık iki hafta içinde en yüksek oyu alan cevabı kabul edeceğim.


Yalnızca girdi tam sayıları nedir? Pozitif ve / veya negatif mi? Giriş listeleri kopyalar içeriyorsa, bunlar kaldırılmalı -1mıdır?
Monica'yı

1
Giriş listelerinin sıralandığını ve kopyaları kendileri içermediğini varsaymalıyız?
ugoren

DailyWTF'de gördüğümde ilk düşüncem, "birleştirme" tanımlamaları gerektiğiydi. Bu sorunun da bunun bir tanımına ihtiyacı vardır.
Peter Taylor

"Ona Kurşun Atlatan Boris diyorlar" "Neden ona böyle diyorlar?" “... Çünkü mermilerden kaçıyor, Avi”. CodeGolf'ta Snatch hayranları var mı?
Bojangles

Yanıtlar:


11

JavaScript

Geleneksel bir algoritma alın ve bir hata ile yazın:

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

Bu kod tam olarak bir değişmez değer içerir 1. Olarak değiştirilirse -1, kopyalar kaldırılacaktır. Karşılaştırılabilir herhangi bir değerde kullanılabilir.


5

APL 22/23

← ⎕ aracılığıyla ekran girişi istenir ve önde gelen veya negatif olarak ayarlanırsa sıralı bir birleştirilmiş liste kopya olmadan döndürür.

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

Bayt sayaçları, tek bayt APL karakterlerinin bu sitede düzgün şekilde görüntülenmesi için UTF8'e dönüştürüldüğünü lütfen unutmayın.


-1 her şeyi nasıl değiştirir?
Johannes Kuhn

@Johannes Kuhn Yukarıdaki örnek için 0, -2 = / v kodu 0 0 ¯1 0 vektörünü verir ve ¯1 yinelenen bir girişin konumunu gösterir. Bu vektörün 1 ve against1'e karşı test edilmesi, boole elemanlarının ters çevrilmesi 0 0 0 0 veya 0 0 1 0 verir. 1 1 1 1 veya 1 1 0 1 verir. Bu vektörler, birleştirilmiş vektörden uygun elemanları seçmek için kullanılır.
Graham

4

k (18)

Geçerli herhangi bir liste türü için çalışmalı

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

Misal:

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

piton

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

2

darbe

Bağlamın ruhuna göre, bu program l, grepsatırdaki küçük harften önce eksi işareti eklerseniz, kopyaları kaldırır . IÖnceki satırın büyük harfinden önce veya 1sonraki satırdaki rakamdan önce eksi işareti eklerseniz , program farklı davranmaz.

Giriş dosyaları satır başına bir tamsayı içerir (bu, listelerin metin dosyaları olarak olağan temsilidir). Bunlar iki argüman olarak aktarılmalıdır. Ortaya çıkan liste standart çıkışa yazılır.

# 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

Bu programı bir röportajda en iyi kodunuzun bir örneği olarak kullanmaktan çekinmeyin. Tek istediğim bunun benim en iyi kodum olduğunu söylememen.


1

Tcl

Alıntı ruhu içinde

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

Yineleniyorsa, negatif değerleri filtreledikten sonra (-) 1 ile çarpın.


Bu cevap, soru değişmeden önce bu şekilde yazılmıştır. Alıntı ruhu içinde, girişleri hala olumsuz yapmayı tercih ediyorum.
Johannes Kuhn

-1

PHP'de acemi değilim Doğru olup olmadığını bilmiyorum

$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
Bu aslında meydan okumaya cevap gibi görünmüyor - Kodunuzun hiçbir yerinde gerçek bir 1 görmüyorum.
Riking
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.