読者です 読者をやめる 読者になる 読者になる

ichirin2501's diary

いっちりーん。

最小公倍数(LCM)

3つ以上の最小公倍数を求めてくれるサイトが見当たらなかったのでプログラム書いた。


簡単な説明

C言語です、てきとーにコンパイルしてくだしあ。


入力:
 標準入力 or 第一引数 = 入力データファイル

出力:
 標準出力 or 第二引数 = 出力データファイル

標準入力 & 引数に出力用ファイル は、できない残念仕様です。



リダイレクト使えって話ですよねw

Sample Input


10,20,30,44,4444
1+2+3+4
2 3 4 5 6 7 8 9 9 999999
2;3;5
4-3-6
0,10,20

Sample Output


Input : 10,20,30,44,4444
LCM : 66660

Input : 1+2+3+4
LCM : 12

Input : 2 3 4 5 6 7 8 9 9 999999
LCM : 39999960

Input : 2;3;5
LCM : 30

Input : 4-3-6
LCM : 12

Input : 0,10,20
error

データを適当な記号で区切れば分割してくれます。
負数は考えてません、値0が含むデータはエラーとしてます。
入力データのチェックがめんどいので、18桁を超えるものはエラーと判定しますた。
ごめんなさいw

#include <stdio.h>
#include <stdlib.h>

#define BUF_SIZE (1<<10)
#define LLINF 9223372036854775807LL
#define max(a,b) ((a)>=(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))

long long gcd(long long x, long long y)
{
   return y?gcd(y,x%y):x;
}

int main(int argc, char** argv)
{
   char InputStr[BUF_SIZE];
   char* p;
   long long data[BUF_SIZE];
   
   if(argc>1){ stdin  = fopen(argv[1],"r"); }
   if(argc>2){ stdout = fopen(argv[2],"w"); }
   
   if( stdin==NULL || stdout==NULL ){ puts("error"); exit(1); }
   
   for(; NULL!=fgets(InputStr,BUF_SIZE-1,stdin); )
   {
      int n = 0;
      p = InputStr;
      char *t;
      
      fprintf(stdout,"Input : %s",InputStr);
      for(; data[n] = strtoll(p,&t,10);p++,n++)
      {
         if(t-p>18){ puts("error"); exit(1); }
         p=t;
      }
      
      if( !(*p==0 || *p==10) ){ puts("error"); exit(1); }
      
      int i;
      long long d = 1;
      long long tmp;
      for( i=0; i<n; i++)
      {
         tmp = gcd(d,data[i]);
         if( LLINF/(min(d,data[i])/tmp) <= max(d,data[i]))
         {
            puts("error"); exit(1);
         }
         d = max(d,data[i])/tmp*min(d,data[i]);
      }
      fprintf(stdout,"  LCM : %lld\n\n",d);
   }
   return 0;
}