Ваша задача состоит в том, чтобы взять два целочисленных полиномиальных выражения с одной переменной и умножить их на их упрощенное перво-членное разложение слева направо (AKA FOIL в случае биномов). Не объединяйте одинаковые термины и не переупорядочивайте результат. Чтобы быть более явным в отношении расширения, умножьте первый член в первом выражении на каждый член во втором по порядку и продолжайте в первом выражении, пока все члены не будут умножены на все остальные члены. Выражения будут даны в упрощенном варианте LaTeX.
Каждое выражение будет представлять собой последовательность терминов, разделенных +
(с ровно одним пробелом на каждой стороне). Каждый термин будет соответствовать следующему регулярному выражению: (нотация PCRE)
-?\d+x\^\d+
В простом английском языке термин является необязательным первым, -
за которым следуют одна или несколько цифр, за которыми x
следует целая неотрицательная сила (с ^
)
Пример полного выражения:
6x^3 + 1337x^2 + -4x^1 + 2x^0
При подключении к LaTeX вы получаете
Вывод также должен соответствовать этому формату.
Так как в этом формате скобки не окружают показатели степени, LaTeX будет отображать многозначные показатели неправильно. (например, 4x^3 + -2x^14 + 54x^28 + -4x^5
отображается как ). Вам не нужно учитывать это, ивы не должны включать скобкив свои выходные данные.
Примеры тестовых случаев
5x^4
3x^23
15x^27
6x^2 + 7x^1 + -2x^0
1x^2 + -2x^3
6x^4 + -12x^5 + 7x^3 + -14x^4 + -2x^2 + 4x^3
3x^1 + 5x^2 + 2x^4 + 3x^0
3x^0
9x^1 + 15x^2 + 6x^4 + 9x^0
4x^3 + -2x^14 + 54x^28 + -4x^5
-0x^7
0x^10 + 0x^21 + 0x^35 + 0x^12
4x^3 + -2x^4 + 0x^255 + -4x^5
-3x^4 + 2x^2
-12x^7 + 8x^5 + 6x^8 + -4x^6 + 0x^259 + 0x^257 + 12x^9 + -8x^7
Правила и предположения
- Вы можете предположить, что все входные данные соответствуют именно этому формату. Поведение для любого другого формата не определено для целей этой задачи.
- Следует отметить, что любой метод взятия двух полиномов действителен при условии, что оба считываются как строки, соответствующие вышеуказанному формату.
- Порядок многочленов имеет значение из-за ожидаемого порядка расширения продукта.
- Вы должны поддерживать входные коэффициенты между и и входные показатели до .
- Поэтому должны поддерживаться выходные коэффициенты между и и показателями до .
- Можно предположить, что каждый входной многочлен содержит не более 16 членов
- Поэтому вы должны (как минимум) поддерживать до 256 терминов в выводе
- Термины с нулевыми коэффициентами должны быть оставлены как есть, с показателями, правильно объединенными
- Отрицательный ноль допускается на входе, но семантически неотличим от положительного нуля. Всегда выводите положительный ноль. Не опускайте нулевые условия.
Счастливого гольфа! Удачи!
Ответы:
R ,
159153148 байтПопробуйте онлайн!
Я действительно хотел использовать
outer
, так что почти наверняка есть более эффективный подход.источник
Хаскелл ,
131122 байтаПопробуйте онлайн!
f
анализирует полином из строки,!
умножает два из них и форматирует результат.H.PWiz сохранил 9 байтов. Благодарность!
Ungolfed
источник
Рубин ,
102 10098 байтПопробуйте онлайн!
Как?
Первый шаг: получить все числа из обоих полиномов:
scan
возвращает числа в виде массива пар строк. Затем сделайте декартово произведение из 2 списков. Теперь у нас есть все числа, где они нам нужны, но все-таки в неправильном порядке.Пример: если мы умножим
3x^4
на-5x^2
, мы получим числа как[["3","4"],["-5","2"]]
, первая идея состояла в том, чтобы сжать и сгладить этот список, а затем поместить числа в выражение, которое будет оценено как[3*-5, 4+2]
. На самом деле нам не нужно переупорядочивать числа, мы могли бы сделать это внутри выражения, используя временную переменную: выражение становится[3*(z=4,-5),z+2]
.После оценки этих выражений мы получаем коэффициент и показатель степени, нам нужно соединить их, используя
"x^"
, а затем объединить все те, которые используют"+"
.источник
Haskell,
124121 байтПримечание: TIO не хватает
Data.Lists
, поэтому я импортируюData.Lists.Split
иData.List
: Попробуйте онлайн!Изменить: -3 байта благодаря @Lynn.
источник
f!x=map f.splitOn x
а затемz=read!"x^"!"+"
сохраняет байт; за последнюю строчкуdrop 3$do[u,v]<-z a;[p,q]<-z b;" + "++shows(u*p)"x^"++show(v+q)
экономит еще две. 120 байтовData.List
вместо TIO импортируется версия TIOData.Lists
, так что это +1 байт.Pyth - 39 байт
Попробуйте онлайн .
источник
JavaScript (Вавилонский узел) , 118 байт
Принимает вход как
(a)(b)
.Попробуйте онлайн!
источник
Python 2 , 193 байта
Попробуйте онлайн!
Примечание: в первый раз выполнил кодовый гольф, так что извините, если попытка отстой хаха
источник
re.finditer
не самый короткий подходСетчатка , 110 байт
Попробуйте онлайн! Объяснение:
Перед каждым термином в первом входе добавьте префикс
#
, копию второго ввода и пробел. Это означает, что всем терминам в копиях второго ввода предшествует пробел, и ни один из терминов из первого ввода не является.Сопоставьте все копии терминов во втором входе и соответствующие им термины из первого ввода. Объедините любые
-
знаки, умножьте коэффициенты и добавьте индексы. Наконец, объедините все полученные замены со строкой+
.Удалите любые пары
-
s и конвертируйте-0
в0
.источник
СНОБОЛ4 (CSNOBOL4) ,
192176 байтПопробуйте онлайн!
источник
Perl 6 , 114 байт
Попробуйте онлайн!
источник
Python 2 , 130 байт
Попробуйте онлайн!
источник
C # (интерактивный компилятор Visual C #) ,
192190 байтСинтаксис запроса кажется на байт короче, чем синтаксис метода.
Попробуйте онлайн!
источник
Желе , 28 байт
Попробуйте онлайн!
Полная программа. Принимает два полинома в виде списка из двух строк.
Пояснение (развернутая форма)
Aliasing
)
так же, какµ€
.Трейлинг
”
подразумевается и может быть опущен.Алгоритм
Допустим, у нас есть этот вход:
Первой процедурой является синтаксический анализ, применяемый к каждому из двух полиномов. Давайте разберемся с первым,
"6x^2 + 7x^1 + -2x^0"
:Первый шаг - разделить строку
'+'
, чтобы разделить термины. Это приводит к:Следующим шагом является разделение каждой строки на
'x'
, чтобы отделить коэффициент от показателя степени. Результат таков:В настоящее время похоже, что в этих строках много мусора, но этот мусор на самом деле не важен. Все эти строки будут оцениваться как ниладические ссылки Jelly. Тривиально, пробелы не важны, так как они не находятся между цифрами чисел. Таким образом, мы могли бы также оценить ниже и получить тот же результат:
Они0 XOR 2 = 2 , Очевидно, что0 XOR n = n , Все показатели целые, поэтому у нас все хорошо. Следовательно, оценка этого вместо вышеизложенного не изменит результат:
^
выглядят немного более тревожно, но на самом деле они тоже ничего не делают! Что ж,^
это побитовый атом XOR, однако ниладические цепочки действуют как монадические ссылки, за исключением того, что первая ссылка фактически становится аргументом, вместо того, чтобы принимать аргумент, если он неладический. Если это не так, то ссылка будет иметь аргумент0
. Экспоненты имеют^
символ s в качестве первого символа и^
не нильадные, поэтому предполагается, что аргумент будет0
. Остальная часть строки, то есть число, является правильным аргументом^
. Так, например,^2
естьВот так:
Этот шаг также будет преобразован
"-0"
в0
.Поскольку мы анализируем оба входа, результат после синтаксического анализа будет следующим:
Разбор теперь завершен. Следующая процедура - Умножение.
Сначала мы возьмем декартово произведение этих двух списков:
Составлено много пар, каждая с одним элементом из левого списка и одной справа по порядку. Это также, случается, предполагаемый порядок вывода. Эта задача действительно требует от нас применения мультипликативной дистрибутивности, поскольку нас просят не обрабатывать результат после этого.
Пары в каждой паре представляют термины, которые мы хотим умножить, причем первый элемент является коэффициентом, а второй - показателем степени. Чтобы умножить слагаемые, мы умножим коэффициенты и сложим экспоненты вместе (хсб хd= а б хсИксd= а б ( хсИксd) = ( а б ) хс + д ). Как мы это делаем? Давайте разберемся со второй парой,
[[6, 2], [-2, 3]]
.Сначала мы транспонируем пару:
Затем мы берем произведение первой пары и сумму второй:
Соответствующая часть кода,
PSƭ€
самом деле не сбрасывает свой счетчик для каждой пары терминов, но, поскольку они являются парами, в этом нет необходимости.Обрабатывая все пары терминов, мы имеем:
Здесь умножение сделано, так как нам не нужно объединять одинаковые термины. Последняя процедура - Prettyfying.
Сначала мы присоединяемся к каждой паре с
"x^"
:Затем мы присоединяемся к списку
" + "
:Обратите внимание, что у нас все еще есть числа в списке, так что на самом деле это не строка. Тем не менее, в Jelly есть процесс, называемый «stringification», запускаемый прямо в конце выполнения программы для вывода результата. Для списка глубины 1 он просто конвертирует каждый элемент в его строковое представление и объединяет строки вместе, поэтому мы получаем желаемый результат:
источник
JavaScript,
112110 байтЯ нашел две альтернативы одинаковой длины. Вызов с карринг синтаксисом:
f(A)(B)
Показать фрагмент кода
Показать фрагмент кода
-2 байта ( Луис ): убрать пробелы вокруг
split
разделителя.JavaScript, 112 байт
Используя
String.prototype.matchAll
.Показать фрагмент кода
источник
split' + ' => split'+'
сохранить 2 байтаjoin
.