DC'de golf için ipuçları


18

DC'de golf oynamak için hangi genel ipuçlarınız var ?

dc, C dilinden önce gelen UNIX / Linux için bir hesap makinesi yardımcı programıdır. DC programlarımı (hesaplamalar?) Nasıl kısaltacağımla ilgileniyorum. Ben en azından biraz DC'ye özgü genel uygulanabilir uygulanabilir fikirler arıyorum (örneğin. Yorum kaldırma yararlı bir cevap değildir)

Lütfen cevap başına bir ipucu gönderin.


7
Bunun yerine Marvel kullanın.
Sihirli Ahtapot Urn

Yanıtlar:


6

If-then-else deyimleri

Biz durumunu kontrol etmek istiyorum varsayalım a==b(let ave bonların sırasıyla adlı kayıtlar saklanabilir).

Düzenle:
[         # Everything is wrapped in one big macro
  [         # An inner macro for our *then* part
              # <-- Stuff to execute if a==b here
  2Q          # Then quit the inner and outer macro
]sE       # `E' is for Execution register ;)
la lb =E  # if a==b, execute E
          # if E is executed, it will quit the whole macro, so the rest is never reached:
          # <-- Stuff to execute if a!=b here
]x        # End macro; Execute

Izin vermek (foo)yoğunlaşma amacıyla bir yer tutucu olun:

[[(then)2Q]sE(condition)E(else)]x

Eminim bu mümkün olan en kompakt ifadedir ( burada da yer almaktadır ).


1
Belki [[thenaction]P][[elseaction]P][r]sI 2 4 =I x sI fbir başlangıçtır? Tehn ve başka eylemler yığının üzerinde, " If" makrosu bunları değiştirir ve şartlı olarak çağrılır. ardından yığının üstü yürütülür ve kullanılmayan makro yığını temizlemek için I içine bırakılır. 2 4karşılaştırılacak örnek verilerdir. Alternatif olarak, [x]sIparça daha okunabilir kabul edilirse karşılaştırmaya taşınabilir [[thenaction]P][[elseaction]P] 4 4 [r]sI =I x sI f. fYığın daha sonra temiz tat örneklerde sadece ... göstermemelidir

1
Dc hakkında Rosetta Kodu'nun sayfa 3 tatlar bahseder dcve ben OpenBSD gördüm 1 sayfa olduğunu dc'ın if-then-elseyapısı. Bence dctüm büyük işletim sistemleri için 3 lezzeti olan bir fan paketine ihtiyacımız var ... o :-) ... ve if-then-elseyukarıdaki teklifim orijinal üzerinde çalışmıyor dcçünkü rkomuttan yoksun ... :-(

1
Ne hakkında: [[(if)2Q]si(condition)i(else)]x- her şeyi bir makroya ve if-bölümünü bunun içindeki başka bir makroya sarmak, böylece 2Qbaşka bir bölüme ulaşmadan önce her şeyden çıkabilirsiniz . Eğer 1 == 1 yapmak istiyorsanız, o zaman 1 başka baskı 2 yazdırırsanız , 1[[1P2Q]si1=i2P]x(burada ve şu anda dc'ye erişimim olmadığı için denenmemiş olacaktır) . ama bulamadı)
daniero

Evet, matematiği yaptım, önerim daha kısa. Aynı örnek ve "gösterim" ile ve boşluk kaldırmak - [/*else*/]sE[[/*then*/]sE]sIlalb=IlExvs [[/*then*/2Q]sIlalb=I/*else*/]x- 6 bayt fark var. Hala denenmemiş tho: P
daniero

1
İyi iş çıkardın @daniero! Zamanım olduğunda yazıyı güncelleyeceğim veya isterseniz yapabilirsiniz.
Joe

5

İle girişi kaydedebilirsiniz d

dToS'yi (yığının üst kısmı) çoğaltan tuşunu kullanarak , girdiyi daha sonra kullanmak üzere çıkarırken kullanmaya devam edebilirsiniz.


@NoOneIsHere oh güzel !!! Teşekkürler!
Rɪᴋᴇʀ

5

Diziler

Yeni başlayanlar için baş ağrısı olmasına rağmen dc, diziler sunar. Bu şekilde çalışırlar:

value index :a    # store `value' in array linked to top of stack `a', with index `index'
      index ;a    # push a[index] on (main) stack

Her zamanki gibi, ilk eleman 0 indeksine sahiptir. Diziler, SUDSI sekansında olduğu gibi sekanslarla çalışırken , özellikle sayıcılarla kombinasyon halinde faydalı olabilir. Ortamınızı yok etmeden belirli bir öğeyi seçmek istiyorsanız, diziler yapmanız gereken sayı karıştırma miktarını (ve sayaç ve karşılaştırma sayısını) azaltabilir. Örneğin, bir yığın sayıyı bir diziye taşımak istiyorsanız, z(yığın derinliği) veya z 1-dizin olarak kullanan , öğeyi saklayan ve z == 0kendini sonlandırıp sonlandırmayacağını kontrol eden özyinelemeli bir işlev yazabilirsiniz .

[z 1- :a z 0 !=F]dsFx    # or I could just write such a function for you :)

Aşağıdakilere dikkat edin:

  • Diziler, adlandırılan yığınlardaki örneklerle ilişkilendirilir. Kendisiyle ilişkilendirilmiş bir diziye sahip bir yığına yeni bir değer basarsanız, bu dizi de "geri itilir" ve "yeni" bir dizi onun yerini alır. Eski dizi, adlandırılan yığındaki karşılık gelen değer de kullanılabilene kadar kullanılamaz (yani yığının üstünde). Bu, benim dışımda olan iyi bir animasyonla daha iyi açıklanabilecek karmaşık bir kavram.
  • Sen olabilir aslında tekabül adlı kayıt içine bir değeri iterek olmadan adlandırılmış dizide şeyler saklamak. Eğer bunu yaparsanız Ancak, olamaz oturumunun kalanında bu adla kayıt / yığını erişin. dcçökecek.
  • Adlandırılmış bir yığından bir değer çıkarırsanız, karşılık gelen dizideki değerler kaybolur; uyarı yok, koruma yok, hiçbir şey. Sadece gitti (bu da faydalı olabilir).

DC ipuçları ile iyi iş!
16:04

dcyakın zamanda güncellenmiş olabilir ve kilitlenme ile ilgili dizi davranışı biraz değişmiş olabilir. Şu anda ikisini de doğrulayamıyorum, ancak son kez Linux'ta kullandığım bir şey farklı olduğunu düşünüyorum.
Joe

1
Ayarlanmamış bir diziden bir dizin okumaya çalışırsanız, hata değil 0 alırsınız. Bu çok yararlı olabilir, ancak dizilere potansiyel olarak 0 saniye koyarsanız da dikkatli olmanız gerekir ... Dizine dokunulduğunu test etmek için başka bir yola ihtiyacınız olacak.
brhfl

5

Koşullar / makrolar yerine n'inci güce 0

Bazen böyle bir şey gerekebilir üçlü koşullu:

A == B ? C : D;

Bunu halletmenin güzel bir yolu @ Joe'nun cevabında açıklanmıştır . Ancak daha iyisini yapabiliriz:

0AB-^E*C+

burada E, D - C'dir.

Bu, 0 değerini iki değerin farkının gücüne yükselterek eşitliği test eder. Bu eşitse 1, aksi takdirde 0 ile sonuçlanır. Gerisi 1 veya 0'ı C veya D değerlerine ölçeklendirir. Bu işe yarar çünkü n! = 1 için dc0 0 = 1 ve 0 n = 0 verir.


4

Bazen bir numarayı yığından atmak gerekir. Bunu yapmanın bir yolu, onu kullanılmayan bir değişkene yerleştirmektir st. Bununla birlikte, bazı durumlarda, başka bir yere, örneğin sayısal bir girdiniz olmadığında giriş tabanına ya da hassasiyetin fark yaratacağı başka bir işleminiz yoksa hassas belirleyiciye girebilirsiniz. Önceki durumda, kullanın i. İkinci durumda, kullanın k.


Sayısal çıktı önemli değilse, okullanılabilir. Ve eğer bunlardan herhangi biri önemsiz ise, sırasıyla depolama olarak kullanılabilirler, sadece bunları atabilirler - I/ K/ Ogeri çağırırlar ve baytları sa/ lavb. Üzerine kaydederler . Geçerli değerler AFAIK: i2-16; knegatif olmayan herhangi bir tam sayı; oherhangi bir tam sayı 1'den büyük
brhfl

4

Uzunluğu Hesaplama: Z,X , vez

ZToS'ları açar ve sayı ise basamak sayısını (ondalık) veya dize ise karakter sayısını iter. Bu, bir sonucun uzunluğunu (tamponlama çıktısı) veya dize uzunluğunu hesaplamak için yararlı olabilir. Sayılar için,Z tamsayı kısmının ve kesir kısmının birleşik uzunluğunu ittiğini .

XToS'yu açar ve sayının kesir kısmındaki basamak sayısını iter. ToS bir dize ise 0, itilir.

Sayının tamsayı bölümündeki basamak sayısını bulmak için kullanılabilir dZrX-. Siz varsayılan hassasiyet değiştirmediyseniz k==0kullanarak, 1/Zdaha kısa olmakla birlikte, diyelim ki bu ameliyattan sonra belli bir sıfır olmayan hassas korumak gerekir:Kr0k1/Zrk ziyade göz zevkini bozar.

zyığındaki öğe sayısını iter. En sevdiğim komutlardan biri, aslında herhangi bir değer açmıyor! Bir sayı dizisi oluşturmak veya bir sayacı arttırmak için kullanılabilir. zdTekrar tekrar kullanmak (örneğin, bir makronun başlangıcında) , her doğal veya tam sayı için bir hesaplamayı artan sırada test etmenizi sağlayabilir.


zBu ve daha önce kullanmış , ama bir sayaç hack olarak kullanmak için bana hiç olmadı ... Mükemmel…
brhfl

4

Rakamlar A için Fhala temel olarak etkili bir şekilde 10 basamak tedavi edilmelidir Ancak 15'e numaraları 10 yerine kullanılabilir (giriş taban varsayıldığında 10) olduğunda farklı yerlerde. Başka bir deyişle, giriş tabanı 10 ileFF 255'i temsil etmezken,(15 * 10) + 15 veya 165'i .

Aslında bu , herhangi bir giriş tabanındaki tüm basamaklar 0için çalışırF2 için 16. Giriş tabanı 5 ise, o zaman 26Eolurdu(2 * 5^2) + (6 * 5) + 14 , ya da 94.

Bu davranışın değiştirilmemiş GNU kaynakları için geçerli olduğunu unutmayın. @SophiaLechner işaret ettiği gibi, ancak, RedHat tabanlı dağıtımlar kullanımı görünen bc-1,06-dc_ibase.patch basamak> = ibase olarak kabul edilir, böylece bu davranış değişikliği ibase - 1ne olursa olsun, gerçek değer. TIO Not dc sahip olmamak görünür bc-1.06-dc_ibase.patch (olsa bile onun Fedora 28 _ (ツ) _ / ¯).


Bu doğru değil - giriş tabanının üzerindeki tek basamaklar umduğunuz gibi yorumlanmasına rağmen, hazır bilginin birden fazla basamağı veya hatta ondalık noktası varsa, taban için geçersiz basamaklar (taban-1) olarak yorumlanır. Yani 10 giriş tabanında FFtemsil 99giriş baz 5'de, 26Eaynı 244, yani taban 10 74.
Sophia Lechner

@SophiaLechner Emin misin? tio.run/##S0n@/9/QIJ/L0CCTy82tgMs0k8vIzLXg/38A Hangi dcsürümü kullanıyorsunuz? Ubuntu'da GNU dc 1.4.1 ve MacOS'ta GNU dc 1.3 kullanıyorum
Digital Trauma

İlginç. Red Hat üzerinde 1.3.95 çalıştırıyorum ve işte örnek programınız: [slechner @ XXX] $ dc -e '10o 10i FFp 5i 26Ep' 99 74 [slechner @ XXX] $ dc - sürüm dc (GNU bc 1.06 .95) 1.3.95
Sophia Lechner

Argh ... kod bloğunun yorumda çalışmasını sağlayamıyor. Mesele şu ki FFpçıktı 991.3.95. Bunu MacOS sürümünüzde kontrol edebilir misiniz?
Sophia Lechner

1
Tabi ki! Tüm araştırmalar için teşekkürler.
Sophia Lechner

2

Hemen çalıştırmak istediğiniz bir işlev makrosunu (kullanacağız F) başlatırken, bunun dsFxyerine bir şey kullanın sFlFx. Aynı şey değişkenler için de geçerlidir:dsa yerine sala.

Depolama ve yükleme (örn. sa[other stuff]la) Arasında başka şeyler yapmanız gerekiyorsa , yukarıdakilerin geçerli olup olmadığını düşünün: Diğer işlemlerden önce yığının üzerinde bir değer bırakırsanız, sonuna kadar en üstte olacak mı? bu operasyonların?


2

Bunu kazara keşfettim. Sıfır oluşturmanın başka bir yolu:_ .

_aşağıdaki basamakların negatif bir sayı olduğuna dair dc sinyalidir. Misal:

_3 # pushes -3

Ama ya onu bir sayı ile takip etmezsek?

_ # pushes 0...sometimes

Alt çizgiyi izleyen bir sonraki boş olmayan karakter bir rakam olmadığında çalışır. Bir rakam onu ​​takip ederse, bir satırsonundan sonra bile, negatif bir işaret olarak yorumlanır.

c4 5_6  # -6,5,4
c4 5_ 6 # -6,5,4
c4 5_
6       # -6,5,4 # still a negative sign since the next thing it sees is a digit
c4 5_z  #  3,0,5,4 # if it's followed by a non-digit, it's a 0
c4 5_p6 #  6,0,5,4
c4 _*   #  0 # 4*0=0

1

Tüm yığının içeriğinin bir programın sonunda yazdırılması gerekiyorsa, bunu başarmak için özyinelemeli bir makro döngü kullanılabilir. Ancak, fkomutu kullanmak çok daha kısadır .


1

dcbir kerede bir satır girişi okur. Birden fazla öğeyi okumanız gerekiyorsa, satır başına bir tane yapmak için? için her satırın okunması için bir veya hantal bir makro döngüsü gerekir. Bunun yerine, tüm giriş öğeleri boşlukla ayrılmış bir satıra yerleştirilebiliyorsa,? giriş öğelerini okuyarak her birini yığının üzerine iter.

Örneğin seq 10 | dc -e'?f', seqtam sayıları 1-10 satıra bir çıkış olarak vermektedir. ?İlk okuyacaktır 1zaman çıkışı olan fbütün yığın döker. Ancak içinde seq 10 | tr '\n' ' ' | dc -e'?f', trtüm boşlukla ayrılmış giriş tamsayılar yapar. Bu durumda ?satırdaki tüm tam sayıları tek seferde okuyacak ve hepsini çıktılayacaktır f.


1

Bir operatör kaynaktan kısıtlanmışsa, a

Benim için birkaç kez kullanışlı olan bir şey, operatörün ASCII değerini iterek, aonu bir dizeye dönüştürmek ve sdaha sonra makro olarak yürütülecek bir kayıtta zorlamak suretiyle belirli bir operatörü kullanmaktan kaçınmaktır. üzerinde. Örneğin, bölme yapmam gerekiyor, ama ya izin verilmiyor ya da karakteri kullanmaktan kaçınmaya çalışıyorum /. Bunun yerine 47asd, gelecekte 16'yı 4'e bölmem gerektiğinde yapabilirim ve sonra 16 4 ldx.

  • Bu yalnızca tek karakterli işleçler için çalışır (dize oluşturamaz) ve aşağıdaki gibi komutlar için çalışmaz s şey tarafından postfix olarak düzeltilmesi gereken için çalışmaz.
  • Bu, birkaç bayt ekler ve bu nedenle yalnızca belirli karakterden kaçınmak gerektiğinde veya bir şekilde bir puan bonusu verdiğinde uygundur.

1

Boşluktan kaçınma

Boşluktan kaçınmak birkaç zorlukla karşı karşıyadır ve genellikle kolaydır dc. Arka arkaya birden fazla numaranın iterek zaman Kenara dizeleri gelen, boşluk gerekli olur biri çok özel zamanı: 1 2 3. Bundan kaçınılması gerekiyorsa:

  • Aralarında boş bir makro yürütün 1[]x2[]x3[]x.
  • Parantez masadan ise, bir zaman makro önden bir NOP saklamak: 35asnve yürütme bunu aradaki: 1lnx2lnx3lnx.

Ayrıca, dc: ',' (054) unimplementeduyarılara katlanmak istiyorsanız, ayrı numaralar da virgül edebilirsiniz .
Dijital Travma

Bunu düşünmemiştim - muhtemelen bir komuta çözümlenmeyen herhangi bir jeton için geçerli… ilginç…
brhfl
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.