Мешок , также называемый мультимножеством, это неупорядоченная коллекция. Вы можете назвать это набором, который допускает дублирование, или списком (или массивом), который не упорядочен / не проиндексирован. В этом задании вас попросят реализовать операции с сумками: сложение, разность, умножение, деление, подсчет и тест на равенство.
операции
Указанные операции могут быть не традиционными.
- сложение объединяет две сумки в одну, сохраняя общее количество каждого значения
[1,2,2,3] + [1,2,4] = [1,1,2,2,2,3,4]
- разница удаляет из сумки каждый элемент другой сумки, или ничего не делает, если такой элемент отсутствует
[1,2,2,4] - [1,2] = [2,4]
[1,2,3] - [2,4] = [1,3]
- Умножение умножает каждый элемент в сумке.
[1,2,3,3,4] * 3 = [1,1,1,2,2,2,3,3,3,3,3,3,4,4,4]
2 * [1,3] = [1,1,3,3]
- деление является необычным: каждый n равных элементов помещается в n одинаковых новых сумок, элементы, которые не могут образовывать n-группу, остаются в сумке. Верните любую из n новых сумок.
[1,1,2,2,2] / 2 = [1,2]
[1,2,2,3,3,3] / 3 = [3]
- подсчет подсчитывает, сколько сумок делителей можно изготовить из дивидендной сумки
[1,1,2,2,2,2,3,3,3] c [1,2,3] = 2
- проверка на равенство проверяет, имеют ли две сумки одинаковые номера для каждого элемента
[1,2,2,3] == [3,2,1,2] = truthy
[1,2,3] == [1,2,2,3] = falsy
(также можно использовать=
для этого)
Если вы используете свои собственные символы для операторов, пожалуйста, укажите.
Форматы
Сумки будут отображаться в виде списков формы [1,1,2,3,4]
. Вы можете использовать любые другие скобки, кроме квадратных, или даже использовать кавычки, или вообще ничего. Элементы будут целыми числами (математически, не обязательно int
) для целей этого вопроса. Сумки не должны быть отсортированы.
Формат ввода будет два пакета или мешок и целое число с оператором. Вы можете указать свой собственный формат, если он содержит эти три.
Формат вывода должен быть один мешок одного и того же формата.
правила
- Вы не можете использовать встроенные функции, операции или библиотеки (включая стандартную библиотеку), которые уже реализуют их; Впрочем, можно использовать конкатенацию и умножение списков, поскольку они по определению являются операциями со списками, а не с сумками (которые в основном выполняют одно и то же).
- применяются стандартные лазейки
- самый короткий ответ выигрывает
Контрольные примеры
[1,2,2,3] + [1,2,4]
[1,1,2,2,2,3,4]
[1,2,2,4] - [1,2]
[2,4]
[1,2,3] - [2,4]
[1,3]
[1,2,3,3,4] * 3
[1,1,1,2,2,2,3,3,3,3,3,3,4,4,4]
2 * [1,3]
[1,1,3,3]
[1,1,2,2,2] / 2
[1,2]
[1,2,2,3,3,3] / 3
[3]
[1,1,2,2,2,2,3,3,3] c [1,2,3]
2
[3,2,1,2] == [1,2,2,3]
truthy
[1,2,3] == [1,2,2,3]
falsy
источник
Ответы:
05AB1E,
9287838277 байтРазделить по операции
объяснение
прибавление
Положите одну сумку в другую и сгладьте их в одну сумку.
умножение
Убедитесь, что номер находится на вершине стека. Назовите это X.
Дублируйте сумку X раз и соедините в одну сумку.
подсчитывать
Для каждого элемента в сумке делителя подсчитайте количество случаев в сумке дивидендов.
Минимальным количеством будет количество сумок, которые мы можем сделать.
равенство
Сортируйте обе сумки и проверьте, равны ли они.
разделение
Посчитайте, сколько раз каждый уникальный элемент встречается в сумке.
Если это происходит как минимум столько раз, сколько делитель. Храните (nr_of_copies_total // divisor) копии в сумке.
разница
Для каждого элемента в вычитаемом элементе сортируйте его перед передней частью минюенда.
Если текущее вычитаемое значение равно первому элементу в minuend, удалите его из minuend.
источник
APL (155)
Это определяет оператор
∆
'bag', который определяет операции bag для заданных функций. Т.е.+∆
было бы дополнение. Затем он читает строку с клавиатуры и оценивает ее как выражение APL.Функции:
+∆
, дополнение-∆
вычитание×∆
, умножение÷∆
, подразделение⊂∆
, считая≡∆
, эквивалентность (хотя из-за игры в гольф любая нераспознанная функция сделает эквивалентность)Объяснение:
∆←{
...}
: определить оператор∆
:O←⍺⍺
: сохранить данную функцию вO
(⎕CR
не будет работать⍺⍺
напрямую)O←⎕CR'O'
: получить строковое представление этой функции'+'=O
...:
: для дополнения,⍺,⍵
: объединить два спискаR[⍋R←
...]
: и отсортировать результат'-'=O:
: для вычитания,⍺{
...}⍵
: запустить следующую рекурсивную функцию:⍵≡⍬:⍺
: если вычитаемое поле пусто, вернуть миненд⍺/⍨(⍳⍴⍺)≢⍺⍳⊃⍵∇1↓⍵
: в противном случае удалите первый элемент вычитаемого и из вычитаемого, и из уменьшающегося и попробуйте снова(⍬=⍴⍵)∧K←'×'=O:
для умножения, и если правильный аргумент не является сумкой:⍵/⍺
: реплицировать каждый элемент левого аргумента правым аргументомK:
... и если правильный аргумент - сумка:⍺/⍵
: реплицировать каждый элемент в правом аргументе по левому аргументу (так, чтобы умножение было коммутативным)'÷'=O:
: для деления,⍵≤⍺∘.+⍺
: посмотреть, какие элементы в ⍺ встречаются не менее ⍵ раз,⍺/⍨
: выберите те из ⍺,∪
: и удалите все дубликаты из этого списка'⊂'=O:
: для подсчета,⍵{
...}⍺
: запустить следующую рекурсивную функцию:(∪⍺)≢∪⍵:0
: если один список содержит элементы, а другой нет, результат равен 01+⍺∇⍵-∆⍺
: в противном случае вычтите дивиденды из делителя, повторите попытку и увеличьте результат.⋄
: если ничего из вышеперечисленного, сделать тест на эквивалентность:⍺[⍋⍺]≡⍵[⍋⍵]
: отсортировать оба списка и посмотреть, равны ли они⎕
: прочитать выражение с клавиатуры, оценить его и вывести результат.Тестовые случаи:
источник
[2,2,2,2,2,2]/3
должно[2,2]
, но ваша, похоже, дает[2]
.∆
, пользователь будет выгружен в собственный REPL APL, где∆
теперь действует. Я думаю, что вы можете сохранить несколько байтов, переместив вычитание до конца, так как это единственный, который требует две строки. Вместо⎕CR
, используйте,*
чтобы символизировать count, и сделатьO←⍺⍺2
, затем2=O:
для плюс,1=O
для mult,0=O:
для эквивалентных,7<O:
для count и0<O:
для div (с подразумеваемым0>O:
для subtr).JavaScript (ES6), 260 байт
Принимает 3 параметра. Первый параметр - это массив, второй - оператор, третий зависит от оператора. Сумки должны содержать неотрицательные целые числа.
Ungolfed:
источник
Октава,
253244226 байтЭта функция должна быть в файле. Чтобы написать функцию в командном окне, вы должны использовать
endfunction
илиend
.Спасибо Луису Мендо за сохранение 18 байт.
Операции:
Пример использования:
Ungolfed:
источник
Mathematica,
387347300284 байтаСлегка деголфированный (он же старая версия), не имел полной поддержки тестов на равенство (вернул истинные значения, но оставил без оценки для несоответствующих сумок).
Реализует требуемый тип данных с головой
b
.Первый
b
определяется какOrderless
. Любой объект, переданный ядру с головой,b
будет автоматически сортировать его аргументы. Таким образом, даже еслиb[3,2,1]
он введен, оценщик никогда не увидит ничего, кромеb[1,2,3]
.Дополнение тривиально определяется как объединение элементов.
Определено специальное правило для различия двух сумок (объяснено ниже). Предыдущая версия имела вспомогательный символ для выражений формы
-bag
.Затем умножение (при условии, что
n
оно является положительным целым числом) рекурсивно определяется как то,n*b[...] = b[...] + (n-1)*b[...]
которое в конечном итоге сводится к простой сумме.Специальное правило для
b[...] - b[...]
подсчитывает количество различных элементов в сумке сумок и вычитает сумку, которая будет вычтена дважды из этого результата. Проще объяснить:Выше список
Keys->Values
.KeyValueMap
сTable
создает списки каждыйKey
Value
раз. (есть также,Max[...,0]
чтобы не пытаться создавать таблицы отрицательной длины). Это выходит как:который сплющен и голова
List
заменена наb
.Деление на целые числа несколько похоже на используемые функции, это просто поэтапное деление числа элементов на целое число.
Деление по наборам или подсчетам Я изменился с момента первоначальной реализации. Сейчас это делается рекурсивно следующим образом. Скажем, мы делим сумку
b1
наb2
(что в коде гольфа естьc
иa
соответственно. Если(b1-b2) + b2 == b1
, тогда добавьте 1 и добавьте к этому результат деления(b1-b2)/b2
. Если нет, верните 0 и выйдите из рекурсии.Если сумки совпадают, встроенный
==
даетTrue
. Последняя строка заставляет,False
если они этого не делают.Тестовые случаи:
источник
Q - 219 символов
a
для сложения,s
для разности (вычитания),m
для умножения,d
для деления,c
для подсчета,e
для равенства.Алгоритм сложения очевиден, он просто объединяет сумки.
Функция вычитания индексирует во входной сумке (представленной в виде массива) весь диапазон индексов, за исключением первых
n
индексов каждого класса эквивалентности, образованных равенством для каждого элемента вy
, гдеn
находится число копий этого представителя вy
. Обработка возможных дубликатовy
делает это настоящим монстром функции.Функция умножения получает
x
значения от каждогоy
, в случае, еслиy
это одно значение, а не массив, она просто копирует их.Функция деления создает значения, количество которых в массиве больше, чем
y
, а затем удаляет дубликаты.Функция подсчета вычисляет количество каждого элемента в
y
, а затем возвращает минимум.Две сумки равны, если их отсортированные представления массива равны.
источник
Ruby, ответ на определение класса,
323291 байтВ основном просто хотел сделать
Bag
реальный класс из-за гибкости Ruby с классами. В этом случае он наследуется отArray
что он короче, чем инициализация внутреннего массива и работа с другими вещами.Я, вероятно, сделаю более серьезный ответ о гольфе, который использует функцию, чтобы справиться с операциями завтра. Я очень устал, и мне было очень весело с этим,
хотя мне приходилось спорить с определением числового класса, чтобыХОЧИТЕ ФУНКЦИЮ COERCE, ЧТОБЫ ЭТО СДЕЛАТЬ, ЧТОБЫ Я НЕ ДОЛЖЕН БЫТЬ ПОВТОРЯТЬ ОПРЕДЕЛЕНИЯ КЛАССА ЧИСЛАNumber * Bag
правильно работатьПопробуйте онлайн! (Пробелы в Ruby не имеют значения, поэтому код там немного раскручен.)
источник
Рубин, 201 байт
Как и было обещано в моем другом ответе, вот тот, который использует функции вместо создания нового класса. Я так близок к преодолению 200-байтовой отметки ... Попробуйте онлайн
При этом используются те же коды операций, что и @Neil в его ответе JavaScript, и тот же порядок аргументов (lhs, код операции, rhs)
Код:
источник
С ++,
555551 байт(разрывы строк добавлены для удобства чтения - требуется только первая новая строка и считается)
объяснение
Мы реализуем нашу сумку в виде карты (значение, количество). Основные операции могут быть реализованы путем манипулирования счетами; вычитание и целочисленное деление также должны удалить любые элементы, чье количество достигает нуля, так что это
std::map::operator==
будет работать в качестве теста на равенство.Следующий расширенный код является общей версией вышеупомянутого, гораздо менее сложного: мы используем отдельное
s()
для выжимания любых значений с нулевым счетом, и мы реализуемconst
операции в терминах операторов присваивания идиоматическим способом C ++. Мы также используемs()
для умножения путем0
возврата действительно пустой пакет (проверено путем добавления(B{1}*0 != B{})
кmain()
); оригинал не проходит этот тест, и неясно, является ли это требованием.тесты
источник
Python 2.7 - 447B (размер файла)
Это моя первая попытка в Codegolf, надеюсь, это удовлетворит. Мне нужно 2 часа. (Но я все еще начинающий в Python)
Изменить: Спасибо "Кевин Лау - не Кенни" за указание на это:
Изменить: Кроме того, я сэкономил место, заменив функции с лямбда-выражений и новые строки и отступы с большим количеством точек с запятой.
Код:
проверки:
Выход:
Я мог бы попробовать это в другой раз с установленным в качестве основы некоторое время. Редактировать: Может быть, я даже попробую только с функциями.
источник
self
- какS
и в случае с ними. Другой трюк заключается в том, что встроеннаяsorted
функция делает именно то, что вы хотите от вашей новой функцииs
, так что вы можете отказаться от определения функции (видя, что вы используете ее только один раз). Вам никогда не нужно,__radd__
потому что вы никогда не добавляете не сумки с сумками, хотя вам все еще нужно__rmul__
. Наконец, вам нужен только один пробел отступа вместо четырех, что значительно сокращает количество байтов