Meydan okuma
Sizin zorluğunuz, bundan sonra ortaya çıkacak lisp benzeri bir dil için bir tercüman tasarlamaktır: GLisp . GLisp için program kodu, parantezle belirtilen rasgele miktarda iç içe ifadelerden oluşur ve aşağıdaki biçimde olur:
(func arg1 arg2 ...)
Yorumlayıcının köşeli ayraçlar, işlevler ve bağımsız değişkenlerden önce ve sonra yabancı boşluk karakterlerine izin vermesi gerektiğini unutmayın.
Türleri
Tamsayı, Liste, Boole ve İşlev olmak üzere dört tür uygulayacaksınız. Tamsayılar ve Boolean değerleri, kendi sözdizimleriyle açıkça kaynak koduna eklenebilir. Yorumcunuz, bir sayı sayısal karakterinin bir Tamsayı gösterdiğini varsaymalıdır (açıkça negatif tamsayılar eklemek için bir sözdizimi uygulamanız gerekmez). Tercümanınız bunu kabul etmeli true
ve false
Boole değerleri olarak tanımlanmalıdır. İşlevler kullanıcı tarafından açıkça tanımlanamaz ve her zaman tek bir değer döndürür (herhangi bir uzunluktaki bir liste tek bir değer olarak sayılır).
Fonksiyonlar
Aşağıdaki işlevlerin uygulanması gerekir ve İşlev , Arity biçimindedir . Bir Arity n
artı işaretiyle devam ederse , bu n
veya daha fazla argümanı ifade eder . Aksi belirtilmedikçe, bir işleve verilen tüm bağımsız değişkenlerin aynı türde olduğunu varsayabilirsiniz. Ayrıca, certian türü için herhangi bir davranış belirtilmezse, o işlevin hiçbir argümanının bu tür olmayacağını varsayabilirsiniz. Bağımsız değişkenler aşağıdaki şemada belirtilecektir:
(func argument1 argument2 ... argumentn)
+ , 2+
- Tüm bağımsız değişkenler Tamsayı türündeyse , bağımsız değişkenlerin toplamını döndürmelisiniz
- Tüm bağımsız değişkenler List türündeyse, bağımsız değişkenlerin birleşimini artan sırada döndürmeniz gerekir (
arg1+arg2+ ...
) - Tüm bağımsız değişkenler Boolean türündeyse , mantıksal Tüm bağımsız değişkenler dizisini döndürmelisiniz
(+ 1 2 3 4 5) -> 15
(+ (list 1 2) (list 3 4)) -> (list 1 2 3 4)
(+ true true true) -> true
- , 2+
- Tüm bağımsız değişkenler Tamsayı türündeyse , bağımsız değişkenlerin (
arg1-arg2- ...
) farkını döndürmelisiniz - Tüm bağımsız değişkenler Boolean türündeyse , mantıksal bağımsız değişkenler dizisinden herhangi birini döndürmelisiniz
(- 8 4 3) -> 1
(- 0 123) -> -123
(- true false false true false) -> true
- Tüm bağımsız değişkenler Tamsayı türündeyse , bağımsız değişkenlerin (
* , 2+
- Tüm bağımsız değişkenler Tamsayı türündeyse , bağımsız değişkenlerin ürününü döndürmelisiniz
- Bir bağımsız değişken List türünde , diğeri Integer türündeyse (bunların yalnızca verilen bağımsız değişkenler olacağını varsayabilirsiniz), öğeleri tekrarlanan zamanlarda yeni bir Liste döndürmeniz gerekir .
arg1
arg2
(* 1 2 3 4 5) -> 120
(* (list 1 2 3) 2) -> (list 1 2 3 1 2 3)
/ , 2+
- Tüm bağımsız değişkenler Tamsayı türündeyse, bağımsız değişkenlerin (
arg/arg2/ ...
) bölümünü döndürmelisiniz ( bölünmenin sırayla yapıldığını ve her adımdaki ondalık bölümün kesildiğini varsayabilirsiniz) - Bir bağımsız değişken List türünde , diğeri Function türündeyse, her bir değer eşlendikten sonra ortaya çıkan Listeyi döndürmeniz gerekir
arg2
(/ 100 10 3) -> 3
(/ (list 1 2 3) inc) -> (list 2 3 4)
- Tüm bağımsız değişkenler Tamsayı türündeyse, bağımsız değişkenlerin (
% , 2
- Tüm bağımsız değişkenler Integer türündeyse , bağımsız değişkenlerin modülünü döndürmelisiniz
(% 4 2) -> 0
= , 2+
- Eğer her iki tüm argümanlar türü ve değeri aynıdır, sen Gerçek dönmelidir. Aksi takdirde false değerini döndürün.
(= 0 0 0) -> true
(= 0 false (list)) -> false
liste , 0+
- Türden bağımsız olarak tüm bağımsız değişkenlerin bir listesini döndürmelisiniz. Herhangi bir argüman verilmezse, boş bir liste döndürmeniz gerekir
(list 3 4 (list 5)) -> (list 3 4 (list 5))
inc , 1
- Argüman Integer türündeyse , bir tamsayı artarak tamsayı döndürmeniz gerekir
- Argüman tipi ise List , sen geri dönmelidir Liste tek rotasyon saat yönünde döndürüldü
(inc 1) -> 2
(inc (list 1 2 3)) -> (list 3 1 2)
aralık , 1
- Argüman tipi ise Tamsayı , sen geri dönmelidir Tamsayı bir azaltılır
- Argüman tipi ise List , sen geri dönmelidir Liste saat yönünün tersine tek rotasyon döndürülmüş
(dec 1) -> 0
(dec (list 1 2 3)) -> (list 2 3 1)
eğer 3
- Herhangi bir türde üç argüman verilirse :
arg1
öğesinin doğruluk değeri doğruysa, geri dönarg2
, başka geri dönarg3
(if (not (list 1)) 8 false) -> false
- Herhangi bir türde üç argüman verilirse :
değil , 1
- Herhangi bir türde argüman verilirse,
arg1
öğesinin doğruluk değeri False ise, returntrue
, else returnfalse
. (not (list)) -> true
- Herhangi bir türde argüman verilirse,
len , 1
- List türünde bir bağımsız değişken verilirse ,
arg1
(len (list 4 2 true (list 3) (list))) -> 5
- List türünde bir bağımsız değişken verilirse ,
Doğruluk tablosu:
0, (list), false -> false
burada (list)
boş bir listeyi gösterir. Diğer her şey true
.
Yorumcunuz, stdin veya bir dosyadan kaynak girdisini okuyan tam bir program ya da kaynağı dize olarak alan ve çıktı değerini döndüren bir işlev olabilir.
Birincisini seçerseniz, Tamsayılar için çıktı basitçe sayılardır, Booleans için true
veya false
listelerdir ve parantezler için parantez içine alınmış değer dizisi (örn. (1 2 3 4 (5 6 7))
Gösterir (list 1 2 3 4 (list 5 6 7))
).
İkincisini seçerseniz, değer uygulama dilinin karşılık gelen türünde veya benzer bir tür yoksa, özel bir türde döndürülmelidir. Dilin bir Liste türü yoksa Listeler Diziler veya Vektörler olarak döndürülebilir , Booleanlar dilde Boole türü olarak veya dil desteklemiyorsa özel bir tür olarak döndürülmelidir.
Test senaryoları
(list 1 2 3 (list 4 5 true)) -> (1 2 3 (4 5 true))
(/ 4000 (+ 1 2 3 4 (* 5 8))) -> 80
(+ (not (- (len (list 5 6 7)) (/ 10 3))) true) -> true
(if ( len (list ) ) 4 (if (+ (= 8 8 8) (not (list 4))) 8 5)) -> 5
Açıklamalar
- Sizin tercüman seçtiğiniz herhangi bir şekilde geçersiz girdi başa olabilir, ama olmamalıdır (sorunsuz bir hata mesajı yazdırmak ve çıkmak olabilir) bir istisna
- İşlevler her zaman soldan sağa argümanları değerlendirir
- Geçersiz giriş, sözdizimsel olarak yanlış olan herhangi bir giriştir. Bu, eşleşmeyen parantezleri, sıfıra bölme ve kısmen uygulanan işlevleri içerir (ancak bonusa gitmediği sürece).
- İçin
=
, değerlerin herhangi bir farklı ise veya türlerinden herhangi birini farklı, dönüşfalse
Bonuslar
- Kısmen uygulanan işlevleri destekliyorsanız * 0,8 puan alın . Örneğin
((+ 2) 3)
, aynı olabilir(+ 2 3)
, ancak bunun gibi şeylere izin verir(/ (list 1 2 3) (+ 2))
. Bir işlevin, minimum bağımsız değişken sayısından daha azını alırsa kısmen uygulandığını varsayabilirsiniz. - Geri
if
döndürülmedikçe uygulanan bağımsız değişkenleri değerlendirmezseniz * 0,85 puan
Bu kod golf, bu nedenle en düşük bayt sayısına sahip yorumlayıcı kazanır!
(+ 3 (if false 5))
? Genel olarak konuşursak, "hiçbir şey döndürmemek" nedir? Geri alınacak herhangi bir birim türü belirtmediniz
(+ bool bool...)
mantıksal VE ve (- bool bool...)
mantıksal VEYA? Standart halka notasyonu +
OR veya *
AND için kullanır . 2. "Geçersiz giriş" (/ 2 0)
sözdizimsel olarak doğru olan vakaları kapsamak üzere mi tasarlanmış ? 3. =
Değerler aynı değilse, geri dönmeli false
mi? 4. 'in tanımı not
geriye doğru gözükmektedir. 5. Jetonlar nelerdir? Yorumlayıcının fazladan boşluk kullanması gerektiğini söylüyorsunuz, ancak hangi boşluklara güvenebileceğini söylemiyorsunuz. Bunun gibi karmaşık sorular için, spesifikasyonun kontrol edilebilmesi için sanal alanı gerçekten kullanmalısınız.
((+ 2 3) 4)
eşit 9
mi yoksa hata mı? Özellikle, var-arg işlevleri için, uygulamanın ne zaman kısmi olarak değerlendirileceği açık değildir. Gibi şeyler ile bile çamurlu olur((if true (+ 2 3) (- 5)) 4)
(if (not (array 1)) 8 false) -> false
?