乱数・物理・セルオートマトン・感染症モデルの4題を完全コード付きで実装する。
#include <stdio.h> #include <stdlib.h> #include <time.h> #define STEPS 100 int main(void) { srand((unsigned)time(NULL)); int x = 0; printf("step,x\n"); for (int t = 0; t <= STEPS; t++) { printf("%d,%d\n", t, x); x += (rand() % 2 == 0) ? 1 : -1; } return 0; }
rand() % 2 で 0 か 1 が出て、それを +1 / -1 に対応付けます。srand を入れないと毎回同じ軌跡が出るので注意。#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #define TRIALS 10000 #define STEPS 1000 int main(void) { srand((unsigned)time(NULL)); double sum_sq = 0.0; for (int tr = 0; tr < TRIALS; tr++) { int x = 0; for (int t = 0; t < STEPS; t++) { x += (rand() % 2) ? 1 : -1; } sum_sq += (double)x * x; } double rms = sqrt(sum_sq / TRIALS); printf("RMS 距離 = %.3f (理論値 sqrt(%d) = %.3f)\n", rms, STEPS, sqrt((double)STEPS)); return 0; }
-lm が必要です。#include <stdio.h> #include <math.h> #define G 9.8 // 重力加速度 [m/s^2] #define K 0.01 // 空気抵抗係数 #define DT 0.01 // 時間刻み [s] int main(void) { // 初期条件: 45度で初速30m/s double x = 0, y = 0; double angle = 45.0 * M_PI / 180.0; double v0 = 30.0; double vx = v0 * cos(angle); double vy = v0 * sin(angle); printf("t,x,y\n"); double t = 0; while (y >= 0) { printf("%.2f,%.3f,%.3f\n", t, x, y); double v = sqrt(vx * vx + vy * vy); double ax = -K * v * vx; double ay = -G - K * v * vy; vx += ax * DT; vy += ay * DT; x += vx * DT; y += vy * DT; t += DT; } printf("# 着地: x=%.2fm, t=%.2fs\n", x, t); return 0; }
#include <stdio.h> #include <string.h> #include <unistd.h> // usleep (POSIX) #define W 30 #define H 15 #define GENS 40 int grid[H][W]; int next_grid[H][W]; int count_neighbors(int y, int x) { int c = 0; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if (dy == 0 && dx == 0) continue; int ny = y + dy, nx = x + dx; if (ny < 0 || ny >= H || nx < 0 || nx >= W) continue; c += grid[ny][nx]; } } return c; } void step(void) { for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) { int n = count_neighbors(y, x); if (grid[y][x]) next_grid[y][x] = (n == 2 || n == 3); else next_grid[y][x] = (n == 3); } } memcpy(grid, next_grid, sizeof(grid)); } void print_grid(int gen) { printf("\033[H\033[2J"); // 画面クリア printf("世代: %d\n", gen); for (int y = 0; y < H; y++) { for (int x = 0; x < W; x++) { putchar(grid[y][x] ? '#' : '.'); } putchar('\n'); } } int main(void) { // グライダーを配置 grid[1][2] = grid[2][3] = 1; grid[3][1] = grid[3][2] = grid[3][3] = 1; for (int g = 0; g < GENS; g++) { print_grid(g); usleep(150000); // 0.15秒待つ step(); } return 0; }
next_grid に書いてから一気にコピーするのが定石です。#include <stdio.h> #define DAYS 100 int main(void) { double N = 1000.0; // 総人口 double S = 999.0; // 感受性 double I = 1.0; // 初期感染者 double R = 0.0; // 回復者 double beta = 0.3; // 感染率 double gamma = 0.1; // 回復率 (10日で回復) printf("day,S,I,R\n"); for (int day = 0; day <= DAYS; day++) { printf("%d,%.1f,%.1f,%.1f\n", day, S, I, R); double dS = -beta * S * I / N; double dI = beta * S * I / N - gamma * I; double dR = gamma * I; S += dS; I += dI; R += dR; } return 0; }
// ループの中でピーク値を記録 double peak = 0; int peak_day = 0; for (int day = 0; day <= DAYS; day++) { if (I > peak) { peak = I; peak_day = day; } // 既存の更新処理... } printf("ピーク: %d日目に %.0f 人\n", peak_day, peak);