Jakie masz ogólne wskazówki na temat gry w golfa w sed? Szukam pomysłów, które można by zastosować do problemów związanych z golfem i które są przynajmniej nieco specyficzne dla sed (np. „Usuń komentarze” nie jest odpowiedzią).
Proszę zamieścić jedną wskazówkę na odpowiedź.
F
polecenie nigdy nie działało. Czy ktoś wie dlaczego?F
działa na moim GNU sed (testowanie Debiana). Oczywiście drukuje się-
tylko przy czytaniu ze standardowego wejścia, ale jest to oczekiwane. Co otrzymasz odsed -e 'F;Q' /etc/hostname
?char 1: unknown command: F
. Może muszę zaktualizować sed; jaką masz wersję?L
Polecenie również nie działa, ale to nie ma sensu, ponieważ w każdym razie-l n
istnieje. Wszystko inne wymienione na stronie GNU sed działa.bash, sed and dc
dla wszystkich, którzy chcą rozmawiać i pytać o te języki. Stwórzmy społeczność!Odpowiedzi:
Jeśli potrzebujesz użyć etykiet, na pewno będziesz chciał, aby nazwy etykiet były jak najkrótsze. W rzeczywistości doprowadzono do skrajności, możesz nawet użyć pustego ciągu jako nazwy etykiety:
źródło
:
teraz wymaga etykiety.Dokumentacja GNU sed opisuje
s
polecenie jako „szwajcarski scyzoryk sed” . Ale jeśli wszystko, co chcesz zrobić, to zastąpić wszystkie wystąpienia jednej postaci inną, wtedyy
polecenie jest tym, czego potrzebujesz:jest o jeden char krótszy niż:
źródło
y/12/21/
Rozważ użycie rozszerzonej składni wyrażenia regularnego (w GNU sed).
-r
Opcja kosztuje jeden bajt w punktacji, ale używając go tylko raz, aby wyeliminować backslashy z parą\(...\)
już zapłacił za siebie.źródło
-r
wydaje się byćsed
specyficzna dla GNU .+
,?
,{}
a|
w regex dopasowania, ponieważ nie są potrzebne ani ukośniki.-E
działa jako alias do-r
wielused
implementacji, jeśli dobrze pamiętam.Podczas wielokrotnego zastępowania w pętli:
Zazwyczaj globalne nie jest konieczne, ponieważ pętla ostatecznie zastąpi wszystkie wystąpienia:
Zwróć także uwagę na powyższe rozszerzenie GNU: etykieta może mieć pustą nazwę, oszczędzając cenniejsze bajty. W innych implementacjach etykieta nie może być pusta, a przeskakiwanie bez przeniesienia etykiety przepływa do końca skryptu (tj. Takiego samego jak
n
).źródło
:
)Nie ma wbudowanej arytmetyki, ale obliczenia można wykonywać w jednostajnym lub jednokodowanym dziesiętnym. Poniższy kod konwertuje liczbę dziesiętną na UCD, gdzie x to jednostka, a 0 jako separator cyfr:
a oto konwersja z powrotem na dziesiętne:
Oba są zaczerpnięte z odpowiedzi na „Pomnóż dwie liczby bez użycia żadnych liczb” .
Zwykłe stare jednoargumentowe można przekonwertować za pomocą tej pary pętli z tej odpowiedzi na „{Curly Numbers};” , gdzie jest jednostka
;
. Użyłemv
ix
dopasowałem Roman do5
i10
;b
pochodzi od „bis”.źródło
/[;v]/!s/\b/0/2
, który należy zmienić/[;v]/!s:x\+:&0:
, aby działał. Zobacz tutaj .Jak wspomniano w
man sed
(GNU), możesz użyć dowolnego znaku jako separatora dla wyrażeń regularnych, używając składnigdzie
%
jest symbolem zastępczym dla dowolnej postaci.Jest to przydatne dla poleceń takich jak
które są krótsze jako
W podręczniku GNU sed wspomniano, ale nie w
man sed
tym, że można zmienić ogranicznikis///
iy///
.Na przykład polecenie
usuwa wszystkie ukośniki z obszaru wzoru.
źródło
Jeśli pytanie nie wyraźnie tego zabrania, konsensus w przypadku tego meta pytania jest taki, że dane liczbowe mogą być jednomyślne . To oszczędza ci 86 bajtów dziesiętnych do jednych zgodnie z tą odpowiedzią .
źródło
Rozwijając tę odpowiedź , dotyczącą konwersji między formatami liczb dziesiętnych i zwykłych liczb jednoznacznych, przedstawiam następujące alternatywne metody z ich zaletami i wadami.
Liczba dziesiętna do zwykłej: 102 + 1 (flaga r) = 103 bajty. Liczę
\t
jako dosłowną kartę, jako 1 bajt.Wypróbuj online!
Zaleta: jest o 22 bajty krótszy, a dodatkowo działa z ujemnymi liczbami całkowitymi jako danymi wejściowymi
Wada: zastępuje przestrzeń wstrzymania. Ponieważ jednak bardziej prawdopodobne jest, że będziesz musiał przekonwertować całkowitą liczbę wejściową na samym początku programu, ograniczenie to jest rzadko odczuwalne.
Zwykły od jednego do dziesiętnego: 102 + 1 (flaga r) = 103 bajty
Wypróbuj online!
Zaleta: jest 14 bajtów krótszy. Tym razem obie wersje końcówek działają jako ujemne liczby całkowite jako dane wejściowe.
Wada: zastępuje przestrzeń wstrzymania
W przypadku skomplikowanego wyzwania musisz dostosować te fragmenty, aby współpracowały z innymi informacjami, które mogą istnieć w obszarze wzorca lub w miejscu przechowywania oprócz liczby do konwersji. Kod może być bardziej golfowany, jeśli wiesz, że pracujesz tylko z dodatnimi liczbami lub że samo zero nie będzie prawidłowym wejściem / wyjściem.
Przykładem takiej odpowiedzi na wyzwanie, w której stworzyłem i wykorzystałem te fragmenty, jest odwrotność liczby (1 / x) .
źródło
s:\n|@$::g
. tio.run-r
, ale przy nowym konsensusie flagi i tak nie liczą się do liczby bajtów , i nie/\n/ta
na/\n/t
, zaoszczędzisz 1 bajt, aby uzyskać 96Porozmawiajmy o komendach
t
iT
, że chociaż są one wyjaśnione na stronie podręcznika, łatwo o tym zapomnieć i przypadkowo wprowadzić błędy, szczególnie gdy kod się komplikuje.Instrukcja strony podręcznika dla
t
:Przykład pokazujący, co mam na myśli: Załóżmy, że masz listę liczb i chcesz policzyć, ile jest negatywów. Kod częściowy poniżej:
Wygląda dobrze, ale tak nie jest. Jeśli pierwsza liczba jest dodatnia, kod nadal będzie myślał, że jest ujemna, ponieważ skok wykonany przez
t
pierwszy wiersz danych wejściowych jest wykonywany niezależnie, ponieważs
podczas inicjalizacji licznika wystąpiło pomyślne podstawienie! Prawidłowe jest:/-/b increment_counter
.Jeśli wydawało się to łatwe, nadal można Cię oszukać, wykonując wiele skoków tam i z powrotem w celu symulacji funkcji. W naszym przykładzie
increment_counter
blok kodu z pewnością użyłby wielus
poleceń. Powrót zb main
może spowodować, że kolejne sprawdzenie w „main” wpadnie w tę samą pułapkę. Dlatego zwykle wracam z bloków kodu za pomocąs/.*/&/;t label
. To brzydkie, ale przydatne.źródło
Zamiast wyczyścić przestrzeń wzorców za pomocą
s/.*//
, użyjz
polecenia (małe litery), jeśli korzystasz z GNU sed. Oprócz niższej liczby bajtów ma tę zaletę, że nie uruchamia następnego cyklu tak, jakd
robi to polecenie , co może być przydatne w niektórych sytuacjach.źródło
.
).Wiem, że to stary wątek, ale właśnie znalazłem te niezdarne konwertery dziesiętne na UCD, z prawie stoma bajtami, niektóre nawet bałaganią przestrzeń wstrzymania lub wymagają specjalnych wadliwych
sed
wersji.Do dziesiętnej UCD używam (68 bajtów, były najlepiej napisali tutaj 87 bajtów)
UCD na dziesiętne to (również 66 bajtów; poprzednio najlepiej opublikowany tutaj 96)
\n
w zastępstwie nie jest przenośny. Zamiast tego możesz użyć innego znaku i zapisać dwa bajty, ale będziesz potrzebować więcej bajtów, aby usunąć dodatek zamiastP;d
; patrz następna uwaga. Lub, jeśli twoje pole trzymania jest puste, nie róbG;s/$/9876543210/
kary bez bajtów.s/\n.*//
zamiastP;d
.sed
wersji GNUźródło
sed
wersjami, które naruszają standard POSIX.Przeczytaj cały tekst naraz za pomocą
-z
Często trzeba operować całym wejściem zamiast jednego wiersza na raz.
N
Komenda jest przydatna, że:... ale zwykle możesz go pominąć i
-z
zamiast tego użyć flagi.-z
Flag sprawia sed użytkowania NUL (\0
) jako separator linii wejściowej zamiast\n
, więc jeśli znasz swoje wejście nie będzie zawierać\0
będzie czytać wszystkie wejścia jednocześnie jako pojedynczy „line”:Wypróbuj online!
źródło
Dodaj nowy wiersz w jednym bajcie
G
Polecenie dołącza do nowej linii i zawartość miejsca przechowywania do przestrzeni wzoru, więc jeśli przestrzeń hold jest pusty, zamiast tego:Możesz to zrobić:
Przygotuj nowy wiersz w trzech bajtach
H
Polecenie dołącza do nowej linii i zawartości przestrzeni wzorca do miejsca przechowywania ix
zamienia dwa, więc jeśli przestrzeń hold jest pusty, zamiast tego:Możesz to zrobić:
Spowoduje to zanieczyszczenie przestrzeni wstrzymania, więc działa tylko raz. Jednak w przypadku dwóch kolejnych bajtów można wyczyścić obszar wzorców przed zamianą, co wciąż oznacza oszczędność dwóch bajtów:
źródło
W sed, najbliższą funkcją, którą możesz mieć, jest etykieta. Funkcja jest przydatna, ponieważ możesz wykonać jej kod wiele razy, oszczędzając w ten sposób wiele bajtów. W sednie jednak musisz podać etykietę zwrotną i jako taki nie możesz po prostu wywołać tej „funkcji” wiele razy w całym kodzie, tak jak zrobiłbyś to w innych językach.
Obejściem, którego używam, jest dodanie do jednej z dwóch pamięci flagi, która służy do wyboru etykiety zwrotnej. Działa to najlepiej, gdy kod funkcji potrzebuje tylko jednej przestrzeni pamięci (drugiej).
Przykład pokazujący, co mam na myśli: wzięty z mojego projektu, aby napisać małą grę w sed
Etykiety powinny być oczywiście golfowane tylko na jedną literę, dla lepszego wyjaśnienia użyłem pełnych nazwisk.
źródło
Puste wyrażenia regularne są równoważne z wcześniej napotkanym wyrażeniem regularnym
(podziękowania dla Riley za odkrycie tego po złożeniu anagolu )
Oto przykład, w którym mamy za zadanie utworzenie 100
@
s w pustym buforze.Drugie rozwiązanie jest o 1 bajt krótsze i wykorzystuje fakt, że puste wyrażenia regularne są wypełniane ostatnim napotkanym wyrażeniem regularnym. Tutaj, dla drugiego podstawienia, ostatnim wyrażeniem regularnym było
.*
, więc puste wyrażenie regularne zostanie tutaj wypełnione.*
. Działa to również z wyrażeniami regularnymi w/conditionals/
.Zauważ, że jest to wcześniej napotkany regex, więc poniższe również by działały.
Puste wyrażenie regularne zostaje wypełnione
@*
zamiast,$
ponieważs/$/@/
nigdy nie jest osiągane.źródło
Przeważnie bezużyteczny krok:
Będzie to tłumaczyć tylko
A
doB
iy
doz
(... i-
do-
), ale nic więcej, takpo prostu wróci:
Można to zapewnić będą bezużyteczne, na próbce za pomocą tego na małymi wartościami szesnastkowym (zawierające tylko
0
,1
,2
,3
,4
,5
,6
,7
,8
,9
,a
,b
,c
,d
,e
lubf
).źródło
sed '; ;/s/b;y|A-y|B-z|;s ;s/ //; ; ;' <<<'Hello world'
(Dlaczego to nie tłumi miejsca?)