Уникайте повторюваних записів, використовуючи зміну знаку


14

Цей анекдот містить такий інтригуючий обмін:

- Добре, Фреде, - перебив його Аві. "Тоді як би ви змінили це, щоб уникнути повторюваних записів?"

"О, просто поміняйте цю на негативну".

Хоча ця претензія не є точною в контексті, мені цікаво, чи є якийсь правдоподібний код, для якого це має сенс.

Ваше завдання полягає в написанні коду (програми, функції, будь-якого іншого), який відповідає цим критеріям:

  1. Об'єднує два вхідні списки в один, зберігаючи дублікати. [редагувати: Ви необов'язково можете припустити, що вони є цілими числами та / або що самі списки є унікальними. Ви не можете припустити, що цілі числа є позитивними (одна відповідь, яка робить це, є зібраною в цілому).]
  2. Буквально "1" з'являється десь у коді. Якщо ви зміните це на буквальне "-1", код робить те саме, але видаляє дублікати.
  3. Код не просто відгалужується на 1 / -1. Ми не шукаємо if (1 < 1) removeDuplicates()або [do_nothing, merge_with_dups, merge_without_dups][1].call(), наприклад.

Введення та вихід можуть бути у будь-якому обраному вами форматі. Одним із прикладів може бути

[1,2],[2,3]->[1,2,2,3]перед зміною знака та [1,2,3]після.

Це конкурс на популярність. Це не код гольфу , якщо ви не хочете показати себе. Я прийму відповідь з найвищим голосом приблизно через два тижні.


Який вхід - лише цілі числа? Позитивний та / або негативний? Якщо вхідні списки містять дублікати, чи слід їх видаляти у -1випадку?
Відновіть Моніку

1
Чи слід вважати, що вхідні списки відсортовані та самі не містять дублікатів?
ugoren

Перша моя думка, коли я побачив, що на DailyWTF - це те, що їм потрібно визначити "злиття". Це питання також потребує його визначення.
Пітер Тейлор

"Вони називають його Борисом Кулею Доджером" "Чому вони його так називають?" "... Тому що він ухиляється від куль, Аві". Будь-які шанувальники Snatch на CodeGolf?
Bojangles

Відповіді:


11

JavaScript

Візьміть звичайний алгоритм і запишіть його з помилкою:

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

Цей код містить рівно один буквальний 1. Якщо його змінити на -1, то дублікати будуть видалені. Його можна використовувати на будь-яких порівняних значеннях.


5

АПЛ 22/23

Запрошує ввести екран через ← ⎕ і повертає впорядкований об'єднаний список з або, якщо для ведучого встановлено мінус, без дублікатів.

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

Лічильники байтів зауважте, що однобайтові символи APL були перетворені в UTF8, щоб правильно відобразити на цьому сайті.


Як -1 змінює все?
Йоганнес Кун

@ Джоханнес Кун Для наведеного вище прикладу код 0, -2 = / v дає вектор 0 0 ¯1 0 з ¯1, що вказує позицію дублюючого запису. Тестування цього вектора на 1 і ¯1 дає 0 0 0 0 або 0 0 1 0, обернення булевих елементів дає 1 1 1 1 або 1 1 0 1. Ці вектори використовуються для вибору відповідних елементів із об'єднаного вектора.
Грем

4

k (18)

Має працювати для будь-якого дійсного списку

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

Приклад:

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


2

Баш

У дусі контексту ця програма видаляє дублікати, якщо ви додасте знак мінус перед малим рядком lу grepрядку. Якщо ви додали знак мінус перед великим регістром Iпопереднього рядка або перед цифрою 1на наступному рядку, програма поводиться не по-іншому.

Вхідні файли містять одне ціле число на рядок (це звичайне подання списків як текстових файлів). Вони повинні бути передані як два аргументи. Отриманий список записується до стандартного аутпуту.

# 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

Сміливо використовуйте цю програму як приклад свого найкращого коду в інтерв'ю. Прошу лише сказати, що ви не кажете, що це мій найкращий код.


1

Tcl

У дусі цитати

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

Якщо це дублікат, помножте його на (-) 1, після цього відфільтруйте від’ємні значення.


Ця відповідь була написана саме до того, як питання змінилося. В дусі цитати я все ж вважаю за краще робити записи негативними.
Йоганнес Кун

-1

Я початківець у PHP, я не знаю, чи правильно це

$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
Не схоже, що це насправді відповідає на виклик - я ніде не бачу буквального 1 у вашому коді.
Рікінг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.