C, 53 ký tự riêng biệt
Điều này sử dụng "#%&()*+,-./01234569;<=>BKQR[\]acdefghilmnoprstu{|}, không gian và dòng mới, được phân phối như sau: 24 × \n, 33 × , 20 × ", 2 × #, 3 × %, 16 × &, 46 × (, 46 × ), 13 × *, 12 × +, 35 × ,, 10 × -, 2 × ., 2 × /, 18 × 0, 9 × 1, 4 × 2, 4 × 3, 4 × 4, 4 × 5, 3 × 6, 3 × 9, 34 × ;, 6 × <, 46 × =, 2 × >, 2 × B, 2 × K, 3 × Q, 2 × R, 8 × [, 1 × \, 8 × ], 39 × a, 23 × c, 5 × d, 19 × e, 15 × f, 1 × g, 22 × h, 36 × i, 5 × l, 1 × m, 35 × n, 9 ×o, 33 × p, 44 × r, 20 × s, 43 × t, 15 × u, 8 × {, 14 × |, 8 × }.
#include <stdio.h>
#include <string.h>
int n(char*a,char*e,int i)
{int c=0;for(;a<e;)c+=*a++=="\n"[0];return c==i;}
int p(char *t, int r, int u)
{char h[]=" RBQK";char*p=t+r;char*a;int c=0;
for(int i=0;i<=3;++i,p+=u){char*s=strchr(h,*p);if(s&&s==h==0){++c;*s=" "[0];}else{a=p;}}
if(c-3)return 0;
char o=h[strspn(h, " ")];
p=strchr(t, o);
if(p==0)return*a==" "[0];
if(p<a){char*s=p;p=a;a=s;}
if(o=="K"[0])return(p-a)==3&&n(a,p,1)||(p-a)==2+5&&n(a,p,1)||(p-a)==9&&n(a,p,2)||(p-a)==11&&n(a,p,2);
if((p-a)%5==0||n(a,p,0))return (int)strchr("RQ", o);
return((p-a)%4==0&&n(a,p,(p-a)/4)||(p-a)%6==0&&n(a,p,(p-a)/6))&&strchr("BQ",o);}
int f(char *t)
{for(int i=0;i<4;++i)if(p(t,i,5)||p(t,i*5,1))return 1;
return p(t,0,6)||p(t,3,4);}
int main()
{char t[20];fread(t,19,1,stdin);t[19]=0;
if(f(t))puts("true");else puts("false");}
Giải trình
#include <stdio.h>
#include <string.h>
/* count newlines */
int n(char *a, char *e)
{
int c = 0;
for (;a<e;) c += *a++=='\n';
return c;
}
/* check a single row, column or diagonal */
int p(char *t, int start, int stride)
{
char h[] = " RBQK"; /* pieces not in line */
char *p = t+start;
char *a;
int c = 0;
for (int i = 0; i <= 3; ++i, p+=stride) {
char *s = strchr(h, *p);
if (s && s == h == 0) {
/* a white piece */
++c;
*s = " "[0];
} else {
/* candidate target square */
a = p;
}
}
/* did we find three white pieces in this line? */
if (c != 3)
return 0;
char o = h[strspn(h, " ")];
p = strchr(t, o);
if (p==0)
return *a == " "[0];
/* ensure a < p */
if (p < a) {
char *s = p;
p = a;
a = s;
}
/* knight moves */
if (o == 'K')
return (p-a)==3 && n(a,p)==1
|| (p-a)==7 && n(a,p)==1
|| (p-a)==9 && n(a,p)==2
|| (p-a)==11 && n(a,p)==2;
/* rook moves */
if ((p-a)%5 == 0 || n(a,p)==0)
return 0==strchr("RQ", o)==0;
/* bishop moves */
return
((p-a)%4==0 && n(a,p)==(p-a)/4 ||
(p-a)%6==0 && n(a,p)==(p-a)/6)
&& strchr("BQ", o);
}
/* main predicate function */
int f(char *t)
{
/* try rows and columns */
for (int i = 0; i < 4; ++i)
if (p(t, i, 5) || p(t, i*5, 1))
return 1;
/* try diagonals */
return p(t, 0, 6) || p(t, 3, 4);
}
int main()
{
char t[20];
fread(t, 19, 1, stdin);
t[19]=0;
if (f(t)) puts("true"); else puts("false");
}
Nó hoạt động bằng cách tìm kiếm một hàng, cột hoặc đường chéo chứa ba trong số các mảnh màu trắng; achỉ vào vị trí mục tiêu (chưa chứa một mảnh màu trắng). Sau đó, phần còn thiếu ( o) được xác định - đó là phần chúng tôi đã không xóa khỏi chuỗi hnhư chúng tôi đã thấy.
Nếu tác phẩm không nằm trên bảng, nó phải nằm trong tay và nó chỉ có thể được chơi trong một không gian. Mặt khác (nếu chúng ta tìm thấy nó trên bảng), nó phải ở vị trí có thể di chuyển vào ô vuông mục tiêu. Vì di chuyển là đảo ngược, chúng tôi trao đổi nếu cần thiết, do đó a < p.
Chúng tôi kiểm tra di chuyển hiệp sĩ trước - có bốn động thái đi xuống hợp pháp và chúng tôi tránh quấn quanh các cạnh trái / phải của bảng bằng cách xác minh số lượng dòng mới chúng tôi vượt qua.
Sau đó, chúng tôi kiểm tra các động tác rook, và sau đó giám mục di chuyển, sử dụng một thuật toán tương tự (và một nữ hoàng có thể sử dụng một trong hai động tác này).
Chương trình kiểm tra
int expect_true(char *board)
{
if (strlen(board) != 19) {
fprintf(stderr, "Wrong length board:\n%s\n\n", board);
return 1;
}
if (!f(board)) {
fprintf(stderr, "Expected true, but got false, for\n%s\n\n", board);
return 1;
}
return 0;
}
int expect_false(char *board)
{
if (strlen(board) != 19) {
fprintf(stderr, "Wrong length board:\n%s\n\n", board);
return 1;
}
if (f(board)) {
fprintf(stderr, "Expected false, but got true, for\n%s\n\n", board);
return 1;
}
return 0;
}
int main()
{
return
+ expect_true("rkb \n"
" \n"
" \n"
"RB Q")
+ expect_false("rk \n"
" \n"
" \n"
"RBbQ")
+ expect_true("rk \n"
" K \n"
" \n"
"RBbQ")
+ expect_true("rk \n"
" \n"
"K \n"
"RBbQ")
+ expect_true("rkRB\n"
" \n"
" Qb \n"
"K ")
+ expect_true("rk \n"
" \n"
"K \n"
"RBbQ");
}
Chương trình đếm (trong C ++)
#include<algorithm>
#include<iostream>
#include<map>
int main()
{
std::map<char,int> m;
for (int c; (c = getchar()) != EOF; )
++m[c];
for (auto e: m)
std::cout << e.first;
std::cout << "\n distributed as follows: ";
for (auto e: m)
std::cout << e.second << "×`" << e.first << "`, ";
}