Желе , 28 байт
ṣ”+ṣ”xV$€)p/ZPSƭ€j⁾x^Ʋ€j“ +
Попробуйте онлайн!
Полная программа. Принимает два полинома в виде списка из двух строк.
Пояснение (развернутая форма)
ṣ”+ṣ”xV$€µ€p/ZPSƭ€j⁾x^Ʋ€j“ + ” Arguments: x
µ Monadic chain.
€ Map the monadic link over the argument.
Note that this will "pop" the previous chain, so
it will really act as a link rather than a
sub-chain.
ṣ”+ ṣ, right = '+'.
Split the left argument on each occurrence of
the right.
Note that strings in Jelly are lists of
single-character Python strings.
€ Map the monadic link over the argument.
$ Make a non-niladic monadic chain of at least
two links.
ṣ”x ṣ, right = 'x'.
Split the left argument on each occurrence of
the right.
V Evaluate the argument as a niladic link.
/ Reduce the dyadic link over the argument.
p Cartesian product of left and right arguments.
€ Map the monadic link over the argument.
Ʋ Make a non-niladic monadic chain of at least
four links.
Z Transpose the argument.
€ Map the monadic link over the argument.
ƭ At the first call, call the first link. At the
second call, call the second link. Rinse and
repeat.
P Product: ;1×/$
S Sum: ;0+/$
j⁾x^ j, right = "x^".
Put the right argument between the left one's
elements and concatenate the result.
j“ + ” j, right = " + ".
Put the right argument between the left one's
elements and concatenate the result.
Aliasing
)
так же, как µ€
.
Трейлинг ”
подразумевается и может быть опущен.
Алгоритм
Допустим, у нас есть этот вход:
["6x^2 + 7x^1 + -2x^0", "1x^2 + -2x^3"]
Первой процедурой является синтаксический анализ, применяемый к каждому из двух полиномов. Давайте разберемся с первым,"6x^2 + 7x^1 + -2x^0"
:
Первый шаг - разделить строку '+'
, чтобы разделить термины. Это приводит к:
["6x^2 ", " 7x^1 ", " -2x^0"]
Следующим шагом является разделение каждой строки на 'x'
, чтобы отделить коэффициент от показателя степени. Результат таков:
[["6", "^2 "], [" 7", "^1 "], [" -2", "^0"]]
В настоящее время похоже, что в этих строках много мусора, но этот мусор на самом деле не важен. Все эти строки будут оцениваться как ниладические ссылки Jelly. Тривиально, пробелы не важны, так как они не находятся между цифрами чисел. Таким образом, мы могли бы также оценить ниже и получить тот же результат:
[["6", "^2"], ["7", "^1"], ["-2", "^0"]]
Они ^
выглядят немного более тревожно, но на самом деле они тоже ничего не делают! Что ж, ^
это побитовый атом XOR, однако ниладические цепочки действуют как монадические ссылки, за исключением того, что первая ссылка фактически становится аргументом, вместо того, чтобы принимать аргумент, если он неладический. Если это не так, то ссылка будет иметь аргумент 0
. Экспоненты имеют ^
символ s в качестве первого символа и ^
не нильадные, поэтому предполагается, что аргумент будет 0
. Остальная часть строки, то есть число, является правильным аргументом ^
. Так, например, ^2
есть0 XOR 2 = 2, Очевидно, что0 XOR n = n, Все показатели целые, поэтому у нас все хорошо. Следовательно, оценка этого вместо вышеизложенного не изменит результат:
[["6", "2"], ["7", "1"], ["-2", "0"]]
Вот так:
[[6, 2], [7, 1], [-2, 0]]
Этот шаг также будет преобразован "-0"
в 0
.
Поскольку мы анализируем оба входа, результат после синтаксического анализа будет следующим:
[[[6, 2], [7, 1], [-2, 0]], [[1, 2], [-2, 3]]]
Разбор теперь завершен. Следующая процедура - Умножение.
Сначала мы возьмем декартово произведение этих двух списков:
[[[6, 2], [1, 2]], [[6, 2], [-2, 3]], [[7, 1], [1, 2]], [[7, 1], [-2, 3]], [[-2, 0], [1, 2]], [[-2, 0], [-2, 3]]]
Составлено много пар, каждая с одним элементом из левого списка и одной справа по порядку. Это также, случается, предполагаемый порядок вывода. Эта задача действительно требует от нас применения мультипликативной дистрибутивности, поскольку нас просят не обрабатывать результат после этого.
Пары в каждой паре представляют термины, которые мы хотим умножить, причем первый элемент является коэффициентом, а второй - показателем степени. Чтобы умножить слагаемые, мы умножим коэффициенты и сложим экспоненты вместе (хсб хd= а б хсИксd= а б ( хсИксd) = ( а б ) хс + д). Как мы это делаем? Давайте разберемся со второй парой,[[6, 2], [-2, 3]]
.
Сначала мы транспонируем пару:
[[6, -2], [2, 3]]
Затем мы берем произведение первой пары и сумму второй:
[-12, 5]
Соответствующая часть кода, PSƭ€
самом деле не сбрасывает свой счетчик для каждой пары терминов, но, поскольку они являются парами, в этом нет необходимости.
Обрабатывая все пары терминов, мы имеем:
[[6, 4], [-12, 5], [7, 3], [-14, 4], [-2, 2], [4, 3]]
Здесь умножение сделано, так как нам не нужно объединять одинаковые термины. Последняя процедура - Prettyfying.
Сначала мы присоединяемся к каждой паре с "x^"
:
[[6, 'x', '^', 4], [-12, 'x', '^', 5], [7, 'x', '^', 3], [-14, 'x', '^', 4], [-2, 'x', '^', 2], [4, 'x', '^', 3]]
Затем мы присоединяемся к списку " + "
:
[6, 'x', '^', 4, ' ', '+', ' ', -12, 'x', '^', 5, ' ', '+', ' ', 7, 'x', '^', 3, ' ', '+', ' ', -14, 'x', '^', 4, ' ', '+', ' ', -2, 'x', '^', 2, ' ', '+', ' ', 4, 'x', '^', 3]
Обратите внимание, что у нас все еще есть числа в списке, так что на самом деле это не строка. Тем не менее, в Jelly есть процесс, называемый «stringification», запускаемый прямо в конце выполнения программы для вывода результата. Для списка глубины 1 он просто конвертирует каждый элемент в его строковое представление и объединяет строки вместе, поэтому мы получаем желаемый результат:
6x^4 + -12x^5 + 7x^3 + -14x^4 + -2x^2 + 4x^3