メモ

yukicoderでゆるふわgolf

yukicoder No.69 文字を自由に並び替え

問題はこちら
No.69 文字を自由に並び替え - yukicoder

Bにある文字がAにも使われているか順番に調べる

int main(){
	char a[11]={},b[11]={};
	int i,j,n;
	scanf("%s%s",a,b);
	n=strlen(a);
	for(i=0;i<n;i++){
		for(j=0;j<n;j++)if(b[j]==a[i]){b[j]=0;break;}
		if(j==n)break;
	}
	puts(i==n?"YES":"NO");
	return 0;
}

こういう考え方もできる

int main(){
	char a[11]={},b[11]={};
	int i,j,n,m[128]={};
	scanf("%s%s",a,b);
	n=strlen(a);
	for(i=0;i<n;i++)m[a[i]]++;
	//aに登場する各文字の個数を調べて
	for(i=0;i<n;i++)m[b[i]]--;
	//bに登場する各文字の個数との差を求めて
	for(i=127;i>0;i--)if(m[i]!=0)break;
	//0になってないところがあるか調べて
	printf(i==0?"YES":"NO");
	//もしあったらだめ、なかったらOK
	return 0;
}

この方針で短縮したのがこれ

a[128],i;main(){for(;read(0,&i,1)&&(a[10]?a[i]-->0:++a[i]););i=!puts(a[i]?"NO":"YES");}

87B

16/04/23追記
自明な短縮箇所を見落としていた…

a[128],i;main(){for(;read(0,&i,1)&&(a[10]?a[i]--:++a[i]););i=!puts(a[i]?"NO":"YES");}

85B

16/06/06追記
配列サイズを省略しても通るついでにread&&の部分も三項演算子で書いたほうが短い

a[],i;main(){for(;read(0,&i,1)?a[10]?a[i]--:++a[i]:0;);i=!puts(a[i]?"NO":"YES");}

81B

a[10]?a[i]--:++a[i] の部分は(評価される値を考慮しなければ)a[i]+=1-2*a[10]だから、getcharを配列のindexにぶち込んで短縮できそう
このとき、途中終了の条件は値が-1になることだから、

a[];main(){for(a[-1]=-2;~(a[getchar()]+=1-a[10]*2););*a=!puts(~a[-1]?"NO":"YES");}
//indexをずらして
a[];main(){for(*a=-2;~(a[getchar()+1]+=1-a[11]*2););*a=!puts(~*a?"NO":"YES");}

1-a[11]*2が、全てのデータを読み込んだ後では1になってしまうから*a=-2がいるけど、ここをどうにか出来ないか

a[];main(i){for(;~(a[getchar()+1]+=i);i=-a[11]?:i);*a=!puts(*a?"YES":"NO");}
//できた

ということで76B