Jakie masz ogólne wskazówki na temat gry w golfa w Lua? Szukam pomysłów, które można by zastosować do ogólnych problemów z golfem, które są przynajmniej nieco specyficzne dla Lua (np. „Usuń komentarze” nie jest odpowiedzią). Proszę zamieścić jedną wskazówkę na odpowiedź.
21
Odpowiedzi:
Oprócz tych już opublikowanych, oto kilka sztuczek, które zebrałem w czasie, w żadnej określonej kolejności ...
W przypadku wywołań funkcji, które mają tylko jeden parametr rozdzielony symbolem (
"
dla łańcuchów,{
dla tabel), parametr nie musi być zawijany wokół nawiasów.Na przykład zamiast robić
print("hello")
, możesz po prostu zrobić:print"hello"
Usuń jak najwięcej białych znaków - jest to szczególnie łatwe po symbolu, który zamyka łańcuchy (lub przed jednym otwarciem), wywołania funkcji, tabele ...
Zamiast tego
print(42) a=1
możesz to zrobićprint(42)a=1
. Inny przykład:print(a and-1 or-2)
.Kiedy to możliwe, użyj operatora trójskładnikowego! Zamiast
if a>0 then print("hello") else print("goodbye") end
woliprint(a>0 and "hello" or "goodbye")
. Więcej informacji tutaj .(To rzeczywiście może się jeszcze lepiej:
print(a>0 and"hello"or"goodbye")
)Użyj cukru syntaktycznego z dwukropka, gdy możesz: zamiast tego
string.rep(str,12)
zrobićstr:rep(12)
. Działa to również na nie-zmienne w ten sposób (i tylko w ten sposób):("a"):rep(5)
Zamiast robić,
tonumber(str)
po prostu róbstr+0
W przypadku funkcji bez parametrów zamiast definiowania ich w zwykły sposób (
function tick() blabla() end
) można wykonaćticks=loadstring"blabla()"
:, która zapisuje 1 lub więcej bajtów, w zależności od zawartości. Ponadto, jeśli zdefiniujesz wiele funkcji, zlokalizujloadstring
wcześniej zmienną 1-znakową, a zaoszczędzisz dużo bajtów;). Podziękowania dla Jima Bauwensa za tę sztuczkę.Lua uważa pusty ciąg (i
0
zbyt odmienny od innych języków) za prawdziwy w testach warunkowych, więc na przykład zamiast robićwhile 1 do ... end
, zachowaj 1 bajt piszącwhile''do ... end
źródło
str+0
odpowiednikiem jest~~str
, może być użyteczny ze względu na pierwszeństwoJuż o tym pomyślałem. Nie wiem, czy to działa w niektórych innych językach, ale Lua jest jedynym, który wiem, co pozwala przechowywać funkcje w zmiennych. Więc jeśli np.
string.sub
Jest używany wielokrotnie w twoim programie, użyj nps=string.sub
.źródło
s=("").sub
lubs=a.sub
dla dowolnej zmienneja
zawierającej wartość ciągu.Jest to dość pełny język do gry w golfa ... ale kilka ogólnych wskazówek, które przychodzą na myśl, to:
if
...then
...else
...end
to poważna strata.for i=1,5 do
.#
Operator jest dość dobre dla golfa (iw ogóle).źródło
Skróć swoją nieskończoną pętlę
Kiedy musisz użyć nieskończonej pętli, możesz pomyśleć o użyciu
while
, ale zamiast tego użycie etykiety jest krótsze o 2 bajty:Wykorzystaj jak najmniej miejsca
Jest prosta rzecz, której możesz (ab) użyć, aby usunąć jeszcze więcej spacji z kodu. Specyfikacje Luy jasno określają nazwę, którą nadajesz zmiennym: muszą zaczynać się od litery. Oznacza to, że czasami można pominąć spacje między liczbami a funkcjami / zmiennymi
Możliwość usunięcia spacji zależy od litery następującej po numerze, oto litera, która na to nie pozwoli:
Korzystając z tego i zwracając uwagę na to, jak wywołujesz zmienne, możesz zwolnić większość kodu źródłowego.
Pobierając przykład już tutaj i korzystając z tej porady, oto jeszcze jeden bajt, który możesz ogolić :).
Użyj właściwej metody wprowadzania
Jeśli spojrzymy na płytę kotłową i koszt każdego głównego typu danych wejściowych, oto, co mamy:
Każda z tych metod pozwala nam pobrać 1 dane wejściowe, przy czym funkcja jest tą o największym koszcie (ale pozwala nam wziąć tabelę jako dane wejściowe)
Teraz widzimy, że jeśli chcesz grać w golfa, skorzystaj z argumentu wiersza poleceń, ale pamiętaj: może być jeszcze krótszy
...
To specjalny bit lua, to zmienna zawierająca rozpakowane treśćarg
lub niespakowanego parametry w przypadku zmiennej liczbie argumentów funkcji.Gdy będziesz musiał uzyskać więcej niż jedno wejście i użyć każdego z nich, dobrze jest zapisać je w zmiennej. Oto kilka sposobów na zapisanie 2 danych wejściowych w zmiennych
a oto najkrótsze połączenie, jakie można było wykonać bez zmiennych:
Od momentu, w którym masz 3 argumenty lub gdy używasz 2 argumentów, z jednym argumentem dwukrotnie, zyskujesz już bajty
a,b=...
! :)Prawie nigdy nie używaj, jeśli!
Nie ma prawie żadnych przypadków, w których użycie instrukcji if / elseif / if będzie kosztować mniej niż trójka. płyta dla takiego stwierdzenia jest naprawdę ciężka:
Na prostym przykładzie zapisujesz już 12 bajtów, a kiedy musisz zrobić kilka innych, staje się to coraz ważniejsze, więc pamiętaj o tym!
Ponadto trójskładniki w lua są wyjątkowe , istnieje pewien warunek w ich działaniu, dla zainteresowanych wyjaśnię to poniżej:
Trójskładniki w lua mają formę
<condition> and <case true: have to be a true value> or <case false: can be anything>
Przede wszystkim zobaczmy tabelę prawdy
or
. Aor
można uznać za funkcję: zawsze zwraca wartość, oto wartość, którą zwraca:To pozwala nam zbudować nasz trójskładnik.
To,
and
co pozwala nam ocenić warunek, zawsze powróci,y
jeśli zostaniex and y
ocenione jako prawdziwe.Problem polega na tym, że to się nie powiedzie, jeśli chcemy
nil
albofalse
powrócić, gdy stan jest spełnionyfalse
. Na przykład, następujący wynik zawsze zwróci 5, pomimo spełnienia warunku.Oto krok po kroku ocena trójskładnika, aby wyjaśnić, jak to działa (przyda się, gdy trzeba je zagnieździć :))
źródło
Zebrałem też kilka wskazówek. Jestem pewien, że niektóre moje pokryją się z tymi, które już podano, ale i tak uwzględnię je w celu stworzenia pełniejszej odpowiedzi.
Przypisz powtarzające się funkcje do zmiennych
Lua pozwala przypisywać funkcje do zmiennych. Nawet zmienne jednego znaku. Oznacza to, że jeśli powtórzysz funkcję
string.sub(x, y)
więcej niż dwa razy, odniesiesz korzyść z przypisania jej do zmiennej.Bez przypisywania do zmiennej (69 znaków):
Przypisywanie do zmiennej (51 znaków):
Są przypadki, w których możesz pójść o krok dalej. Lua pozwala OOP na manipulowanie ciągami, tak jak:
str:sub(x, y)
lubstr.sub(x, y)
To otwiera nowe opcje dla naszego kodu. Możesz przypisać zmienną do funkcji poprzez jej odwołanie, jak pokazano (46 znaków).Użyj najbardziej wydajnego sposobu parsowania ciągów
Możesz użyć
for
pętli istring.sub
iterować postać po znaku w Lua. Czasami może to działać najlepiej, w zależności od potrzeb, ale innym razem string.gmatch będzie działał z mniejszą liczbą znaków. Oto przykład obu:A kiedy gra się w golfa, różnica jest bardziej zauważalna:
Restrukturyzacja przypisań w celu optymalizacji białych znaków
W Lua nie musisz umieszczać spacji między zamkniętymi nawiasami lub końcowym cudzysłowem a następnym znakiem. Do tej pory znalazłem dwa przypadki, w których restrukturyzacja z myślą o tym spowoduje odcięcie postaci.
Przypisywanie zmiennych:
Jeśli oświadczenia:
Zwróć jak najmniej znaków
Jeśli musisz zwrócić wartość true lub false, wydaje się, że musisz koniecznie użyć co najmniej 5 znaków dla wartości zwracanej. W rzeczywistości działa równie dobrze:
źródło
nil
ifalse
FALSE w Lua, wszystko inne jest prawdą, dzięki czemu wskazówki na temat wymianyx==0
,x==""
ax==''
przezx
to fałszywe. Obecnie zmieniam nanil
:).Są to tylko optymalizacje Lua (myślę):
Ciągi są automatycznie konwertowane na liczby podczas wykonywania na nich operacji arytmetycznych. Uważaj tylko na instrukcje warunkowe, nie będą one automatycznie konwertowane. Jest to doskonałe do wprowadzania danych liczbowych przez użytkownika przy jednoczesnym oszczędzaniu miejsca.
Przełączanie zawartości dwóch zmiennych nie wymaga zmiennej tymczasowej.
a,b=b,a
zamieni wartości a i b.Ponadto, aby rozszerzyć to, co powiedziano powyżej, każdy znak alfanumeryczny może dotykać znaku innego niż alfanumeryczny.
a,b=io.read():match"(.+)/(.+)"u,v=a,b
Jest to więc doskonały, działający skrypt, nawet przy braku białych znaków.źródło
Połącz przypisania zmiennych lokalnych
Zamiast:
Użyj równoległego przypisania:
6 bajtów zapisanych dla każdej zmiennej!
Deklaruj zmienne lokalne za pomocą nieużywanych parametrów funkcji
Zamiast:
Posługiwać się
Zapisano 6 bajtów (minus 1-2 bajty dla każdej zmiennej, która może być zduplikowana).
źródło
local
jest uzasadnione podczas gry w golfa, ponieważ wystarczy użyć innej nazwy. Moglibyśmy użyć WSZYSTKICH nazw do 7 znaków i tabel z indeksami ciągów do 7 kombinacji znaków, zanimFunkcje Variadic
Główną funkcją wariadyczną, która będzie cię martwić, jest
print()
. Na przykład, gdy go użyjesz,String.gsub()
wydrukuje zmodyfikowany ciąg ORAZ liczbęgsub
uruchomień.Aby pominąć to drugie wyjście, obuduj pareny,
gsub
aby zmusić je do zwrócenia tylko jednej wartościźródło
Wiedzieć, jak wydrukować
Istnieją dwie główne metody wypisywania danych w lua
W przypadku wielokrotnej konkatenacji można ją skrócić, używając
io.write()
przypisanej zmiennej o wartości jednej litery zamiast standardowego operatora konkatenacji..
Zyskujesz 2 bajty przy każdym połączeniu, płacąc z góry
Jesteś nawet na trzeciej konkatenacji i zacznij zyskiwać bajt na czwartej.
źródło
print
i nieprintf
!Kilka wskazówek w określonej kolejności:
string
to dość długie imię. Skutecznie('').char
jest taki sam jakstring.char
. Jeszcze lepsze wyniki można osiągnąć, jeśli użyjesz go razem ze średnikiem zmiennych:,a=...; print(a:sub(1, 5))
ale niektórestring
funkcje nie przyjmują ciągów jako danych wejściowych.tonumber
i+0
często marnuje tylko bajty.load'your function code here'
zamiastfunction()your function code here end
. Dostęp do argumentów funkcji za pomocą...
wewnątrz.a:gsub('.',load'my function')
wydaje się być najkrótszym sposobem na iterację znaków w łańcuchua:find('.',1,1)
(aby przetestować ten problem, spróbuj dołączyć%
w różnych miejscach danych wejściowych i sprawdzić wyniki). Niezliczone pomysły zostały złamane, ponieważ Lua próbowała przeanalizować dane wejściowe jako wzorzec.nil
ma trzy bajty,_
jest jeden (to po prostu losowa nazwa, która najprawdopodobniej nie istnieje). Ponadto każda cyfra będzie działać jako prawdziwa wartość.x and i or o
. To nie jest tylko potrójny operator - to kompletne wyrażenie logiczne. W rzeczywistości oznacza to: „jeślix
to prawda, spróbuji
. Jeśli x lub i jest fałszem, zwróć o”. Więc jeślii
nie jest to prawdą, wynik jesto
. Obieand
lubor
części można również pominąć (x and i
,x or o
).math.floor
:5.3//1==5.0
. Należy pamiętać, że wynikowa liczba zawsze odpowiada typowi wejścia 1 (liczba całkowita / liczba zmiennoprzecinkowa).źródło