Haskell , 1080 1033 bayt
;
f=
g
ij=f
a =hi
hi = g
hij= ij
g ' ' =0
g '"' =0;
g '$' =0;
g '&' =0-0
g '(' =0-0-0
g '*' =0-0-0;
g ',' =0-0-0;
g '.' =0-0-0-0
g '0' =0-0-0-0-0
g '2' =0-0-0-0-0;
g '4' =0-0-0-0-0;
g '6' =0; g '8' =0
g ':' =0; g '<' =0-0
g '>' =0; g '@' =0-0;
g 'B' =0; g 'D' =0-0;
g 'F' =0; g 'H' =0-0-0
g 'J' =0; g 'L' =0-0-0-0
g 'N' =0; g 'P' =0-0-0-0;
g 'R' =0; g 'T' =0-0-0-0;
g 'V' =0; g 'X' =0-0-0-0-0
g 'Z' =0; g '^' =0; g '`' =0
g 'b' =0; g 'd' =0; g 'f' =0;
g 'h' =0; g 'j' =0; g 'l' =0;
g 'n' =0; g 'p' =0; g 'r' =0-0
g 't' =0; g 'v' =0; g 'x' =0-0-0
g 'z' =0; g '\92' =0-0; g '|' =0;
g '~' =0; g y = 1 ;z=0; i(-0)z=z;
i m('\10':y ) ="y"; ; ; ; ; ; ; ;
i m(mnmnmnmnm:y ) = i(m - 1 ) y ; ;
i k m ="y"; ; k i [ ] =01<1010101010;
k m('\10':y ) = k(m + 1 )(i m y ) ; ;
k m y =01>10; m o = k 1$'\10':o ; ; ;
o i('\10':y ) = o i y ; ; ; ; ; ; ; ; ;
o i(k:y )|g k<i = o(1 - i ) y ; ; ; ; ; ;
o i(k:y )|g k>i = o(1 - i ) y ; ; ; ; ; ;
o i [ ] =01<10; o i y =01>10;v=01>10101010
s y|o 1 y = m y|o(-0) y = m y ; s y =v; ; ;
Çevrimiçi deneyin!
açıklama
Haskell için bu oldukça ilginç bir görevdi.
parite
Başlamak için, bir karakterin çift veya tek bir kod noktasına sahip olup olmadığını belirlemenin bir yoluna ihtiyacımız var. Bunu yapabilmenin normal yolu, kod noktasını almak ve 2 ile modifiye etmektir. Ancak, farkında olabileceği gibi, bir karakterin kod noktasının elde edilmesi bir içe aktarma gerektirir, bu da kaynak kısıtlaması nedeniyle Kullanılmış. Daha deneyimli bir Haskeller özyineleme kullanmayı düşünür. Char
's Enum
typeclass'ın bir parçası olduğu için seleflerini ve haleflerini alabiliriz. Ancak pred
ve succ
bunlar alternatif bayt paritesine yok çünkü aynı zamanda hem kullanışsız bulunmaktadır.
Bu bizi oldukça sıkıştırarak karakterlerle herhangi bir manipülasyon yapamayız. Bunun çözümü her şeyi kodlamaktır. Karakterleri bile en çok değişmez olarak gösterebiliriz, sorun yaşadığımız ihtimaller '
gariptir , çünkü karakterin yanında olamaz, değişmez karakterlerin çoğunu ifade etmeyi imkansız hale getirir. Böylece, tüm çift baytları kodlar ve sonunda tek baytlar için bir yakalama ekleriz.
Sorun Bayt
Değişmez değerlerin tek tırnak içine sarılarak yapılamadığı bazı çift baytlar olduğunu fark edebilirsiniz. Bunlar yazdırılamaz, yeni satırlardır ve \
. Yazdırılamayanlar hakkında endişelenmemize gerek yok çünkü hiçbirini kullanmadığımız sürece doğrulamamız gerekmiyor. Aslında hala sekme gibi tuhaf yazdırılamazlar kullanabiliriz, sadece buna ihtiyacım yok. Newline büyük ölçüde göz ardı edilebilir, çünkü yine de programdan kesilecektir. (Newline ekleyebiliriz, çünkü kod noktası oldukça uygundur, ancak buna gerek yoktur). Bu yapraklar \
, şimdi \
tek bir sayı ve ardından çift sayı olan kod noktası 92'ye sahiptir, bu yüzden mükemmel şekilde geçerlidir. Daha sonra newline'ı temsil etmemiz gerektiğinde neyse ki aynı mülke sahip olduğunu fark edeceğiz .\92
kanıtlar ve oranlar arasında değişmektedir.'\92'
'\10'
Aralık sorunları
Şimdi gerçek kodu yazmaya başlamak için tek bir satıra çok sayıda karakter koymamız gerekiyor. Bunu yapmak için kapağı yazdım:
;
f=
g
ij=f
a =hi
hi = g
hij= ij
Kapak geçerli Haskell olmak dışında hiçbir şey yapmaz. Başlangıçta kodda bize yardımcı olacak tanımlar yapmayı umuyordum, ama olmadı. Ayrıca, beyaz boşluk ve noktalı virgül gibi kapak yapmak için daha kolay yollar vardır, ancak baytları bu şekilde kaydetmezler, bu yüzden değiştirmek için uğraşmadım.
Hardcoder
Artık bir satırda yeterli alana sahip olduğum için kodlama değerlerine başlıyorum. Bu çoğunlukla oldukça sıkıcı, ancak birkaç ilgi çekici şey var. Bir kere çizgiler daha da uzamaya başladığında ;
, bir satıra birden fazla bildirim koymak için kullanabiliriz , bu da bize bir ton bayt kazandırır.
İkincisi, her zaman bir çizgiyle her zaman başlayamadığımızdan g
, çizgileri biraz girintilemek zorundayız. Şimdi Haskell gerçekten girintiyi önemsiyor, bu yüzden şikayet edecek. Ancak girintili çizgiden önceki son satır noktalı virgülle bitiyorsa buna izin verir. Neden? Ben en ince değilim, ama işe yarıyor. Bu yüzden noktalı virgülleri satırların sonuna koymayı unutmamalıyız.
Fonksiyon Yapı Taşları
Hardcoder tamamlandıktan sonra programın sonuna kadar düzgün bir şekilde seyreder. Birkaç basit fonksiyon geliştirmemiz gerekiyor. Önce drop
denilen bir sürümünü inşa ediyorum i
. i
farklıdır drop
biz dize sadece döner sonunun damla denerseniz ki "y"
. i
yeni bir satır bırakmaya çalışırsa geri dönülmesinden farklıdır "y"
, bunlar yararlı olacaktır çünkü daha sonra programın bir üçgen olduğunu doğruladığımızda False
, son satır tamamlanmadığında veya bir çizgi erken biter.
k
k
nssTrue
nk
n + 1False
.
Sonra için bir takma ad yapmak k
, m
. m
sadece k
ile1
ilk argüman ve yeni satır ikinci argüman başına ilave.
Sonra var o
. o
bir sayı ve bir dize alır. Dize baytlarının (satırsonlarını yoksayarak) g
girdi numarasıyla başlayarak parite içinde (bizim kullanarak) değişip değişmeyeceğini belirler .
Son olarak , her ikisiyle de s
çalışan hangisi var ve eğer başarılı olursa yeniliyor . Her ikisi de başarısız olursa, sadece geri döner . Bu istediğimiz işlev. Girdinin üçgen ve dönüşümlü olduğunu belirler.o
1
0
m
False