সি ++ 11, 6-8 মিনিট
আমার টেস্ট রানটি আমার ফেডোরা 19, আই 5 মেশিনে প্রায় 6-8 মিনিট সময় নেয়। তবে রূপান্তরটির এলোমেলোতার কারণে এটি দ্রুততর হতে পারে বা তার থেকেও বেশি সময় নিতে পারে। আমি মনে করি স্কোরিংয়ের মানদণ্ডটি পুনরায় সাজানো দরকার।
ফলাফল সমাপ্তির শেষে পাঠ্য হিসাবে ছাপানো হয়, সুস্থ ব্যক্তি বিন্দু ( .
) দ্বারা সংজ্ঞায়িত , সংক্ষিপ্ত ব্যক্তি দ্বারা তারকাচিহ্ন দ্বারা ( ) চিহ্নিত করা হয় *
, যদি না ANIMATE
পতাকাটি সত্য হিসাবে সেট না করা থাকে, তবে এটি ক্ষেত্রে এটি বিভিন্ন ভাইরাস সংক্রমণের জন্য সংক্রামিত লোকদের জন্য বিভিন্ন চরিত্র প্রদর্শন করবে।
এখানে 10x10, 200 পিরিয়ডের জন্য একটি জিআইএফ রয়েছে।
মিউটেশন আচরণ
প্রতিটি রূপান্তর এর আগে কখনও দেখা যায় না এমন নতুন স্ট্রেন দেবে (সুতরাং এটি সম্ভব যে এক ব্যক্তি চারটি প্রতিবেশী মানুষকে ৪ টি স্বতন্ত্র স্ট্রেন দ্বারা সংক্রামিত করে), যদি না ৮০০ টি স্ট্রেন তৈরি না করা হয়, সেক্ষেত্রে কোনও ভাইরাস আর কোনও রূপান্তর ঘটবে না।
8 মিনিটের ফলাফলটি নিম্নলিখিত সংখ্যক সংক্রামিত লোক থেকে আসে:
সময়কাল 0, সংক্রামিত: 4
সময়কাল 100, সংক্রামিত: 53743
সময়কাল 200, সংক্রামিত: 134451
সময়কাল 300, সংক্রামিত: 173369
পিরিয়ড 400, সংক্রামিত: 228176
পিরিয়ড 500, সংক্রামিত: 261473
পিরিয়ড 600, সংক্রামিত: 276086
সময়কাল 700, সংক্রামিত: 265774 74
সময়কাল 800, সংক্রামিত: 236828
সময়কাল 900, সংক্রামিত: 221275
6 মিনিটের ফলাফল নিম্নলিখিতটি থেকে আসে:
সময়কাল 0, সংক্রামিত: 4
সময়কাল 100, সংক্রামিত: 53627
সময়কাল 200, সংক্রামিত: 129033 33
সময়কাল 300, সংক্রামিত: 186127
পিরিয়ড 400, সংক্রামিত: 213633
পিরিয়ড 500, সংক্রামিত: 193702
পিরিয়ড 600, সংক্রামিত: 173995
সময়কাল 700, সংক্রামিত: 157966
সময়কাল 800, সংক্রামিত: 138281
সময়কাল 900, সংক্রামিত: 129381
ব্যক্তির প্রতিনিধিত্ব
প্রতিটি ব্যক্তি 205 বাইট প্রতিনিধিত্ব করা হয়। ভাইরাস সংরক্ষণের জন্য চারটি বাইট এই ব্যক্তিটি চুক্তি করছেন, এই ব্যক্তি কতদিন আক্রান্ত হয়েছে তা সংরক্ষণের জন্য একটি বাইট এবং 200 বাইট সংরক্ষণের জন্য তিনি কতবার সংক্রমণ করেছেন ভাইরাসের প্রতিটি স্ট্রেনে (2 বিট প্রতিটি)। সম্ভবত সি ++ দ্বারা কিছু অতিরিক্ত বাইট-প্রান্তিককরণ করা হয়েছে তবে মোট আকারটি 200MB এর কাছাকাছি হবে। পরবর্তী পদক্ষেপটি সংরক্ষণ করার জন্য আমার কাছে দুটি গ্রিড রয়েছে, সুতরাং এটি মোট 400 এমবি ব্যবহার করে।
আমি প্রাথমিক পর্যায়ে প্রয়োজনীয় সময় কাটাতে (যা পিরিয়ডস <৪০০ অবধি অবধি কার্যকর)।
প্রোগ্রাম প্রযুক্তিগতকরণ
প্রতি 100 টি পদক্ষেপে এই প্রোগ্রামটি সংক্রামিত ব্যক্তির সংখ্যা মুদ্রণ করবে, যদি না ANIMATE
পতাকা সেট না করা হয় , তবে সেক্ষেত্রে true
এটি প্রতি 100 মিমি পুরো গ্রিডটি মুদ্রণ করবে।
এর জন্য সি ++ 11 লাইব্রেরি প্রয়োজন ( -std=c++11
পতাকা ব্যবহার করে সংকলন করুন , বা ম্যাক সহ clang++ -std=c++11 -stdlib=libc++ virus_spread.cpp -o virus_spread
)।
ডিফল্ট মানগুলির জন্য বা এটির মতো যুক্তি ছাড়াই এটি চালনা করুন:
./virus_spread 1 0.01 1000
#include <cstdio>
#include <cstring>
#include <random>
#include <cstdlib>
#include <utility>
#include <iostream>
#include <deque>
#include <cmath>
#include <functional>
#include <unistd.h>
typedef std::pair<int, int> pair;
typedef std::deque<pair> queue;
const bool ANIMATE = false;
const int MY_RAND_MAX = 999999;
std::default_random_engine generator(time(0));
std::uniform_int_distribution<int> distInt(0, MY_RAND_MAX);
auto randint = std::bind(distInt, generator);
std::uniform_real_distribution<double> distReal(0, 1);
auto randreal = std::bind(distReal, generator);
const int VIRUS_TYPE_COUNT = 800;
const int SIZE = 1000;
const int VIRUS_START_COUNT = 4;
typedef struct Person{
int virusType;
char time;
uint32_t immune[VIRUS_TYPE_COUNT/16];
} Person;
Person people[SIZE][SIZE];
Person tmp[SIZE][SIZE];
queue infecteds;
double transmissionProb = 1.0;
double mutationProb = 0.01;
int periods = 1000;
char inline getTime(Person person){
return person.time;
}
char inline getTime(int row, int col){
return getTime(people[row][col]);
}
Person inline setTime(Person person, char time){
person.time = time;
return person;
}
Person inline addImmune(Person person, uint32_t type){
person.immune[type/16] += 1 << (2*(type % 16));
return person;
}
bool inline infected(Person person){
return getTime(person) > 0;
}
bool inline infected(int row, int col){
return infected(tmp[row][col]);
}
bool inline immune(Person person, uint32_t type){
return (person.immune[type/16] >> (2*(type % 16)) & 3) == 3;
}
bool inline immune(int row, int col, uint32_t type){
return immune(people[row][col], type);
}
Person inline infect(Person person, uint32_t type){
person.time = 1;
person.virusType = type;
return person;
}
bool inline infect(int row, int col, uint32_t type){
auto person = people[row][col];
auto tmpPerson = tmp[row][col];
if(infected(tmpPerson) || immune(tmpPerson, type) || infected(person) || immune(person, type)) return false;
person = infect(person, type);
infecteds.push_back(std::make_pair(row, col));
tmp[row][col] = person;
return true;
}
uint32_t inline getType(Person person){
return person.virusType;
}
uint32_t inline getType(int row, int col){
return getType(people[row][col]);
}
void print(){
for(int row=0; row < SIZE; row++){
for(int col=0; col < SIZE; col++){
printf("%c", infected(row, col) ? (ANIMATE ? getType(row, col)+48 : '*') : '.');
}
printf("\n");
}
}
void move(){
for(int row=0; row<SIZE; ++row){
for(int col=0; col<SIZE; ++col){
people[row][col] = tmp[row][col];
}
}
}
int main(const int argc, const char **argv){
if(argc > 3){
transmissionProb = std::stod(argv[1]);
mutationProb = std::stod(argv[2]);
periods = atoi(argv[3]);
}
int row, col, size;
uint32_t type, newType=0;
char time;
Person person;
memset(people, 0, sizeof(people));
for(int row=0; row<SIZE; ++row){
for(int col=0; col<SIZE; ++col){
people[row][col] = {};
}
}
for(int i=0; i<VIRUS_START_COUNT; i++){
row = randint() % SIZE;
col = randint() % SIZE;
if(!infected(row, col)){
infect(row, col, 0);
} else {
i--;
}
}
move();
if(ANIMATE){
print();
}
for(int period=0; period < periods; ++period){
size = infecteds.size();
for(int i=0; i<size; ++i){
pair it = infecteds.front();
infecteds.pop_front();
row = it.first;
col = it.second;
person = people[row][col];
time = getTime(person);
if(time == 0) continue;
type = getType(person);
if(row > 0 && randreal() < transmissionProb){
if(newType < VIRUS_TYPE_COUNT-1 && randreal() < mutationProb){
newType++;
if(!infect(row-1, col, newType)) newType--;
} else {
infect(row-1, col, type);
}
}
if(row < SIZE-1 && randreal() < transmissionProb){
if(newType < VIRUS_TYPE_COUNT-1 && randreal() < mutationProb){
newType++;
if(!infect(row+1, col, newType)) newType--;
} else {
infect(row+1, col, type);
}
}
if(col > 0 && randreal() < transmissionProb){
if(newType < VIRUS_TYPE_COUNT-1 && randreal() < mutationProb){
newType++;
if(!infect(row, col-1, newType)) newType--;
} else {
infect(row, col-1, type);
}
}
if(col < SIZE-1 && randreal() < transmissionProb){
if(newType < VIRUS_TYPE_COUNT-1 && randreal() < mutationProb){
newType++;
if(!infect(row, col+1, newType)) newType--;
} else {
infect(row, col+1, type);
}
}
time += 1;
if(time == 4) time = 0;
person = setTime(person, time);
if(time == 0){
person = addImmune(person, type);
} else {
infecteds.push_back(std::make_pair(row, col));
}
tmp[row][col] = person;
}
if(!ANIMATE && period % 100 == 0) printf("Period %d, Size: %d\n", period, size);
move();
if(ANIMATE){
printf("\n");
print();
usleep(100000);
}
}
if(!ANIMATE){
print();
}
return 0;
}