Różnicowanie symboliczne 1: Przeminęło Coefishin '
Zadanie
Napisz program, który pobiera wielomian w x od stdin (1 <deg (p) <128) i różnicuje go. Wielomian wejściowy będzie ciągiem następującej postaci:
"a + bx + cx^2 + dx^3 +" ...
gdzie współczynnik każdego składnika jest liczbą całkowitą (-128 <a <128). Każdy termin jest oddzielony jedną spacją, znakiem + i inną spacją; warunki liniowe i stałe pojawiają się jak wyżej (tj. brak x^0
lub x^1
). Warunki pojawią się w kolejności rosnącego stopnia, a moce o zerowym współczynniku zostaną pominięte. Wszystkie terminy ze współczynnikiem 1 lub -1 wyświetlają ten współczynnik jawnie.
Twój wynik musi mieć dokładnie taką samą formę. Zauważ, że współczynniki na wyjściu mogą być tak duże, jak 127 * 127 == 16129.
Przykłady
"3 + 1x + 2x^2" ==> "1 + 4x"
"1 + 2x + -3x^2 + 17x^17 + -1x^107" ==> "2 + -6x + 289x^16 + -107x^106"
"17x + 1x^2" ==> "17 + 2x"
Punktacja
Twój wynik to długość twojego programu w bajtach, pomnożona przez trzy, jeśli używasz wbudowanej lub biblioteki, która wykonuje algebrę symboliczną.
Odpowiedzi:
Retina ,
534342414035 bajtówDla 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
zamiast
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: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ć.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.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.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 jakoTeraz 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
:Pierwszy przypadek tak naprawdę nie ma nic wspólnego z innymi, dlatego trzymamy go oddzielnie.
źródło
CJam,
4341 bajtówDzięki @ jimmy23013 za wskazanie jednego błędu i odgranie dwóch bajtów!
Wypróbuj online w interpretatorze CJam .
Jak to działa
źródło
Perl,
6463 bajtówKod 62b + 1 linia poleceń (-p)
W tej chwili nie jest to niesamowite, ale nadal będę starał się to skracać.
Przykład użycia:
Dzięki Denis za -1b
źródło
Julia, 220 bajtów
Bez wyrażeń regularnych!
Tworzy to funkcję lambda, która przyjmuje ciąg i zwraca ciąg. Wewnętrzne naśladują to, co dzieje się, gdy analizowany jest kod Julii: ciąg jest przetwarzany na symbole, wyrażenia i wywołania. Mogę spróbować napisać pełną funkcję różnicowania symbolicznego Julii i zgłosić ją jako część Julii.
Niegolfowane + wyjaśnienie:
źródło
C,
204162 bajtyZasadniczo przeanalizuj każdy termin i wydrukuj zróżnicowany termin po kolei. Dość bezpośredni.
źródło
JavaScript ES6, 108 bajtów
Fragment kodu ES5:
źródło
Python 2, 166 bajtów
Chłopcze, wydaje się to dłuższe niż powinno.
Funkcja
d
przyjmuje nietrwały składnikt
i zwraca jego pochodną. Powodem, dla którego jadef
zamiast funkcji lambda jest to, że mogę przypisać wykładnik minus 1 doe
, który następnie jest używany cztery razy. Główną irytującą rzeczą jest konieczność rzucania tam i z powrotem między ciągami znaków i ints, chociaż pomaga w tym operator wsteczny Python 2.Następnie dzielimy dane wejściowe na terminy i wzywamy
d
każdego z nich"x"
, co eliminuje stały składnik. Wyniki są ponownie łączone i drukowane.źródło
CJam,
62575549 bajtówDennis wstydził się tego, zanim jeszcze zauważyłem, że strona została ponownie uruchomiona. Ale oto moje dzieło:
Najnowsza wersja zapisuje kilka bajtów ze skrótami sugerowanymi przez @Dennis (używaj zmiennych i rozdzielaj spacje zamiast
+
).Wypróbuj online
źródło
_({'^a\}{;}?
jest o 1 bajt dłuższy niż:T({T'^a\}&
.~
bloku w pozostałym bloku i możesz go również wyeliminować.x
. Znalazłem kilka ulepszeń, gdy byłem przy tym. Głównie, ponieważ mam teraz wartości w zmiennych, mogę je przywołać tam, gdzie naprawdę ich potrzebuję, oszczędzając trochę manipulacji stosami. Miałem też błąd,a
który powinien był zostać usunięty, gdy wcześniej zoptymalizowałem generowanie danych wyjściowych.Pyth, 62 bajty
Całkiem brzydkie rozwiązanie, wykorzystujące pewne podstawienia wyrażeń regularnych.
źródło
Python 3, 176 bajtów
Rzeczywiście, główną irytacją jest konieczność konwersji między ciągami znaków i ints. Ponadto, jeśli wymagany byłby stały termin, kod miałby tylko 153 bajty.
źródło
Python 2, 229 bajtów
źródło
Python 2, 174 bajty
Niestety sztuczka DLosc polegająca na zmianie nazwy metody podziału i wykonaniu różnicowania w określonej funkcji nie skraca mojego kodu ...
źródło