Взял и от нечего делать разобрал файлик с выгрузкой данных по электронному голосованию:
http://observer2020.mos.ru/observer/downloads/ballots_decrypted_2020-07-01T19:47:00.csv
Получился такой вот забавный график (кликабельно):
Интересно было бы сопоставить явно видимые на графике “скачки” с разными событиями прошедшей недели – например, резкий прирост голосов “за” в Москве в 17:00 25 июня, или синхронные скачки “против” в Москве и Нижнем в 16:00 26 июня и в 14:00 29 июня.
Наговняканный за полчаса код прилагается:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct voteblock {
int time; // time in seconds since day start
int res[2][2];
};
voteblock votes[2300000]; // max. block number is about 2.27M
int gettime(char *token){
token[2] = '\0';
token[5] = '\0';
int hours = atoi(token);
int minutes = atoi(token + 3);
int seconds = atoi(token + 6);
return hours * 60 * 60 + minutes * 60 + seconds;
}
void process_vote(char *buf){
char *token;
int district, res;
token = strtok(buf, "\";"); // номер голоса
int n = atoi(token);
token = strtok(NULL, "\";"); // избир. округ
if (strcmp(token, "77") == 0){
district = 0;
} else if (strcmp(token, "52") == 0) {
district = 1;
} else {
fprintf(stderr, "Unknown district %s\r\n", token);
return;
}
strtok(NULL, "\";"); // адрес голоса в блокчейне
token = strtok(NULL, "\";#"); // блок голоса
int block = atoi(token);
token = strtok(NULL, "\";"); // время записи блока голоса
int time = gettime(token);
strtok(NULL, ";"); // зашифрованный голос
token = strtok(NULL, "\";"); // расшифрованный голос
if (strcmp(token, "2212294583") == 0){
res = 0;
} else if (strcmp(token, "450215437") == 0) {
res = 1;
} else {
fprintf(stderr, "Unknown vote result %s\r\n", token);
return;
}
strtok(NULL, "\";"); // блок расшифровки
strtok(NULL, "\";"); // время записи блока расшифровки
strtok(NULL, "\";"); // транзакция
votes[block].time = time;
votes[block].res[district][res]++;
}
void print_votes_table(){
int day = 0;
int starttime = 7 * 3600; // 10:00:00 MSK = 7:00:00 UTC
int delta = 10 * 60; // 10 minutes granularity
int allvotes[2][2] = { 0 };
// to put the last line
votes[sizeof(votes) / sizeof(voteblock) - 1].time = INT_MAX;
for (int i = 0; i < sizeof(votes) / sizeof(voteblock); i++){
if (votes[i].time >= 0){
if ((votes[i].time > starttime + delta) || (votes[i].time < starttime)) {
/* either end of current stats block or end of day*/
if (votes[i].time < starttime) {
starttime = 0;
day++;
} else {
starttime += delta;
}
// finalize this line
printf("%i\t%i\t%i\t%i\t%i\t%i\r\n", day, starttime, allvotes[0][0], allvotes[0][1], allvotes[1][0], allvotes[1][1]);
}
allvotes[0][0] += votes[i].res[0][0];
allvotes[0][1] += votes[i].res[0][1];
allvotes[1][0] += votes[i].res[1][0];
allvotes[1][1] += votes[i].res[1][1];
}
}
}
int main(void){
char buf[1024]; // should be enough
fgets(buf, sizeof(buf), stdin); // skip first line
while (!feof(stdin)){
fgets(buf, sizeof(buf), stdin);
process_vote(buf);
}
print_votes_table();
return 0;
}
Запись опубликована в блоге Шуры Люберецкого. Вы можете оставлять свои комментарии там, используя свое имя пользователя из ЖЖ (вход по OpenID).