Streszczenie wykonawcze
Biorąc pod uwagę dane wejściowe reprezentujące dwa wektory i ich odpowiednie „wagi”, uzyskaj dane wyjściowe, które reprezentują również ważoną sumę tych wektorów.
Wyzwanie
Dane wejściowe będą się składać z co najmniej jednego wiersza następujących znaków:
- dokładnie jedno wystąpienie cyfry 0, która reprezentuje początek w płaszczyźnie dwuwymiarowej;
- dokładnie dwie inne cyfry (1-9; mogą, ale nie muszą być tą samą cyfrą), których pozycje w stosunku do źródła reprezentują wektory, a których wartości reprezentują wagi przypisane do tych wektorów;
- pewna liczba „znaków tła”. Solver może wybrać konkretny znak tła; na przykład wybiorę „.” (głównie dla czytelności dla ludzi). Alternatywnie, znakami tła mogą być cokolwiek, co wygląda jak puste miejsce.
(Solver może wybrać, czy wejście jest pojedynczym ciągiem wieloliniowym, czy tablicą ciągów jednowierszowych.)
Na przykład dane wejściowe
....2
.0...
...3.
reprezentuje wektor o współrzędnych (3,1) o wadze 2 i wektor o współrzędnych (2, -1) o wadze 3.
Dane wyjściowe powinny być prawie takie same jak dane wejściowe, z następującymi zmianami:
- „znak wyniku” wybrany przez solver, który ma zostać dodany w pozycji określonej przez ważoną sumę wektorów wejściowych (równoważnie w pozycji, która jest odpowiednią liniową kombinacją wektorów wejściowych);
- tyle znaków tła, ile potrzeba, aby dopasować początek, dwa wektory wejściowe i wektor wyjściowy na tym samym obrazie. W razie potrzeby można dołączyć dodatkowe znaki tła; jedynym ograniczeniem jest to, że jeśli znak tła jest znakiem widocznym, wówczas cały wynik musi mieć kształt prostokątny, a każdy znak nie reprezentujący wektora musi być znakiem tła. (Jeśli jako znaki tła używane jest puste miejsce, ograniczenia te nie muszą być egzekwowane.)
(Na ogół, jeśli mamy jeden wektor (v, w) o wadze a i drugi wektor (x, y) o wadze b, ich ważona suma to a (v, w) + b (x, y) = (av + bx, aw + by).)
W poprzednim przykładzie odpowiednią kombinacją liniową jest 2 * (3,1) + 3 * (2, -1) = (12, -1). Jeśli użyjemy „X” jako znaku wynikowego, wynik może wyglądać następująco
....2.........
.0............
...3.........X
lub
................
...2............
0...............
..3.........X...
................
................
Zwykle punktowanie w golfa : wygrywa najkrótsza odpowiedź w bajtach.
Przykładowe wejście i wyjście
Jeśli zostanie użyte puste miejsce, powyższe dane wejściowe będą wyglądać
2
0
3
i wyglądałby wynik
2
0
3 X
Wiodące / końcowe białe znaki / linie są nieistotne; jeśli są niewidoczne dla czytelnika, jest w porządku. (Biorąc to pod uwagę, w pozostałych przykładach wrócę do używania „.” Jako znaku tła, aby ułatwić czytanie.)
Jeśli oba wektory mają wagę 1, wynik będzie wyglądał jak równoległobok: dane wejściowe
.1.
...
1.0
prowadzi do wyjścia
X.1.
....
.1.0
Zauważ, że ten równoległobok może zostać zdegenerowany, jeśli wektory wejściowe są współliniowe: wejście
0.1..1
prowadzi do wyjścia
0.1..1.X
Wektor wynikowy może być równy jednemu wektorowi wejściowemu lub źródłu; w takim przypadku po prostu nadpisuje znak wejściowy. Na przykład dane wejściowe
..2.0.1...
daje wynik
..X.0.1...
(w przypadku wejścia i / lub wyjścia można usunąć początkowe i końcowe okresy). Dane wejściowe
.....3
......
...0..
......
......
2.....
daje wynik
.....3
......
...X..
......
......
2.....
Wreszcie dane wejściowe
90
.8
daje wynik
........90
.........8
..........
..........
..........
..........
..........
..........
X.........
Odpowiedzi:
MATL , 48 bajtów
Znakiem tła jest spacja. Dane wejściowe to tablica znaków 2D z wierszami oddzielonymi średnikami. Tak więc przypadki testowe mają odpowiednie dane wejściowe:
Dane wyjściowe zawierają znaczną ilość białych znaków wypełniających.
Wypróbuj online!
źródło
Python 3,
374355 bajtówNiezbyt wyrafinowane rozwiązanie Pythona, które jest bardzo hojne z wypełnieniem (wykorzystuje maksymalną odległość od szachownicy). Dane wejściowe to pojedynczy wiersz, w którym wiersze są oddzielone rurami | (chociaż algorytm może z łatwością użyć wszystkiego, co nie jest alfanumeryczne, co nie jest znakiem nowej linii ani EOF). Wszystko inne niż alfanumeryczne lub | działa na dopełnienie wejściowe, dopełnienie wyjściowe wykorzystuje kropki. Doceniamy opinie i ulepszenia od bardziej doświadczonych golfistów python.
Edycja: Kilka ulepszeń dzięki @TheBikingViking. Dodałem także jeszcze więcej marginesów, ponieważ nie byłem dość hojny z paddingiem.
źródło
[a,b][condition]
zamiastb if condition else c
w wierszu 2.sorted
bierze dowolny iterator, w tym instrukcję generatora, więc możesz upuścić zewnętrzną parę nawiasów kwadratowych. 3.zip(p)
powinien działać zamiastp[0] for p in P
.P+=[stuff]
zamiastP.append([stuff])
w linii 7. 5. Zrób["."]
zamiastlist(".")
. (3. powinno byćzip(p)[0]
.)P
wzip
.S=[stuff]*2*L
na linii 10.index
(błąd nie został znaleziony). Będzie jednak działaćfind
. [Re. posortowane] Dziękujemy, przegapiłem ich usunięcie podczas dodawaniasorted
. [3] zip (* P) [0] nie działa w Pythonie 3 (obiekt zip nie jest indeksowany). [4] P + = [rzeczy] nie będzie działać, chociaż P + = [[rzeczy]] zadziała. [5] Dziękuję. [pozostałe 5] Nie działa. Potrzebuję nowych list, a nie referencji.JavaScript,
534528502 bajtówPamiętaj, że wypełnienie jest optymalne. Ten program zakłada, że i zawiera nieprzetworzony ciąg znaków, z wierszami oddzielonymi
\n
znakami. Wypełnianie odbywa się spacjami, a wynikowy znak jest małymi literamix
.To moja pierwsza próba gry w golfa.
Techniczne rzeczy: - Rozmiar programu z grubsza podwoił się (a jego złożoność dramatycznie wzrosła), aby wziąć pod uwagę wynikowy wynik, głównie dlatego, że ciągi JavaScript są niezmienne.
Objaśnienie linia po linii:
Często ich używam, więc przechowywanie ich w sznurkach pozwoliło mi zaoszczędzić trochę miejsca. Możesz zobaczyć poniżej, że dla
split
funkcji po prostu utworzyłem alias; to dlatego, że potrzebowałem tylko jednego argumentu, drugi był stały. DlaindexOf
ijoin
, byłoby jednak być dłuższy.Nic skomplikowanego, czytam szerokość i wysokość początkowej tablicy. Zwróć uwagę na użycie,
i[n]
aby uzyskać dostępindexOf
, podczas gdysplit
jest obsługiwane inaczej.To robi się interesujące. Ta funkcja w zasadzie tworzy konkatenaty J-1 razy łańcuch X i zwraca go. Służy do generowania ciągów odstępów dla wypełnienia.
Ta tablica będzie zawierać liczbę linii i kolumn dodanych przez wypełnienie (w pierwszym przypadku wyłączone przez współczynnik h). Ostatnia komórka jest śmieciowa i nie pozwala mi na dodatkowy argument w funkcji poniżej.
Ta funkcja sama obsługuje dopełnienie (zarówno linie, jak i kolumny); określa, w oparciu o współrzędną wektora wynikowego (X) i liczbę linii / kolumn do wygenerowania (E), czy konieczne jest jego utworzenie.
X+E+1+T
to tylko podstęp, aby zaoszczędzić trochę miejsca,U
to ciąg napełniania (przestrzeń dla kolumn, a cała linia do linii), i będziemy wracać doR
. Ta funkcja zasadniczo zwraca, w przypadku linii, wypełnienie wymagane na początku lub na końcu wspomnianej linii, a w przypadku kolumny zwraca wymagane linie wypełnienia przed lub po oryginalnych liniach.Tutaj czytamy pozycję początku i pobieramy jego współrzędne. L to funkcja służąca do konwersji indeksu na numer linii.
Dodałem trochę białych znaków, aby ułatwić czytanie. Tutaj dzieje się tak, że dla każdej możliwej liczby szukamy jej w oryginalnym ciągu. Ta
~
sztuczka jest stosunkowo powszechna w Javascript; jest to bitowy operator NOT, ale najważniejsze jest tutaj to~-1==0
, co pozwala mi przetestować koniec pętli. Następnie usuwam znak z łańcucha (dlatego zrobiłem kopię), co pozwala mi kontynuować wyszukiwanie tak długo, jak to konieczne. Następnie dodaję współrzędne wektora(x, y)
, używając prostej odejmowania.Tutaj podzieliłem oryginalny ciąg na linie i dla każdej linii wywołuję,
G
która wygeneruje dopełnienie przed i po liniach.l-w+2
I tak dalej pochodzą z prostego obliczenia indeksu, który pozwala mi sprawdzić, czy muszę dodać dopełnienie czy nie. Na przykład, jeślix>0
ix+l-w+1>0
, to(x+l-w+1)+1
po wierszu należy dodać spacje.+x
Jest usuwany ze względu na to jest pierwszy parametr iX+E+1+T
stosowane w definicjiG
.Podobna czynność dotyczy pierwszych znaków, a następnie kolumn. Jest tu wiele faktoryzacji, które pozwalają mi korzystać tylko z jednej funkcji. Zanotuj ostatni parametr; w pierwszym przypadku chcę napisać, aby
C[0]
móc później dowiedzieć się, ile kolumn dodałem na początku każdej linii; pozwala mi to uzyskać ostateczną pozycję postaci wynikowej. Nie dbam jednak o kolumny dodane po oryginalnym wierszu, dlatego drugie wezwanie doG
zapisu do niepotrzebnej komórkiC[2]
jest nieużywane.Tutaj po prostu czytam nową długość linii i tworzę z niej linię spacji. Zostanie to wykorzystane do utworzenia pionowego wypełnienia.
Jest to dokładnie to samo, co dwie linie powyżej. Jedyną różnicą jest pisanie do
C[1]
tego czasu i używanie separatorówN+O
iO+N
. Pamiętaj, żeO
to nowa linia iN
linia spacji. Następnie aplikujęB
na wynik, aby go ponownie podzielić (muszę edytować wiersz zawierający znak wynikowy, aby go edytować).Jest to indeks pionowy wynikowego znaku.
Tutaj jestem zmuszony zmodyfikować,
O
aby móc podzielić odpowiednią linię na tablicę znaków. Jest tak, ponieważ ciągi JavaScript są niezmienne; jedynym sposobem edycji łańcucha jest przekonwertowanie go na tablicę (co tutaj robię), edycja we właściwej pozycji i ponowne dołączenie łańcucha. Zwróć także uwagę nah
współczynnik, ponieważG
funkcja została wywołana raz na linię początkową.W końcu zastępuję nowy ciąg w tablicy i łączę go ponownie w ciąg. Łał!
źródło