Prindeal (belirgin ilkelerle-dee-al ) yeni bir ezoterik : sadece dört komutları vardır programlama dili pr int , içinde eksiltme , de eksiltme ve diğ ıas . Minimalizmine rağmen, Prindeal'de dört komutu akıllıca birleştirerek karmaşık matematiksel işlemler yapılabilir.
Bu kodda golf mücadelesinde göreviniz, Prindeal kodunu çalıştırabilecek en kısa programı yazmaktır.
Teknik özellik uzun ama mümkün olduğunca netleştirmeye çalıştım ve Prindeal'ı öğrenmek için çaba sarf ederseniz, oldukça şık olacağına inanıyorum!
Kavrama Prindeal
Ön İşleme
Bir Prindeal programı yorumlanmadan önce, bu şeylerin bu sırayla kaldırılması gerekir:
#
Çizginin bitimine kadar olan işaretten sonra herhangi bir şey , artı#
kendisi. (Bu yorumlar.)- Herhangi bir satırdaki sondaki boşluk.
- Tamamen boş satırlar.
Örneğin, Prindeal programı
p cat #The next line has 7 trailing spaces.
p dog
#p mouse
önceden işlenmiş olur
p cat
p dog
Bundan sonra bu ön işleme adımının atıldığını varsayacağız.
Değişkenler
Nasıl kullanıldığını göstermeden önce değişkenleri hızlıca tanımlamamız gerekir.
Değişkenler (ve değişkenlere referanslar), Prindeal komutlarının argümanlarına iletilen şeydir. Değişkenler her zaman globaldir , bu nedenle bir değişkende yapılan değişiklikler, nerede olursa olsun, her yere yansıtılır.
Her değişken, negatif olmayan isteğe bağlı bir tam sayı tutar (0, 1, 2, 3, ...). Değişkenlerin önceden başlatılması gerekmez - her zaman ilk kullanıldığında veya çağrıldığında 0 değeriyle başlarlar .
- Bir değişken adı bir rakam ile başlamaz alphanumerics ve alt çizgilerden oluşan bir boş olmayan bir dize olabilir [a-zA-Z_][0-9a-zA-Z_]*
de regex . Büyük / küçük harfe duyarlıdır spiny_lumpsuck3r
ve Spiny_lumpsuck3r
farklı değişkenlerdir.
infaz
Prindeal zorunlu bir programlama dilidir. Bir Prindeal programı çalıştırıldığında, ifadeleri yukarıdan aşağıya doğru yürütülür ve ardından program sona erer.
Bir Prindeal programındaki girintili olmayan her satır, bağımsız değişkenleri alabilen veya vermeyen tek bir komutun yürütülmesini içeren bir ifadedir.
Girintili satırlar yalnızca diğer ad komutlarından sonra gerçekleşir . Spesifik olarak, tam olarak tek boşluklarla girintili üç satır her takma komuttan sonra oluşur ve bunun bir parçası olarak kabul edilir. Yani takma ifadeler gerçekten dört satırdır. (Bir satır olabilirler, dördü sadece daha okunaklı.)
Takma Olmayan Tablolar
Diğer ad hariç, bir Prindeal programındaki her ifade şu şekildedir:
[command name] [argument 1] [argument 2] [argument 3] ...
İsteğe bağlı sayıda argüman olabilir (hiçbiri dahil değil). Her argüman her zaman bir değişkendir (( diğer adı tartışırken göreceğimiz gibi ) bir değişkene referanstır .
Yürütüldüğünde, her ifade, hatalarla karşılaşılıp karşılaşılmadığına bağlı olarak bir başarısızlık veya başarı olarak işaretlenir . (Bu yalnızca takma adı kullanmaya başladığımızda gerçekten önemlidir .)
Yerleşik baskı , artırma ve azaltma , yukarıdaki formdaki ifadelerdir. İşte yaptıkları:
print komut adına sahiptir
p
ve bir argüman alır. Girilen değişkenin adını ve değerini (ondalık olarak) "=", sonra bir yeni satırla ayırarak yazdırır. Her zaman bir başarı olarak işaretlenir .Örneğin, Prindeal programı
p _MyVariable_321 p screaming_hairy_armadillo
çıktı
_MyVariable_321 = 0 screaming_hairy_armadillo = 0
çünkü tüm değişkenler 0'dan başlar. (Eşittir işaretinden önceki ve sonraki boşluklar gereklidir.)
artışın komut adı vardır
i
ve bir argüman alır. 1 tarafından iletilen değişkenin değerini artırır. Her zaman başarılı olarak işaretlenir .Örneğin, program
i alpaca p alpaca i alpaca p alpaca
çıktı
alpaca = 1 alpaca = 2
Daha
alpaca
önce hiç erişilmemiş olmasına rağmen, 0'dan 1'e nasıl artırıldığını unutmayın .azaltma komut adına sahiptir
d
ve bir argüman alır. Girilen değişken sıfırdan farklı ise değeri 1 ile düşürülür ve ifade başarılı olarak işaretlenir . Girilen değişken 0 ise, hiçbir şey yapılmaz ve ifade bir hata olarak işaretlenir .Örneğin, program
i malamute p malamute d malamute #success p malamute d malamute #failure p malamute d akita #failure p akita
çıktı
malamute = 1 malamute = 0 malamute = 0 akita = 0
0 değerine sahip bir değişkeni azaltmanın hata üretmenin tek yolu olduğuna dikkat edin .
Diğer Ad Bildirimi ve Diğer Ad Komutları
Takma komutu özel bir sözdizimi vardır ve yeni komutlar tanımlamak için kullanılabilir, çünkü en güçlüdür. Takma komut adıdır a
ve bir takma ad deyimi forma sahiptir:
a [name of new command]
[statement A]
[statement B]
[statement C]
Her birinin [statement X]
herhangi bir diğer adı olmayan ifadeyi, yani formlu bir şeyi temsil ettiği yerde [command name] [argument 1] [argument 2] [argument 3] ...
.
Aliased komutunun adı [name of new command]
boş olmayan herhangi bir alfanümerik dize ve rakamlı bir [a-zA-Z_][0-9a-zA-Z_]*
regex ile başlamayan alt çizgiler olabilir.
(Bu, değişkenlerle aynı ad grubudur, ancak takma komutlar ve değişkenler, farklı yerlerde kullanılan farklı şeylerdir . Bir değişken, kötü sonuçları olmayan bir komutla aynı şekilde adlandırılabilir.)
Bir alias ifadesi çalıştırıldığında, orijinal dört p
i
d
a
komutun yanına yeni bir komut eklenir . Yeni komut, [command name]
in ifadeleri olarak kullanılabilir ve diğer tüm diğer alias olmayan komutlar gibi bağımsız değişkenlerle çağrılabilir .
Bir takma komut adı olan bir ifade çalıştırıldığında, orijinal alias deyiminden tam olarak iki ifade daha çalıştırılır:
[statement A]
her zaman çalıştırılır[statement B]
eğer çalıştırılan[statement A]
bir oldu başarı[statement C]
eğer çalıştırılan[statement A]
bir oldu başarısızlık
A, B ve C İfadeleri her zaman tembel olarak çalıştırılır , yani çalıştırıldığı sırada anında değerlendirilirler.
Yürütme bittiğinde , aliased komutu B veya C ifadesiyle aynı başarı veya başarısızlık bayrağıyla işaretlenir, hangisi çalıştırıldıysa . ( takma ifadelerin kendilerinin kendi içlerinde bulunamadıkları için işaretlenmeleri gerekmez.)
Diğer Ad Örneği 1
Diyelim ki değişkeni
frog
iki kat artıran yeni bir komut istiyoruz . Bu diğer ad ifadesi bunu başarır:a increment_frog_twice i frog i frog d frog
Bildirimi A (
i frog
) her zaman çalıştırmak ve her zaman olduğu gibi işaretlenir başarı deyimi B (böylecei frog
de her zaman çalıştırılır) ve değişkenfrog
böylece 2 ile artırılırincrement_frog_twice
komut her zaman olduğu gibi işaretlenir başarı tablosu B daima çalıştırılması nedeniyle ve B her zaman olduğu başarı . C (d frog
) ifadesi hiçbir zaman çalıştırılmaz.Yani çıktı
a increment_frog_twice i frog i frog d frog p frog increment_frog_twice p frog
olabilir
frog = 0 frog = 2
Bu örneği genelleştirebiliriz, böylece herhangi bir değişkenin takma komutuna bir argüman vererek iki kez artırılması mümkündür.
Bir alias ifadesinde, 1, 2, 3, vs. tamsayıları aliased komutuna geçirilen 1., 2., 3. vb. Argümanları temsil eder. (Bu argümanlar düz değişkenler veya değişkenlerin kendilerine referanslar olabilir.) Bu sayılar yalnızca bir alias ifadesinde A, B ve C ifadesinin argümanlarında görünebilir . Başka bir yerde görünmeleri onların için bir anlam ifade etmiyor.
Diğer Ad Örneği 2
Bu, son örneği genelleştirir - girilen herhangi bir değişken
increment_twice
2 ile artacaktır1
, çünkü girilen ilk argümana bir referans:a increment_twice i 1 i 1 d 1 #never reached p toad increment_twice toad p toad
Bu programın çıktısı
toad = 0 toad = 2
Daha sonra iki argüman alan ve
increment_twice
her ikisini de çağıran başka bir komutu takma ad verebiliriz:a increment_twice i 1 i 1 d 1 #never reached a increment_both_twice increment_twice 1 increment_twice 2 d 1 #never reached increment_both_twice platypus duck p platypus p duck
Buradaki çıktı olacaktır.
platypus = 2 duck = 2
Aliased komutlarının özyinelemeli olabileceğini anlamak önemlidir, çünkü gerçek güçleri yatar. Örneğin, 0'a iletilen herhangi bir değişkeni ayarlayan bir komut yapabiliriz:
Diğer Ad Örnek 3
set_to_zero
Komut bir argüman alır ve 0'a onun değişken belgeleri ve bir şekilde işaretlenir başarı yapıldığında:a set_to_zero d 1 set_to_zero 1 i _dummy_ i oryx i oryx i oryx p oryx set_to_zero oryx p oryx
Bu programın çıktısı
oryx = 3 oryx = 0
Olan şu ki
set_to_zero oryx
, çalıştırıldığındad 1
başarılı bir şekildeoryx
3'ten 2'ye düşürür , sonra tekrarset_to_zero 1
aranırset_to_zero oryx
. Böylece süreçd 1
bir başarısızlık olana kadar tekrar eder , yinelemeyi durdurur ve_dummy_
değişkeni arttırır, böylece bir başarı elde edilir.
Meydan okuma
Prindeal kodunu tam olarak yukarıda açıklandığı şekilde çalıştırabilecek bir program yazın. Prindeal kodunu stdin, komut satırı veya metin dosyası olarak alın. Prindeal programının çıktısını stdout'a veya dilinizin en yakın alternatifi olarak yazdırın.
Alternatif olarak, kodu bir dizge olarak alan ve çıktı dizesini basan ya da döndüren bir işlev yazabilirsiniz.
Ek olarak şunu varsayabilirsiniz:
- Giriş Prindeal kodu yalnızca yeni satırlar ve yazdırılabilir ASCII ve (isteğe bağlı olarak) boş bir satırla bitecek şekilde yazacaktır .
- Giriş kodu geçerli Prindeal - iyi biçimlendirilmiş ve sözdizimsel olarak doğru olacaktır.
- Kodun çalıştırılması, sonsuz döngüler veya tanımlanmamış komutlara veya verilmemiş bağımsız değişkenlere geçersiz referanslar üretmez.
- Komut adları
p
,i
,d
vea
üzerinde ad verilmiş asla. ( Değişkenlerin bu isimlere sahip olmayacağını varsaymayabilirsiniz.)
Ayrıca, değişken değerleriniz gerçekten isteğe bağlı bir tamsayı olup olmadığı da önemli değildir, çünkü yalnızca 1000'den daha küçük sayılar test edilecektir. Ayrıca, dilin tekrarlama limitleri ( Python gibi ) varsa, aşağıdaki test programı çalıştığı sürece daha karmaşık Prindeal programlarının karşılaşabileceği bir sorun yoktur.
Test programı
Burada kukla değişkenlerin ( _
konvansiyonla başlayarak ) ve birçok yardımcı takma adın kullanılmasıyla toplama, çarpma ve üsteleme işlemlerini oluşturan geniş bir Prindeal programı :
#Command Definitions:
a s #flag as a success
i _
d _
d _
a f #flag as a failure
d _
d _
d _
a z #1 = zero
d 1
z 1
s
a n #1 = one
z 1
i 1
s
a move #2 += 1, 1 = zero
moveH 1 2
move 1 2
s
a moveH #move helper
d 1
i 2
f
a dupe #2 += 1, 3 += 1, 1 = zero
dupeH1 1 2 3
dupe 1 2 3
s
a dupeH1 #dupe helper
d 1
dupeH2 2 3
f
a dupeH2 #dupe helper
i 1
i 2
s
a copy #2 = 1
z 2
copyH 1 2
s
a copyH #copy helper
dupe 1 2 _copy
move _copy 1
s
a addTo #1 += 2
copy 2 _add
#testing comments #
move _add 1#in weird places # just because #
s
#it's a g##d idea
###
a add #1 = 2 + 3
#its a good idea
z 1
addH 1 2 3
s
##
#
a addH #add helper
#this is a comment
addTo 1 2 #as is this
addTo 1 3
s
a mul #1 = 2 * 3
mulH1 1 2
mulH2 1 3
s
a mulH1 #mul helper
z 1
copy 2 _mul
s
a mulH2 #mul helper
mulH3 1 2
mulH2 1 2
s
a mulH3 #mul helper
d _mul
addTo 1 2
f
a mulBy #1 *= 2
mul _mulBy 1 2
copy _mulBy 1
s
a pow #1 = 2^3
powH1 1 3
powH2 1 2
s
a powH1 #pow helper
n 1
copy 2 _pow
s
a powH2 #pow helper
powH3 1 2
powH2 1 2
s
a powH3 #pow helper
d _pow
mulBy 1 2
f
#Running Tests:
p A
p B
p C
n A #A = 1
n B #B = 1
add C A B #C = A + B = 1 + 1 = 2
p ____
p A
p B
p C
add B A C #B = A + C = 1 + 2 = 3
p ____
p A
p B
p C
mul d B C #d = B * C = 3 * 2 = 6
p ____
p d
mulBy d B #d = d * B = 6 * 3 = 18
p ____
p d
d A #A = A - 1 = 1 - 1 = 0
mulBy d A #d = d * A = 18 * 0 = 0
p ____
p d
pow A C B #A = C ^ B = 2 ^ 3 = 8
p ____
p A
p B
p C
pow A B C #A = B ^ C = 3 ^ 2 = 9
p ____
p A
p B
p C
pow C A B #C = A ^ B = 9 ^ 3 = 729
p ____
p A
p B
p C
(Bu kodla oynuyorsanız, aynı değişken bir argüman olarak birden çok kez verilirse birçok komutun başarısız olacağını unutmayın. Bu kolayca düzeltilebilir, ancak sonuçtaki kod daha uzundur.)
Prindeal tercümanınız tam olarak çıktı üretebilmelidir:
A = 0
B = 0
C = 0
____ = 0
A = 1
B = 1
C = 2
____ = 0
A = 1
B = 3
C = 2
____ = 0
d = 6
____ = 0
d = 18
____ = 0
d = 0
____ = 0
A = 8
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 2
____ = 0
A = 9
B = 3
C = 729
puanlama
Bayt cinsinden en kısa kod kazanır. Tiebreaker daha önceki bildirime gidiyor.
Brownie Bonus: Prindeal'da harika bir program yaz. Toplama ve çarpma yaptım, çıkarma veya bölme yapabilir misiniz?
p
ve sonrap p
hangisi 1 yazdırabilir?