Golf dilinde saklama ipuçları


16

Golf dili yazıyorum.

Kod-golf dilinde depolama için değişkenler, yığınlar, bantlar, kayıtlar vb. Önerir misiniz? Örtük girdi ne olacak?

Kaba tanımlar:

  • Bir değişken basitçe bir değer atanır ve daha sonra bu isimle alınabilmesi bir isim (golf dillerinde uzun genellikle bir karakter) 'dir.
  • Bir kayıt değişkene benzer, ancak değeri ayarlamak / almak için kendi (genellikle tek bayt) komutları vardır.
  • Bir yığın en son eklenen değerleri ( "üstte") değiştirilmiş olanlar vardır değerleri, değişken uzunluklu dizi / listesidir.
  • Bir kuyruk "ile ilgili değerler, aksi bir yığın gibi alt " değiştirilmiş olanlar vardır.
  • Bir bant , her bir değer, bir indeksine sahip bir değerler statik bir dizi / listesidir. Yığın ve bant arasındaki temel fark, banttaki değerlerin yerinde değiştirilmesidir.

Farklı senaryolar ve genel olarak her seçeneğin avantajlarını ve dezavantajlarını bilmek isterim. Lütfen düşüncelerden kaçının ve mantıklı ifadeleri yedekleyin.


1
Bence bu terimlerin bir tanımını
sorunuza eklemelisiniz

2
@Fatalize Teknik olarak depolama yöntemi ne tür bir golf dili yaptığınıza bağlı değildir, golf dili türü depolama yöntemine bağlıdır ...
ETHproductions

1
@ETHproductions Tamamen birbirine bağımlılar.
17'de

1
Çeşitli depolama terimlerinin kaba tanımlarını ekledim, beğenmiyorsanız düzenlemek veya geri almaktan çekinmeyin.
ETHproductions

2
Depolama yöntemi ve dil türü arasında çok yakın bir ilişki var, ancak her ikisine de bakmanız gerekiyor. Örneğin, "zorunlu" diller (talimatlarını kesinlikle soldan sağa uygulayan diller) yığın tabanlı (CJam, 05AB1E), bant tabanlı (BrainF ***) veya tamamen başka bir şey olabilir (V, birkaç kayıt ile birlikte "tampon" adı verilen büyük bir 2B dizge). Ayrıca, tümü belirtilen yöntemlerden neredeyse hiç faydalanmayan önek tabanlı diller (Pyth), infix tabanlı diller (Japt, Pip ve temel olarak her ana dil), bağlantı tabanlı diller (Jelly) vb.
ETHproductions

Yanıtlar:


4

Tüm depolama türleri, bir noktada bir şeyin depolanmasını ve daha sonra alınmasını içerir. Bunu yalnızca bir işlemde yapmak için, otomatik olarak depolama veya alma işlemini gerçekleştirmeli ve diğer işlemde saklanan değerin konumunu belirtmelisiniz.

Yani, açık depolama için, bu işlemden önce n. Hesaplanan değeri almak için bir operatör oluşturabilir veya n işleminden sonra geçerli değeri geri koyabilirsiniz. Alternatif olarak, programın başlangıcından itibaren mutlak konumu kullanabilir veya bazı işlemlerden sonra (yığın gibi) bazı öğeleri otomatik olarak kaldırma gibi daha fazla şey yapabilirsiniz. Ayrıca, bu otomatik işlemlerle veya bu otomatik işlemlerle depolama alanının farklı kopyalarını alarak birden çok operatör de yapabilirsiniz. İşlemlerde belirtmek için gereken maksimum sayıyı oldukça küçük yapmaya çalışmalısınız, böylece her sayı için bir operatör atayabilirsiniz.

Ancak çoğu durumda, bir operatöre bile ihtiyacınız yoktur ve dil bunu örtük olarak yapar. Bu, yığınlar veya kuyruklar gibi daha standart bir modeli düşünmeniz gerektiği zamandır. Şimdilik en başarılı, doğrudan depolamadan bile bahsetmeyen zımni programlama gibi görünüyordu.

Böyle yeni bir model tasarlamak istiyorsanız, değerlendirmeleri bir dag olarak genişletmeyi deneyebilir ve başka bir şey belirtilmezse varsayılan bir dag düşünmeyi deneyebilirsiniz. Büyük olasılıkla, varsayılan değer yalnızca bir ağaçtır, ancak aynı girişe birden fazla yaprak bağlanabilir. Örneğin, dengeli bir ağaç için bir kuyruk veya yaprakların çoğunlukla sabit olduğu derin bir ağaç için bir yığın veya yaprakların daha çok girdinin kopyaları olduğu derin bir ağaç için Jelly gibi bir şey kullanabilirsiniz.

Ancak, bir ikili ağacın şeklini operatör başına sadece 2 bit olarak kodlayabileceğinizi unutmayın. Dolayısıyla, dilinizde 64'ten az operatör varsa, geleneksel modelleri görmezden gelebilir ve sadece tüm ağacı yedek bitlerde kodlayabilirsiniz (bunlara combine_parent ve below_leaf bayrakları deyin). Daha fazla operatör olsa bile, oldukça iyi bir varsayılan (Jelly modeli gibi) ve değiştirmek için 3 değiştirici yapabilirsiniz.

Kolaylık sağlamak amacıyla örtülü ve açık depolama için aynı modeli kullanabilirsiniz, ancak zorunlu değildir. Örneğin, örtülü depolama için bir yığın kullanabilirsiniz, ancak açık depolamadaki (veya örtük olana ek olarak başka bir açık depolamadaki) öğeleri açmayın. Muhtemelen nihai belgelerde yığın olarak adlandırılmayacaktır, ancak fikri anlarsınız.

Referans için, bir ikili ağacın mükemmel kodlamasının boyutu Katalan sayılarının logaritmasıdır . Ve "ikili" bir dag'ın mükemmel kodlamasının boyutu, A082161'in logaritmasıdır , ancak açıkça pratik değildir. Bu, farklı bağımsız değişkene sahip bir operatörün iki farklı operatöre sahip olduğunu varsayar;

Bazen döngüler için değişkenler isteyebilirsiniz. Döngüleri başka şekillerde yeniden yazmak mümkün olabilir. Ancak gerçekten ihtiyacınız varsa, değişkeni tanımlamak için bir ada ek olarak 1 baytlık bir yapı kullanmayın. yalnızca önceden başlatılmış değerleri kullanmıyorsanız, bu değişkeni okuyup yazmadığınızı veya yazıp yazmadığınızı belirtmek için genellikle 1-bit bayrak kullanmak daha etkilidir.


7

Hepsini öneririm!

Daha ciddisi, hepsi zaman zaman kullanışlı oluyor ve daha fazlası daha iyi! Örtük girdi asla kötü değildir , kapatmak için bir işaretiniz vardır. Değişkenler yararlıdır, bu nedenle yığın veya kaset üzerinde bulunmaları gerekmez; kayıtlar için de aynı şey geçerli. Yığınlar veri depolamak için yararlıdır ve bantlar da öyle. Birden fazla, örneğin bir yığın ve kayıtlar ya da bir yığın ve GolfScript gibi değişkenler uygulamaya çalışmanızı öneririm. Her bir işlevi bir bayt haline getirebiliyorsanız, dilinizin her biri avantajlarını kullanabileceğiniz için golfte etkili olacaktır.

Bir örnek:

  • Diyelim ki girdi olarak iki sayı almak ve dize uzunluklarını eklemek istiyorum
  • Değişkenler bunun için daha iyi olabilir (bir yığın olmayabilir)
  • GolfScript'teki örnek kod (örtülü girdi ile):

    ~,\,+
    ~ # Eval input (e.g. "1 2" > 1, 2)
    , # Take Length
    \ # Reverse items on the stack
    , # Take Length
    + # Add
      # Implicit output
    

    Ancak, değişkenlerle (daha uzun olduğunu biliyorum, sadece yığındaki yerleri değiştirmek zorunda değilsiniz):

    ~,:a;,:b;ab+
    ~ # Eval input
    , # Get length
    :a# Store in "a"
    ; # Discard value left on stack
    , # Length
    :b# Store in "b"
    ; # Discard
    a # Recall a
    b # Recall b
    + # Add
      # Implicit output
    

Aşırı yükler

Yardımcı olabilecek başka bir şey aşırı yüklenmelerdir. Örneğin, değişken bir depolama fonksiyonunuz varsa, belki de bir monad (tek giriş fonksiyonu; J / K / APL'nin terim dış tarafı teriminden) yığın veya kasete eklemek için kullanılabilir.

Misal:

c12 # Stores "1" into register 2
c1] # Pushes "1" onto the stack ("]" is used to denote the end of the monad)

Belki yanlış türlerde bir argüman çağrılırsa, daha sonra yığın boşsa değerleri doldurmak için kullanılan bir kuyruğa eklenir?
Esolanging Fruit

5

Program ilgisiz bir şey yaparken bazı şeyleri yoluna almak için bazı hızlı kullanılabilir depolama (verilen - teyp, kuyruk, yığın) ve bazı kalıcı depolama (değişkenler, kayıtları) sahip öneririz. Çok daha fazlasının nadiren bir şey vereceğini ve daha fazla 1 baytlık talimatlar için daha fazla karakteri boş bırakacağını söyleyebilirim.

Verilen tanımlardan, en iyi çalışacağını düşündüğüm olanlar bir yığın ve kayıtlar olacaktır.
Yığın, çünkü kasetin içinde yeni bir şey saklamak için işlevleri kullanması gerekirken, bir yığın basit itme ve pop işlevlerine (genellikle komutlarda yerleşik olarak) sahip olmalıdır. Kayıtlar, çünkü genellikle değişkenlere kıyasla daha az bayt alırlar ve bir şey için 2-4'ten fazla farklı şey depolamanız gerekiyorsa, yanlış bir şey yapıyorsunuz.

Bunların işlevlerini sadece isimlerinin veya tanımlarının yalın önerdiği şeylerle sınırlamayın - gibi bazı işlevler put the 1st thing of the stack on top of the stackkesinlikle yardımcı olabilir.


5

Temel olarak farklı bir şekilde ele alınması gereken iki tür depolama vardır; son zamanlarda üretilen değerlere ve / veya girdilere erişim; ve uzun süreli depolama.

Uzun süreli depolama için değişkenler en iyi sonucu verir; sınırlı sayıda seçeneğe sahip olan herhangi bir şey ölçeklendirilmez (ancak bu özellikteki diller, Jelly gibi, yine de orta ölçekli görevlerde bile oldukça iyi olabilir). Ancak, değişkeni saklarken çoğu zaman değişken adları girmeye gerek yoktur ; bir değişkeni bir değerde saklamak için bir komuta sahip olun ve isimleri tahmin edilebilir bir desene göre otomatik olarak oluşturun, böylece değeri saklamak ve almak basit durumlarda bir komut olabilir. (Örneğin, en son atanan değişkeni, en sonuncusu en sonuncusu, en sonuncusu en sonuncusu vb. Küçük bir sabit sayıya kadar artı argüman alan genel bir komutu geri yükleme komutlarınız olabilir.)

Kısa süreli depolama için mümkün olduğunca örtük olmasını istersiniz. Gördüğüm neredeyse tüm golf dilleri, bir komutun çıkışını varsayılan olarak bir komutun girişine bağlar; bunun tam olarak nasıl yapıldığı dilden dile değişir, ancak normalde aynı şeydir. Ancak, 2 girişli bir komut için ikinci giriş daha ilginçtir. Yığından almak, değerlerin yalnızca bir kez kullanıldığı durumlarda iyi çalışır, ancak değerleri yeniden kullanırken iyi ölçeklenmez. (Yığın işleme ilkellerinden kaçınmaya çalışın; bunları kullanmak için başvurmanız gerekiyorsa, çok fazla bayt harcıyorsunuz.) Alternatif olarak, örtük ikinci argüman olarak birkaç bayt tasarruf sağlama eğiliminde olduğu için kullanıcı girdisini veya yeni atanan bir değişkeni kullanmak basit programlar, ancak '

Şu anda üzerinde çalıştığım bir golf dilinde , ayrıştırma ağacının şeklini belirtmek için çok ucuz bir mekanizmanın (tek bir bit ) bir kombinasyonunu kullanıyorum , varsayılan olarak kullanıcı girişlerinden eksik argümanları otomatik olarak dolduruyor ve bir kontrol noktası kullanıyorum başka bir şeye eksik argümanlar için varsayılanı ayarlamayı mümkün kılan yaklaşım (artı birçok özel durum). Bir noktada, bilgiyi program boyunca daha büyük mesafelerde iletmek için değişkenler ekleyeceğim.


0

Bir kaset ve bir kayıt öneririm.

Bantları yığınlara tercih ederim, çünkü bantların daha az elemanı vardır, bu da manipülasyonunu kolaylaştırır. Ayrıca, kayıtları kasetteki kasete yerleştirebilmeleri ve tam tersi, kolay ve kısa kodlar sağlar.

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.