LoginSignup
0
1

More than 5 years have passed since last update.

オフラインリアルタイムどう書く F04 の ruby と C99 による実装例

Last updated at Posted at 2017-04-19

問題:http://nabetani.sakura.ne.jp/hena/ordf04octsp/
実装リンク集:http://qiita.com/Nabetani/items/8ead5622e192d9655cf5

いつもどおり、テストデータの大半を省略した ruby の実装から:

def solve(src0)
  src = src0.to_i
  Array.new(8){ |s|
    if src[s]==1
      w = (1..8).find{ |x| src[(s+x)%8]==1 }
      w + (w==4 ? 1 : 2)
    end
  }.compact.sort.join
end

DATA.all?{ |line|
  num, src, expected = line.split(/\s+/ )
  actual = solve( src )
  okay = expected == actual
  puts( "%s %s:%s->%s ( %s )" % [(okay ? "ok" : "**NG**"), num, src, actual, expected] )
  okay
}.tap{ |x| puts( x ? "everything is okay" : "something wrong" ) }

__END__
0 165 3445
1 80  48
2 255 33333333

剰余を使ってぐるぐる回せばいいよ、というストレートな実装。
ビットの扱いが ruby だと楽だよね。

中央が直線になったときに頂点数が変わる部分は、アドホックな感じで。

で。

これをそのまま C99 に移植したのが下記:

//clang -std=c99 -Wall
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int compare( const void * a, const void * b ){
  const char * ac = (const char * )a;
  const char * bc = (const char * )b;
  return *ac-*bc;
}

char * solve_impl( int src )
{
  char buffer[9]={0};
  char * pos=buffer;
  for( int s=0 ; s<8 ; ++s ){
    if ( src & (1<<s ) ){
      int w=1;
      for( ; w<=8 ; ++w ){
        if ( src & (1<<((w+s)%8)) ){
          break;
        }
      }
      *pos=w+( w==4 ? '1' : '2' );
      ++pos;
    }
  }
  qsort( buffer, pos-buffer, 1, compare );
  return strdup( buffer );
}

char * solve( char const * src )
{
  return solve_impl( atoi( src ) );
}

void test( char const * src, char const * expected )
{
  char *  actual = solve( src );
  _Bool ok = 0==strcmp(actual, expected);
  printf( "%s : %s / %s / %s\n", (ok  ? "ok" : "**NG**"), src, expected, actual );
  free( actual );
}

int main()
{
  /*0*/ test( "165", "3445" );    
  /*1*/ test( "80", "48" );    
  /*2*/ test( "255", "33333333" );
  return 0;
}

ソートがめんどくさい。実にめんどくさい。
それ以外はまあこんなもんかと思う。
'1''2' との加算で文字列を作る辺りは C言語らしさを出せたと思う。

0
1
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1