C、53文字
これは"#%&()*+,-./01234569;<=>BKQR[\]acdefghilmnoprstu{|}
、スペースと改行を使用し、次のように配布されます。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");}
説明
#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");
}
3つの白い部分を含む行、列、または対角線を探すことで機能します。a
ターゲット位置を指します(まだ白い部分を含んでいません)。次に、欠落している部分(o
)が識別されますh
。これは、見たときに文字列から削除しなかったものです。
駒がボード上にない場合、それは手札になければならず、スペースでのみプレイできます。それ以外の場合(ボード上で見つけた場合)、ターゲットの正方形に移動できる位置にある必要があります。動きはリバーシブルなので、必要に応じて交換しa < p
ます。
最初に騎士の動きをテストします-4つの正当な下向きの動きがあり、通過する改行の数を確認することで、ボードの左端と右端の回り込みを回避します。
その後、同様のアルゴリズムを使用してルークムーブをテストし、次にビショップムーブをテストします(クイーンはこれらのムーブのいずれかを使用できます)。
テストプログラム
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");
}
カウントプログラム(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 << "`, ";
}