<Tüm diller> golf için ipuçları


81

Bu yazının amacı, <all languages>belirli bir yerine kolayca uygulanabilecek tüm golf ipuçlarını toplamaktır .

Yalnızca mantığının dillerin çoğuna uygulanabileceği cevaplarını yayınlayın .

Lütfen cevap başına bir ipucu


5
Hangi metrik tarafından "çoğunluk"?
counterclockwis'i

2
@leftaroundabout, aynı sözcüğün ölçüsü tarafından
ajax333221

8
Sorun, birçok dilin (genellikle kısa ömürlü), tipik olmayan programlama ifadelerinin hiç bir anlam ifade etmeyen çok tipik olmayan paradigmalara sahip deneysel olmalarıdır. Yani " tüm dillerin çoğunluğu " yerine getirmek neredeyse imkansız. Bir şekilde, örneğin "düzenli olarak codegolf.SE'de kullanılan dillerin çoğunluğu" ile sınırlandırmalısınız. Şu anda, cevaplar “uzaktan C türevli dillerin çoğunluğu” gibi oldukça fazla görünüyor, ancak tüm yazılı kodların büyük çoğunluğu bunlarda yazılı olsa da, bu dillerin çoğunluğu değil .
saat

3
Kalanlar hakkında, sanırım hepimiz kabaca ne anlama geldiklerini biliyoruz. Bu, çoğunlukla dilden bağımsız optimizasyonlar, yani sadece Brainfuck'ta değil, aynı zamanda Python, C, Java ve Fortran'da da faydalı olanlar. Benzer şekilde çalışan birçok dilde uygulayabileceğiniz genel fikirler. Püf noktalarında ve CW sorularında bu kadar kesin ve spesifik olmanın bir gereği olduğunu sanmıyorum . Bu, başkalarının golf oynamasına yardım etmek, kızdırmak değil.
Joey,

14
Umarım kimse adı verilen bir dil <all languages>
yaratmaz

Yanıtlar:


72

Birleştirme Döngüleri

Genellikle iki sonuç döngüsünü veya iki iç içe döngüyü bir arada birleştirebilirsiniz.

Önce:

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

Sonra:

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

Ugoren döngüler hala aynı değil. @ Gaffi haklı.
kaoD

5
@kaoD, her iki durumda fooda, azamanlar barolarak adlandırılır b. Bunun nedeni, "after" ifadesinde, döngü a+bzamanlar, ilk açağrı foo, sonraki çağrıdır bar.
ugoren

Buna tekrar bakıyorum (çok, sonra) ve şimdi kendi sorumu anlamıyorum. Belki de daha önce üçlü operasyonu anlamadım. Şimdi gördüğüm gibi, mantıklı.
Gaffi

1
Woops, bunu gece geç saatte okudum. Haklısın!
kaoD

3
Çok benzer: for(y=0;y<Y;++y)for(x=0;x<X;++x)genellikle for(i=0;i<X*Y;++i)ile xdeğiştirilir i%Xve ydeğiştirilir i/X.
Lynn

62

Sadece açıkça söylemek gerekirse:

Algoritma seçiminizi sorgulayın ve tamamen yeni bir şey deneyin.

Golf oynarken (özellikle daha uzun programlara neden olan daha zor problemler), çoğu zaman diğer temel seçenekleri denemeden ilk seçtiğiniz yola sadık kalabilirsiniz . Tabii ki, bir seferde veya genel fikrin bir parçası olarak bir veya birkaç çizgiyi mikro-golf yapabilirsiniz, ancak genellikle tamamen farklı bir çözüm denemezsiniz.

Bu özellikle Hits 495'te (Kaprekar) fark edildi; burada gerçek algoritmadan sapma ve aynı sonuca ulaşmak için uygulayabileceğiniz kalıpları arama birçok dilde daha kısaydı (sadece J değil).

Dezavantajı, muhtemelen aynı şeyi yarım düzine kez çözmenizdir. Ancak HQ9 + hariç gerçekten tüm dillerde çalışır ( Hello World'ü çıkarmanın başka bir yolunu bulmak biraz boşuna olacaktır).


12
+1 Golf oynamak için iyi olmaya ek olarak, bu gerçek dünyadaki tüm programcılar için iyi bir egzersizdir!
Gaffi

52

Test Odaklı Geliştirme kullanın

Kodun çeşitli girişleri işlemesi gerekiyorsa, kapsamlı testler yazın ve hepsini çok hızlı bir şekilde çalıştırmayı kolaylaştırın. Bu, bir seferde bir bebek basamağı riskli dönüşümleri denemenizi sağlar. Golf daha sonra sapık niyeti ile refactoring gibi olur.


4
Bu yöntemin bir spinoff kullanın. Sorunların kendileri genellikle oldukça basit olduğu için işi yapan bir program yazıyorum. Genellikle bu "kolayca golf oynar" dır, bu yüzden özlüdür, ama yeni çizgiler vs. vardır. Bu dosyayı kopyalayıp yeni bir yere kopyaladım ve her seferinde kontrol edip programların seçilen bazı girdiler için aynı değerleri döndürdüğünü söylüyorum. Kırık bir programla beni terk ederken bir hata yaparsam, ne değiştiğimin hafızasını ve golf parçamı anlayamazsam, referans kaynağı olarak kaydedilen bir "spesifikasyon" dan bahsederim.
shiona

2
Bu yöntemi çok seviyorum, bu nedenle yazdığım tüm problemlere kapsamlı test paketleri dahil etme eğilimindeyim.
Joey,

@RubberDuck Kendinizi tekrar etmeyin ilkesi sık sık kesinlikle takip edilir.
Jonathan Frech

48

Mantıksal ifadeleri azaltmaya çalışın

Örneğin, eğer Ave Bboolean ve bir ölçüde numaraları gibi dil davranır mantıksal ifadenin vardır A and (not B)ve A>Beşdeğerdir. Örneğin Python'da

if A and not B:
    foo()

aynıdır:

if A>B:
    foo()

3
Bunu asla düşünmezdim.
cjfaure

27
B>A or foo()Bunu ifade etmek için daha kısa bir yol olurdu, yalnızca gerektiğinde hesaplamaları sağlamak için boolean ifadelerinin tembel değerlendirmesinden yararlanın.
scragar 11:14

5
@ scragar: Doğru, ama bu ipucunun amacı bu değil. (Yine de değerli bir bağımsız
bahşiştir

3
@scragar, B>A or foodeğerlendirmek istiyorum fooeğer B==Abiz istemiyor budur. (Sağ?)
msh210

2
Ayrıca, uzun süredir kısıtlanmış koşullarınız varsa (örneğin 5/6 parametrelerle), bunun için en kısa boolean ifadesini bulmak için bir Doğruluk tablosu ve Karnaugh haritası kullanabilirsiniz
Katenkyo

33

Sahip olduğunuz değerleri kullanarak değişkenleri sıfırlayın.

Bunun yerine, x=1zaten 1'e eşit bir şey aramaya çalışın.
Örneğin, bir işlevin dönüş değeri: printf("..");x=0;-> x=!printf("..");. 0 ile en kolay olanıdır, çünkü her zaman ihmal edebilirsiniz veya ihtiyacınız olan tek şey doğru gerçek değer olduğunda (ve 1 ya da 19 olması önemli değil).



1
@ std''OrgnlDave, Doğru, ama bu soru tüm diller için ortak olan şeyler hakkında.
ugoren

33

Tek terimli kullanın ~için x+1vex-1

Bu numara, bir bit bitsel olumsuzlama işleci ~ve bir düzenli düzenli olumsuzlama işleci olan diller için geçerlidir -.

Programınız, şans eseri, ifadeyi içeriyorsa, baytları kaydetmek için -x-1onunla değiştirebilirsiniz ~x. Bu çok sık gerçekleşmez, ancak -her iki ifadeyi de negatif edersek ( ) x+1eşittir -~x! Benzer şekilde, x-1eşittir ~-x. (Tilde hangi yöne işaret ettiğini düşünün: sağ +, sol -.)

Bu yararlıdır, çünkü tüm dillerde bu operatörlere sahip olduğunu düşünebiliyorum, çoğu operatörden daha yüksek önceliğe sahipler. Bu parantez içinde kaydetmenize olanak sağlar. Burada dört baytı nasıl kurtardığımızı izleyin:

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

30

Boşluğu sıkıştır

Dilinizde boşluk için kuralları bilin. Bazı noktalama işaretlerinin veya diğer karakterlerin etrafındaki beyaz alanlara ihtiyacı olmayabilir. Bu Bourne kabuğu işlevini düşünün :

f () { echo a; echo b; }

Bourne kabuğunda ();meta karakterlerdir ve çevreleyen boşluklara ihtiyaç duymazlar. Ancak, {}kelimeler ve meta karakterlerin yanında olmadıkça boşluk gerekir. Yanında 4 boşluk bırakabiliriz ();, ancak {ve arasında boşluk bırakmalıyız echo.

f(){ echo a;echo b;}

In Common Lisp ve PicoLisp , ()meta karakter olan. İki sayının ortalamasını bulmak için bu kodu göz önünde bulundurun:

(/ (+ a b) 2)

2 alanda golf oynayabiliriz.

(/(+ a b)2)

Bazı dillerin boşluk için tuhaf ve ince kuralları vardır. Bir tamsayı çizgisinin toplamını ve ürününü yazdıran bu Ruby programını düşünün.

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

Her birinin &kendinden önce bir alana ihtiyacı var. Ruby, i=$F.map &:to_ianlamına gelir i=$F.map(&:to_i)burada &bir blok parametresi geçirir. Ancak, bir ikili işlecin nerede olduğu i=$F.map&:to_ianlamına gelir .i=$F.map.&(:to_i)&

Bu tuhaflık, belirsiz noktalama işaretleri kullanan Perl veya Ruby gibi dillerde olur. Şüpheniz varsa, boşluk kurallarını test etmek için bir REPL kullanın veya kısa programlar yazın.


1
Neden "{" ve "echo" arasında bir boşluk olması gerekiyor ama ";" arasında değil ve "echo"?
Ryan,

3
Kullanım kılavuzundaki terimleri OpenBSD sh (1) için kullandım, ki "{" ayrılmış bir kelime ve ";" bir meta karakterdir. Bu nedenle, "{echo" bir kelimedir ama "; echo" iki kelimedir. Diğer kılavuzlar bunu farklı şekilde açıklayabilir. Ayrıca, Z kabuğu zsh farklı kurallara sahiptir.
saat

28

Birden çok kez kullanılırsa fonksiyonlara yeni adlar ata

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

Sadece yeterince arama yaparsak x.
elipszilon

28

Tek Harfli Değişken İsimleri

52 tane var; hepsini kullan! Farklı yaklaşımları denemek ve uzunlukları karşılaştırmaktan korkmayın. Dili ve mevcut özel kısayolları / kütüphane işlevlerini öğrenin.


8
Büyük / küçük harfe duyarlı olmayan diller için :-)
Gaffi

12
Genellikle $ve _tanımlayıcı olarak kullanılabilir.
Griffin

4
@Gaffi: Görev seni ASCII ile sınırlandırmadığı veya karakterlerden ziyade baytları saymadığı sürece Unicode tanımlayıcılarına izin veren diller için fazlasıyla yeterli.
Hammar

Unicode yerine bayt sayıyorsanız genişletilmiş ascii kullanmak, eğer gerekiyorsa başka bir ~ 120 tanımlayıcıyı sıkmak için bir yol olabilir (bir golf senaryosu için yine de
26'dan fazlaya

2
@T-SQL'de geçerli bir değişken adı, yerine kullanın @a.
BradC

25

Koşullu operatörü kullanın.

Koşullu bir operatör

bool ? condition_true : condition_false

IF ifadesinden daha faydalı, karakter açısından akıllıca .

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

olarak yazılabilir

r=a>b?a:b;

25
a&&b||cBunun yerine üçlü olmayan dilleri kullanabilirsiniz . Biraz daha uzun, ama yine de bir daha kısa if.
Michael Kohl

Sonra tekrar, bazıları seçeneklerden birini kullanamaz (VBA akla gelir), ancak ikisi de hala iyi önerilerdir. :-)
Gaffi

1
Gaffi: VBA, Iffbir işlevi olmasına rağmen, tüm argümanların değerlendirmesine tabi.
Joey,

Ve üçlü kullanma içinde ifadeleri de çok yararlı olabilir eğerif(a ? b : c)
Jojodmo

4
@MichaelKohl , doğru olduğunda a&&b||cgeri dönebilecek olan not iff yanlıştır, küçük bir dava, ama bunu unutmamalıyız ^^cab
Katenkyo

24

Kodunuzun bir açıklamasını yazın

Bir açıklama yazmak, kodunuzun her bir bölümüne tekrar dikkatlice bakmanızı ve belirli bir bölümün yazılmasında düşüncelerinizi ve seçimlerinizi açıkça belirtmenizi sağlar. Bunu yaparken, bazı baytları kurtarabilecek farklı yaklaşımların mümkün olduğunu veya bilinçli bir şekilde zorunlu olmayan varsayımlar yaptığınızı fark edebilirsiniz.

Bu ipucu, algoritma seçiminizi sorgulayın ve tamamen yeni bir şeyler deneyin ; Ancak, aslında her bir parçanın nasıl çalışması gerektiğini yazmanın adımının bazen alternatiflerin farkında olmak için çok önemli olduğunu buldum.

Bir bonus olarak, bir açıklama içeren cevaplar diğer kullanıcılar için daha ilgi çekicidir ve bu nedenle daha fazla puan kazanılması daha olasıdır.


23

Karakter sayınızı iki kez kontrol edin

Beyinsiz gibi geliyor, ancak dikkatli olunca, aslında hiçbir şey yapmadan birkaç karakteri "kaydedebilirsiniz"!

Windows kullanıyorsanız \r\n, tam yerine \rveya \nReturn tuşuna basıldığında giriyor olabilirsiniz - her satıra fazladan bir bayt ekleyerek! Kontrol karakterlerini sadece bunu yapmadığınızı kontrol etmek için çevirin.

Not Defteri'nde ++ tüm dönüştürebilirsiniz \r\nsadece satır sonları için \rgiderek Edit > EOL Conversion > UNIX/OSX Format.

Ayrıca, karakter sayınıza takip eden boşluk bırakmadığınızdan emin olun! Kodunuzdaki alt satırdaki satır besleme de önemsizdir, bu nedenle sayılmaları da gerekmez.


Bunun aslında sayıldığı bir dava gördüğümü sanmıyorum ...
Jacob

4
Ben sadece bu sorunu kendim yaşadım (dolayısıyla neden ekliyorum).
Sean Latham,

21

Soruyu dikkatlice oku

Kod golf (sorulur ve ne değildir sorusunu anlamak hakkında kadar değil sadece sorulan ne tatmin (olabilir) bu kodu üreten olarak başka herhangi bir ortamda zımni görünecek olsa da, sorulan).

Açıkça istenenin dışındaki herhangi bir girişin ele alınması gerekmez. Bazı test durumları varsa ve genel gereklilik yoksa, kodunuz yalnızca bu durumlarda işe yarayabilir. Vb.


15
Bence burada daha iyi bir başlık "Gereksiz uç davalarla ilgilenme" olur. "Boşlukları bulmaya çalış" ifadesi, kuralların ustaca yeniden yorumlanması yoluyla belirtilenleri yapmaktan kaçınmanın yollarını aklınıza getirir; oysa sunduğunuz şey, çözümünüzü aşırı uygulamamak için sadece iyi bir tavsiyedir.
Jonathan Van Matre

1
Evet, ama kuralların ustaca bir yeniden yorumlanması da kod golfünün bir parçası! (0 char çözüm, vb.)
Tobia

8
Yine de bu farklı bir cevap olurdu / olmalıdır. Örneğin, sadece float desteği gerektirmeyen sadece ints için işe yarayan bir çözüm uygulamak ile "100'den büyük olan herhangi bir asıl" metnini basan bir cevap vermek zorunda olduğu için temel bir fark var. asıl asal sayı olmak "#:.
Jonathan Van Matre

Bazı OP'lerin “değişime tabi Test vakaları; kodunuz değişiklikten sonra da çalışması gerekiyor” bildirimini içerdiğini ve testcas'ları kodlayan tek bir cevap görürlerse gerçekten değiştirdiklerini düşünüyorum.
Outgolfer Erik

20

0 ile herhangi bir 2 n -1 arasındaki sayıları kontrol etmek için bit yönünde işlemleri kullanın

Biraz kenar davası olabilir, ama bazen işe yarayabilir. M = 2 n -1 'in uygulandığı tüm sayıların , 1 olarak ayarlanmış en sağdaki bit değerlerine sahip olduğuna dayanır .

Öyleyse, 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2 vb.

İşin püf noktası x&~m. Bu her ne zaman doğrudur dönecektir xolduğunu değil 0 ile arasında m(dahil) ve yanlış aksi. Bir sonraki en kısa eşdeğer ifadeden 6 bayt kaydeder: x>=0&&x<=mancak açıkçası yalnızca m2 n -1 değerini karşıladığında çalışır .


18

Yeni değişkenler yerine işlev parametrelerini yeniden kullanın


1
Örneğin, C'de ana işleviniz her zaman programa verilen argüman sayısı (1 - program adı - 'varsayılan') 'dır, bu nedenle main(i){...şimdi sizinle birlikte 1 değeri olmayan bir değişken var Herhangi bir ödevi yap. Orada 2 karakter kaydedildi ..
Griffin

6
C. Script dillerinin bildirimlere ihtiyacı olmadığını ve bence bir değişkeni tanımlayan çoğu derlemede bir parametre tanımlamaktan daha uzun olmadığını düşünüyorum.
ugoren

java'da, bir parametreyle aynı tipte bir fonksiyonun içindeki bir diziye ihtiyaç duyduğunuzda, bu parametreyi en son olarak koyarak birkaç bayttan tasarruf edebilir ve onu vararg parametresi haline getirebilirsiniz; (Bir cümleyi en uzun sözcüğü bulmak için bir işlevde bazı baytları tıraş etmek için kullanılır)
masterX244

18

Rakam kaydetmekten büyük / küçük:

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

Sadece kod takas hatırlamak ifiçin elseve onlar tam olarak aynı şeyi (veya eşitsizlik taraf değiştirmeye) olacak!

Not: Bu, herhangi bir 10'luk güç ve negatifleri ile uygulanabilir:...-100, -10, 10, 100...

(kaynak link)


Bunun amacını anladığımdan emin değilim. Bu neyi azaltır?
Gaffi

@Gaffi bir karakter
kaydedersiniz

Ne alternatifi? Üzgünüm, engellemeye çalışmıyorum, sadece anlamıyorum. (newb, burada, görünüşte ...)
Gaffi

1
Ah, anlıyorum. 9'dan 10'a, 99'dan 100'e kadar herhangi bir tamsayı geçişi için çalışıyor. Üzgünüm, çok uzun sürdü! (Yalnızca tamsayı diyorum, çünkü n = 9.5 ile ilgili bir sorun görebiliyorum ...)
Gaffi

8
Ayrıca, bazı dillerde (eğer desteklenirse) eğer sayılarınız yeterince büyük / küçükse, bilimsel gösterimler aslında bazı karakterleri kurtarabilir: if(n>99999)vsif(n<1e5)
scragar 11:14

16

> = Ve <= yerine> ve <tuşlarını kullanın.

Kodlanmış tamsayı değerlerine karşı kontrol ederken, >ve <yerine >=ve <=mümkün olan yerlerde kullanın . Örneğin,

if(x>24&&x<51)

Kullanmadan 2 bayt daha kısa

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

3
İlgili: eminseniz bir sonuç kullanabilirdin, negatif olamaz <1yerine ==0sıfır çek olarak (veya >0yerine !=0yansıtılmış kontrolü için).
Kevin Cruijssen,

1
xTam sayı olma konusunda bir not eklememeli misiniz ?
Zacharı

15

Erken döngü aralarından kaçının

Bir boolean kontrolün 1 veya daha fazla örneğini kontrol etmek için bir döngüden geçiyorsanız, ilk gerçek değerden döngüden çıkmak daha verimli bir program yapabilir. Bununla birlikte, arayı kaldırmak ve tüm yinelemeler boyunca döngü daha kısa kodlara izin verir.

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
Ayrıca kolaylaştırabilirsiniz ifbu durumlarda uzak deyimi: m|=i>=100. (Ve ayrıca kolaylaştırabilirsiniz i>=100için i>99bu durumda ama bu burada çok alakalı değil)
mannus

15

-yerine kullanmak!=

sayısal karşılaştırmalar için:

Bir b eşitse, a-bsonuçlanan 0falsy olan. 0Gerçeğinden başka bir şey var ; öyleyse,
eğer bir boole bağlamında kullanılıyorsa, a-b<=>a!=b

if/elseÜçlü operatörle veya bu operatörle birlikte kullanırsanız , bu eşitlik için size bir bayt kazandırabilir:
a==b?c:d<=>a-b?d:c


12

Uzun diziler için ayrık dizeler

Çoğu dilde, bir dizgiyi, bir tür jetonun etrafındaki dizgilerin dizisine bölme yöntemi vardır. Uzunluk kaçınılmaz bir dil eşiğine ulaştığında bu kaçınılmaz olarak bir dizi değişmezden daha kısa olacaktır, çünkü dize başına ek yük, (en azından) iki dize sınırlayıcıdan ziyade bir tek char token'in bir kopyası olacaktır.

Örneğin, GolfScript'te

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

olur

"Foo
Bar
Baz
Quux"n/  # 20 chars

Bazı diller için eşik bir dize kadar düşüktür. Örneğin, Java’da

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

olur

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

6
Kayda değer bir istisnası otomatik olarak iki bayt pahasına boşluk böler bir dizilim-of-the dizileri içerir Ruby gibidir: %w{Foo Bar Baz Quux}.
Martin Ender

1
Perl benzer qw(Foo Bar Baz Quux)bir şey sağlar: dizelerin bir listesi haline gelir.
BenGoldberg

12

Başkalarının ne yaptığını anlayın

Eğlenceli olmanın yanı sıra, başkalarının kodunu incelerseniz, bazen düşünmediğiniz iyi bir algoritma veya gözden kaçırdığınız bir numara (bazen açık bir kod) keşfedebilirsiniz.

Bazen başka bir dile çevirebileceğiniz ve diğer dilin özelliklerinden yararlanabileceğiniz bir cevap vardır.


10

operatör önceliğini bilmek

Birkaç ifadeyi ne zaman birleştirirseniz, parantezleri kaydetmek için işleri yeniden düzenleyip düzenleyemeyeceğinizi görmek için operatör öncelik tablosunu kontrol edin.

Örnekler:

  • Bildiğim tüm dillerde, bitsel operatörler, boolean operatörlerinden daha yüksek önceliğe sahiptir: (a&b)&&cparantez gerektirmez: a&b&&caynen (a*b)+cdeğil.
  • a+(b<<c)olarak yeniden yazılabilir a+b*2**c.
    Bu, bu örnek için hiçbir şey kaydetmez, ancak cküçük bir tamsayı değişmez ise olacaktır (<14).
  • Bit düzey işlemleri en aritmetik işlemlerin daha düşük önceliğe sahip, bu nedenle dil örtük int boolean atmalarını bile, bir bayt kaydedebilirsiniz a<b&&c<dile a<b&c<d(kısa devre değerlendirme gerekmedikçe)

7

Daha kısa döngüler

Eğer varsa Xifadeleri {içine }sizin için-döngü, hareket edebilir X-1ifadeleri (içindeki )ikinci noktalı virgül sonrası için-döngü for(blah;blah;HERE)3 bayt kaydedin. (ifadeleri virgül kullanarak ayırın ,)

Onun yerine

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

ifadelerden birini diğerinin dışına çıkarken for-loop'un (parantezlerine taşıyabilirsiniz)

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

ve 3 bayttan tasarruf edin (@ETHProductions sayesinde 1 bayt daha tasarruf edildi)


Basitçe söylemek gerekirse,

onun yerine

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

ifadeleri hareket ettirin, böylece bununla bitin

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

ve 3 bayt tasarruf edin


@ETHproductions Bahşiş bıraktığın için teşekkürler :)
Kritixi Lithos

Ve eğer forson söz ise, ;isteğe bağlı olur
elipszilon

7

Tek terimli kullanın ~için a-b-1vea+b+1

Ek olarak @Lynn ilgili 'ın önerileri x+1-~x; ve x-1~-x , ayrıca golf a-b-1ve a+b+1.

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

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

Sık sık kullanmayacağınız bir ipucu gibi görünebilir, ~xbunun yerine kullanmak yerine -x-1sık sık olmaz, ama burada yararlı bir ipucu olarak görmek için yeterince zaman kullandım. Özellikle dizi indeksleme ile bazı durumlarda yukarıdakileri kullanabilirsiniz.


6

Sıkıştırın veya çizgileri sıkıştırın

Basit bir numara, ands (veya ors, 'bu durumda sadece' all 'yerine' any 'ifadesini kullanırsanız) ile zincirlenmiş uzun bir koşul dizisini sıkmaya çalışırken ortaya çıktım.

Örneğin:

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

Oluyor

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

Bu harika bir tane, denemek zorundayım!
stokastic

4
Yerleşik hangi diller var all(array-of-Booleans)?
Peter Taylor

3
Ruby'de var. [a>0,a<10,a+b==4,a+3<1].all?
kernigh

4
Her ne kadar bu Python olsaydı, bunun gibi bir şey kullanıyor if 10>a>0 and a+b==4>1>a+3:
olsaydınız

@PeterTaylor Haskell de var
gururlu haskeller

6

Gerekli performansı sağlamak için derleyiciye güvenin.

Hangi optimizasyonların derleyici tarafından ve hangi optimizasyon seviyelerinde garanti edildiğinden emin olun ve bunları liberal bir şekilde kullanın. Performans kaygılı bir gereksinim olmasa bile , optimizasyonları hala test edebilir ve ardından bir karakter iskonto edebilirsiniz çünkü kodunuz derleyici bayrağı olmadan teknik olarak hala geçerlidir.

2 ^ n'yi hesaplamak için aşağıdaki Haskell işlevini göz önünde bulundurun (Haskell'in zaten yerleşik bir üstel çalıştırma operatörü olduğu gerçeğini göz ardı ederek) (23 karakter):

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

Sorun şu ki - korkunç derecede yavaş, üstel bir zamanda çalışıyor. Bu, kodunuzu test edilemez hale getirebilir veya soru tarafından verilen performans kısıtlamalarını kaldıramaz. Tekrarlanan işlev çağrılarını engellemek için geçici bir değişkeni veya hemen çağrılan bir işlevi kullanmak için cazip olabilirsiniz (25 karakter):

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

Ancak derleyici bunu sizin için zaten yapabilir, -Oderleyici bayrağı olarak ayarlamanız yeterlidir ! Yaygın olarak kullanılan alt ifadeleri elimine etmek için site başına birkaç fazladan fazla karakter harcamak yerine, derleyiciye tüm program boyunca toplamda bir veya iki karakter toplamı için temel optimizasyonlar yapmasını söyleyin.


@ETHproductions evet, üzgünüm, yaptım
John Dvorak

İlk örnek sadece olmaz p(x-1)*2mıydı?
Cyoce

5

Belki biraz açık ama ...

Operatör dönüş değerlerini kullanın

Atama operatörünün bir değer döndürdüğünü unutmayın!

Örneğin, x'e y eklemek ve ardından x'in bir şeyden büyük olup olmadığını kontrol etmek istiyorsanız, yapabilirsiniz

if(25<x+=y)

onun yerine

x+=y;if(x>25)

Ya da kırptıktan sonra dizenin uzunluğunu bulmak istersiniz:

strlen(s=trim(s))

Ziyade

s=trim(s);strlen(s)

Hangi dilde atama yapabileceği Görüşme? Yoksa bu bir anahtar kelime argümanı mı?
kedi,

2
Bence atamalar en azından C, C ++, C # ve Java'daki ifadelerdir (atanan değişkenin ifade değeri olarak yeni değeri olan). a = (b=c)+1;ayarlar biçin cayarlar, sonra ve aiçin b+1.
Lynn

@Lynn Deneyin a=1+b=c. Ve listenize PHP ve JavaScript ekleyebilirsiniz.
Titus

2
Ruby bunu en iyisini yapar. =Operatöre soldan sağa göre daha yüksek bir öncelik verir , bu yüzden 1+x=2geçerlidir ve değerlendirir3
Cyoce

@Cyoce afaik, bir ödevin bir ifade olduğu tüm dillerde bu şekildedir.
Titus

5

Dil sürümünün / derleyicinin / çevre sorunlarının / yeni özelliklerin kullanılması

Bu özellikle için kullanışlıdır , ancak diğer zorluklara da uygulanabilir. Bazen, bir derleyici hatası bayttan atılabilir, bir uygulama hatası birkaç karakter kaydetmenize izin verebilir veya gerçekten kanama sağlayan bir özellik puanınızı artırabilir.


4

Mümkünse ve / veya kullanarak kontrol ediyorsanız çoklu / iç içe birleştirin.

yani:

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

}

onun yerine:

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

5
Ayrıca, &daha fazla karakter silmek için bitty koşullarını kullanın ( , `|).
FUZxxl

2
Her ne kadar bit &yönünde kullanmak yerine &&1 karakteri kaldırsa da bazı durumlarda operatör önceliğini bozar ve çalışması için parantez koymak zorunda kalırsınız. Akıllıca kullanın.
DollarAkshay

4

Değişkenlerinizi başlatmak için daha iyi yollar bulun

Diğer bazı cevaplar da bunu söylemekten çok yaklaştı, ancak birçok (kesinlikle yazılan?) Dilde, şu xşekilde boş dize olarak başlatılması daha kısa :

x:=""

veya xboş rune (char) gibi:

x:=''

göre

var x string

ve

var x rune

Önceden varolan değerleri kullanmak açıkça tercih edilir, ancak bu kadar kolay değildir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.