Блог пользователя ruslanjan

Автор ruslanjan, история, 3 года назад, По-русски

Я разработал систему прокторинга для олимпиад и более конкретнее для Международной Жаутыковской Олимпиаде по Информатике где она и была успешна протестирована. Если вам нужна бесплатная система для проктораства олимпиады или теста или экзамена то можете ею воспользоваться proctr.tv.

Это первая версия но в данный момент готовится вторая и в ней будет встроен online judge и система тестов.

Если вы нашли ошибку или хотите связаться со мной то можете писать мне на почту [email protected].

Сейчас система была уже использована на Казахстанской Республиканской олимпиаде и отборе на APIO

Полный текст и комментарии »

  • Проголосовать: нравится
  • +19
  • Проголосовать: не нравится

Автор ruslanjan, история, 5 лет назад, По-русски

Tекущие языки по типу C++, Java или Python создавались не для олимпиад и уж точно не для точной оценки решения системой. Помимо того что эти языки разные (скорость, наличие или отсутствие управление памяти) они еще и несут за собой багаж функции которые вовсе не нужны для олимпиад, к примеру импортирование библиотек (C++, Python, Java), пакеты (Java с ее package) и т.п.

В чем же проблема?

Не так просто придумать задачу в которой ни один язык не будет иметь преимущества (Обычно на это забивают взяв C++ за основу). Сделаете задачу на длинку тогда Python и Java будет иметь преимущество а участники с плюсами будут лишние минуты тратить на реализацию или дали задачу которая требует аккуратно реализации привет java. И таких примеров много, можно сказать что каждый язык это инструмент и нужно подбирать для задачи нужный но будем реалистичнее многие машинально выучили свои шаблоны для алгоритмов и оптимизации (например cin.tie(NULL) в C++ или реализация своего ридера в java) и они не могут быть перемещены между языками уж слишком они различны.

Это не только проблема участников

Помимо жури также страдают и создатели систем тестирование. Запуск чужого кода на языке не рассчитанного на запуск в песочнице как javascript создает проблемы с безопасностью в тестирующих системах и не легкой задачей подсчета памяти и времени. Об уязвимостях можно писать отдельную статью, так что вот неполный список с чем надо бороться: Бесконечна компиляция (в C++, да есть такой баг), Создание потоков, Создание подпроцессов, Выход в интернет, Доступ к файлам, Превышение Памяти. Каждый из них может уронить воркер, систему или даже получить решение. Это крайне сложная задача

Эти языки не пригодятся

Вы будите правы сказав что эти языки применяют однако как их используют в соревновательном программирование ни как не подходит для проектов, например в C++ никто не заботится о освобождению памяти. В итоге придется учить язык как будто сначала. Изучается только то что необходимо для олимпиад (но все равно это даст буст в программирование).

Все прогают на C++ какая разница?

Если вы пишите на C++ тогда сразу читайте "Рецепт панацеи". Для вас будет не разница а больше возможностей :)

Рецепт панацеи

Панацея — Новый язык, специально разработанный для соревнование который будет включать возможности многих языков. Вот вам его код решения возведения в степень.

Основная идея

// Вообще STRONG_TYPING включен по умолчанию
#enable STRONG_TYPING
#define ll int

int bp(int a, int b) {
    if (!b)
        return 1;
    if (b&1)
        return a;
    int x = bp(a, b/2);
    return x*x;
}

int p, q;
scanf("%d %d", &p, &q);
printf("%d", bp(p, q));

Кажется знакомым? Синтаксис будет взят у C++ и Java (Питонщики не расстраивайтесь :3 ). Ключевой идей будет #enable этот препроцессор будет задавать какой режим или функция будут использоваться программой к примеру будет ли она строго типизированная или динамическая. По сути собирая набор #enable вы получаете свой язык для решения конкретной задачи.

Список режимов и доступных(Будет дорабатываться):

  • #enable FUCNTIONAL_PROGRAMMING — Функции становятся не мутабельны т.е. нельзя изменить передаваемую переменную. Некоторые встроеные функции становятся не доступными (их заменяют другие) Когда нужно писать аккуратно.
  • #enable DYNAMIC_TYPING — нельзя влючать одновременно с STRONG_TYPING.
  • #enable STRONG_TYPING — включен по умолчанию.
  • #enable NO_TYPE_CONVERSION — не будет приведение типов — 1.0 + int(2) -> error. Когда нужно писать очень аккуратно
  • #define так же доступен

Пример с динамической типизацией:

#enable DYNAMIC_TYPING

// в DYNAMIC_TYPING можно указать тип если вы к примеру перешли с из STRONG_TYPING в DYNAMIC_TYPING
def bp(a, int b) { // def нужен что бы указать что это функция но (int bp()) тоже правильно
    if (!b)
        return 1;
    if (b&1)
        return a;
    let x = bp(a, b/2); // let - объявление переменной
    return x*x;
}

let p, q;
p = int(readItem()) // Функция считывает до пробела или переноса и возвращает `String`
q = int(readItem())
print(bp(p, q));

Как оценивать? Он же будет медленным

Да возможно будет но мы больше не будет оценивать время, теперь мы будем оценивать количество инструкций т.к. наш язык будет работать на виртуальной машине. А об этом подробнее в Структуре языка

Структура языка Кратко

  • Нету компиляции только проверка типов
  • объекты и примитивы
  • возможность создавать свои структуры через struct Type {}
  • встроеные api функции для io
  • встроенная библиотека std с реализованными алгоритмами как в c++ написанная на этом же языке
  • Управление памятью как C++. Режимы и дополнительные функции например динамической типизации доступные через препроцессор #enable THING
  • Имеет все возможности C++, Java, Python используемые в соревнованиях.
  • Возможность писать богатые чекеры, интеракторы а также дополнительные функции для конкретной задачи
  • У каждой операцией над примитивами будет свой вес а их сумма количество инструкций. например int + int имеет вес 1 а int/int имеет вес 2.

Преимущества

  • На много безопаснее для системы чем C++. можно сказать что полностью но багов никто не отменял
  • Система будет намного быстрее без проверок безопасности и компиляции.
  • Возможность соревноваться по количеству инструкций а так же ставить балы по ним. Как в игре "TIS-100"
  • Возможность писать богатые чекеры, интеракторы а также дополнительные функции для конкретной задачи. Это сделает задачи более интересными и даст больше свободы авторам задач
  • Использовать лучшее от всех языков.
  • Сразу понятен тем кто пишет на java или c++.
  • С++ код будет почти валидным.
  • Решения не будет страдать от Wall Time Limit
  • В количество инструкций будет входить только ваше решение, IO не будет учитываться как многие другие вещи вне вашем контроле в других языках.

Итог

Возможно отдельный язык покажется лишним но для проверяющих систем это будет больший прыжком в качестве тестирования.

P.S. Это черновик нового языка. Идеи предложения принимаются.

P.S.S. Если это будет интересной идеи то разработаю более подробный план и приступлю к реализации.

Полный текст и комментарии »

  • Проголосовать: нравится
  • -59
  • Проголосовать: не нравится

Автор ruslanjan, история, 6 лет назад, По-русски

Многие из тех кто начинает решать на cf пишут код в запуске.
Но Интерфейс беден и не оптимизирован для олимпиад. Нет вкладок, автодополнение и другого.
Поэтому я написал Arrow Compile and Run online.
Это его первая версия. Там уже есть автодополнение и более удобный интерфейс. Пока он поддерживает C++, Java8 и Python3 т.к. это самые популярные языки.
В планах:
1. Вкладки для того чтобы писать сразу несколько кодов
2. Больше языков
3. Отчет по памяти
4. более проработанный интерфейс
Ограничения:
Timelimit: 20s
Memory limit: 300M

Полный текст и комментарии »

  • Проголосовать: нравится
  • +40
  • Проголосовать: не нравится

Автор ruslanjan, история, 6 лет назад, По-русски

будет ли этот код правильно читать время и память?

from gevent import subprocess
import resource

time_limit = 1
memory_limit = 1024 * 1000


p = subprocess.Popen("./main")
try:
    p.wait(timeout=time_limit)
except:
    print('Time limit')
    exit(0)

print('\n')
if resource.getrusage(resource.RUSAGE_CHILDREN).ru_maxrss > memory_limit:
    print("Memory Limit")
    exit(0)
print('OK')

Полный текст и комментарии »

  • Проголосовать: нравится
  • +47
  • Проголосовать: не нравится

Автор ruslanjan, история, 9 лет назад, По-русски

Кому интересно. Вот код:

#include <time.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>

long B=10000; 
long LB=4;   
long MaxDiv=450;  

void SetToInteger (long n, long *x, long Integer) 
{
	long i;
	for (i=1; i<n; i++) x[i] = 0;
	x[0] = Integer;
}

long IsZero (long n, long *x) 
{
	long i;
	for (i=0; i<n; i++)  
    	if (x[i])   
    		return 0;
        return 1;
}

void Add (long n, long *x, long *y) 
{
	long carry=0, i;
	for (i=n-1; i>=0; i--) 
	{
	    x[i] += y[i]+carry;
	    if (x[i]<B) 
	    	carry = 0;
	    else 
	    {
    		carry = 1;
    		x[i] -= B;
    	}
  	}  
}

void Sub (long n, long *x, long *y) 
{
	long i;
	for (i=n-1; i>=0; i--) 
	{
    	x[i] -= y[i];
		if (x[i]<0) 
		{
	    	if(i) 
   		 	{      
    	    	x[i] += B;
    	   		x[i-1]--;
    	  	}
  		}
  	}  
}

void Mul (long n, long *x, long q) 
{
	long carry=0, xi, i;
	for (i=n-1; i>=0; i--) 
	{
	    xi  = x[i]*q;               
	    xi += carry;                
	    if (xi>=B) 
	    {
      		carry = xi/B;
      		xi -= (carry*B);
    	}
   	 	else 
      		carry = 0;
    	x[i] = xi;
	}  
}

void Div (long n, long *x, long d, long *y) 
{
	long carry=0, xi, q, i;
  	for (i=0; i<n; i++) 
  	{
		xi = x[i]+carry*B;
   		q = xi/d;
    	carry = xi-q*d;   
    	y[i] = q;        
  	}  
}

void arccot (long p, long n, long *x, long *buf1, long *buf2) 
{
	long p2=p*p, k=3, sign=0;
	long *uk=buf1, *vk=buf2;
	SetToInteger (n, x, 0);
  	SetToInteger (n, uk, 1);    
  	Div (n, uk, p, uk);
  	Add (n, x, uk);              
  	while (!IsZero(n, uk)) 
  	{
    	if (p<MaxDiv)
      		Div (n, uk, p2, uk); 
    	else 
    	{
      		Div (n, uk, p, uk);   
      		Div (n, uk, p, uk);  
    	}
    	Div (n, uk, k, vk);       
    	if (sign) 
    		Add (n, x, vk); 
    	else 
    		Sub (n, x, vk);      
    	k+=2;
    	sign = 1-sign;
  	}	
}

void Print (long n, long *x) 
{
  	long i; 
  	printf ("%d.", x[0]);
  	for (i=1; i<n; i++) 
  	{
    	printf ("%.4d", x[i]);
    	if (i%25==0) printf ("%8d\n", i*4);
  	}                          
  	printf ("\n");
}
int main () {  
  	clock_t endclock, startclock; 
  	long NbDigits=10000/*вот тут сколько строк будет сгенерировано(Строка длинною 25 символов)*/, NbArctan;
  	long p[10], m[10];
  	long size=1+NbDigits/LB, i;
  	long *Pi = (long *)malloc(size*sizeof(long));
  	long *arctan  = (long *)malloc(size*sizeof(long));
  	long *buffer1 = (long *)malloc(size*sizeof(long));
  	long *buffer2 = (long *)malloc(size*sizeof(long)); 
  	startclock = clock();    
  	NbArctan = 3;
  	m[0] = 12; m[1] = 8;  m[2] = -5;
  	p[0] = 18; p[1] = 57; p[2] = 239; 
  	SetToInteger (size, Pi, 0);
  	for (i=0; i<NbArctan; i++) 
  	{
    	arccot (p[i], size, arctan, buffer1, buffer2);
    	Mul (size, arctan, abs(m[i]));
    	if (m[i]>0) 
    		Add (size, Pi, arctan);  
    	else 
    		Sub (size, Pi, arctan);  
	}
  	Mul (size, Pi, 4);
  	endclock = clock ();
  	Print (size, Pi); 
  	printf ("time: %9.2f seconds\n",(float)(endclock-startclock)/(float)CLOCKS_PER_SEC ); 
  	free (Pi);
  	free (arctan);
    free (buffer1);
    free (buffer2);
}

Полный текст и комментарии »

  • Проголосовать: нравится
  • +9
  • Проголосовать: не нравится