Retina , 53 43 42 41 40 35 bajtów
^[^x]+ |(\^1)?\w(?=1*x.(1+)| |$)
$2
Dla celów zliczania każda linia przechodzi w osobny plik, ale możesz uruchomić powyższy jako pojedynczy plik, wywołując Retina z -s
flagą.
Oczekuje to, że liczby w ciągu wejściowym zostaną podane pojedynczo i da wynik w tym samym formacie. Na przykład
1 + 11x + -111x^11 + 11x^111 + -1x^11111
-->
11 + -111111x + 111111x^11 + -11111x^1111
zamiast
1 + 2x + -3x^2 + 2x^3 + -1x^5
-->
2 + -6x + 6x^2 + -5x^4
Wyjaśnienie
Kod opisuje pojedyncze podstawienie wyrażenia regularnego, które zasadniczo składa się z 4 podstawień skompresowanych w jedno. Zauważ, że tylko jedna z gałęzi zapełni grupę, $2
więc jeśli którykolwiek z pozostałych trzech pasujących elementów, dopasowanie zostanie po prostu usunięte z łańcucha. Możemy więc spojrzeć osobno na cztery różne przypadki:
^[^x]+<space>
<empty>
Jeśli możliwe jest dotarcie do spacji od początku łańcucha bez napotkania znaku x
, oznacza to, że pierwszy termin jest terminem stałym i usuwamy go. Ze względu na chciwość +
, będzie to również pasować do plus i drugiej spacji po stałym terminie. Jeśli nie ma stałego terminu, ta część po prostu nigdy nie będzie pasować.
x(?= )
<empty>
Dopasowuje to, po x
którym następuje spacja, tj. x
Terminu liniowego (jeśli istnieje), i usuwa go. Możemy być pewni, że jest po nim spacja, ponieważ stopień wielomianu wynosi zawsze co najmniej 2.
1(?=1*x.(1+))
$1
Wykonuje to pomnożenie współczynnika przez wykładnik. Odpowiada to pojedynczej 1
wartości współczynnika i zastępuje ją przez cały odpowiedni wykładnik za pośrednictwem lookahead.
(\^1)?1(?= |$)
<empty>
Zmniejsza to wszystkie pozostałe wykładniki, dopasowując końcowe 1
(zapewnione przez lookahead). Jeśli możliwe jest dopasowanie ^11
(i granicy słów), usuwamy to, co dba o prawidłowe wyświetlanie terminu liniowego.
W przypadku kompresji zauważamy, że większość warunków nie ma na siebie wpływu. (\^1)?
nie będzie pasować, jeśli spojrzenie w trzecim przypadku jest prawdziwe, więc możemy połączyć te dwa razem jako
(\^1)?1(?=1*x.(1+)| |$)
$2
Teraz mamy już uprzedzona potrzebne do drugiej sprawy i inni nigdy nie może być prawdą podczas dopasowywania x
, dzięki czemu możemy łatwo uogólnić 1
Do \w
:
(\^1)?\w(?=1*x.(1+)| |$)
$2
Pierwszy przypadek tak naprawdę nie ma nic wspólnego z innymi, dlatego trzymamy go oddzielnie.