Czynnością, którą czasami robię, gdy się nudzę, jest pisanie kilku znaków w pasujących parach. Następnie rysuję linie (ponad szczytami nigdy poniżej), aby połączyć te postacie. Na przykład mógłbym napisać a następnie narysować linie jako:
Albo mógłbym napisać
Po narysowaniu tych linii próbuję narysować zamknięte pętle wokół kawałków, aby moja pętla nie przecięła żadnej z linii, które właśnie narysowałem. Na przykład w pierwszej jedyną pętlą, którą możemy narysować, jest wokół całej rzeczy, ale w drugiej możemy narysować pętlę wokół tylko s (lub wszystkiego innego)
Jeśli zastanowimy się nad tym przez chwilę, okaże się, że niektóre ciągi znaków można narysować tylko po to, aby zamknięte pętle zawierały wszystkie litery lub żadną z nich (jak w naszym pierwszym przykładzie). Nazwiemy takie ciągi dobrze połączonymi ciągami.
Pamiętaj, że niektóre ciągi znaków można narysować na wiele sposobów. Na przykład można narysować na dwa następujące sposoby (i nie uwzględniono trzeciego):
Jeśli jeden z tych sposobów można narysować w taki sposób, że można utworzyć zamkniętą pętlę zawierającą niektóre znaki bez przecinania którejkolwiek linii, łańcuch nie jest dobrze połączony. (więc nie jest dobrze powiązane)
Zadanie
Twoim zadaniem jest napisanie programu identyfikującego dobrze powiązane ciągi. Twoje dane wejściowe będą składać się z łańcucha, w którym każdy znak pojawia się parzystą liczbę razy, a twój wynik powinien być jedną z dwóch różnych spójnych wartości, jedną, jeśli łańcuchy są dobrze połączone, a drugą w przeciwnym razie.
Ponadto program musi być dobrze połączony ciąg sens
Każda postać pojawia się w twoim programie parzystą liczbę razy.
Powinien generować prawdziwą wartość po przekazaniu.
Twój program powinien być w stanie wygenerować prawidłowe dane wyjściowe dla dowolnego łańcucha składającego się ze znaków z drukowalnego ASCII lub własnego programu. Każda postać pojawia się parzystą liczbę razy.
Odpowiedzi będą oceniane jako ich długości w bajtach, przy czym mniej bajtów jest lepszym wynikiem.
Wskazówka
Ciąg nie jest dobrze połączony, jeśli istnieje ciągły niepusty pusty podciąg, tak że każdy znak pojawia się w tym podciągu parzystą liczbę razy.
Przypadki testowe
abcbac -> True
abbcac -> False
bbbb -> False
abacbc -> True
abcbabcb -> True
abcbca -> False
źródło
abcbca -> False
.there
.Odpowiedzi:
Regex (ECMAScript 2018 lub .NET),
1401261181009882 bajtów^(?!(^.*)(.+)(.*$)(?<!^\2|^\1(?=(|(<?(|(?!\8).)*(\8|\3$){1}){2})*$).*(.)+\3$)!?=*)
Jest to znacznie wolniejsze niż wersja 98-bajtowa, ponieważ
^\1
lewa strona z wyprzedzeniem, a zatem jest oceniana po niej. Poniżej znajduje się prosty przełącznik, który odzyskuje prędkość. Ale z tego powodu dwa poniższe TIO są ograniczone do ukończenia mniejszego zestawu przypadków testowych niż wcześniej, a jeden .NET jest zbyt wolny, aby sprawdzić swój regex.Wypróbuj online! (ECMAScript 2018)
Wypróbuj online! (.NETTO)
Aby upuścić 18 bajtów (118 → 100), bezwstydnie ukradłem naprawdę fajną optymalizację z wyrażenia regularnego Neila, który pozwala uniknąć konieczności umieszczania spojrzenia w środku negatywnego spojrzenia (uzyskując 80 bajtów nieograniczonego wyrażenia regularnego). Dziękuję Neil!
Stało się to przestarzałe, kiedy zrzuciło niewiarygodne 16 dodatkowych bajtów (98 → 82) dzięki pomysłom jaytea , które doprowadziły do 69-bajtowego nieograniczonego wyrażenia regularnego! Jest znacznie wolniejszy, ale to golf!
Zauważ, że
(|(
brak operacji poprawienia powiązania wyrażenia regularnego powoduje, że ocenia on bardzo powoli w .NET. Nie mają tego efektu w ECMAScript, ponieważ opcjonalne dopasowania o zerowej szerokości są traktowane jako niepasujące .ECMAScript zabrania kwantyfikatorów w odniesieniu do asercji, co utrudnia grę w golfa w ograniczonych źródłach . Jednak w tym momencie gra jest tak dobrze golfa, że nie sądzę, aby zniesienie tego konkretnego ograniczenia otworzyło dalsze możliwości gry w golfa.
Bez dodatkowych znaków potrzebnych do przejścia przez ograniczenia (
10169 bajtów):^(?!(.*)(.+)(.*$)(?<!^\2|^\1(?=((((?!\8).)*(\8|\3$)){2})*$).*(.)+\3))
Jest powolny, ale ta prosta edycja (tylko 2 dodatkowe bajty) odzyskuje utraconą prędkość i więcej:
^(?!(.*)(.+)(.*$)(?<!^\2|(?=\1((((?!\8).)*(\8|\3$)){2})*$)^\1.*(.)+\3))
Napisałem go za pomocą molekularnego lookahead (
10369 bajtów) przed przekształceniem go w look-look o zmiennej długości:^(?!.*(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$))
Aby pomóc w poprawnym powiązaniu mojego wyrażenia regularnego, użyłem odmiany powyższego wyrażenia regularnego:
(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$)\1
W połączeniu z
regex -xml,rs -o
tym identyfikuje ścisły podciąg wejściowy, który zawiera parzystą liczbę każdego znaku (jeśli taki istnieje). Jasne, mógłbym napisać program, który nie robi wyrażeń regularnych, aby to dla mnie zrobić, ale gdzie byłaby w tym zabawa?źródło
Galaretka, 20 bajtów
Wypróbuj online!
Pierwszy wiersz jest ignorowany. Ma tylko spełnić warunek, że każda postać pojawia się parzysta liczba razy.
Następny wiersz najpierw
Ġ
roups indeksy według ich wartości. Jeśli następnie weźmiemy długość każdej podlisty na wynikowej liście (Ẉ
), otrzymamy liczbę wyświetleń każdego znaku. Aby sprawdzić, czy którykolwiek z nich nie jest parzysty, otrzymujemy ostatniḂ
wynik z każdej liczby i pytamy, czy istniejeẸ
Xist prawdziwa (niezerowa) wartość.Dlatego to łącze pomocnicze zwraca informację, czy podciąg nie może zostać zakreślony.
W głównym łączu bierzemy wszystkie podłańcuchy input (
Ẇ
),Ṗ
op wyłączamy ostatni (abyśmy nie sprawdzali, czy cały ciąg może zostać zakreślony) i uruchamiamy link pomocniczy (Ç
) na€
dowolnym podciągu. Rezultatem jest wtedy, czyẠ
podciągów 11 nie można zakreślić.źródło
J , 34 bajty
Wypróbuj online!
-8 bajtów dzięki FrownyFrog
oryginał
J , 42 bajty
Wypróbuj online!
wyjaśnienie
źródło
abc
, tylko wpis Perla nie „zawiedzie” go. (Ma jednak inne problemy.)1:@':.,02|~*'=1(#.,)*/@(0=2|#/.~)\.\
2:@':.,|~*'>1(#.,)*/@(1>2|#/.~)\.\
wydaje się również ważnyPython 3.8 (wersja wstępna) , 66 bajtów
Wypróbuj online!
Era wyrażeń przydziału jest już nad nami. Z PEP 572 zawartym w Pythonie 3.8 gra w golfa nigdy nie będzie taka sama. Można zainstalować wcześniejszą developer preview 3.8.0a1 tutaj .
Wyrażenia przypisania pozwalają
:=
na przypisanie do zmiennej wbudowanej podczas obliczania tej wartości. Na przykład(a:=2, a+1)
daje(2, 3)
. Można to oczywiście wykorzystać do przechowywania zmiennych do ponownego użycia, ale tutaj idziemy o krok dalej i używamy go jako akumulatora w zrozumieniu.Na przykład ten kod oblicza sumy skumulowane
[1, 3, 6]
Zwróć uwagę, że przy każdym przejściu przez zrozumienie listy skumulowana suma
t
jest zwiększana o,x
a nowa wartość jest zapisywana na liście utworzonej przez zrozumienie.Podobnie
b:=b^{c}
aktualizuje zestaw znaków,b
aby przełączać, czy zawiera on znakc
, i ocenia nową wartośćb
. Więc, kod[b:=b^{c}for c in l]
iteruje znakówc
wl
i gromadzi zbiór znaków widoczny nieparzystą liczbę razy w każdym niepustym przedrostkiem.Ta lista jest sprawdzana pod kątem duplikatów, czyniąc ją zrozumieniem zestawu i sprawdzając, czy jej długość jest mniejsza niż
s
, co oznacza, że niektóre powtórzenia zostały zwinięte. Jeśli tak, powtórzenie oznacza, że w częścis
widzianej pomiędzy tymi czasami każdy znak napotkał parzystą liczbę liczb, co powoduje, że łańcuch nie jest dobrze powiązany. Python nie zezwala na to, aby zestawy zestawów były niehashowalne, więc zestawy wewnętrzne są konwertowane na ciągi.Zestaw
b
jest inicjowany jako opcjonalne argumenty i pomyślnie modyfikowany w zakresie funkcji. Martwiłem się, że to uniemożliwi ponowne użycie funkcji, ale wydaje się, że resetuje się między kolejnymi uruchomieniami.W celu ograniczenia źródła nieparzyste znaki są umieszczane w komentarzu na końcu. Pisanie
for(c)in l
zamiastfor c in l
anulować dodatkowe pareny za darmo. Wstawiamyid
do początkowego zestawub
, który jest nieszkodliwy, ponieważ można go uruchomić jako dowolny zestaw, ale pustego zestawu nie można zapisać,{}
ponieważ Python utworzy pusty słownik. Ponieważ literyi
id
należą do tych, które wymagają parowania, możemy umieścićid
tam funkcję .Zauważ, że kod wypisuje zanegowane wartości logiczne, więc poprawnie się da
False
.źródło
Python 2 , 74 bajty
Wypróbuj online!
Iteruje przez ciąg znaków, śledząc
P
zestaw znaków widzianych do tej pory nieparzystą liczbę razy. Listad
przechowuje wszystkie poprzednie wartościP
, a jeśli widziszP
już obecnyd
, oznacza to, że w postaciach widzianych od tego czasu, każda postać pojawiła się parzystą liczbę razy. Jeśli tak, sprawdź, czy przeszliśmy przez cały sygnał wejściowy: jeśli tak, zaakceptuj, ponieważ cały ciąg jest sparowany zgodnie z oczekiwaniami, a w przeciwnym razie odrzuć.Teraz o ograniczeniach źródłowych. Postacie wymagające parowania są umieszczane w różnych nieszkodliwych miejscach, co podkreślono poniżej:
W
f<s
Zwraca0
podczas parowania akcjęf
, korzystając z nazwa funkcji jest teżf
tak, że to określone (przez czas funkcja jest wywoływana.) Do0^0
wchłania się^
symbol.0
WP={0}
to niefortunne: w Pythonie{}
Wynikiem jest pusty dict zamiast pustego zestawu jak chcemy, a tutaj możemy umieścić w dowolnym elemencie bez znaków i będzie to nieszkodliwe. Nie widzę jednak nic do dodania, włożyłem0
i zduplikowałembmn0
, co kosztuje 2 bajty. Zauważ, że początkowe argumenty są oceniane, gdy funkcja jest zdefiniowana, więc zmiennych, które sami definiujemy, nie można wstawić tutaj.źródło
Perl 6 , 76 bajtów
Wypróbuj online!
Cokolwiek lambda, które zwraca None Junction of None Junction, które można podwyższyć do wartości true / falsey.
?
Zalecałbym jednak nie usuwać tego, który zwiększa wynik zwracania, w przeciwnym razie dane wyjściowe stają się dość duże .Rozwiązanie to jest trochę bardziej skomplikowane niż to konieczne, ze względu na kilka zaangażowane funkcje są odłączone, np
..
,all
,>>
,%%
itd. Bez ograniczeń źródłowego, może to być 43 bajtów:Wypróbuj online!
Wyjaśnienie:
źródło
Perl 5
-p
,94,86,78 bajtówouput 0, jeśli dobrze połączone 1 w innym przypadku.
78 bajtów
86 bajtów
94 bajty
Jak to działa
-p
z}{
zakończoną lewą do wyjścia$\
na końcum-.+(?{
..})(?!)-
, aby wykonać kod na wszystkich niepustych podciągach (.+
najpierw dopasowuje cały ciąg, a po wykonaniu kodu między(?{
..})
cofnięciami z powodu nieudanego wymuszenia(?!)
$Q|=@q&grp,
śmieci ze względu na ograniczenie źródła$\|=
liczba całkowita bitowa lub przypisanie, jeśli jest prawie jedna 1,$\
będzie wynosić 1 (prawda), domyślnie jest pusta (fałsz)$&eq$_
przypadek, w którym sbustrowanie jest całym łańcuchem, jest bitowo xoredowany^
z „brakiem dziwnego znaku”($g=$&)=~/./g
do skopiowania dopasowanego podłańcucha do$g
(ponieważ zostanie przytłoczony po następnym dopasowaniu wyrażenia regularnego) i zwróci tablicę znaków podłańcucha./^/
śmieci, których wynikiem jest 1grep
1&(@m=$g=~/\Q$_/g),
dla każdego znaku w podciągu uzyskuje tablicę znaków w$g
dopasowaniu do siebie, tablica w skalarnie ocenia się na jej rozmiar, agrep
filtrowanie znaków o nieparzystym wystąpieniu1&x
jest równoważne zx%2==1
źródło
Siatkówka ,
15096 bajtówWypróbuj online! Link zawiera przypadki testowe, w tym siebie. Edycja: Grałem trochę w golfa w oryginalnym wyrażeniu regularnym z pomocą @Deadcode, a następnie nieco mniej ekstrawagancko cofałem się, aby zachować układ źródłowy. Wyjaśnienie:
Upewnij się, że nie ma podciągów
\3
, które pasują do następujących ograniczeń.Upewnij się, że podciąg nie jest całym oryginalnym łańcuchem.
Zapewnij, że nie ma
\6
takiego znaku , który:Aby zdać ograniczenie układu źródło, wymieniłem
((((
z(?:(^?(?:(
i((
z(|(
. Nadal miałem jedno ograniczenie źródłowe,))
a pozostałe postacie!()1<{}
, więc zmieniłem+
na{1,}
i wstawiłem bezużyteczne,(?!,<)?
aby pochłonąć resztę.źródło
C # (interaktywny kompilator Visual C #) ,
208206200198 bajtówWypróbuj online!
-2 bajty dzięki @KevinCruijssen!
W końcu mam poniżej 200, więc na razie mogę grać w golfa :) Skończyłem tworzenie drugiego TIO, aby przetestować wszystko na podstawie poprzedniej odpowiedzi.
Wypróbuj online!
Rzeczy, które utrudniały to zadanie:
==
nie był dozwolony++
był niedozwolonyAll()
Funkcja Linq była niedozwolonaSkomentowany kod poniżej:
źródło
Python 2 , 108 bajtów
Wypróbuj online!
-2 dzięki Ørjan Johansen .
źródło
Brachylog , 16 bajtów
Wypróbuj online!
Odbitki
false.
dla autentycznych przypadków itrue.
dla fałszywych przypadków. Wersja TIO jest zbyt wolna, aby poradzić sobie sama, ale jest wyraźnie powiązana, ponieważ jest ciągiem znaków z unikatowymi powtórzeniami dwukrotnie.Wyjaśnienie
źródło
05AB1E ,
2220 bajtówWyprowadzane,
1
jeśli ciąg jest dobrze połączony i0
jeśli ciąg nie jest dobrze połączony.Wypróbuj online lub sprawdź wszystkie przypadki testowe .
Wyjaśnienie:
Program podstawowy to
ŒsKεsS¢ÈP}à
( 11 bajtów ), który wyprowadza,0
jeśli jest dobrze połączony i1
jeśli nie jest dobrze połączony. KropkaÈ
(is_even) jest pół-op, który nie odwraca wyjście, więc1
na dobrze połączonych ciągów i0
za nie dobrze połączonych ciągów. Pozostałe części nie są zgodne z regułami wyzwań.źródło