Japt'te golf için ipuçları


18

Şimdi Code Golf'e tamamen bağımlıyım, muhtemelen birkaç golf dili almaya çalışmanın zamanı geldi.

Neredeyse tamamen JavaScript'te oynadığım düşünüldüğünde, Japt başlangıç ​​için mantıklı bir dil gibi görünüyor. Bir sonraki fırsatta belgelere dalacağım ama bu arada Japt için her türlü ipucunu aşağıdaki cevaplara gönderin.

Japt ve genel olarak golf dillerinde bir acemi olduğum için, ipuçlarınızı JavaScript'e "çevirebilseniz", mümkünse, bu şeylerle başa çıkmama yardımcı olmak için büyük bir yardımcı olurdu.


Heh, bunu gönderdiğin için teşekkürler. Bunu yapmaya devam edecektim çünkü Japt'u bir noktada yeniden tasarlamak istiyorum, ama bu yakın zamanda olmayacak ve muhtemelen zaten çok fazla ipucu vermeyecek. Kendim için ipucu: bir eğitim yazın: P
ETHproductions 17:17

Japt sohbet odasını ziyaret etmeyi unutmayın :)
Oliver

Yanıtlar:


11

JavaScript'ten Japt'a geçiş

Bildiğiniz gibi Japt, JavaScript'in kısaltılmış, genişletilmiş bir sürümüdür. Japt'u yarattım çünkü String.fromCharCode(x)ve gibi uzun mülk adlarından ve Math.floor(x)bir aralık oluşturmak gibi şeyler yapmaktan sıkıldım. JavaScript'ten Japt'a giderken bilmeniz gereken minimum minimum değer:

  • Japt aktarılan bir dildir; Japt kodu JavaScript'e aktarılır ve ardından JS olarak çalıştırılır. (Sanırım derlenmiş diyebilirsin , ama nakledilen daha yenilikçi geliyor. Yasal Uyarı: Yenilikçi olmak hakkında kesinlikle hiçbir şey bilmiyorum)
  • Tüm girişler varsayılan olarak tam programlardır. Giriş dolaylı ayrıştırılır ve ilk altı giriş değişkenleri konur U, V, W, X, Y, ve Z; tam diziN . Son ifadenin sonucu otomatik olarak yazdırılır.
  • Tüm büyük harfler değişkendir ve aktarıldığında aynı kalır. Çoğu önceden ayarlanmış değerlere sahiptir, bu değer Japt belgelerinin "Değişkenler" bölümünde ( yorumlayıcıda ) bulunur.
  • Tüm küçük harfler prototip işlevler veya yöntemlerdir . Japt sayılar, dizeler ve diziler üzerine a- z(ve à- ÿ) yöntemlerini ekler . Bu harflerden birini kullandığınızda, Japt .ve (; Uciçinde Japt U.c(, türüne bağlı olarak tavan, charCodeAt veya concat anlamına gelebilecek JavaScript ile eşdeğerdir U. Japt'un gücünün çoğu buradan geliyor; bu yöntemlerin tam listesini Japt belgelerinin "_____ fonksiyonları" bölümlerinde bulabilirsiniz ( yorumlayıcıda ).
  • Bir alan temsil eder )ve )temsil eder )). Çünkü Japt'i ilk tasarladığımda mümkün olduğunca çok bayt kaydetmek istedim ve bunu ilk olarak böyle yapmayı düşündüm. (Rağmen Us w ndaha iyi görünüyor Us)w)n), IMHO.)
  • Bir fonksiyon olarak ifade edilir ABC{...}burada, ABCdeğişken herhangi bir dize olabilir. İşlevler çoğunlukla JS'de olduğu gibi çalışır, en son ifade olan ana fark otomatik olarak döndürülür ( returnES6 parantezlerini kullanmak veya süslemek yerine ).
  • 'tek bir karakter dizesini belirtir (yani 'aile aynıdır "a") ve bir #sonraki karakter kodunu alır ve bu sayı olur ( #eile aynıdır 101).
  • $Transpilasyon işlemi sırasında dolar işaretleri arasındaki her şey aynı kalır. forÖrneğin, Japt bunlara sahip olmadığı için döngüler uygulamak için bunu kullanabilirsiniz , ancak diğer yöntemleri ( mdizeler ve diziler veya osayılar gibi) kullanmanızı öneririm .
  • Diğer birçok karakter yaygın JS kullanılan - "", 0-9, (, +, =, vb - Aynı (Zaten çoğunlukla) transpiled zaman muaftır.

Temel Japt kodunu yazmak için bilmeniz gereken tek şey bu. Japt'te maksimum golf gücü elde etmek daha fazla bilgi gerektirir, ancak bu diğer cevaplarda bulunabilir.


İşte temel bir örnek. Bir dizi ASCII karakteri almak ve her birini onaltılık karakter koduyla değiştirmek istediğinizi varsayalım. Bunu JavaScript'te nasıl yapabileceğiniz aşağıda açıklanmıştır:

U.split("").map(x=>x.charCodeAt(0).toString(16)).join("")

Şimdi Japt'ye dönüştürün. .split("")JS'de q""Japt'e eşdeğer , hatta daha da kısadır q. .join("")aynı zamanda q, nesnenin dize yerine bir dizi olmasıdır. .map(olduğunu m, .charCodeAt(olduğunu cve .toString(olduğunu s. Yani Japt kodumuz şöyle görünebilir:

Uq mX{Xc0 s16} q 

Japt'ta olsa da, mdizelerde olduğu gibi dizelerde de çalışır, böylece her ikisini de kaldırabiliriz q:

UmX{Xc0 s16}

Çevrimiçi test edin! "JS kodu" kutusunda görebileceğiniz gibi, bu doğrudan şuraya aktarılır:

U.m(function(X){return X.c(0).s(16)})

Japt ile çalışmayı öğrendikçe, JavaScript'ten ileri geri dönüşüm yapmaya gittikçe daha az odaklanacak ve Japt'ta kendi dili olarak kod yazabileceksiniz. İşte JavaScript bölümünü tamamen bırakarak bir açıklama:

UmX{Xc0 s16}
               // Implicit: U = input string
UmX{       }   // Take U, and replace each character X with the result of this function:
    Xc0        //   Take the char-code at index 0 in X (the first and only one).
        s16    //   Convert this to a hexadecimal string.
               // Implicit: output result of last expression

Başka bir adım göstermek daha iyi olabilir: unicode kısayolları. Bu durumda, onlarla 2B tasarruf edebiliriz. Ayrıca, sonunda belirli şeyleri dışarıda bırakabileceğinizi de eklemek isteyebilirsiniz. Bu başka bir bayt kurtarabilir.
Luke

Mükemmel bir astar, teşekkürler, ETH. Sanırım beni birkaç basit zorluğa sokmaya yetecek kadar var.
Shaggy

Bunu şimdiye kadar README'den topladığım şeyle birleştirerek, yukarıdaki örneğin daha da kısaltılabileceği doğru olur Um_c s16mu?
Shaggy

Ya da, yine de daha kısa: ¡Xc s16?
Shaggy

1
@Shaggy Haklısın! Dostum, bunu çabucak anladın ;-) Ben muhtemelen diğer cevaplar gibi bazı temel Japt golf ipuçları (Unicode kısayolları ve benzeri gibi) ekleyeceğim.
ETHproductions

8

Dizi Dizilerini Sıkıştırma

GÜNCELLEME: Bu ipucunda yer alan araçlar o zamandan beri yeniden yazıldı, geliştirildi ve Japt yorumlayıcıma entegre edildi . En iyi sonuçlar için, bu kompresörü aşağıda bağlı olanlardan herhangi birinde kullanmanız önerilir. Biraz daha zamanım olduğunda bu ipucuna tekrar bakacağım ve yeni kompresör göz önünde bulundurularak yeniden yazacağım.

Giriş

Kodunuzda bir dizi dizeniz varsa, onu sıkıştırmanın en belirgin yolu her dizeyiOc ayrı ayrı çalıştırmaktır . Bu ipucunun amaçları doğrultusunda, ["lollipop","marshmallow","nougat","oreo"]başlangıçta 42 bayt ağırlığında olan diziyle çalışacağız . Her dizeyi çalıştırmak Ocbize şunları verir:

[`lo¥ipop`,`Ú\hÚaow`,`Í`,`eo`]

Şimdi 33 bayt, iyi bir tasarruf.


Aşama 1

Ama daha iyisini yapabiliriz. Diziyi satır satırından ayrılmış bir dizeye birleştirirsek, dizimizi almak için köşeli parantezlerden, virgüllerden ve yabancı backticklerden kurtulabilir ve satır satırına ayırabiliriz. Bunu örnek dizimize uygulamak bize aşağıdakileri verir:

`lo¥ipop
Ú\hÚaow
Í
eo`·

Şimdi 26 bayta kadar.


Adım 2

Ama yine de daha iyisini yapabiliriz! Sıkıştırma işlemine dahil edilebilecek yeni satır yerine dizeleri ayırmak için küçük harf kullanabiliriz. zdizelerimizin hiçbirinde kullanılmaz, hadi bunu bırakalım ve nasıl başlayacağımızı görelim.

`lo¥ipopzÚ\hÚaowzÍzeo`qz

Ah, fındık - orada gelişme yok; bayt sayımız bir arttı! Kullanabileceğin başka bir mektup var olabilir ama, senin dizeleri bağlı denemek için epeyce olabilir - bizim örneğimizde 11 vardır: b,c,d,f,j,k,q,v,x,y,z. Her birini denemek oldukça sıkıcı olurdu, bu kullanışlı araç burada devreye giriyor; satırsonu ayrılmış dizelerinizi beslediğinizde, dizelerin hiçbirinde bulunmayan her harfle sınırlandırılmaya çalışılacaktır:

  • en kısa sıkıştırılmış dize,
  • kullandığı sınırlayıcı ve
  • uzunluğu.

Örnek dizelerimizin içinden geçilmesi, bunun ben iyi sonuçları verdiğini gösterir :

`lo¥ipáæqrÚaowbÍÞo`qb

Ve işte burada, sadece 24 bayta düştük.


Aşama 3

Ama daha iyisini yapabiliriz ! Dizinizdeki dizelerin sırası önemli değilse, belki de daha kısa çalışabilecek farklı bir sınırlayıcı ile birlikte farklı bir permütasyon olabilir. Bununla birlikte, her olasılığı denemek çok daha sıkıcı olacaktır. 4 telimizle denemek için 24 farklı permütasyon vardır. 264 haline gelen 11 olası harfin her biri ile! Bu araç devreye giriyor. Yine, yeni satır ayrılmış dizelerinizi besleyin ve her permütasyonun ve her sınırlayıcı mektubun her kombinasyonunu deneyecek, çıktı:

  • en kısa sıkıştırılmış dizedeki dizelerin sırası,
  • sıkıştırılmış dize,
  • kullandığı sınırlayıcı ve
  • uzunluğu.

İçinden bizim örnek dizeleri Koşu gösterir "nougat","oreo","lollipop","marshmallow"ile bbir ayırıcı sadece 23 nihai bayt sayısı ile, daha iyi sonuçlar vermektedir:

`ÍÞo½o¥ipáæqrÚaow`qb


Bonus İpucu: Tamsayı Dizi Sıkıştırma

Aynı prensibi, önce her birini daha yüksek bir tabana dönüştürerek tamsayı dizilerine uygulayabilirsiniz. Bu örnek kullanılarak, 36 baytlık dizi:

[588181,156859,595676,475330,680474]

İlk olarak 32 temel dizeden oluşan bir diziye dönüştürüp ardından ilk sıkıştırma programında çalıştırarak 29 bayta düşürebiliriz:

`huclt4p5r5ÛÊg62tkogq`qt mnH

Veya ikinci programı kullanarak 27 bayt kadar düşük:

`4p5Ïcl5ÛÊg62tkogq`qt mnH

Tamsayı dönüşümünü dizide zaten çalıştırdığınız bir yönteme taşıyarak bunun üzerine başka bir bayt veya 2 kaydedebilirsiniz.


notlar

  1. 1 veya 2 ekstra bayt q<letter>(<space>)maliyetini hesaba katmayı unutmayın ·. Bununla birlikte, sınırlayıcınıza bağlı olarak bir bayt geri almak için Unicode kısayollarından birini kullanabilirsiniz ( örneğin , aynıdır ql<space>).
  2. Son aracı kullanırken dikkat edilmesi gereken bir nokta: Ne kadar çok dizeniz varsa, o kadar fazla permütasyon olur ve program yavaşça çalışana kadar yavaşlar. Yukarıda ayrıntılı olarak açıklandığı gibi, 4 örnek dizimiz ve 11 olası harfimizle, 264 olası kombinasyon var, aynı 11 harfle dize sayısını sadece 1 artırın ve zaten denemek için 1320 kombinasyonumuz var. (İsterseniz kombinasyon sayısını saymak için bu aracı kullanabilirsiniz ).

Kredi

  • Oliver, bu ipucunda bulunan araçları yaratmak için ilham kaynağı oldu.
  • Düzeltme için ETHproductions.

6

Dizeleri sıkıştırma

Japt (şu anda) string sıkıştırması için shoco kütüphanesini kullanmaktadır . OcKüçük harfli harfler içerdiği sürece rastgele bir dizeyi sıkıştırabilirsiniz :

Oc"Hello, World!"

Bu çıktı HÁM, WŽld! ( Žteknik olarak yazdırılamaz bir karakterdir). Bunu ters çenelere sararak açabilirsiniz:

`HÁM, WŽld!`

Çevrimiçi test edin!

Alternatif olarak, Odişlevi rasgele bir dizenin sıkıştırmasını açmak için kullanabilirsiniz . Bu genellikle yararlı değildir, ancak amaçları vardır ...


Eğer "Merhaba Dünya!" meydan okuyordum, sadece kullanır HÁM, WŽld!mıydım yoksa geri çukurlara konması gerekir mi? Ben ikincisini tahmin ediyorum.
Shaggy

2
@Shaggy Bir soruyu cevaplarken tüm kodu eklemeniz gerekir, bu yüzden `HÁM, WŽld! bu durumda
Martijn Vissers

6

Karakter Kodlarıyla Sayıları Kısaltma

Japt'te #bir karakter kodu oluşturmak için bunu ve ardından bir karakter kullanabilirsiniz. Bu, daha uzun sayıları kısaltırken kullanışlı olur.

@ETHproductions'ta belirtildiği gibi, UTF-8'e geçmek istemiyorsanız, bu yalnızca 100-255 aralığındaki üç basamaklı çalışmalarda çalışır.

Örnekler:

123 kısaltılabilir #{

101 kısaltılabilir #e

Bunları birlikte zincirleyebilirsiniz:

123101 kısaltılabilir #{#e

Sen kullanabilirsiniz String.fromCharCode(123)JavaScript veya 123dJapt uygun karakteri bulmak için.

String.fromCharCode(123) İadeler {


Teşekkürler, @obarakon, topu yuvarlamak için harika bir ipucu; String.fromCharCode()bayt sayınızı artırabilecek çok uzun JS yöntemlerinden biridir. Muhtemelen, bunlar tamsayı olarak kabul edilir mi? Yani, 123bir çözümde tamsayıya ihtiyacım varsa , #{bir bayt kaydetmek için kullanabilirsiniz .
Shaggy

1
Evet, bunlar tamsayılar. -QBayrağı giriş pencerenize eklerseniz, çıktı türünü daha iyi görüntüleyebilirsiniz: dizeler , diziler vb. Tırnak işaretleri
Oliver

1
Bunu belirtmeliyim String.fromCharCode(123)JavaScript eserleri fakat yapabileceğin 123daynı sonucu elde etmek için Japt içinde ;-) Ayrıca, bu sadece aralığında üç basamaklı ishal çalışır 100- 255(sürece sizsiniz, UTF-8'e geçmek için istekli)
ETHproductions

@ETHproductions İyi çağrı, güncellendi!
Oliver

5

Hızlı ipucu: Boş dizi []

Japt boş dizisi için bir sabitine sahiptir: A. Ancak, erişebilmek için, ;Japt'ın alternatif sabitlerini kullanmak için programınıza noktalı virgül koymanız gerekir , aksi takdirde Aolur 10. Yani kullanarak ;Aaslında üzerinde tasarruf 0 bayt sunuyor [], ama olacak bir değişkene dizinizi atamak için (örneğin, gerekirse bayt kaydetmek A=[]).

Ancak, (ve yalnızca programınız) herhangi bir girdi almıyorsa, girdi dizisi olan Ndeğişkeni kullanarak boş girdi dizisine yalnızca 1 baytla erişebilirsiniz - girdi olmadan boş olur. Burada deneyin .

Bu aynı zamanda bazı durumlarda, programınızın varsayılan sabit değerleri kullanmak ve izin yararı vardır, yaşayamaz kullanmakta üzerinde bayt hala tasarrufu ;Aprogram için kısayol giriş sayesinde alıyor bile s1ve s2.


2
Vay, kullanmayı düşünmemiştim N, güzel fikir.
ETHproductions

2
İyi olan, @Shaggy!
Oliver

4

JavaScript'i değerlendirme

Japt, ham JavaScript'i sararak yürütmenize izin verir $...$.

Örneğin, $alert("hello world")$

Bu Japt otomatik-kapama yararlanarak kısaltılabilir $ve ).

$alert("hello world")$ kısaltılabilir $alert("hello world"

JavaScript'i Sıkıştırma

JavaScript'i kullanarak da sıkıştırabilirsiniz Ox.

Kullanmak istediğiniz bir JavaScript işlevi varsa, diyelim ki screen.width, dizeyi "screen.width"kullanarakOc sıkıştırabilir ve ardından sonucu Ox` arasına ekleyebilirsiniz ...

Başka bir şey izlemediğinde Japt'ta kapatma tırnaklarına ihtiyacınız olmadığını unutmayın.


@Shaggy Dizeyi Oxdeğerlendirmek için gerekir . Aksi takdirde, metnin çıktısını alırsınız "screen.width". Örnek
Oliver

4

Bayrakları tanıyın

En son meta konsensüse göre (Aralık 2017) , komut satırı bayrakları artık bayt sayılmaz. Japt için gerçekten harika bir haber, çünkü giriş / çıkışta ekstra tedavi için birçok bayrak var.

Japt'taki mevcut tüm bayraklar değerlendirme sırasına göre aşağıda açıklanmaktadır . Aynı gruptaki bayraklar birbirlerine özeldir. Farklı gruplardaki bayraklar gibi bir şey sonuçlanan bir arada kullanılabileceğini Not bu :)

mdefæ

Tüm program ilk argüman ( U) üzerinden eşlenir .

Daha fazla argüman varsa, bunlar olduğu gibi iletilir (yani çift ​​eşlenmiş değil ). Aksi takdirde, ikinci argüman dizindir ve üçüncüsü de tıpkı tüm dizidir U.m. Eğer Ubir sayıdır, o aralığına dönüştürülür; dize ise karakter dizisine dönüştürülür ve sonuçlar birleştirilir.

  • -m: Yukarıdakileri uygular ve başka bir şey yapmaz.
  • -d: trueBir sonuç doğruysa döndürür , falseaksi takdirde.
  • -e: trueTüm sonuçlar doğruysa döndürür , falseaksi takdirde.
  • -f: USonuçları doğrudur.
  • : -fİlk öğesini uygular ve döndürür.

gh

Belirtilen dizindeki bir öğeyi alır.

  • -g: İlk elemanı alır (indeks 0).
  • -gX: Elemanı indekste alır X(herhangi bir pozitif tamsayı olabilir).
  • -h: Son elementi alır.

Sonucu boole'ye dönüştürün.

  • -!: Boole uygula.
  • : Boole'i ​​iki kez değil uygulayın (gerçeği döndürür).

N

Sonucu sayıya dönüştürün. Tekli artı kullanılır.

PRSQ

Bir çeşit dizgiye dönüştür.

  • -P: İle diziye katılın "".
  • -R: İle diziye katılın "\n".
  • -S: İle diziye katılın " ".
  • -Q: Uygula JSON.stringify(yalnızca bir dizi değil, herhangi bir nesne olabilir). Örnek .

x

İşlevi xçıktıya uygular. (Kelimenin tam anlamıyla x, "herhangi bir küçük harf alfabe işlevi" değil.)

  • Dizi: Toplam.
  • String: Her iki uçtan da kırpın.
  • Sayı: Tamsayıya yuvarlanır.

2
Bayrakları kullanmanın bir Japt sunumu olarak sayılmadığını, bu belirli bayraklarla bir dil sunumu olarak sayıldığını unutmayın.
Nit

3

Unicode kısayolları

Gibi sadece tek bir ASCII char içinde saklanan edilemez Japt birçok ortak yapıları vardır qS , p2 , mX{, , vb Yani bu aşmanın, Japt aralığında karakterlerdir "Unicode kısayolları" vardır \xA1- \xDE( ¡- Þ) bu ortak yapılara doğru genişler. Bunların tam bir listesini tercüman belgelerinde bulabilirsiniz .

Ek olarak, @açılımı XYZ{ve _açılımı Z{Zelde etmenizi sağlamakla işlevlerine. Öyleyse örnek programımızı başka bir cevaptan golf oynayalım :

UmX{Xc0 s16}

Birincisi, X{Xile değiştirebiliriz _, bu da bize şunları verir:

Um_c0 s16}

Sonra başka bir bayt tasarrufu m_ile değiştirebiliriz ®:

U®c0 s16}

Ya da yerini alabilecek X{ile @bize veren:

Um@Xc0 s16}

Bu daha sonra ¡iki baytı kaydetmek için kısayolu kullanmamıza izin verir :

¡Xc0 s16}

Bu iki yoldan biri diğerinden 1 bayt daha kısaltılabilir. Hangisini bulabilir misin?


1
®c s166 bayt için - bir kurabiye kazanabilir miyim ?!
Shaggy

@Shaggy Yeterince sert bakarsanız 1 bayt daha tasarruf edebilirsiniz ...;)
ETHproductions 18:17

Olur ®c sGmu?
Shaggy

1
Evet! Bence bu gidebildiğin kadar düşük. Aferin! :-)
ETHproductions

2
Birkaç kısa ay içinde Japt'ün ilerleyişini görmek inanılmaz bunlara bakmak. Bu şimdi ile başarılabilir csG.
Shaggy

3

Önceden ayarlanmış değişkenlerden yararlanın

Değişkenler A- SJapt'te temsil edilmesi birden fazla bayt alan ortak değerlere önceden ayarlanmıştır:

  • A- Gvardır 10- 16.
  • Holduğu 32, Iolduğu 64, Jolduğunu -1, Lolduğunu 100.
  • Knew Date()çeşitli şekillerde manipüle edebileceğiniz olarak tanımlanır .
  • Mve Oçeşitli yararlı işlevlere sahip nesnelerdir. Dokümanlar'da daha fazla bilgi edinebilirsiniz.
  • Pboş dizedir, Qbir alıntı işaretidir, Rbir yeni satırdır ve Sbir boşluktur.
  • Tolarak ayarlandığından 0, gerekirse bir akümülatör olarak kullanabilirsiniz.

Programdaki ilk karakter noktalı virgülse ; , A-Laşağıdaki gibi sıfırlanır:

  • Aboş dizidir [].
  • Bolduğunu "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  • C dır-dir "abcdefghijklmnopqrstuvwxyz".
  • D dır-dir "QWERTYUIOP\nASDFGHJKL\nZXCVBNM".
  • Eolduğu "[a-z]"veF bir "[A-Za-z]"(I düzenli ifade özellikleri gibi, bu ek yararlı önce)
  • Golduğunu 36, Holduğunu 65ve Iolduğunu91 (alfabe aralıkları için yararlıdır).
  • Jtek bir virgüldür; L, tek bir dönem.

Günümüzde sadece A, B, C, ve Dbu listeden gerçekten yararlıdır. Bu değerlere ve çok daha fazlasına önceden ayarlanacak 256 iki bayt değişkene izin veren daha iyi bir sistem eklemeyi planlıyorum.


3

Otomatik işlevleri kullanma

Büyük olasılıkla bunu zaten biliyorsunuzdur ve sırasıyla @ve _için kısayollardır ( Unicode kısayollarında ele alınmıştır)XYZ{Z{Z cevap). Ancak bazen işlevleri daha da kısaltabilirsiniz.

Bir dizi karakteriniz olduğunu ve her karakteri karakter koduyla eşlemek istediğinizi varsayalım. Bunu aşağıdakilerden biriyle yapabilirsiniz:

mX{Xc} 
m_c} 

Ama daha iyi bir yol var. Bir yöntem veya işleç, başka bir yöntemden veya a'dan sonraki ilk öğe ise, (bir dizeye dönüştürülür. Yani bu iki çizgi eşdeğerdir:

r'a'b  // Replace all "a"s with "b"s; transpiles to .r("a","b")
ra'b   // Does the same thing, 1 byte less; transpiles to the same thing

Peki bu işlevlerimize nasıl yardımcı oluyor? İşlevleri kabul eden çoğu yöntem, bir yöntemi veya operatörü temsil eden bir dize verilirse, işlevi bir işlev olarak yorumlar. Yani bunu da yapabilirsiniz:

m_c}  // Map each item to its char code
m'c   // Does the same thing, 1 byte less
mc    // Also does the same thing, 2 bytes less

Ben buna "otomatik fonksiyonlar" diyorum. Birkaç farklı çeşit vardır:

  • m@Xc}mc
  • m@Xc1}mc1
  • m@X+1}m+1
  • m@1+X}m!+1
  • m@2pX}m!p2

Umarım fikri anlarsınız. Bağımsız değişkenleri değiştirmek için yöntem veya operatörün önüne ön ek uygulayın !.


Burada, otomatik işlevlerin kullanılmasının kısayolların kullanılmasıyla daha fazla tasarruf sağlayabileceğini belirtmek gerekir mi? örneğin, m@2pXÃm!p2<space>m!².
Shaggy

Vay! Haritada bir dize kullanmayı düşünmemiştim, bunun mümkün olduğunu bile bilmiyordum. Belki gelecekte bunun sayesinde birkaç bayt tasarruf edeceğim.
RedClover

Hey @Soaku, Japt ile cevap verdiğini bir şekilde özledim, bu yüzden sana geç bir Hoşgeldin uzatmama izin ver! Umarım şimdiye kadar kullanmaktan keyif almışsınızdır. Herhangi bir sorunuz, öneriniz varsa veya sadece konuşmak istiyorsanız, Japt sohbet odasında bize katılmaktan çekinmeyin (Github genellikle ilk ikisi için de çalışır;))
ETHproductions 13:18 '

3

Örtük Değişken Ataması

Japt'te yeni bir satır başlattığınızda, önceki satırın sonucu otomatik olarak giriş değişkenlerinden birine ( U- Z) atanır , birinci satır U, ikinci satırV vb.

Bir örnek alalım: biri 1-10 sayılarını ve diğeri karelerini içeren 2 diziyi oluşturmak istediğinizi varsayalım. Bunu yapmanın uzun yolu şöyle olacaktır:

U=Aõ V=Um² [do something with the arrays]

Bununla birlikte, otomatik değişken atamasını kullanmak, aşağıdakilere kısaltılabilir:

Aõ
Um²
[do something with the arrays]

Orada 4 bayt tasarruf ettik. Ancak, bu örnekte, 1-10 dizisi belirli senaryolara atandığı Uve atlanmadığı için bir bayt daha kaydedebiliriz :U

Aõ
m²
[do something with the arrays]

Dikkat

Bu ipucuna dikkat etmeniz gereken bir şey, daha sonra programınızda ihtiyaç duyabileceğiniz herhangi bir giriş değişkeninin üzerine yazmamanızdır. Bu, başlangıcında bir veya daha fazla boş satır bırakarak önlenebilir. Aşağıdaki örnekte, 2 diziler değişken atanacak Vve W, yerine Uve V:


Aõ
Vm²
[do something with the arrays]

3

Javascript'i bilin

Herhangi bir Japt kodu aktarılan JS olarak çalıştığından, JS operatörlerinin ve yerleşik yöntemlerin iyi anlaşılması, Japt kodunun golf parçalarında çok yardımcı olur.

İlgili JS ipuçları

[]Vm@...
...
  • Kısa devre
  • Sayılarla bölme
    • Bu, dizeleri kabul eden ancak sayıları kabul etmeyen herhangi bir yöntem için genelleştirilebilir. Oradan geçirilen bir sayı, genellikle bir bayt (ör. 0Üzerinde '0) kaydedilerek dolaylı olarak bir dizeye yayınlanır .

İlgili JS yerleşik işlevleri

İşlev değişkenlerine hangi parametrelerin aktarıldığına yakından bakın.

Dize yöntemleri için, bir dize veya regex'i gbayraklı veya bayraksız geçirme arasında davranışların nasıl farklı olduğunu bilmek iyidir .


3

Gerektiğinde birden çok satır kullanın

Çok zor olmayan birçok zorluk için, çözümü sadece bir fonksiyon satırında, yerleşik işlevleri uygulama sırası olarak ifade edebilirsiniz. Ancak daha karmaşık olanların döngü yapıları, özyineleme veya büyük kod parçalarını yeniden kullanmaları gerekir. Burada çok hatlı programlama devreye giriyor.

Kapanış parens kaldırmak

Görev : Bir sayı dizisi verildiğinde, her öğeyi kare içindeki dizinle eşleştirin ve toplamına göre sıralayın.

[5,1,17,9,3] => [[5,0],[1,1],[17,4],[9,9],[3,16]] => [[1,1],[5,0],[9,9],[3,16],[17,4]]

Tek hat çözümdür íUm@Yp2})ñx, ama })iki bayt maliyeti (ve kimse baytlık kısayol bulunmaktadır). })İzini bir ñxsonraki satıra taşıyarak kaldırabilirsiniz , böylece kod şöyle görünür:

íUm@Yp2
ñx

ve aktarılan JS:

U = U.í(U.m(function(X, Y, Z) { return Y.p(2) })); U.ñ("x")

Bunun tek satırlık çözümle aynı şeyi yaptığını açıkça görebilirsiniz, ara sonucu tekrar atar U.

Örtük argümanlarla rüçhan

Özyineleme işlevi ß, UVWXYZbelirtilmezse, örtük parametrenin tümünü alır . Uaçık bir şekilde ana girdidir, ancak VWXYZihtiyacınız olan diğer değerleri takip etmek için herhangi birini kullanabilirsiniz . Örneğin, aşağıdakine benzer bir şey yapabilirsiniz:

(modify input and implicit assign to U)
(modify V and implicit assign to V)
(test something and call ß without arguments; U and V are passed automatically)

İstediğin geçici değişkendir Alternatif olarak, satır içi atama gibi kullanabilirsiniz (T=...)değişken olarak,T (0) nadiren .

Uzun bir işlevi yeniden kullanma

Bunun için iyi bir örnek görev bulabileceğimi sanmıyorum, bu yüzden bu ipucunun kullanıldığı tek çözüme başvuracağım ve sadece bazı genel fikirleri özetleyeceğim.

  • Bir işlevi yeniden kullanmak için, bir değişkende saklamanız gerekir. Fonksiyon-açacağı ile bir çizgi başlayarak {, @ya da _iş yapar. Alternatif olarak, şöyle bir şey de yapabilirsiniz(T=@...}) işlev atamasını daha karmaşık bir satıra gömmek .
  • Saklanan işlevi çağırmak aslında önemsiz değildir. Diyelim ki Vbir işlevdir ve V(U)JS'de aramak istiyoruz . VUbasitçe ifade ettiği için çalışmıyor V,U. V(Uya da değil; onunV,(U) . Fonksiyon yöntemleri bile çok yardımcı olmuyor. Bulduğumuz en iyi yol:
    • [U]xV (harita ve toplam) sonuç sayı ise
    • UmVeğer Utek bir karakter olup V, bir dize döndürür veya
    • $V($Uveya [U]mV ggenel olarak.
  • Bununla birlikte, haritalama veya onunla döngü yapmak oldukça kolaydır. Bir dizi üzerinden eşlemek için kullanın UmV. Tatmin edici ilk tamsayıyı bulmak için Vkullanın Va.

2

Otomatik İşlevlerle Eğlenceli

ETH'nin otomatik işlevlerle ilgili genel ipucunun bir takibi olarak , bu ipucu, onlarla elde edebileceğiniz bayt tasarruf hilelerinin birkaç spesifik örneğini sunacak, daha fazla düşündüğümde ekleyeceğim.


Bir dizideki en büyük tamsayıyı alın.

[3,1,4,2]Değişkene atanmış diziye sahip olduğumuzu Uve ondan en büyük sayıyı almak için karınca olduğunu varsayın . Biz olabilir diziyi sıralama ve daha sonra son öğe kahpeden 4 bayt bunu:

Un o

Bunun dezavantajı, orijinal diziyi değiştirmiş olmamız; UŞimdi [1,2,3]her zaman istenmeyebilir. Neyse ki, bir bayt daha kısa olan diziyi değiştirmeden bunu yapmanın bir yolu var:

Urw

Burada yaptığımız w, tamsayıda kullanıldığında tamsayı ve yöntemin bağımsız değişkenini (ör . 2w5Döndürür 5) döndüren yöntemi kullanarak diziyi azaltır . Yukarıda Yani eşdeğerdir UrÈwYya UrXY{XwY}. Ancak, bu ipucunun dizideki tüm tamsayıların negatif olması durumunda çalışmayacağını unutmayın .


1
Yan not: Bir dizinin min ve maks değerini almak için işlevler eklemeyi planlıyorum, ancak muhtemelen sadece v2'de.
ETHproductions

2

Ne zaman değil kullanmakí

ízipiki diziyi veya dizeyi eşleştiren ve isteğe bağlı olarak her çifti bir işlev aracılığıyla eşleyen kullanışlı bir yerleşiktir . Bununla birlikte, düzensiz diziler veya dizeler verildiğinde şu anda birkaç küçük sorun var:

  • İlk dizi ikinciden daha fazla öğeye sahipse, ikincisinde var olmayan öğeler olarak verilir undefined.
  • İkinci dizi birinciden daha fazla öğeye sahipse, ilk dizinin sonunda işlemeyi durdurur.

Bu, örneğin, iki eşit olmayan dizeyi karşılaştırmayı ve her çiftten daha yüksek kod noktasıyla karakter almayı zorlaştırabilir. Bunu biliyor olsan bileU daha uzun olacağını , bu basit görevi çözmek hala çok bayt gerektirir:

UíUç hV @[XY]n o

Bunun yerine ne olabilir, iki dizelerden oluşan bir dizi olarak girdi almak olacağını devrik , diziyi etmek yve ardından her satırı doğru sonuca eşlemek olacaktır:

Uy m_q n o

Bunun avantajı her zaman daha kısa ipleri boşluklarla doldurmak ve her iki ipin tamamını geçmek için bir parça kek yapmaktır.

Gerçek hayattan örnekler: 1 , 2


2

ASCII Serisini oluşturun

Güncelleme: Japt şimdi ASCII serisi için bir sabite sahip; ile alternatif değer E, erişilebilir ;. Bkz bu ipucunu Japt en sabitler üzerinde daha fazlası.

Japt'in ASCII aralığı için yerleşik (henüz) olmasa da, sadece 5 baytlık bir dizi karakter oluşturabilirsiniz:

95odH

Dene


Nasıl çalışır

95obir sayı üzerinde kullanıldığında o kod noktasındaki karakteri döndüren otomatik işlevden[0,95) geçirilen her öğenin bulunduğu aralığı oluşturur . Bir sayıyı bağımsız değişken olarak ddYönteme iletme, bu durumdaH iletin, Japt sabiti 32'dir ve dönüştürülmeden önce orijinal sayıya eklenir.

JavaScript'te eşdeğer bir çözüm:

[...Array(95)].map((_,x)=>String.fromCharCode(x+32))

Rastgele Karakterler

ASCII aralığında rastgele bir karakter almak için kullanmak öaralığından rastgele bir sayı döndüren yerine [0,X), Xo üzerinde çalıştırılan numaradır.

95ö dH

Veya, birden fazla rastgele karakter dizisi elde etmek için, ihtiyacınız olan karakter sayısını argüman olarak iletin ö. Aşağıdaki 10 karakter döndürür:

95öA mdH

1

Gereksiz yapısal karakterleri kaldırın

Yapısal karakter olarak, yani {}, (), $, hatta "ve `. Bu karakterleri genellikle bir programın sonunda (örn. UmX{Xc +"; "} -> UmX{Xc +"; ) Gerçekleştiklerinde çıkarabilirsiniz .

Ayrıca, aşağıdaki yerlerde göründükleri zaman parenleri veya boşlukları kaldırabilirsiniz:

  • Noktalı virgül ;(veya programın sonu) karşısında ;
  • Sağında {(ve uzantısı tarafından @) ya da [, ya da solunda ]veya }.

Ayrıca, argümanları ayırmak için virgüllere çok nadiren ihtiyaç duyulur. Eğer yazarsanız AB, örneğin, Japt sen demek bilir AveB ayrı ayrı. İki sayısal değişmezi ayırmak için yalnızca virgül kullanmanız yeterlidir.Us2,5 .

Son olarak, bir varsa Ubir program başlangıcında veya sonrasında bir {veya ;bir yöntem çağrısı (küçük harf veya ilgili Unicode kısayol) ya da herhangi bir ikili hariç operatör tarafından takip +ve -( *, &, ==vs.), kaldırmak olabilir Ubir tasarruf bayt ve Japt sizin için ekleyecektir.


UProgramın başında olmasa bile ommite edilebilecek birkaç örnek daha buldum .
Shaggy

@Shaggy Ah, aynı zamanda bir {ya da sonra çalışır ;. Farkında olduğunuz başka var mı? (Bu özelliği kodladığımdan beri bir süre geçti: P)
ETHproductions 18:17

Onları kafamın üstünden düşünemiyorum; Yarın bilgisayarıma geri döndüğümde tekrar kontrol edeceğim.
Shaggy

1

Bir Dizideki Son Öğeyi Değiştirme

Bazen bir dizideki son öğeyi değiştirmeniz gerekebilir, bu yüzden bunu yapmanın kısa bir yolu. [2,4,8,32]Girdi değişkenine atanan dizi ile çalışacağız Uve son tamsayıyı (32 ) 2'ye .

Bunu başarmanın açık yolu bu 9 baytlık çözümdür ( Demo ):

UhJUgJ /2
  • hnxendeksine öğesi ayarlar niçinx .
  • gndizindeki öğeyi döndürür n.
  • J Japt sabiti -1 negatif indeks desteği sayesinde bir dizideki son elemanla çalışmamızı sağlayan ; dizinin boyutunu bilmediğinizde kullanışlıdır.
  • Ve /2sadece 2'ye bölmek.

Yukarıdaki setleri endeksinde eleman Yani -1endeksinde elemana dizideki -1: JavaScript 2'yle Veya bölünmüş dizide U[3]=U[3]/2. Böyle yazdığınızda, bunun için çok uzun soluklu bir yol gibi görünüyor. Neyse ki, orada olan daha kısa bir yol; dizideki son öğeyi açabilir, değiştirebilir ve diziye geri itebiliriz. Bu işlemlerin her birini ayrı ayrı yapmak 9 bayttan fazla sürecektir, ancak hepsini sadece 7 bayt için bir seferde yapabiliriz, 2 bayt tasarruf ( Demo )

UpUo /2

JS'ye çevrildiğinde, şuna eşdeğerdir:

U.push(U.pop()/2)&&U
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.