オフラインリアルタイムどう書く E05 に出した問題の実装例(ruby, C11)
問題 http://nabetani.sakura.ne.jp/hena/orde05dokitruck/
実装リンク集 http://qiita.com/Nabetani/items/c516875b13a4d282affe
です。
で。
実装方針はいくつかあって。
- 右から行くか、左から行くか。
- ひとつひとつ行くか、一気に行くか。
- データを何で持つか
辺りで自由に選べるつもり。
私は、後ろから、一気に計算して、データはビット。
まずは、C11かC99 ぐらいによる実装:
// clang -std=c11 -Wall
// clang x86_64-apple-darwin15.5.0
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <memory.h>
char * build_ans( int s )
{
char * r = calloc(4, 1);
for( int i=0 ; i<3 ; ++i ){
if ( s&(1<<i) ){
strcat( r, (char[2]){'a'+i});
}
}
if ( !*r ){
r[0]='-';
}
return r;
}
char * solve( char const * src )
{
int s=7;
for( char const * it = src + strlen( src ) -1 ; src<=it ; --it ){
switch(*it-'0'){
case 1: s|=s/2; break;
case 2: s|=(s&2)*2+!!(s&4); break;
case 3: s|=!!(s&4)+(s&1)*2; break;
case 4: s|=s*2; break;
case 5: s|=(s&1)*4+(s&4)/2; break;
case 6: s|=(s&1)*4+!!(s&2); break;
case 7: s&=5; break;
case 8: s&=6; break;
case 9: s&=3; break;
}
}
return build_ans(s);
}
void test( char const * src, char const * expected )
{
char const * actual = solve( src );
bool okay = 0==strcmp( actual, expected );
printf( "%s %s->%s ( e:%s )\n", ( okay ? "ok" : "**NG**" ), src, actual , expected );
free( actual );
}
int main()
{
/*0*/ test( "1728398", "bc" );
// 略
/*36*/ test( "697535114542", "ac" );
return 0;
}
いつも通り、テストデータの大半は省略。
状態は生死の二種類が3個なので、3bit で表現すれば良い。
生を 1 にしたので、「&=
」で死をもたらし、「|=
」が生きる可能性を増やしている。
solve
の中がごちゃごちゃしているけど、コースを構成するブロックのごちゃごちゃ具合を表現しているので仕方ない。
データで持てればかっこいいけど、今回はコードで表現している。
念の為に書いておくと「!!
」は、論理否定二回で、 0 以外を 1 にするという趣旨の計算を意味している。
全く同じ趣旨の計算を ruby で書いたものが以下。というか、先に ruby で書いていた。
def apply( s, c )
case c
when "0"; s
when "1"; s | s[1] | s[2]*2
when "2"; s | s[1]*4 | s[2]
when "3"; s | s[0]*2 | s[2]
when "4"; s | s[0]*2 | s[1]*4
when "5"; s | s[0]*4 | s[2]*2
when "6"; s | s[0]*4 | s[1]
when "7"; s & 5
when "8"; s & 6
when "9"; s & 3
end
end
def solve( src )
r=src.chars.reverse.inject(7) do |s,c|
apply( s, c )
end
%w( a b c ).each.with_index(0).map{ |c,ix|
r[ix]==0 ? "" : c
}.join.tap{ |x| return x.empty? ? "-" : x }
end
$stdout.sync=true
DATA.map do |line|
num, src, expected = line.split(/\s+/)
actual = solve( src )
okay = actual==expected
puts( "%s %2d %s->%s ( e:%s )" % [ ( okay ? "ok" : "**NG**" ), num, src, actual, expected ] )
okay
end.all?.tap{|x| puts( x ? "everything is ok" : "something wrong" ) }
__END__
0 1728398 bc
1 789 -
2 274 ac
3 185 abc
36 697535114542 ac
bit 演算すら、ruby の方が楽に書ける。
Author And Source
この問題について(オフラインリアルタイムどう書く E05 に出した問題の実装例(ruby, C11)), 我々は、より多くの情報をここで見つけました https://qiita.com/Nabetani/items/5408971a1cc390efca95著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .