Skip to content

Instantly share code, notes, and snippets.

@sdkfz181tiger
Last active May 13, 2024 06:31
Show Gist options
  • Save sdkfz181tiger/9946b9cf4ec886e198826f5571688744 to your computer and use it in GitHub Desktop.
Save sdkfz181tiger/9946b9cf4ec886e198826f5571688744 to your computer and use it in GitHub Desktop.
C/C++課題ネタ03_ローマ数字、コラッツ数列、円周率、ISBN-10
//==========
// ローマ数字に変換
// 1, Compile
// g++ -std=c++17 -Wall -Wextra main.cpp
// 2, Run
// ./a.out
#include <math.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
const vector<pair<const int, const char*>> ROMAN = {
{1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"},
{100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"},
{10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"}
};
int main(){
printf("Hello, Cpp!!\n");
// ローマ数字に変換
int num = 13;
string result;
for(const auto & [key, str]: ROMAN){
//printf("ROMAN[%d]: %s\n", key, str);
while(key <= num){
num -= key;
result += str;
}
}
printf("Result: %s\n", result.c_str());
return 0;
}
//==========
// 最長コラッツ数列
// 1, Compile
// g++ -std=c++17 -Wall -Wextra main.cpp
// 2, Run
// ./a.out
#include <math.h>
#include <stdio.h>
#include <string>
#include <set>
#include <vector>
using namespace std;
set<int> corats;// 計算済みの値を格納するSet
bool existsCorats(const int num){
const auto it = corats.find(num);
if(it != corats.end()) return true;
return false;
}
void insertCorats(const vector<int> nums){
for(auto num: nums) corats.insert(num);
}
bool checkCorats(int num){
//printf("checkCorats: %d\n", num);
// コラッツ数列を辿る
vector<int> nums = {num};
while(1 < num){
if(num%2 == 0){
num /= 2;// 偶数の場合はn/2
}else{
num = num * 3 + 1;// 奇数の場合は3倍+1
}
if(!existsCorats(num)){
// 計算済みでない値が出た場合
nums.push_back(num);
}else{
// 既に計算済みの値が出た場合(これ以上計算しない)
insertCorats(nums);
return true;
}
}
// 1に到達した場合
if(*(nums.end()-1) == 1){
insertCorats(nums);
return true;
}
return false;
}
int main(){
printf("Hello, Cpp!!\n");
// 最長コラッツ数列(未証明)
// 任意の整数nから始まり、次の要素を偶数の時はn/2に、
// 奇数の時は3倍+1とすると必ず1に到達する
for(int i=1; i<100; i++){
if(!checkCorats(i)) continue;
printf("Corats: %d\n", i);
}
// Check
printf("Check: ");
for(const auto num: corats) printf("%d, ", num);
printf("\n");
return 0;
}
//==========
// モンテカルロ法によるπの近似値計算
// 1, Compile
// g++ -std=c++17 -Wall -Wextra main.cpp
// 2, Run
// ./a.out
#include <math.h>
#include <random>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
const int RAD = 300;// 円の半径
// Random(メルセンヌツイスター)
random_device seed_gen;
default_random_engine engine{seed_gen()};
int getRandom(int min, int max) {
if (max <= min) return min;
uniform_int_distribution<int> dist(min, max - 1);
return dist(engine);
}
bool isInside(const int x, const int y){
const int dX = RAD - x;
const int dY = RAD - y;
const int dist = dX*dX + dY*dY;
return dist < RAD*RAD;
}
int main(){
printf("Hello, Cpp!!\n");
// モンテカルロ法によるπの近似値計算
// 1, 円の面積: PI*r^2
// 2, 正方形の面積(円に外接): (r*2)^2
// 3, 円と正方形の面積の比: PI/4
// 4, 正方形内のとある点が円の内部にある確率は上記の比と一致する
// 5, モンテカルロ法によってPIを近似値計算する
int cnt = 0;// カウンタ
const int total = 10000;// 試行回数
for(int i=0; i<total; i++){
const int x = getRandom(0, RAD);
const int y = getRandom(0, RAD);
printf("x: %d, y:%d\n", x, y);
if(isInside(x, y)) cnt++;// 円の内側であればカウントアップ
}
// PIを計算する(カウンタ/試行回数*4.0)
const float pi = ((float)cnt / (float)total) * 4.0f;
printf("cnt: %d, total:%d, rate: %f\n", cnt, total, pi);
return 0;
}
//==========
// ISBN-10の検証
// 1, Compile
// g++ -std=c++17 -Wall -Wextra main.cpp
// 2, Run
// ./a.out
#include <math.h>
#include <stdio.h>
#include <string>
using namespace std;
bool isISBN10(const string isbn){
printf("isISBN-10: %s\n", isbn.c_str());
vector<int> nums;
for(auto &c:isbn){
const int num = c - '0';
if(num < 0 || 9 < num) continue;
nums.push_back(num);
}
const int len = nums.size();
int sum = 0;
for(int i=0; i<len; i++){
printf("Test[%d]: %d, %d\n", nums[i], len-i, nums[i] * (len - i));
sum += nums[i] * (len - i);
}
const int odd = sum % 11;
printf("Sum: %d, Odd: %d\n", sum, odd);
return odd == 0;
}
int main(){
printf("Hello, Cpp!!\n");
// ISBN-10の検証
// 1, 10桁の数値に、桁数に応じた重みを掛け合わせてその合計を算出
// ex: 10*4+9*5+8*6 ... 1*8 = 209
// 2, 合計が11の倍数になる様に、1桁目の数値がチェックデジットになっている
// ex: 209 = 11*19
const string isbn = "4-566-01411-8";
if(isISBN10(isbn)){
printf("OK: %s\n", isbn.c_str());
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment