Haskell , 1080 1033 byte
;
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; ; ;
Cobalah online!
Penjelasan
Ini merupakan tugas yang cukup menarik bagi Haskell.
Keseimbangan
Untuk memulainya kita perlu beberapa cara untuk menentukan apakah suatu karakter memiliki titik kode genap atau ganjil. Cara normal yang dapat dilakukan seseorang adalah mendapatkan titik kode dan memodifikasinya dengan 2. Namun, karena orang mungkin sadar, mendapatkan titik kode dari suatu karakter memerlukan impor, yang karena pembatasan sumber berarti bahwa tidak dapat bekas. Haskeller yang lebih berpengalaman akan berpikir untuk menggunakan rekursi. CharIni adalah bagian dari Enumtypeclass sehingga kita bisa mendapatkan pendahulu dan penggantinya. Namun preddan succkeduanya juga tidak dapat digunakan karena mereka tidak mengganti paritas byte.
Jadi ini membuat kita cukup macet, hampir tidak bisa melakukan manipulasi dengan karakter. Solusi untuk ini adalah untuk mem-hardcode semuanya. Kita dapat mewakili (kebanyakan) bahkan karakter sebagai literal, kemungkinan kita memiliki masalah dengan 'itu aneh sehingga tidak bisa di sebelah karakter itu sendiri membuat literal tidak mungkin untuk mengekspresikan sebagian besar karakter aneh. Jadi kita membuat kode semua byte genap, dan kemudian menambahkan tangkapan semua untuk byte aneh di akhir.
Bytes yang bermasalah
Anda mungkin memperhatikan bahwa ada beberapa bahkan byte yang tidak dapat dibuat literal dengan membungkusnya dalam tanda kutip tunggal. Mereka adalah unsintables, newlines dan \. Kita tidak perlu khawatir tentang hal-hal yang tidak patut karena selama kita tidak menggunakannya, kita tidak perlu memverifikasi. Bahkan kita masih bisa menggunakan unsintables aneh, seperti tab, saya hanya akhirnya tidak perlu. Newline secara bijaksana dapat diabaikan karena itu akan dipangkas dari program. (Kita dapat memasukkan baris baru, karena itu titik kode agak mudah, tetapi kita tidak perlu). Daun ini sangat valid. Kemudian ketika kita perlu mewakili baris baru kita akan melihat bahwa untungnya memiliki properti yang sama .\ , sekarang\ memiliki codepoint 92, yang nyaman adalah bilangan ganjil diikuti oleh bilangan genap, sehingga \92berganti-ganti antara genap dan odds dengan demikian literal'\92''\10'
Masalah spasi
Sekarang untuk mulai menulis kode aktual kita harus dapat menempatkan sejumlah besar karakter pada satu baris. Untuk melakukan ini, saya menulis topi:
;
f=
g
ij=f
a =hi
hi = g
hij= ij
Tutup tidak melakukan apa pun kecuali Haskell valid. Saya awalnya berharap untuk membuat definisi yang akan membantu kami dalam kode nanti, tetapi tidak. Ada juga cara yang lebih mudah untuk membuat tutup, misalnya spasi putih dan titik koma, tetapi mereka tidak menyimpan byte melalui cara ini jadi saya belum repot-repot mengubahnya.
Hardcoder
Jadi sekarang saya memiliki cukup ruang pada sebuah baris saya mulai nilai hardcoding. Ini sebagian besar sangat membosankan, tetapi ada beberapa hal yang menarik. Untuk satu kali garis mulai semakin lama bisa kita gunakan; untuk meletakkan beberapa deklarasi pada sebuah baris, yang menghemat satu ton byte.
Yang kedua adalah karena kita tidak selalu dapat memulai sebuah baris dengan yang gsering kita harus membuat indentasi sedikit. Sekarang Haskell benar-benar peduli tentang lekukan, sehingga akan mengeluh tentang ini. Namun jika baris terakhir sebelum baris indentasi berakhir dengan tanda titik koma, itu akan memungkinkannya. Mengapa? Saya belum pingsan, tapi berhasil. Jadi kita hanya harus ingat untuk meletakkan titik koma di akhir baris.
Fungsi Blok Bangunan
Setelah hardcoder selesai, lancar berlayar ke akhir program. Kita perlu membangun beberapa fungsi sederhana. Pertama saya membangun versi drop, bernama i. iberbeda dari dropitu jika kita mencoba untuk melewati akhir string itu hanya mengembalikan "y". iberbeda dari drop juga dalam bahwa jika ia mencoba untuk menjatuhkan baris baru itu akan kembali "y", Ini akan berguna karena nanti ketika kita memverifikasi bahwa program adalah segitiga ini akan memungkinkan kita untuk kembaliFalse ketika baris terakhir tidak selesai, atau ketika garis berakhir lebih awal.
kknssTruenkn + 1False
Kami kemudian membuat alias untuk k, m. mhanya kdengan 1dalam argumen pertama, dan baris baru diawali dengan argumen kedua.
Selanjutnya yang kita miliki o. omengambil nomor dan string. Ini menentukan apakah byte string (mengabaikan baris baru) bergantian dalam paritas (menggunakan kami g) dimulai dengan nomor input.
Terakhir kita memiliki syang berjalan odengan keduanya 1dan 0, jika berhasil maka itu berlaku untuk m. Jika gagal keduanya hanya kembali False. Ini adalah fungsi yang kita inginkan. Ini menentukan bahwa input adalah segitiga dan bergantian.