Wskazówki dotyczące gry w golfa w <wszystkich językach>


81

Celem tego postu jest zebranie wszystkich wskazówek golfowych, które można łatwo zastosować, <all languages>a nie konkretny.

Publikuj tylko odpowiedzi, że jego logikę można zastosować do większości języków

Proszę, jedna wskazówka na odpowiedź


5
„Większość” według jakich wskaźników?
przestał obracać przeciwnie do zegara

2
@leftaroundabout według metryki tego samego słowa
ajax333221

8
Problem polega na tym, że wiele języków jest (często krótkotrwałych) eksperymentalnych z bardzo nietypowymi paradygmatami, dla których typowe wyrażenia programistyczne nie mają żadnego sensu. Tak więc „większość wszystkich języków” jest praktycznie niemożliwa do spełnienia. Powinieneś ograniczyć to w jakiś sposób, np. Do „większości języków regularnie używanych na codegolf.SE”. W tej chwili odpowiedzi wyglądają bardzo podobnie do „większości zdalnie języków pochodzących z języka C”, ale te, choć znaczna większość całego napisanego w nich kodu , nie są większością języków .
przestał obracać przeciwnie do zegara

3
po lewej, chyba wszyscy wiemy, co mniej więcej oznaczają. Chodzi głównie o optymalizacje niezależne od języka, tj. Te nie tylko przydatne w Brainfuck, ale może jednocześnie Python, C, Java i Fortran. Ogólne pomysły, które można zastosować w wielu językach, które działają podobnie. Nie sądzę, że trzeba być tak precyzyjnym i konkretnym w poradach i pytaniu CW. Chodzi o pomaganie innym w golfa, a nie wkurzanie ich.
Joey,

14
Mam nadzieję, że nikt nie tworzy języka o nazwie <all languages>...
mbomb007

Odpowiedzi:


72

Scal pętle

Zwykle można scalić dwie konsekwentne pętle lub dwie zagnieżdżone pętle w jedną.

Przed:

for (i=0; i<a; i++) foo();
for (i=0; i<b; i++) bar();

Po:

for (i=0; i<a+b; i++) i<a?foo():bar();

ugoren pętle wciąż nie są takie same. @ Gaffi ma rację.
kaoD

5
@kaoD, w obu przypadkach foonazywa się arazy, barnazywa się brazy. Wynika to z faktu, że w trybie „po” pętla działa a+brazy, pierwsze awywołanie foo, następne wywołanie bar.
ugoren

Patrzę na to jeszcze raz (znacznie, dużo później) i nie rozumiem teraz mojego pytania. Może wcześniej nie rozumiałem operacji trójskładnikowej? To, co widzę teraz, ma sens.
Gaffi,

1
Ups, przeczytałem to bardzo późno w nocy. Masz rację!
kaoD

3
Bardzo podobne: for(y=0;y<Y;++y)for(x=0;x<X;++x)często może stać się for(i=0;i<X*Y;++i)z xwyrazami i%Xi yzastąpione i/X.
Lynn

62

Wystarczy wspomnieć o oczywistym:

Podważ swój wybór algorytmu i wypróbuj coś zupełnie nowego.

Podczas gry w golfa (szczególnie trudniejsze problemy, które skutkują dłuższymi programami) zbyt często możesz trzymać się wybranej ścieżki, nie wypróbowując innych podstawowych opcji. Oczywiście możesz zagrać w mikro golfa na raz lub kilka linii na raz lub część ogólnego pomysłu, ale często nie próbujesz zupełnie innego rozwiązania.

Było to szczególnie widoczne w Uderzeniu 495 (Kaprekar), gdzie odbieganie od faktycznego algorytmu i szukanie wzorców, które można zastosować, aby uzyskać ten sam wynik, było krótsze w wielu językach (tylko nie J).

Minusem jest to, że prawdopodobnie rozwiązujesz to samo pół tuzina razy. Ale działa we wszystkich językach oprócz HQ9 + (gdzie znalezienie innego sposobu na wyświetlenie Hello World byłoby nieco daremne).


12
+1 Oprócz tego, że jest dobry do gry w golfa, jest to dobre ćwiczenie dla każdego programisty w wielu rzeczywistych sytuacjach!
Gaffi,

52

Użyj rozwoju opartego na testach

Jeśli kod musi obsługiwać różne dane wejściowe, napisz kompleksowe testy i bardzo szybko uruchom je wszystkie. Pozwala to wypróbować ryzykowne transformacje krok po kroku. Gra w golfa staje się wtedy jak refaktoryzacja z przewrotną intencją.


4
Korzystam z podziału tej metody. Ponieważ same problemy są zwykle dość proste, piszę program, który wykonuje tę pracę. Zwykle jest to „czytelnie gra w golfa”, więc jest zwięzłe, ale pojawiają się nowe linie itp. Kopiuję ten plik do nowej lokalizacji i sprawdzam go, sprawdzając co jakiś czas, czy programy zwracają te same wartości dla wybranych danych wejściowych. Jeśli kiedykolwiek popełniam błąd, zostawiając mnie zepsutym programem, bez pamięci o tym, co zmieniłem i bez zrozumienia mojego golfa, mam coś w rodzaju „specyfikacji” zapisanej jako źródło odniesienia.
shiona

2
Uwielbiam tę metodę, dlatego często dołączam kompleksowe pakiety testowe do wszystkich pisanych przeze mnie problemów.
Joey,

@RubberDuck Zasada Nie powtarzaj się jest często ściśle przestrzegana.
Jonathan Frech

48

Spróbuj zmniejszyć logiczne instrukcje

Na przykład, jeśli Ai Bsą wartościami logicznymi, a Twój język traktuje wartości logiczne w pewnym stopniu A and (not B)i A>Bsą one równoważne. Na przykład w Pythonie

if A and not B:
    foo()

jest taki sam jak:

if A>B:
    foo()

3
Nigdy bym o tym nie pomyślał.
cjfaure

27
B>A or foo()byłoby jeszcze krótszym sposobem na wyrażenie tego, skorzystaj z leniwej oceny wyrażeń boolowskich, aby upewnić się, że oblicza rzeczy tylko wtedy, gdy jest to konieczne.
scragar

5
@scragar: Prawidłowo, ale nie o to chodzi w tym poradniku. (Jest to jednak cenna niezależna wskazówka).
Wrzlprmft

3
@scragar, B>A or fooocenia, fooczy B==Anie tego chcemy. (Racja?)
msh210

2
Ponadto, jeśli masz długie zaabsorbowane warunki (powiedzmy z parametrami 5/6), możesz użyć tabeli Prawdy i mapy Karnaugh, aby znaleźć najkrótsze boolowskie wyrażenie dla niej
Katenkyo

33

Zainicjuj zmienne przy użyciu wartości, które już masz.

Zamiast tego x=1spróbuj poszukać czegoś, co już jest równe 1.
Na przykład wartość zwracana przez funkcję: printf("..");x=0;-> x=!printf("..");. Najłatwiej jest z 0, ponieważ zawsze możesz zanegować lub gdy wszystko, czego potrzebujesz, to właściwa wartość prawdy (i nie przejmuj się, czy jest to 1 czy 19).



1
@ std''OrgnlDave, prawda, ale to pytanie dotyczy rzeczy wspólnych dla wszystkich języków.
ugoren

33

Użyj unary ~dla x+1ix-1

Ta sztuczka dotyczy języków, w których występuje jednoargumentowy operator negacji bitowej ~i jeden zwykły operator negacji -.

Jeśli Twój program przypadkowo zawiera wyrażenie -x-1, możesz je zastąpić, ~xaby zapisać bajty. Nie zdarza się to zbyt często, ale uważaj, co się stanie, jeśli negujemy ( -) oba wyrażenia: x+1równa się -~x! Podobnie x-1jest równy ~-x. (Zastanów się, w którą stronę wskazuje tylda: prawa jest +, lewa jest -.)

Jest to przydatne, ponieważ we wszystkich językach, o których myślę, że mają te operatory, mają wyższy priorytet niż większość operatorów. Pozwala to zaoszczędzić na nawiasach. Zobacz, jak zapisujemy tutaj cztery bajty:

(x+1)*(y-1)     ==>    -~x*~-y

30

Ściśnij białe znaki

Poznaj zasady dotyczące białych znaków w swoim języku. Niektóre znaki interpunkcyjne lub inne znaki mogą nie wymagać otaczających białych znaków. Rozważ tę funkcję powłoki Bourne'a :

f () { echo a; echo b; }

W powłoce Bourne'a ();są metaznakami i nie potrzebują otaczających białych znaków. Są {}to jednak słowa i wymagają spacji, chyba że znajdują się obok metaznaków. Możemy zagrać w golfa 4 pola obok ();, ale musimy zachować przestrzeń pomiędzy {i echo.

f(){ echo a;echo b;}

W Common Lisp i PicoLisp , ()są metaznakami. Rozważ ten kod, aby znaleźć średnią dwóch liczb:

(/ (+ a b) 2)

Możemy zagrać w golfa na 2 pola.

(/(+ a b)2)

Niektóre języki mają dziwne i subtelne reguły dotyczące białych znaków. Rozważ ten program Ruby, który wypisuje sumę i iloczyn linii liczb całkowitych.

#!ruby -an
i=$F.map &:to_i
puts"#{i.reduce &:+} #{i.reduce &:*}"

Każdy &potrzebuje miejsca przed sobą. W Ruby i=$F.map &:to_ioznacza, i=$F.map(&:to_i)gdzie &przekazuje parametr bloku. Ale i=$F.map&:to_ioznacza, i=$F.map.&(:to_i)gdzie &jest operator binarny.

Ta dziwność zdarza się w językach takich jak Perl czy Ruby, które używają niejednoznacznych znaków interpunkcyjnych. W razie wątpliwości użyj REPL lub napisz krótkie programy, aby przetestować reguły białych znaków.


1
Dlaczego między „{” a „echo” musi być spacja, ale nie między „;” i „echo”?
Ryan,

3
Użyłem terminów z podręcznika dla OpenBSD sh (1), który mówi, że „{” jest słowem zastrzeżonym, a „;” jest meta-postacią. Z tego powodu „{echo” to jedno słowo, ale „; echo” to dwa słowa. Inne podręczniki mogą to wyjaśniać inaczej. Ponadto, Zsh shell Z ma inne zasady.
kernigh

28

przypisuj funkcjom nowe nazwy, jeśli są używane wielokrotnie

x = SomeLongFunctionName
x(somedata)
x(somemoredata)
etc

Tylko jeśli użyjemy wystarczającej liczby połączeń z x.
elipszilon

28

Nazwy zmiennych jednoliterowych

Masz ich 52; użyj ich wszystkich! Nie bój się wypróbować różnych metod i porównać długości. Zna język i konkretne dostępne skróty / funkcje biblioteczne.


8
26 dla języków bez rozróżniania wielkości liter. :-)
Gaffi

12
Często $i _mogą być używane jako identyfikatory.
Griffin

4
@Gaffi: I więcej niż wystarcza dla języków, które pozwalają na identyfikatory Unicode, chyba że zadanie ogranicza Cię do ASCII lub liczy bajty zamiast znaków.
hammar

Jeśli liczysz bajty zamiast Unicode, to użycie rozszerzonego ascii może być sposobem na wyciśnięcie kolejnych ~ 120 identyfikatorów, jeśli ich potrzebujesz (nie że w przypadku skryptu golfowego powinieneś potrzebować więcej niż 26)
Scragar

2
@jest poprawną nazwą zmiennej w T-SQL, użyj jej zamiast @a.
BradC

25

Użyj operatora warunkowego.

Operator warunkowy

bool ? condition_true : condition_false

jest bardziej korzystne, charakter mądry, niż IF oświadczenie .

if(a>b){r=a;}else{r=b;}

można zapisać jako

r=a>b?a:b;

25
a&&b||cZamiast tego można używać języków, które nie mają trójki . Nieco dłużej, ale wciąż krócej niż if.
Michael Kohl

Z drugiej strony, niektórzy nie mogą skorzystać z żadnej z tych opcji (przychodzi na myśl VBA), ale obie są nadal dobrymi sugestiami. :-)
Gaffi

1
Gaffi: VBA ma Iff, choć jest to funkcja, więc podlega ocenie wszystkich argumentów.
Joey,

Używanie trójek w instrukcji if może być również bardzo pomocneif(a ? b : c)
Jojodmo

4
@MichaelKohl zauważa, że a&&b||cmoże powrócić, cgdy ajest prawdą, iff bjest fałszem, trochę
przewrotny

24

Napisz objaśnienie swojego kodu

Napisanie wyjaśnienia zmusza cię do dokładnego spojrzenia na każdą część kodu i do wyrażenia swoich myśli i wyborów przy pisaniu określonego fragmentu. W ten sposób może się okazać, że możliwe są różne podejścia, które mogą zaoszczędzić niektóre bajty, lub że podświadomie przyjęliście założenia, które niekoniecznie się utrzymują.

Ta wskazówka jest podobna do Pytanie o wybór algorytmu i wypróbuj coś zupełnie nowego ; odkryłem jednak, że krok polegający na spisaniu, w jaki sposób ma działać każda część, jest czasem kluczowy dla uświadomienia sobie alternatyw.

Jako bonus, odpowiedzi zawierające wyjaśnienia są bardziej interesujące dla innych użytkowników i dlatego są bardziej prawdopodobne, że zostaną ocenione.


23

Sprawdź dwukrotnie liczbę swoich postaci

Brzmi jak oczywisty, ale uważając, możesz być w stanie „uratować” kilka postaci, nie robiąc nic!

Jeśli używasz systemu Windows, możesz wprowadzać dane \r\nzamiast po prostu \rlub \npo naciśnięciu klawisza Return - dodając dodatkowy bajt na wiersz! Przekręć znaki kontrolne, aby podwójnie sprawdzić, czy tego nie robisz.

W Notepad ++ można przekonwertować wszystkie \r\nzakończenia linii, \rprzechodząc do Edit > EOL Conversion > UNIX/OSX Format.

Upewnij się także, że nie dołączasz żadnych białych znaków do liczby postaci! Przesuw wiersza w dolnej linii kodu również nie ma znaczenia, więc nie trzeba go też liczyć.


Nie sądzę, że kiedykolwiek widziałem przypadek, w którym to się naprawdę liczyło ...
Jacob

4
Właśnie miałem ten problem (dlatego go dodaję).
Sean Latham

21

Przeczytaj uważnie pytanie

Gra w golfa kodowego polega zarówno na zrozumieniu pytania (co jest zadawane, a czego nie zadawane, nawet jeśli byłoby to sugerowane w innych ustawieniach), jak na tworzeniu kodu, który (może) zaspokoi tylko to, o co pytamy.

Wszelkie dane wejściowe inne niż jawnie wymagane nie muszą być przetwarzane. Jeśli istnieją pewne przypadki testowe i nie ma ogólnych wymagań, kod może działać tylko w tych przypadkach. Itp.


15
Myślę, że lepszym nagłówkiem byłoby „Nie zajmuj się niepotrzebnymi przypadkami krawędzi”. Wyrażenie „Spróbuj znaleźć luki” przywodzi na myśl sposoby unikania robienia tego, co jest określone przez jakąś pomysłową reinterpretację zasad, podczas gdy to, co oferujesz, jest jedynie dobrą radą, aby nie nadmiernie wdrażać rozwiązania.
Jonathan Van Matre

1
Tak, ale pomysłowa interpretacja zasad jest również częścią gry w golfa! (0 rozwiązań char itp.)
Tobia,

8
To powinna / powinna być inna odpowiedź. Istnieje podstawowa różnica między, na przykład, wdrożeniem rozwiązania, które działa tylko dla ints, ponieważ OP nie wymagało obsługi zmiennoprzecinkowej, a odpowiedzią, która wypisuje tekst „dowolna liczba pierwsza większa niż 100”, ponieważ „nie powiedziałeś, że trzeba być rzeczywistą liczbą pierwszą ”.
Jonathan Van Matre

Myślę, że niektóre OP zawierają komunikat „Przypadki testowe mogą ulec zmianie; Twój kod musi nadal działać po zmianie” i naprawdę je zmienić, jeśli zobaczą tylko jedną odpowiedź, która koduje przypadki testowe.
Erik the Outgolfer,

20

Użyj operacji bitowych do sprawdzania liczb od 0 do dowolnych 2 n -1

Może to być trochę ostry futerał, ale czasami może się przydać. Opiera się na fakcie, że wszystkie liczby, których dotyczy m = 2 n -1, mają skrajnie prawe n bitów ustawione na 1.

Tak więc 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2 i tak dalej.

Sztuką jest x&~m. Zwróci wartość true, gdy niex jest pomiędzy 0 a (włącznie), a false w przeciwnym razie. Zapisuje 6 bajtów od następnego najkrótszego równoważnego wyrażenia :, ale oczywiście działa tylko wtedy, gdy spełnia 2 n -1.mx>=0&&x<=mm


18

Ponownie użyj parametrów funkcji zamiast nowych zmiennych


1
Na przykład w C twoja funkcja główna zawsze przekazuje liczbę argumentów dostarczonych do programu (czyli 1 - nazwa programu - domyślnie), więc main(i){...masz teraz zmienną o wartości 1 bez konieczności wykonywać dowolne zadania. 2 znaki tam zapisane.
Griffin

6
Myślę, że jest to dość specyficzne dla C. Skrypty nie potrzebują deklaracji, aw większości skompilowanych języków zdefiniowanie zmiennej nie jest dłuższe niż zdefiniowanie parametru.
ugoren

w Javie, gdy potrzebna jest tablica wewnątrz funkcji tego samego typu co jeden parametr, można zaoszczędzić kilka bajtów, umieszczając ten parametr jako ostatni i czyniąc go parametrem vararg; (użył tego, aby
zmniejszyć liczbę

18

Większa / mniejsza niż, aby zapisać cyfrę:

//use:
if(n>9){A}else{B}
//instead of:
if(n<10){B}else{A}

Pamiętaj tylko, aby zamienić kod z ifna elsei zrobią dokładnie to samo (lub zmienią boki nierówności)!

Uwaga: można to zastosować przy dowolnej sile 10 i ich negatywach:...-100, -10, 10, 100...

(link źródłowy)


Nie jestem pewien, czy rozumiem o co chodzi. Co to zmniejsza?
Gaffi

@ Gaffi, zapisujesz jedną postać i robią dokładnie to samo
ajax333221

vs. jaka alternatywa? Przepraszam, nie próbuję być uparty, po prostu tego nie rozumiem. (newb, tutaj, najwyraźniej ...)
Gaffi

1
O, rozumiem. Działa na dowolnym przejściu liczb całkowitych z 9 na 10, 99 na 100 itd. Przepraszam, że zajęło mi to tak długo! (Mówię tylko liczbę całkowitą, ponieważ widzę problem z n = 9,5 ...)
Gaffi

8
Również w niektórych językach (jeśli są obsługiwane), jeśli twoje liczby są wystarczająco duże / małe, notacja naukowa może faktycznie zaoszczędzić ci kilka znaków: if(n>99999)vsif(n<1e5)
scragar

16

Użyj> i <zamiast> = i <=

Podczas sprawdzania z zakodowanymi liczbami całkowitymi wartości, użyj >oraz <zamiast >=i <=gdzie to możliwe. Na przykład za pomocą

if(x>24&&x<51)

Jest o 2 bajty krótszy niż użycie

if(x>=25&&x<=50)

3
Powiązane: Jeśli masz pewność, że wynik nie może być ujemny, możesz użyć <1zamiast kontroli ==0zerowej (lub >0zamiast !=0kontroli lustrzanej).
Kevin Cruijssen

1
Czy nie powinieneś dodać uwagi o xbyciu liczbą całkowitą?
Zacharý

15

Unikaj przedwczesnych przerw w pętli

Jeśli biegnie się przez pętlę, aby sprawdzić 1 lub więcej wystąpień kontroli boolowskiej, może to sprawić, że wydajniejszy program może wyjść z pętli na pierwszej prawdziwej wartości. Jednak usunięcie przerwy i zapętlenie wszystkich iteracji pozwala na skrócenie kodu.

int main() {
bool m = false;
int n = 1000;
for (int i = 0; i < n; i++) {
if (i >= 100) {
m = true;
break; // remove this line
}
} 
return 0;
}

5
Można również uprościć ifoświadczenie daleko w tych przypadkach: m|=i>=100. (I można również uprościć i>=100, aby i>99w tym przypadku, ale nie jest to bardzo istotne tutaj)
Marinus

15

użyj -zamiast!=

dla porównań numerycznych:

Jeśli a jest równe b, a-bpowstaje 0, co jest fałszem. Wszystko inne niż 0jest prawdą; więc
jeśli jest używany w kontekście logicznym, a-b<=>a!=b

Jeśli używasz go razem if/elsez operatorem trójskładnikowym, może to również zaoszczędzić jeden bajt dla równości:
a==b?c:d<=>a-b?d:c


12

Rozdzielone ciągi dla długich tablic

Większość języków ma sposób na podzielenie łańcucha na tablicę łańcuchów wokół jakiegoś tokena. Będzie to nieuchronnie krótsze niż literał tablicowy, gdy długość osiągnie próg zależny od języka, ponieważ dodatkowy narzut na łańcuch będzie jedną kopią tokena o jednym znaku, a nie (przynajmniej) dwoma ogranicznikami łańcucha.

Np. W GolfScript

["Foo""Bar""Baz""Quux"]  # 23 chars

staje się

"Foo
Bar
Baz
Quux"n/  # 20 chars

W niektórych językach próg jest tak niski jak jeden ciąg. Np. W Javie

new String[]{"Foo"}  // 19 chars

staje się

"Foo".split("~")  // 16 chars

6
Godnym uwagi wyjątków Ruby, który stanowi tablicę-of-ciągi dosłownych automatycznie Dzieli przestrzeniami kosztem dwóch bajtów: %w{Foo Bar Baz Quux}.
Martin Ender

1
Perl zapewnia coś podobnego: qw(Foo Bar Baz Quux)staje się listą ciągów znaków.
BenGoldberg,

12

Zrozum, co zrobili inni ludzie

Oprócz zabawy, gdy badasz kod innych osób, możesz czasem odkryć dobry algorytm, o którym nie pomyślałeś, lub sztuczkę (czasem oczywistą), którą przeoczysz.

Czasami istnieje odpowiedź, którą można przetłumaczyć na inny język i skorzystać z zalet tego drugiego języka.


10

znać swoje pierwszeństwo operatora

Ilekroć połączysz kilka wyrażeń, sprawdź tabelę priorytetów operatora dla swojego języka, aby zobaczyć, czy możesz zmienić kolejność rzeczy, aby zapisać nawiasy.

Przykłady:

  • We wszystkich językach, które znam, operatory bitowe mają wyższy priorytet niż operatory logiczne: (a&b)&&cnie wymagają nawiasów: a&b&&ctak jak (a*b)+cnie.
  • a+(b<<c)można przepisać jako a+b*2**c.
    To nie oszczędza niczego dla tego przykładu, ale będzie, jeśli cjest to mała literałowa liczba całkowita (<14).
  • Operacje bitowe mają niższy priorytet niż większości operacji arytmetycznych, więc jeśli Twój język pośrednio rzuca logiczną do int, można zapisać bajt na a<b&&c<dz a<b&c<d(chyba trzeba krótką ocenę obwodu)

7

Krótsze pętle

Jeśli masz Xinstrukcje {wewnątrz }pętli for, możesz przenosić X-1instrukcje (wewnątrz )pętli for po drugim średniku, for(blah;blah;HERE)aby zapisać 3 bajty. (rozdziel instrukcje za pomocą przecinka ,)

Zamiast

for(int i=0;i<9;){s+=s.length();println(i++);}

możesz przenieść jedną z instrukcji do (nawiasów klamrowych for-loop, )a drugą pominąć

for(int i=0;i<9;println(i++))s+=s.length();

i zapisz 3 bajty (zapisałeś 1 bajt więcej dzięki @ETHProductions)


Mówiąc prościej,

zamiast

for(blah;blah;){blah 1;blah 2;...;blah X}

przesuń wyciągi, żeby tak się skończyło

for(blah;blah;blah 2,...,blah X)blah 1;

i zapisz 3 bajty


@ETHproductions Dzięki za grę w golfa napiwek :)
Kritixi Lithos

A jeśli forto ostatnie zdanie, ;staje się opcjonalne
elipszilon

7

Użyj unary ~dla a-b-1ia+b+1

Oprócz sugestii @Lynn dotyczących x+1-~x; i x-1~-x możesz także grać w golfa a-b-1i a+b+1.

a-b-1    // 5 bytes
a+~b     // 4 bytes

a+b+1    // 5 bytes
a-~b     // 4 bytes

Może to wyglądać na wskazówkę, której nie będziesz używać tak często, tak jakby używanie ~xzamiast -x-1nie zdarzało się często, ale użyłem jej wystarczająco dużo razy, aby uznać ją za przydatną wskazówkę. Zwłaszcza w przypadku indeksowania tablic w niektórych przypadkach możesz użyć ich powyżej.


6

Kompresuj i / lub smugi

Prosta sztuczka, którą wymyśliłem, próbując wycisnąć długą serię warunków połączonych przez ands (lub ors, w tym przypadku po prostu zamień „all” na „any”).

Na przykład:

if a>0 and a<10 and a+b==4 and a+3<1:

Staje się

if all([a>0,a<10,a+b==4,a+3<1]):

To fajne, muszę spróbować!
stokastic

4
Które języki mają all(array-of-Booleans)wbudowane?
Peter Taylor

3
Ruby to ma. [a>0,a<10,a+b==4,a+3<1].all?
kernigh,

4
Chociaż gdyby to był Python, if 10>a>0 and a+b==4>1>a+3:
użyłbyś

@PeterTaylor Haskell też ma
dumny haskeller

6

Polegaj na kompilatorze, aby zapewnić wymaganą wydajność.

Pamiętaj, które optymalizacje są gwarantowane przez kompilator i na jakich poziomach optymalizacji, i używaj ich swobodnie. A nawet jeśli wydajność nie jest problemem wymóg, nadal można przetestować z optymalizacji sprawie, i to tylko dlatego, że jeden znak zniżka kod jest wciąż technicznie poprawny bez flagi kompilatora.

Rozważ następującą funkcję Haskella, aby obliczyć 2 ^ n (ignorując fakt, że Haskell ma już wbudowany operator potęgowania lub trzy) (23 znaki):

p 0=1;p x=p(x-1)+p(x-1)

Problem w tym, że jest strasznie powolny, działa w wykładniczym czasie. Może to spowodować, że Twój kod będzie niestabilny lub nie spełnią żadnych ograniczeń wydajności podanych w pytaniu. Możesz skusić się na użycie zmiennej tymczasowej lub bezpośrednio wywołanej literału funkcji, aby uniknąć powtarzających się wywołań funkcji (25 znaków):

p 0=1;p x=(\y->y+y)$p$x-1

Ale kompilator może już to zrobić, wystarczy ustawić -Ojako flagę kompilatora! Zamiast wydawać kilka dodatkowych znaków na witrynę, aby ręcznie wyeliminować typowe podwyrażenia, po prostu powiedz kompilatorowi, aby wykonał podstawowe optymalizacje dla ogólnej liczby jednego lub dwóch znaków w całym programie.


@ETHproductions tak, przepraszam, zrobiłem
John Dvorak

Czy pierwszy przykład nie powinien być po prostu p(x-1)*2?
Cyoce

5

Może nieco oczywiste, ale ...

Skorzystaj z wartości zwracanych przez operatora

Pamiętaj, że operator przypisania zwraca wartość!

Na przykład, jeśli chcesz dodać y do x, a następnie sprawdzić, czy x jest większe od czegoś, możesz to zrobić

if(25<x+=y)

zamiast

x+=y;if(x>25)

A może po przycięciu chcesz znaleźć długość sznurka:

strlen(s=trim(s))

Zamiast

s=trim(s);strlen(s)

W jakim języku możesz wykonywać zadania w ramach połączenia? czy to jest słowo kluczowe arg?
kot

2
Myślę, że przypisania są wyrażeniami (z nową wartością przypisanej zmiennej jako ich wartością wyrażenia) w co najmniej C, C ++, C # i Javie. a = (b=c)+1;ustawia bna c, a następnie ustawia ana b+1.
Lynn,

@Lynn Try a=1+b=c. Możesz dodać PHP i JavaScript do swojej listy.
Tytus

2
Ruby robi to najlepiej. Daje =operatorowi wyższy priorytet po lewej niż po prawej stronie, więc 1+x=2jest ważny i ocenia na3
Cyoce

@Cyoce afaik jest tak we wszystkich językach, w których przypisanie jest wyrażeniem.
Tytus

5

Wykorzystaj wersję językową / kompilator / dziwactwa środowiskowe / nowe funkcje

Jest to szczególnie przydatne w przypadku , ale można je zastosować do innych wyzwań. Czasami błąd kompilatora może odejść od bajtu, błąd implementacji może pozwolić Ci zaoszczędzić kilka znaków lub naprawdę najnowocześniejsza funkcja może poprawić twój wynik.


4

Połącz wiele / zagnieżdżonych, jeśli kontrole za pomocą i / lub, jeśli to możliwe.

to znaczy:

if (a && (b || c)) {

}

zamiast:

if (a) {
    if (b) {
        //Do Stuff
    } elseif (c) {
        //Do same stuff
    }
}

5
Ponadto użyj bitowych warunków ( &, `|), aby usunąć więcej znaków.
FUZxxl,

2
Chociaż użycie bitowe &zamiast &&usuwać 1 znak w niektórych przypadkach zaburza pierwszeństwo operatora i będziesz musiał umieścić nawiasy, aby działało. Użyj go mądrze.
DollarAkshay

4

Znajdź lepsze sposoby inicjalizacji zmiennych

Kilka innych odpowiedzi już prawie o tym wspomniało, ale w wielu językach (ściśle wpisanych?) Inicjowanie xjako pusty ciąg znaków jest krótsze :

x:=""

lub xjako pusta runa (char) jak:

x:=''

niż

var x string

i

var x rune

Korzystanie z istniejących wartości jest oczywiście preferowane, ale nie takie łatwe.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.