Учитывая непустой список целых положительных чисел , ваша задача - определить количество уникальных значений± x ± y ± z ± …
Например, рассмотрим список . Существует восемь возможных способов создания сумм:
Существует шесть уникальных сумм , поэтому ответ .6
Тестовые случаи
[1, 2] => 4
[1, 2, 2] => 6
[s]*n => n+1
[1, 2, 27] => 8
[1, 2, 3, 4, 5, 6, 7] => 29
[3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] => 45
[1, 7, 2, 8, 3, 1, 6, 8, 10, 9] => 56
[93, 28, 92, 100, 43, 66, 2, 98, 2, 52, 57, 75, 39, 77, 45, 15, 13, 82, 81, 20, 68, 14, 5, 3, 72, 56, 57, 1, 23, 25, 76, 59, 60, 71, 71, 24, 1, 3, 72, 84, 72, 28, 83, 62, 66, 45, 21, 28, 49, 57, 70, 3, 44, 47, 1, 54, 53, 56, 36, 20, 99, 9, 89, 74, 1, 14, 68, 47, 99, 61, 46, 26, 69, 21, 20, 82, 23, 39, 50, 58, 24, 22, 48, 32, 30, 11, 11, 48, 90, 44, 47, 90, 61, 86, 72, 20, 56, 6, 55, 59] => 4728
Эталонное решение (оптимизирует по скорости, а не по размеру).
Если вы не можете обработать последний случай, потому что вы используете метод грубой силы или что-то подобное, это нормально.
счет
Это код-гольф , поэтому выигрывает самое короткое действительное решение (измеряется в байтах).
code-golf
math
combinatorics
Esolanging Fruit
источник
источник
[2,2,2,2,...]
), ответ должен быть длиной массива + 1. Это потому, что в этом случае положение знаков не имеет значения, и только номер каждого вопросаОтветы:
Wolfram Language (Mathematica) , 27 байтов
Попробуйте онлайн!
Нахождение количества уникальных сумм с перестановкой знаков эквивалентно нахождению количества уникальных сумм подмножеств.
Доказательством будет добавление суммы входных данных к каждой из сумм с заменой знака и деление на два. Тогда есть очевидная биекция.
объяснение
Выполните итерацию по входным данным с начальным значением
{0}
: возьмите объединение между<current value>
и<current value> + input element
(отображает в списки).Гольф версия
Length
функции.источник
Желе , 6 байт
Попробуйте онлайн!
Задний план
Пусть L - входной список, а {P, N} - разбиение на алгебраические слагаемые с положительными и отрицательными знаками. Спецификация испытания требует вычисления s {P, N} = сумма (P) - сумма (N) .
Однако, поскольку сумма (P) + сумма (N) = сумма (L) и сумма (L) не зависит от разбиения, мы имеем s {P, N} = сумма (P) - сумма (N) = сумма ( P) - (сумма (L) - сумма (P)) = 2 сумма (P) - сумма (L) .
Таким образом, каждому уникальному значению суммы (P) соответствует одно уникальное значение s {P, N} .
Как это работает
источник
MATL ,
1110 байтПопробуйте онлайн! Это порт ответа от Octav / MATLAB Луиса Мендо . Я все еще пытаюсь выучить MATL, и я решил опубликовать его вместе с объяснением, поскольку MATL является языком месяца.
Объяснение:
Вот подробное описание для тех, кто не знаком с программированием на основе стека в целом и MATL в частности.
Входной вектор неявно размещается в стеке. Обратите внимание, что когда операция выполняется над элементом в стеке, этот элемент удаляется из стека.
И затем он неявно выводит последний элемент в стеке.
источник
Python 2 , 55 байт
Попробуйте онлайн!
источник
Python 2 , 52 байта
Попробуйте онлайн!
Использует двоичное представление числа для хранения достижимых сумм подмножеств.
источник
k<<n
добавляет n к каждой сумме. Ориентируясь сk
магазинами, эти новые суммыk
сохраняются при сохранении всех предыдущих, а дублированные симы не записываются05AB1E , 4 байта
Использует тот же подход, что и в ответе Денниса «Желе» .
Попробуйте онлайн!
источник
Haskell, 46 байтов
Попробуйте онлайн!
Вместо суммирования подмножеств входного списка, мы делаем все комбинации либо сохранения числа, либо замены его
0
, например,Это на два байта короче
subsequences
.источник
f x=sum[1|i<-[0..sum x],elem i$sum<$>mapM(:[0])x]
будет короче, чем импорт, но, видимо, это не так.import Data.List;length.foldr((<*>)union.map.(+))[0]
R,
8375 байт-8 байт благодаря JayCe и Джузеппе
Создает матрицу всех возможных комбинаций (1, -1) для размера входного вектора, умножает ее на исходный вектор, чтобы получить суммы. Тогда уникально и найди длину результата.
function(v)nrow(unique(t(t(expand.grid(rep(list(c(1,-1)),sum(v|1)))))%*%v))
Предыдущая версия:
f=function(v)nrow(unique(as.matrix(expand.grid(rep(list(c(1,-1)),length(v))))%*%v))
Разоблаченный с комментариями:
источник
t
: TIOsum(v|1)
на байт корочеlength(v)
Октава / MATLAB,
454140 байтВвод - это вектор-столбец (используется в
;
качестве разделителя).Ошибки кода для последнего контрольного примера из-за ограничений памяти.
Это использует идею из ответа JungHwan Min (подмножества вместо чередующихся знаков), чтобы сохранить несколько байтов.
Попробуйте онлайн!
источник
Пари / ГП , 39 байт
Попробуйте онлайн!
источник
Python 3 , 61 байт
Попробуйте онлайн!
Рекурсивный подход, отслеживание уникальных сумм подмножеств.
Самое интересное, что это бьет
itertools
с большим отрывом:76 байт
Попробуйте онлайн!
источник
Pyth , 5 байт
Использует тот же подход, что и в ответе Денниса «Желе» .
Попробуй это здесь.
источник
Атташе , 29 байт
Попробуйте онлайн!
Это работает путем сворачивания
±
оператора над списком ввода, затем взятия±
этого списка и подсчета уникальных атомов массива.Вот несколько примеров того, как работает складывание:
Затем мы генерируем все перестановки последнего знака, применяя PlusMinus еще раз.
Более эффективная версия, 31 байт
Попробуйте онлайн! Это не делает тайм-аут в финальном тестовом примере, поскольку не генерирует ненужных комбинаций.
источник
R , 62 байта
Попробуйте онлайн!
Алгоритм портов Денниса. Он наиболее близок к ответам Octave / MATL, поскольку использует аналогичный растровый и матричный продукт для включения / исключения терминов.
источник
APL (Dyalog Classic) ,
1211 байтов-1 спасибо H.PWiz
Попробуйте онлайн!
источник
-⍨
может быть⊢
Perl 5
-p
, 39 байтПопробуйте онлайн!
источник
JavaScript (ES6), 63 байта
Попробуйте онлайн!
источник
Шелуха , 5 байт
Попробуйте онлайн!
Порт Денис Желе ответ.
объяснение
источник
Perl 6 , 33 байта
Попробуйте онлайн!
источник
Утилиты Bash + GNU, 49 байт
Попробуйте онлайн!
Ввод в виде списка через запятую в командной строке.
объяснение
источник
машинный язык x86_64 для Linux,
3129 байтПопробуйте онлайн!
Вдохновленный ответом @ xnor. Требуется машина с
POPCNT
инструкцией.источник
C (gcc) ,
7469 байтПопробуйте онлайн!
C порт ответа @ xnor
источник
APL (Dyalog Classic) ,
343332 байтаПопробуйте онлайн!
Спасибо @ngn за -1 байт!
источник
1-⍨≢⍵
->≢1↓⍵
+.×⍨
->+.×
Чисто , 82 байта
Попробуйте онлайн!
Определяет функцию,
? :: [Int] -> Int
используемуюf :: [Int] -> ([Int] -> Int)
в качестве помощника для уменьшения каждой возможной суммы после сложения или вычитания.источник
APL (Dyalog Classic) , 21 байт
Попробуйте онлайн!
объяснение
Последовательность функций, эквивалентная
{((⍴⍵)⍴2)⊤⍳(⍴⍵)}
, которая генерирует матрицу, которая имеет двоичные представления от 0 до длины ввода в виде столбцовКарты
1
с на-1
с и0
с на1
сМатричное умножение с вводом, которое дает массив всех возможных сумм
Удалить дубликаты, затем сосчитать
источник
Java 8,
2078344 байтаПорт @ xnor's Python 2 ответа .
-39 байтов благодаря @Jakob .
Попробуйте онлайн .
источник
Long
:s->Long.bitCount(s.reduce(1l,(a,e)->a|a<<e))
..reduce
(.bitCount
а также могу добавить ..>.>) -39 байтов прямо здесь! :)Java 8, 85 байт
Еще один порт Java от ответа xnor . Как и в исходном ответе, здесь используется битовая карта произвольной точности, чтобы не было верхнего предела размера суммы подмножества.
Это лямбда от последовательного
java.util.stream.Stream<Integer>
доint
.Попробуйте онлайн
Обратите внимание, что объединитель (третий аргумент
reduce
) не используется, поскольку поток является последовательным. Функция, которую я выбрал, является произвольной.источник
Юлия 0,6 ,
5452 байтаПопробуйте онлайн!
( -2 байта путем замены
¬
на~
, спасибо Джо Кингу )Работает для всех тестовых случаев. Использует трансляцию для сбора всех возможных сумм, а затем подсчитывает их.
Объяснение:
Старое решение:
Юлия 0,6 , 64 байта
Попробуйте онлайн!
Работает для входных массивов длиной до 63 (поэтому не работает для последнего контрольного примера, что хорошо в соответствии с OP).
Объяснение:
источник
JavaScript (Babel Node) , 64 байта
Попробуйте онлайн!
Это не будет работать для последнего теста.
Более эффективное решение (работает на последнем тестовом примере):
JavaScript (Babel Node) , 71 байт
Попробуйте онлайн!
Это не будет работать в реальном браузере из-за
Array#smoosh
.Благодаря Bubbler,
[x+f,x-f]
->[x+f,x]
сохраняет 2 байта.источник
[x+f,x]
вместо[x+f,x-f]
( доказательство JungHwan Мин ).F=([f,...r],s=[0])=>f?F(r,[...s,...s.map(x=>x+f)]):new Set(s).size
[...s,...s.map(x=>x+f)]
,s.concat(s.map(x=>x+f))
и,s,s.map(x=>s.push(x+f))
доля такой же длины ...Красный , 73 байта
Порт Денниса Python 2 ответ. Не обрабатывает последний контрольный пример.
Попробуйте онлайн!
источник