/*
  米国大統領選挙(本戦)超簡単シミュレーション)
  2016年11月9日(初版)
*/

/*
  ここに、メルセンヌ・ツイスター乱数の組込み方の記載がある
  http://nalab.mind.meiji.ac.jp/~mk/labo/text/giji-ransuu/node11.html
  
  ■メルセンヌ・ツイスター乱数のテストプログラムのコンパイル方法
  > gcc -O -c mt19937ar.c
  > gcc -o mtTest mtTest.c mt19937ar.o
  > ./mtTest > foo
  > diff foo mt19937ar.out

  ■このプログラムのコンパイル方法
  
  (1)"mt19937ar.c"に以下の変更を行い"mt19937ar.cpp"としてセーブする

  #include "mt19937ar.h"
  ↓
  extern "C" {
  #include "mt19937ar.h"
  };

  (2)ライブラリを作成する
  > g++ -O -c mt19937ar.cpp


  (3)このプログラムをコンパイルする
  >gcc -o election2 election2.cpp mt19937ar.o 

  ■このプログラムの実行方法
  > ./election2

*/


#include <stdio.h>

extern "C" {
#include "mt19937ar.h"
};


int Clinton, Trump, Democratic, Republic;

typedef struct STATE{
  char name[40];
  char abbr[3];
  int population;
  int ec;
  int winner;
} STATE;

STATE state[51] = {
  {"アラバマ州","AL",4708708 ,9},
  {"アラスカ州","AK",698473 ,3},
  {"アリゾナ州","AZ",6595778 ,11},
  {"アーカンソー州","AR",2889450 ,6},
  {"カリフォルニア州","CA",36961664 ,55},
  {"コロラド州","CO",5024748 ,9},
  {"コネチカット州","CT",3518288 ,7},
  {"デラウェア州","DE",885122 ,3},
  {"フロリダ州","FL",18537969 ,29},
  {"ジョージア州","GA",9829211 ,16},
  {"ハワイ州","HI",1295178 ,4},
  {"アイダホ州","ID",1545801 ,4},
  {"イリノイ州","IL",12910409 ,20},
  {"インディアナ州","IN",6423113 ,11},
  {"アイオワ州","IA",3007856 ,6},
  {"カンザス州","KS",2818747 ,6},
  {"ケンタッキー州","KY",4314113 ,8},
  {"ルイジアナ州","LA",4492076 ,8},
  {"メイン州","ME",1318301 ,4},
  {"メリーランド州","MD",5699478 ,10},
  {"マサチューセッツ州","MA",6593587 ,11},
  {"ミシガン州","MI",9969727 ,16},
  {"ミネソタ州","MN",5266214 ,10},
  {"ミシシッピ州","MS",2951996 ,6},
  {"ミズーリ州","MO",5987580 ,10},
  {"モンタナ州","MT",974989 ,3},
  {"ネブラスカ州","NE",1796619 ,5},
  {"ネバダ州","NV",2643085 ,6},
  {"ニューハンプシャー州","NH",1324575 ,4},
  {"ニュージャージー州","NJ",8707739 ,14},
  {"ニューメキシコ州","NM",2009671 ,5},
  {"ニューヨーク州","NY",19541453 ,29},
  {"ノースカロライナ州","NC",9380884 ,15},
  {"ノースダコタ州","ND",646844 ,3},
  {"オハイオ州","OH",11542645 ,18},
  {"オクラホマ州","OK",3687050 ,7},
  {"オレゴン州","OR",3825657 ,7},
  {"ペンシルベニア州","PA",12604767 ,20},
  {"ロードアイランド州","RI",1053209 ,4},
  {"サウスカロライナ州","SC",4561242 ,9},
  {"サウスダコタ州","SD",812383 ,3},
  {"テネシー州","TN",6296254 ,11},
  {"テキサス州","TX",24782302 ,38},
  {"ユタ州","UT",2784572 ,6},
  {"バーモント州","VT",621760 ,3},
  {"バージニア州","VA",7882590 ,13},
  {"ワシントン州","WA",6664195 ,12},
  {"ウェストバージニア州","WV",1819777 ,5},
  {"ウィスコンシン州","WI",5654774 ,10},
  {"ワイオミング州","WY",544270 ,3},
  {"コロンビア特別区","DC",601723 ,3},
};

int main()
{
  unsigned long init[4]={0x123, 0x234, 0x345, 0x456}, length=4;
  init_by_array(init, length);
  
  for(int z =0; z < 10; z++){ // この大統領選挙を10回実施する

    Clinton = 0;
    Trump = 0;
    
    Democratic = 0;
    Republic = 0;

    for (int i=0; i<51; i++){  // 50州+コロンビア特別区
      
      int population = state[i].population; 

      Democratic = 0;
      Republic = 0;

      for (int k=0; k < population; k++){

        //if ((genrand_int32() % 2) == 0){ // 完全に半数ずつが投票
        //if ((genrand_int32() % 100) < 49){  // 100人に一人がトランプ氏に移動(0〜48までの49個 vs 49〜99までの51個)
        if (genrand_int32() % 10000 < 4999){  // 10000人に一人がトランプ氏に移動(0〜4998までの4999個 vs 4998〜9999までの5001個)
          Democratic++;
        }
        else{
          Republic++;
        }
      }
      
      // printf("State:%s Democratic = %d, Republic = %d\n",  state[i].abbr, Democratic, Republic); 
      
      /* 
         州の選挙人を総取り(同数の場合は、共和党に入れることにした(トランプさんが若干有利)になる。
         
         正確には、『同数の場合、各州の議員団は州ごとに投票を行い、そこで得票数が最も多かった候補に
         1票を投じることで均衡を崩す。議員数が偶数の州で引き分けとなった場合、その州は投票権を失う』
         となっている。
      */
      if (Democratic > Republic){
        Clinton += state[i].ec;
      }
      else{
        Trump += state[i].ec;
      }
    }

    printf("Clinton = %d, Trump = %d\n",  Clinton, Trump);

  }
}