Twoim zadaniem jest pobranie dwóch wielomianowych wyrażeń całkowitych z jedną zmienną i pomnożenie ich do ich nieskomplikowanego rozszerzenia od lewej do prawej w pierwszym semestrze (AKA FOIL w przypadku dwumianów). Nie łącz podobnych terminów ani nie zmieniaj kolejności wyników. Aby być bardziej precyzyjnym na temat rozwinięcia, pomnóż pierwszy wyraz w pierwszym wyrażeniu przez każdy wyraz w drugim, w kolejności, i kontynuuj w pierwszym wyrażeniu, aż wszystkie wyrażenia zostaną pomnożone przez wszystkie pozostałe wyrażenia. Wyrażenia zostaną podane w uproszczonym wariancie LaTeX.
Każde wyrażenie będzie sekwencją terminów oddzielonych +
(z dokładnie jedną spacją po każdej stronie). Każde wyrażenie będzie zgodne z następującym wyrażeniem regularnym: (notacja PCRE)
-?\d+x\^\d+
W prostym języku angielskim termin jest opcjonalnym początkiem, -
po którym następuje jedna lub więcej cyfr, a następnie x
nieujemna moc całkowita (z ^
)
Przykład pełnego wyrażenia:
6x^3 + 1337x^2 + -4x^1 + 2x^0
Po podłączeniu do LaTeX otrzymujesz
Dane wyjściowe powinny również być zgodne z tym formatem.
Ponieważ nawiasy nie otaczają wykładników w tym formacie, LaTeX faktycznie renderuje wykładniki wielocyfrowe niepoprawnie. (np. 4x^3 + -2x^14 + 54x^28 + -4x^5
renderuje jako ) Nie trzeba tego uwzględniać i nie należy umieszczać nawiasów w wynikach.
Przykładowe przypadki testowe
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
Zasady i założenia
- Możesz założyć, że wszystkie dane wejściowe są zgodne z tym dokładnie formatem. Zachowanie dla dowolnego innego formatu jest niezdefiniowane na potrzeby tego wyzwania.
- Należy zauważyć, że każda metoda pobierania dwóch wielomianów jest poprawna, pod warunkiem, że oba są odczytywane jako ciągi znaków zgodne z powyższym formatem.
- Kolejność wielomianów ma znaczenie ze względu na oczekiwaną kolejność rozszerzenia produktu.
- Musisz obsługiwać współczynniki wejściowe od do i wykładniki wejściowe do .
- W związku z tym należy wspierać współczynniki wyjściowe od do i wykładniki do .
- Możesz założyć, że każdy wielomian wejściowy zawiera nie więcej niż 16 terminów
- Dlatego musisz (przynajmniej) obsługiwać do 256 terminów w danych wyjściowych
- Terminy o zerowych współczynnikach należy pozostawić bez zmian, a wykładniki należy odpowiednio połączyć
- Ujemne zero jest dozwolone na wejściu, ale jest nie do odróżnienia semantycznie od zera dodatniego. Zawsze wyprowadzaj dodatnie zero. Nie pomijaj zerowych terminów.
Wesołego golfa! Powodzenia!
Odpowiedzi:
R ,
159153148 bajtówWypróbuj online!
Naprawdę chciałem użyć
outer
, więc prawie na pewno jest bardziej wydajne podejście.źródło
Haskell ,
131122 bajtówWypróbuj online!
f
analizuje wielomian z ciągu,!
mnoży dwa z nich i formatuje wynik.H.PWiz zapisał 9 bajtów. Dzięki!
Nie golfił
źródło
Rubin ,
102 10098 bajtówWypróbuj online!
W jaki sposób?
Pierwszy krok: pobierz wszystkie liczby z obu wielomianów:
scan
zwraca liczby jako tablicę par ciągów. Następnie zrób kartezjański produkt z 2 list. Teraz mamy wszystkie liczby, w których ich potrzebujemy, ale nadal w niewłaściwej kolejności.Przykład: jeśli pomnożymy
3x^4
przez-5x^2
, otrzymamy liczby jako[["3","4"],["-5","2"]]
, pierwszym pomysłem było skompresowanie i spłaszczenie tej listy, a następnie umieszczenie liczb w wyrażeniu, które będzie oceniane jako[3*-5, 4+2]
. W rzeczywistości nie musimy zmieniać kolejności liczb, moglibyśmy to zrobić w wyrażeniu za pomocą zmiennej tymczasowej: wyrażenie staje się[3*(z=4,-5),z+2]
.Po ocenie tych wyrażeń otrzymujemy współczynnik i wykładnik, musimy połączyć je za pomocą
"x^"
, a następnie połączyć wszystkie tem za pomocą"+"
.źródło
Haskell,
124121 bajtówUwaga: brakuje TIO
Data.Lists
, więc importujęData.Lists.Split
iData.List
: Wypróbuj online!Edycja: -3 bajty dzięki @Lynn.
źródło
f!x=map f.splitOn x
a następniez=read!"x^"!"+"
zapisuje bajt; do ostatniego wierszadrop 3$do[u,v]<-z a;[p,q]<-z b;" + "++shows(u*p)"x^"++show(v+q)
zapisuje dwa kolejne. 120 bajtówData.List
zamiast tego importuje się wersja TIOData.Lists
, więc ma +1 bajt.Pyth - 39 bajtów
Wypróbuj online .
źródło
JavaScript (węzeł Babel) , 118 bajtów
Pobiera dane wejściowe jako
(a)(b)
.Wypróbuj online!
źródło
Python 2 , 193 bajtów
Wypróbuj online!
Uwaga dodatkowa: po raz pierwszy wykonuję wyzwanie w golfa kodem, więc przepraszam, jeśli próba jest do bani
źródło
re.finditer
może nie być najkrótszym podejściemSiatkówka , 110 bajtów
Wypróbuj online! Wyjaśnienie:
Przed każdym terminem na pierwszym wejściu wpisz prefiks
#
, kopię drugiego wejścia i spację. Oznacza to, że wszystkie warunki w kopiach drugiego wejścia są poprzedzone spacją i żaden z terminów z pierwszego wejścia nie jest.Dopasuj wszystkie kopie terminów z drugiego wejścia i odpowiadający im termin z pierwszego wejścia. Połącz wszystkie
-
znaki, pomnóż współczynniki i dodaj wskaźniki. Na koniec połącz wszystkie powstałe podstawienia z łańcuchem+
.Usuń wszystkie pary
-
si przekonwertuj-0
na0
.źródło
SNOBOL4 (CSNOBOL4) ,
192176 bajtówWypróbuj online!
źródło
Perl 6 , 114 bajtów
Wypróbuj online!
źródło
Python 2 , 130 bajtów
Wypróbuj online!
źródło
C # (interaktywny kompilator Visual C #) ,
192190 bajtówSkładnia zapytania wydaje się być bajtem krótszym niż składnia metody.
Wypróbuj online!
źródło
Galaretka , 28 bajtów
Wypróbuj online!
Pełny program Traktuje dwa wielomiany jako listę dwóch ciągów.
Wyjaśnienie (forma rozszerzona)
Aliasing
)
jest taki sam jakµ€
.Końcowe
”
jest implikowane i można je pominąć.Algorytm
Powiedzmy, że mamy następujące dane wejściowe:
Pierwszą procedurą jest analiza składniowa, zastosowana do każdego z dwóch wielomianów. Zajmijmy się pierwszym
"6x^2 + 7x^1 + -2x^0"
:Pierwszym krokiem jest podzielenie łańcucha
'+'
, aby oddzielić warunki. To skutkuje:Następnym krokiem jest podzielenie każdego łańcucha
'x'
, aby oddzielić współczynnik od wykładnika. Rezultat jest następujący:Obecnie wygląda na to, że w tych ciągach jest dużo śmieci, ale śmieci te są w rzeczywistości nieistotne. Wszystkie te ciągi będą oceniane jako niladowe ogniwa galaretowe. Trywialnie, spacje są nieistotne, ponieważ nie znajdują się między cyframi liczb. Więc moglibyśmy równie dobrze ocenić poniższe i nadal uzyskać ten sam wynik:
Do0 XOR 2 = 2 . Oczywiście,0 XOR n = n . Wszystkie wykładniki są liczbami całkowitymi, więc nic nam nie jest. Dlatego ocena tego zamiast powyższego nie zmieni wyniku:
^
s wyglądać nieco bardziej niepokojące, ale w rzeczywistości nic nie robić albo! Cóż,^
jest bitowym atomem XOR, jednak łańcuchy niladyczne działają jak łącza monadyczne, z tym wyjątkiem, że pierwsze łącze faktycznie staje się argumentem, zamiast brać argument, jeśli jest ono zerowe. Jeśli nie, link będzie miał argument0
. Wykładniki mają^
s jako swój pierwszy znak i^
nie są niladyczne, więc zakłada się, że argument jest taki0
. Reszta ciągu, tj. Liczba, jest właściwym argumentem^
. Tak na przykład^2
jestNo to ruszamy:
Ten krok zostanie również przekonwertowany
"-0"
na0
.Ponieważ analizujemy oba dane wejściowe, wynik po analizie będzie następujący:
Analiza jest teraz zakończona. Następną procedurą jest mnożenie.
Najpierw bierzemy produkt kartezjański z tych dwóch list:
Powstaje wiele par, każda z jednym elementem z lewej listy i jedną z prawej, w kolejności. Jest to również zamierzona kolejność danych wyjściowych. To wyzwanie naprawdę wymaga od nas zastosowania multiplikatywnej dystrybucji, ponieważ jesteśmy proszeni o dalsze przetwarzanie wyniku po tym.
Pary w każdej parze reprezentują warunki, które chcemy pomnożyć, przy czym pierwszy element jest współczynnikiem, a drugi wykładnikiem. Aby pomnożyć warunki, mnożymy współczynniki i dodajemy wykładniki razem (xdob xre= a b xdoxre= a b ( xdoxre) = ( a b ) xc + d ). Jak to zrobimy? Powiedzmy sobie drugą parę,
[[6, 2], [-2, 3]]
.Najpierw transponujemy parę:
Następnie bierzemy iloczyn pierwszej pary i sumę drugiej:
Odpowiednia część kodu,
PSƭ€
tak naprawdę, nie resetuje swojego licznika dla każdej pary terminów, ale ponieważ są to pary, nie musi.Obsługując wszystkie pary warunków, mamy:
Tutaj mnożenie odbywa się, ponieważ nie musimy łączyć podobnych terminów. Ostatnią procedurą jest Całowanie.
Najpierw łączymy każdą parę z
"x^"
:Następnie dołączamy do listy
" + "
:Zauważ, że wciąż mamy liczby na liście, więc tak naprawdę nie jest to ciąg znaków. Jednak Jelly ma proces zwany „strucyfikacją”, uruchamiany zaraz po zakończeniu programu do wydrukowania wyniku. Aby uzyskać listę głębokości 1, tak naprawdę po prostu konwertuje każdy element na jego reprezentację ciągu i konkatenuje ciągi razem, więc otrzymujemy pożądany wynik:
źródło
JavaScript,
112110 bajtówZnalazłem dwie alternatywy o tej samej długości. Wywołanie ze składnią curry:
f(A)(B)
Pokaż fragment kodu
Pokaż fragment kodu
-2 bajty ( Luis ): Usuń spacje wokół
split
ogranicznika.JavaScript, 112 bajtów
Korzystanie
String.prototype.matchAll
.Pokaż fragment kodu
źródło
split' + ' => split'+'
zaoszczędzić 2 bajtyjoin
.