外国人就労拡大で際立つ日本の「ブラック国家ぶり」 のシミュレーション
2022年10月1日
/*
g++ -g specific_skill2.cpp -o specific_skill2
*/
/*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct person{
int age;
int type1_lifetime; // 1号の残り時間
int retirement_age; // 65歳で引退
///////////
struct person *prev; /* 前の構造体を示すポインタ */
struct person *next; /* 次の構造体を示すポインタ */
} PERSON;
int int_max(int a, int b)
{
if (a < b)
return b;
else
return a;
}
PERSON *p_first_person, *p_last_person;
void init_person_list(PERSON **p_first_person, PERSON **p_last_person)
{
PERSON *p_top_person = (PERSON *)malloc(sizeof(PERSON));
if(p_top_person == NULL) {
printf("メモリが確保できません\n");
exit(EXIT_FAILURE);
}
memset(p_top_person, 0, sizeof(PERSON)); // ゼロクリア
PERSON *p_tail_person = (PERSON *)malloc(sizeof(PERSON));
if(p_tail_person == NULL) {
printf("メモリが確保できません\n");
exit(EXIT_FAILURE);
}
memset(p_tail_person, 0, sizeof(PERSON)); // ゼロクリア
*p_first_person = p_top_person;
*p_last_person = p_tail_person;
(*p_first_person)->prev = NULL;
(*p_last_person)->next = NULL;
(*p_first_person)->next = (*p_last_person);
(*p_last_person)->prev = (*p_first_person);
return;
}
void add_person(PERSON *p_ref_person)
{
PERSON *new_p_person = (PERSON *)malloc(sizeof(PERSON));
if(new_p_person == NULL) {
printf("メモリが確保できません\n");
exit(EXIT_FAILURE);
}
memset(new_p_person, 0, sizeof(PERSON)); // ゼロクリア
memcpy(new_p_person, p_ref_person, sizeof(PERSON)); // 引数の動的メモリの内容コピー
// personの追加属性記述ここから
// personの追加属性記述ここまで
PERSON *p_person = p_last_person->prev;
p_person->next = new_p_person;
new_p_person->prev = p_person;
p_last_person->prev = new_p_person;
new_p_person->next = p_last_person;
return;
}
void delete_person(PERSON *p_person)
{
// ポインタを貼り替えて
p_person->prev->next = p_person->next;
p_person->next->prev = p_person->prev;
// そのメモリを解放する
free(p_person);
return;
}
int type1(int k){
int number = 40000 + 4000 * (k - 2019);
if (number > 60000){
number = 60000;
}
return number;
}
// 2.1.1 C言語のrand関数を用いた方法
double Uniform( void ){
return ((double)rand()+1.0)/((double)RAND_MAX+2.0);
}
// 3.3. 正規分布・ガウス分布 (Normal Distribution)
double rand_normal( double mu, double sigma ){
double z=sqrt( -2.0*log(Uniform()) ) * sin( 2.0*M_PI*Uniform() );
return mu + sigma*z;
}
int main()
{
srand(13);
// 社員格納用リストの作成
init_person_list(&p_first_person, &p_last_person);
int pass1_number;
for (int i = 2019; i < 2080; i++){
// for (int i = 2019; i < 2200; i++){
// 1号試験パス者の生成
pass1_number = type1(i);
for (int k = 0; k < pass1_number; k++){
PERSON person;
person.age = int_max((int)rand_normal(26.0, 3.5), 18); // 18歳以下は応募できない
// printf("person.age = %d\n",person.age);
person.type1_lifetime = 5;
person.retirement_age = 65;
add_person(&person);
} // for (int k = 0, k < type1(k); k++)
// 1号試験パス者の生成(ここまで)
// ===== PERSON ループを回す========
PERSON* p_person = p_first_person->next;
while (p_person != p_last_person){
// 1号 強制帰国
if (p_person->type1_lifetime == 0){ // 5年を使い果した
if (Uniform() <= 0.4){ // 2号合格率 40%
p_person->type1_lifetime = -1; // 免責フラグ
}
else{
PERSON* p_person_prev = p_person->prev;
delete_person(p_person);
p_person = p_person_prev;
}
}
if (p_person->age > 65){ // 65歳以上になったら、強制帰国
PERSON* p_person_prev = p_person->prev;
delete_person(p_person);
p_person = p_person_prev;
}
// 次のループに回る
p_person = p_person->next;
}
p_person = p_first_person->next;
while (p_person != p_last_person){
// 1号 強制帰国を迎えるまでのタイムリミットを減らす
if (p_person->type1_lifetime != -1){
p_person->type1_lifetime -= 1;
}
// 全員の年齢の加算
p_person->age += 1;
// 次のループに回る
p_person = p_person->next;
}
int type1_person_count = 0;
int type2_person_count = 0;
p_person = p_first_person->next;
while (p_person != p_last_person){
if (p_person->type1_lifetime != -1)
type1_person_count += 1;
else
type2_person_count += 1;
p_person = p_person->next;
}
//printf("i:%d, type1:%d, type2:%d\n", i, type1_person_count, type2_person_count);
printf("%d, %d, %d, %d\n",
i,
type1_person_count,
type2_person_count,
type1_person_count + type2_person_count);
}// for (int i = 2019; i < 2100; i++){
return 0;
}