Избегайте повторяющихся записей, используя изменение знака


14

Этот анекдот содержит следующий интригующий обмен:

"Хорошо, Фред", прервала Ави. «Тогда как бы вы изменили это, чтобы избежать повторяющихся записей?»

«О, просто поменяйте это на отрицательное».

Хотя это утверждение не является точным в контексте, я действительно задаюсь вопросом, есть ли какой-то вероятный код, для которого это имеет смысл.

Ваша задача - написать код (программу, функцию, что угодно), который соответствует этим критериям:

  1. Объединяет два списка ввода в один, сохраняя дубликаты. [edit: При желании вы можете предположить, что они являются целыми числами и / или что сами списки уникальны. Вы не можете предполагать, что целые числа положительны (один ответ, который делает это, встречен).]
  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
Должны ли мы предполагать, что входные списки отсортированы и не содержат дубликатов?
Угорен

Моей первой мыслью, когда я увидел это на 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

APL 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 меняет все?
Йоханнес Кун

@Johannes Kuhn Для приведенного выше примера код 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

к (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 в вашем коде.
Riking
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.