Перейти к публикации
  • Сейчас на странице   Всего пользователей: 2   (0 пользователей, 2 гостя)

Rooster

Программирование[9]

Перепись  

260 пользователей проголосовало

У вас нет прав на голосование в этом опросе, или на просмотр результатов опроса. Пожалуйста, войдите или зарегистрируйтесь для голосования в опросе.

Рекомендованные сообщения

(изменено)

ну да, первые 5 тоже случайные

и противоречия не будет даже если 1000000000000000 раз подряд попадутся первые 5

но это уже из разряда очковтирательства

 

постановка задачи в любом случае хуйня


Изменено пользователем E1azor

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение

какие миллион раз, тебя попросили 1 раз 5 случайных

генеришь 5 индексов - конец задачи


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

Поделиться сообщением


Ссылка на сообщение
GoldRobot написал 11 часов назад:

[Then(@"я открыл семейную ипотеку ГПБ")]

public void ТоЯОткрылСемейнуюИпотекуГПБ(){....}

 

А что эта then делает

это cucumber, чтобы тесты bdd-шные писать

 

пишешь на каком-то языке сценарий (каюсь перед тутошними богами разработки, сценарии на русском), далее реализуешь методы, которые выполняются в сценарии

ну и чтоб местных буйных успокоить - как выглядят ui-ные тесты в яндексе

 

тоже внезапно на русском:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Screenshot_2020-07-24-09-38-31-199_com.avp.document.viewer.reader.jpg

GoldRobot понравилось это

Поделиться сообщением


Ссылка на сообщение
Kant написал 7 часов назад:

какие миллион раз, тебя попросили 1 раз 5 случайных

генеришь 5 индексов - конец задачи

сгенерил: 1,2,3,4,5

докажи что не случайные


:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение
DomikTS- написал 11 часов назад:
PochtiKakLoda написал 12 часов назад:

нихуевые тут кодерки в топике, щас еще хиру присумонить и будет полный набор

Loda, а в Германии переменные называете на немецком?))
типа @Then('ichHabeEineGlucklichScwein')

имхо все, и коммиты, и переменные, и комментарии должны быть на англ, даже если все разрабы рускоговорящие

тут даже если у тебя typo в английском слове - пул реквест не апрувят :onneponimaet:

Поделиться сообщением


Ссылка на сообщение

Так вся соль бдд в том, чтобы у тебя даже уборщица пришла и первый раз увидев автотест, поняла чо ты там проверяешь, весьма логично писать сценарии на русском

nobodies и madvlaydin понравилось это

Поделиться сообщением


Ссылка на сообщение
Zellar написал 23.07.2020 в 04:44:

todo приложение сделать

ты так и не ответил на вопрос, в чём проблема?

 

приходишь ты такой на собеседование и тебе такой вопрос зададут: "в чём проблема сделать todo приложение?"

что ответишь


:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:    всё что пишу -- шизофренический бред     :zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

:zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu::zatrolka_tupostu:

Поделиться сообщением


Ссылка на сообщение
E1azor написал 1 час назад:
Kant написал 9 часов назад:

какие миллион раз, тебя попросили 1 раз 5 случайных

генеришь 5 индексов - конец задачи

сгенерил: 1,2,3,4,5

докажи что не случайные

что ты за чудище, еще за алгоритмику втирает

5 случайных ЭЛЕМЕНТОВ

ПОХУЙ ЧТО ТАМ ВНУТРИ

БЛЯТЬ

ПРИСТРЕЛИТЕ ЕГО НАХУЙ УЖЕ

ЗАЧЕМ ОН ТРИГЕРИТ МЕНЯ А

Kant и E1azor понравилось это

ward написал 04.01.2022 в 02:54:

Hades для стада долбоебичей которые прокликивали Дэш и думали ебать они в артхаузнвй рогалик играют, не такие как все.

mazt3r написал 20.09.2019 в 11:27:

ласт оф ас - хуета для лисят и прочих мальчиков с вагиной между ног.

 

Поделиться сообщением


Ссылка на сообщение

зачем вы читаете его посты? давно бы скрыли и не жрали бы говно

GoldRobot понравилось это

 

очень крутые котейки

RqvSzvr.png


Кому-то пизды дал - нужно сделать скрин обязательно. (с) Solo

Поделиться сообщением


Ссылка на сообщение
(изменено)

хорошо что вопросик аж на молекулы разобрали, как раз тот уровень где я улавливаю о чем речь, так что всем ++

елазорыч так-то прав, ну или точно есть какой-то смысл, типа есть 2млн данных, и запрос каждый раз отдает 5 рандомных данных, не повторяя значения, тогда думаю на первый миллион данных совпадений будет мало (хз сколько в цифрах), но на второй миллион, будет постоянно реролить и следовательно время выполнения взлетит до небес

 

на совпадения думаю можно забить и не реролить миллион раз, если рандомится одно и то же значение, по-моему гениальное решение

 


Изменено пользователем DnoInvokera

have courage and be kind

  😈🫀💋 🩸👣🤌🏿🦄 🐝 ☄️❣️ 💕 💞❤️😈

 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖

220941652_Annotation2021-03-20123345.jpg.23dcff343d6a377badf433b20f5271fd.jpg

💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 

Поделиться сообщением


Ссылка на сообщение
Just.Doit написал 22 минуты назад:

зачем вы читаете его посты? давно бы скрыли и не жрали бы говно

а как это сделать?

Поделиться сообщением


Ссылка на сообщение
nobodies написал 21 минуту назад:
Just.Doit написал 44 минуты назад:

зачем вы читаете его посты? давно бы скрыли и не жрали бы говно

а как это сделать?

рофлишь чтоли? жить на пд и не знать как дебсов игнорить...

307323623_Screenshotfrom2020-07-2413-58-30.png.c82136fd4ed1bc167543b8979224a405.png1873690821_Screenshotfrom2020-07-2413-59-34.png.3a2f2341e8bab09fe9b691015d071c6e.png

nobodies, E1azor и ElGobedano понравилось это

 

очень крутые котейки

RqvSzvr.png


Кому-то пизды дал - нужно сделать скрин обязательно. (с) Solo

Поделиться сообщением


Ссылка на сообщение

Белая тема:monkamega:

 

Адепты секты белой темы повсюду

E1azor понравилось это

Поделиться сообщением


Ссылка на сообщение
DnoInvokera написал 33 минуты назад:

хорошо что вопросик аж на молекулы разобрали, как раз тот уровень где я улавливаю о чем речь, так что всем ++

елазорыч так-то прав, ну или точно есть какой-то смысл, типа есть 2млн данных, и запрос каждый раз отдает 5 рандомных данных, не повторяя значения, тогда думаю на первый миллион данных совпадений будет мало (хз сколько в цифрах), но на второй миллион, будет постоянно реролить и следовательно время выполнения взлетит до небес

 

на совпадения думаю можно забить и не реролить миллион раз, если рандомится одно и то же значение, по-моему гениальное решение

 

 

Так ты спрашивал как выбрать 5 элементов из списка с миллионом значений, а не миллион раз рандомить.
Ну если вдруг тебе надо миллион значений оригинальных рандомить, просто можно цикл сделать, который рандомит по 5 индексов, а потом по этим индексам возвращает 5 значений и удаляет их из списка, и так по кругу, пока значения не закончатся. Я б наверно так сделал, хотя меня наверняка за это решение сейчас нахуй пошлют ;D


Доброта и взаимовыручка в разделе железо

OK4eIq8maRQ.jpg

Поделиться сообщением


Ссылка на сообщение
(изменено)
DnoInvokera said 12 hours ago:

хотел загуглить но уже второй день руки не доходят

как выбрать рандомные 5 элемента из списка, если в списке миллион элементов, ну типа на скорость

 

UCYZ0gY.png

 

ну вот так бля, а как еще??

 

(сорс код сэмпла: https://github.com/python/cpython/blob/master/Lib/random.py#L374)


Изменено пользователем moonfangtopich

Поделиться сообщением


Ссылка на сообщение
E1azor написал 22.07.2020 в 21:32:
madvlaydin написал 22.07.2020 в 18:25:

тогда гитлаб дай, ну или битбакет наконец

уже бегу скидывать тебе свой код который стоит милионы долларов

я кидал исходники каких-то лаб с универа

вот ещё одну лабу могу скинуть, на дрочи  :honkler:

  лаба

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <windows.h>
#include <process.h>

// режим построения программы, в котором выводится
// обратная польская запись токенов в читаемом виде
#define DEBUG

// коды ошибок
#define ERROR_FATAL			-1
#define ERROR_MEMORY		-2
#define ERROR_OVERFLOW		-3

// макросы для вывода ошибок
#define ERR(s, r) {fprintf(out_errors, s); fprintf(out_errors, "\n"); return r;}
#define ERR_NULL_PTR(ptr) {if(ptr == NULL){fprintf(out_errors, "не хватает оперативной памяти\n"); return ERROR_MEMORY;}}
#define ERR_NULL_PTR_STATIC(ptr) {if(ptr == NULL){fprintf(out_errors, "Критическая ошибка: не хватает оперативной памяти для статической таблицы\n"); return ERROR_FATAL;}}
#define ERR_LONG_ID {fprintf(out_errors, "Критическая ошибка: слишком длинное символьное представление идентификатора или константы\n"); return ERROR_FATAL;}
#define ERR_FILE(fid,fname) {if(fid == NULL){fprintf(out_errors, "Критическая ошибка: невозможно открыть файл \"%s\"\n", fname); return ERROR_FATAL;}}
#define DEFRAG(err_id) {if(defrag(err_id) == ERROR_FATAL) {fprintf(out_errors, "Критическая ошибка: не хватает оперативной памяти\n"); return;}}

// макросы устанавливающие является ли символ буквой или цифрой
#define BUKVA(c) ((c >= 'a' && c <='z') || (c >= 'A' && c <='Z') || c == '_')
#define CIFRA(c) ((c >= '0' && c <='9'))

// макрос для вывода в файл листинга
#define PUT(s) {fprintf(out, s); fprintf(out, "\n");}

const char *PHASE_NAME[5] = {"инициализация", "лексический анализ", "синтаксический анализ", "генерация кода", "деинициализация"};

// номера таблиц токенов (условно)
#define KEYS_ID			1
#define OPER_ID			2
#define SEP_ID			3
#define ID_ID			4
#define CONSTS_ID		5
#define WHILE_BEGIN_ID	6
#define WHILE_END_ID	7

// атребуты токета
struct ATR
{
	char *name;
	bool defined;
};

//статическая таблица
struct STATIC_TABLE
{
	int N;							//размер таблицы
	ATR *el;						//массив элементов
	int load(const char *x);		//загрузки таблицы
	int find(const char *x);		//поиск элемента
	void release(void);
};

// динамическая таблица - статическая хеш таблица )
struct TABLE
{
	int N;							// размер
	int count;						// сколько элементов содержит таблица
	ATR *el;						// массив элементов размера N
	int init(const int N0);			// задать размер таблицы
	int save(const char *file_name);// сохранить в файл
	int load(const char *file_name);// загрузить из файла
	bool overflow(const double min_void_hash);	// статус переполненности, если таблица должна быть пуста не менее чем на min_void_hash%
	int resize(const double hash_resize);	// увеличить размер таблицы на hash_resize%
	int find(const char *x);		// найти элемент
	int add(const char *x);			// добавить элемент
	int hash(const char *x, const int iter);	//вычислить хеш функцию (число от 0 до N0-1)
	void release(void);
};

// токен: номер таблицы, номер строки в таблице (индекс)
struct TOKEN
{
	int table;
	int i;
};

// строка таблицы разбора
struct TAB
{
	int to;			// в какое состояние переходить или -1 если следует перейти в состояние из вершины стека либо -2 если это конец программы
	int read;		// нужно ли брать очередной токен из потока токенов
	int save;		// нужно ли сохранять в стеке номер текущего состояния
	int error;		// будет ли ошибка если текущий токен не найден среди токенов из tok[]
	int N;			// количество позволяющих переход токенов в строке
	TOKEN *tok;		// массив из N токенов
	void release(void);
};

// описание таблиц
STATIC_TABLE keys;	//1
STATIC_TABLE oper;	//2
STATIC_TABLE sep;	//3
TABLE id;			//4
TABLE consts;		//5

int *stack;				// стек состояний
int stack_size;
int stack_head;
TOKEN *stack_tokens;	// стек токенов
int stack_tokens_size;
int stack_tokens_head;
TAB *tab;				// таблица разбора
int tab_size;

// размеры
#define STRING_LEN		256	//длинные имена не допускаются
int STACK_LEN;
int STACK_TOKENS_LEN;
int TABLE_ID_LEN;
int TABLE_CONSTS_LEN;

int PHASE_ID;			// Порядковый номер этапа трансляции

// файл для записи ошибок
FILE *out_errors = fopen("_errors.txt","w");

// политика увеличения размера стека и таблиц
#define RESIZE_STACK		0.5
#define RESIZE_HASH			0.5
#define MIN_VOID_HASH		0.9



int STATIC_TABLE::load(const char *file_name)
{
	char next[STRING_LEN];
	char c;
	int i, j;
	FILE *in;
	in = fopen(file_name, "r");
	ERR_FILE(in, file_name);
	fscanf(in, "%d", &N);
	getc(in);
	el = new ATR[N];
	ERR_NULL_PTR_STATIC(el);
	for(i = 0; i < N; i++)
	{
		for(j = 0; ;j++)
		{
			if(j >= STRING_LEN) {ERR_LONG_ID;}
			fscanf(in, "%c", &c);
			if(c == '\n')
			{
				next[j] = 0;
				break;
			}
			next[j] = c;
		}
		el[i].name = new char[strlen(next)+1];
		ERR_NULL_PTR_STATIC(el[i].name);
		strcpy(el[i].name, next);
	}
	fclose(in);
	return 0;
}

int STATIC_TABLE::find(const char *x)
{
	int i1 = 0, i2 = N - 1, i, res;
	for(;;)
	{
		i = (i1 + i2) / 2;
		if(i2 - i1 < 0) break;
		res = strcmp(x, el[i].name);
		if(res < 0)
		{
			i2 = i - 1;
		}else
		if(res > 0)
		{
			i1 = i + 1;
		}else
		if(res == 0) return i;
	}
	return -1;
}

void STATIC_TABLE::release(void)
{
	if(el != NULL)
	{
		for(int i = 0; i < N; i++)
		{
			if(el[i].name != NULL) delete el[i].name;
		}
		delete el;
	}
}

int TABLE::init(const int N0)
{
	N = N0;
	el = new ATR[N];
	ERR_NULL_PTR(el);
	for(int i = 0; i < N; i++)
	{
		el[i].name = NULL;
		el[i].defined = false;
	}
	count = 0;
	return 0;
}

int TABLE::save(const char *file_name)
{
	int i;
	FILE *out;
	out = fopen(file_name, "w");
	ERR_FILE(out, file_name);
	fprintf(out, "%d\n", N);
	for(i = 0; i < N; i++)
	{
		if(el[i].name != NULL)
		{
			fprintf(out, "%d %d %s\n", i, el[i].defined, el[i].name);
		}
	}
	fprintf(out, "-1 -1 -1\n");
	fclose(out);
	return 0;
}

int TABLE::load(const char *file_name)
{
	int i, j;
	bool defined;
	char c;
	char next[STRING_LEN];
	FILE *in;
	in = fopen(file_name, "r");
	ERR_FILE(in, file_name);
	fscanf(in, "%d", &N);
	if(init(N) == ERROR_MEMORY)
	{
		fclose(in);
		return ERROR_FATAL;
	}
	for(;;)
	{
		fscanf(in, "%d%d", &i, &defined);
		el[i].defined = defined;
		if(i == -1) break;
		fscanf(in, "%c", &c);
		for(j = 0; ;j++)
		{
			if(j >= STRING_LEN) {ERR_LONG_ID;}
			fscanf(in, "%c", &c);
			if(c == '\n')
			{
				next[j] = 0;
				break;
			}
			next[j] = c;
		}
		el[i].name = new char[strlen(next)+1];
		ERR_NULL_PTR_STATIC(el[i].name);
		strcpy(el[i].name, next);
		count++;
	}
	fclose(in);
	return 0;
}

bool TABLE::overflow(const double min_void_hash)
{
	return (N - count) / (double)N < min_void_hash;
}

int TABLE::resize(const double hash_resize)
{
	int i, new_N = (int)(N * (1. + hash_resize)) + 1;
	TABLE t;
	t.init(new_N);
	for(i = 0; i < N; i++)
	{
		if(el[i].name != NULL)
		{
			if(t.add(el[i].name) < 0) return ERROR_MEMORY;			
		}
	}
	release();
	*this = t;
	return 0;
}

int TABLE::find(const char *x)
{
	for(int j = 0; j < N; j++)
	{
		int i = hash(x, j);
		if(el[i].name == NULL) return -1;
		if(strcmp(x, el[i].name) == 0) return i;
	}
	return -1;
}

int TABLE::add(const char *x)
{
	if(overflow(MIN_VOID_HASH)) return ERROR_OVERFLOW;
	for(int j = 0; ; j++)
	{
		int i = hash(x, j);
		if(el[i].name == NULL)
		{
			el[i].name = new char[strlen(x) + 1];
			ERR_NULL_PTR(el[i].name);
			strcpy(el[i].name, x);
			el[i].defined = false;
			count++;
			return i;
		}
	}
	return ERROR_OVERFLOW;
}

int TABLE::hash(const char *x, const int iter)
{
	double E = 0;
	for(int i = 0; i < (int)strlen(x); i++)
	{
		E += pow((double)i+2, sin((double)x[i]));
	}
	while(E < 1)
	{
		E *= 2;
	}
	E -= (int)E;
	return ((int)(E * N) + iter*iter)%N;
}

void TABLE::release(void)
{
	if(el != NULL)
	for(int i = 0; i < N; i++)
	{
		if(el[i].name != NULL) delete el[i].name;
	}
	delete el;

}

int write_token(FILE *f, int table, int i)
{
	fprintf(f, "%d	%d\n", table, i);
	return 0;
}

bool token_equal(TOKEN &t1, TOKEN &t2)
{
	return (t1.table == t2.table) && (t1.table >= 4 || t1.i == t2.i);
}

char *get_token_string(TOKEN &t)
{
	if(t.table == 1) return keys.el[t.i].name;
	if(t.table == 2) return oper.el[t.i].name;
	if(t.table == 3) return sep.el[t.i].name;
	if(t.table == 4)
	{
		if(t.i == -1)
		{
			return "идентификатор";
		}
		else
		{
			return id.el[t.i].name;
		}
	}
	if(t.table == 5)
	{
		if(t.i == -1)
		{
			return "константа";
		}
		else
		{
			return consts.el[t.i].name;
		}
	}
#if defined(DEBUG)
	if(t.table == 6)	//начало цикла while
	{
		char *ttt = new char[256];
		sprintf(ttt, "%s %d", "While{", t.i);
		return ttt;
		//return "While{";
	}
	if(t.table == 7)	//конец цикла while
	{
		char *ttt = new char[256];
		sprintf(ttt, "%s %d", "}", t.i);
		return ttt;
		//return "}";
	}
#endif
	ERR("Критическая ошибка: не правильно задан номер таблицы\n", NULL);
}

// увеличивает размеры стека
int increace_stack()
{
	int new_len;
	// увеличение стека
	if(stack_head >= STACK_LEN)
	{
		new_len = (int)(STACK_LEN * (1 + RESIZE_STACK)) + 1;
		int *mem = new int[new_len];
		ERR_NULL_PTR(mem);
		memcpy(mem, stack, sizeof(int) * STACK_LEN);
		STACK_LEN = new_len;
		delete stack;
		stack = mem;
#if defined(DEBUG)
		printf("размер стека состояний изменен до %d, число элементов = %d\n", STACK_LEN, stack_head + 1);
#endif
		return 0;
	}else
	if(stack_tokens_head >= STACK_TOKENS_LEN)
	{
		new_len = (int)(STACK_TOKENS_LEN * (1 + RESIZE_STACK)) + 1;
		TOKEN *mem = new TOKEN[new_len];
		ERR_NULL_PTR(mem);
		memcpy(mem, stack_tokens, sizeof(TOKEN) * STACK_TOKENS_LEN);
		STACK_TOKENS_LEN = new_len;
		delete stack_tokens;
		stack_tokens = mem;
#if defined(DEBUG)
		printf("размер стека токенов изменен до %d, число элементов = %d\n", STACK_TOKENS_LEN, stack_tokens_head + 1);
#endif
		return 0;
	}
	return ERROR_FATAL;
}


// увеличивает размер хеш таблицы
int increace_table()
{
	if(id.overflow(MIN_VOID_HASH))
	{
		if(id.resize(RESIZE_HASH) != 0) ERR("Не хватает памяти, чтобы увеличить размер таблицы идентификаторов", ERROR_MEMORY);
#if defined(DEBUG)
		printf("размер таблицы идентификаторов изменен до %d, число элементов = %d\n", id.N, id.count);
#endif
		return 0;
	}
	if(consts.overflow(MIN_VOID_HASH))
	{
		if(consts.resize(RESIZE_HASH) != 0) ERR("Не хватает памяти, чтобы увеличить размер таблицы констант", ERROR_MEMORY);
#if defined(DEBUG)
		printf("размер таблицы констант изменен до %d, число элементов = %d\n", consts.N, consts.count);
#endif
		return 0;
	}
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ЛЕКСИЧЕСКИЙ АНАЛИЗАТОР
///////////////////////////////////////////////////////////////////////////////

int make_tokens(const char *file_name_in, const char *file_name_out)
{
	char c;
	char temp[3];
	char word[STRING_LEN];
	int t;
	temp[1] = 0;
	temp[2] = 0;
	FILE *in;
	FILE *out;
	in = fopen(file_name_in, "r");
	ERR_FILE(in, file_name_in);
	out = fopen(file_name_out, "w");
	ERR_FILE(out, file_name_out);
	for(;;)
	{
		c = getc(in);
		temp[0] = c;
// Пробелы
		if(c == ' ' || c == '\n')
		{
		}else
// Комментарии
		if(c == '/')
		{
			c = getc(in);
			if(c == '*')
			{
				for(;;)
				{
					c = getc(in);
					if(c == -1) ERR("неожиданный конец файла внутри комментария", ERROR_FATAL);
					if(c == '*') break;
				}
				c = getc(in);
				if(c != '/') ERR("неожиданный символ в конце комментария", ERROR_FATAL);					
			}
			else
			{
				ERR("неожиданный символ в начале комментария", ERROR_FATAL);
			}
		}else
// Идентификатор или зарезервированное слово
		if(BUKVA(c))
		{
			word[0] = c;
			for(int i = 1; ;i++)
			{
				if(i >= STRING_LEN) {ERR_LONG_ID;}
				c = getc(in);
				if(c == -1) ERR("неожиданный конец файла внутри идентификатора", ERROR_FATAL);
				if(!(BUKVA(c) || CIFRA(c)))
				{
					fseek(in, -1, SEEK_CUR);
					word[i] = 0;
					t = keys.find(word);
					if(t != -1)
					{
						// зарезервированное слово
						write_token(out, KEYS_ID, t);
					}
					else
					{
						// идентификатор
						t = id.find(word);
						if(t != -1)
						{
						// старый идентификатор
							write_token(out, ID_ID, t);
						}
						else
						{
						// новый идентификатор
							t = id.add(word);
							if(t < 0)
							{
								fclose(out);
								fclose(in);
								return t;
							}
							write_token(out, ID_ID, t);
						}
					}
					break;
				}
				word[i] = c;
			}
		}else
// Константа (числовая)
		if(CIFRA(c))
		{
			word[0] = c;
			for(int i = 1; ;i++)
			{
				if(i >= STRING_LEN)
				{
					ERR_LONG_ID;
				}
				c = getc(in);
				if(c == -1) ERR("неожиданный конец файла внутри числовой константы", ERROR_FATAL);
				if(!CIFRA(c))
				{
					fseek(in, -1, SEEK_CUR);
					word[i] = 0;
					t = consts.find(word);
					if(t != -1)
					{
						// старая константа
						write_token(out, CONSTS_ID, t);
					}
					else
					{
						// новая константа
						t = consts.add(word);
						if(t < 0)
						{
							fclose(out);
							fclose(in);
							return t;
						}
						write_token(out, CONSTS_ID, t);
					}
					break;
				}
				word[i] = c;
			}
		}else
// Разделители
		if((t = sep.find(temp)) != -1)
		{
			write_token(out, SEP_ID, t);
		}else
// Знаки операций
		if((t = oper.find(temp)) != -1)
		{
			if(c == '<' || c == '>')
			{
				char cc = getc(in);
				if(cc == '=')
				{
					temp[1] = cc;
					t = oper.find(temp);
					write_token(out, OPER_ID, t);
					temp[1] = 0;
				}
				else
				{
					fseek(in, -1, SEEK_CUR);
					write_token(out, OPER_ID, t);
				}
			}
			else
			write_token(out, OPER_ID, t);
		}else
// Конец файла
		if(c == -1)
		{
			break;
		}else
// Иное (ошибка)
		ERR("недопустимый символ для начала лексемы", ERROR_FATAL);
	}
// завершающий токен

	write_token(out, -1, -1);
	fclose(out);
	fclose(in);
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// СИНТАКСИЧЕСКИЙ АНАЛИЗАТОР
///////////////////////////////////////////////////////////////////////////////

const int STATES_SIMPLE[] =			{37, 44, 46};
const int STATES_BEGIN[] =			{35, 38, 45, 63};		//35 - while, 43 - }
const int STATES_END[] =			{43, 39, 48, 64};
const int STATES_RES_DONT_WRITE[] =	{43, 48};

bool state_simple(int s)
{
	int i;
	for(i = 0; i < 3; i++)
		if(s == STATES_SIMPLE[i]) return true;
	return false;
}
bool state_begin(int s)
{
	int i;
	for(i = 0; i < 4; i++)
		if(s == STATES_BEGIN[i]) return true;
	return false;
}
bool state_end(int s)
{
	int i;
	for(i = 0; i < 4; i++)
		if(s == STATES_END[i]) return true;
	return false;
}
bool state_dont_write(int s)
{
	int i;
	for(i = 0; i < 2; i++)
		if(s == STATES_RES_DONT_WRITE[i]) return true;
	return false;
}

int make_tree(const char *file_name_tab, const char *file_name_tokens, const char *file_name_tree)
{
	FILE *tok_in, *out, *tab_in;
	TOKEN t, t_prev;
// стек для хранения состояний в которые потребуется вернуться
	stack = new int[STACK_LEN];
	ERR_NULL_PTR_STATIC(stack);
// стек для постфикизации токенов
	stack_tokens = new TOKEN[STACK_TOKENS_LEN];
	ERR_NULL_PTR_STATIC(stack_tokens);
	stack_size = 0;
	stack_head = -1;
	stack_tokens_size = 0;
	stack_tokens_head = -1;
	int i, j, s, s_prev, count_whiles;
	bool flag_fined, flag_define, flag_solving;
		// s - текущее состояние из таблицы разбора
		// t - очередной токен
		// s_prev, t_prev - предыдущие


	tab_in = fopen(file_name_tab, "r");
	ERR_FILE(tab_in, file_name_tab);
	tok_in = fopen(file_name_tokens, "r");
	ERR_FILE(tok_in, file_name_tokens);
	out = fopen(file_name_tree, "w");
	ERR_FILE(out, file_name_tree);
	

// считываем таблицу разбора из файла
	fscanf(tab_in, "%d", &tab_size);
	tab = new TAB[tab_size + 1];
	ERR_NULL_PTR_STATIC(tab);
	for(i = 1; i <= tab_size; i++)
	{
		fscanf(tab_in, "%d", &j);				//не нужный номер состояния
		fscanf(tab_in, "%d", &tab[i].to);
		fscanf(tab_in, "%d", &tab[i].read);
		fscanf(tab_in, "%d", &tab[i].save);
		fscanf(tab_in, "%d", &tab[i].error);
		fscanf(tab_in, "%d", &tab[i].N);
		tab[i].tok = new TOKEN[tab[i].N];
		ERR_NULL_PTR_STATIC(tab[i].tok);
		for(j = 0; j < tab[i].N; j++)
		{
			fscanf(tab_in, "%d", &tab[i].tok[j].table);
			fscanf(tab_in, "%d", &tab[i].tok[j].i);
		}
	}
	fclose(tab_in);


// составляем обратную польскую запись дерева программы в соответствии с таблицей разбора грамматики
	s = 1;
	flag_define = false;
	flag_solving = false;
	count_whiles = 0;
	fscanf(tok_in, "%d%d", &t.table, &t.i);
	for(;;)
	{
		//printf("s = %d, t = (%d, %d)\n", s, t.table, t.i);
		//printf("(%d, %d, %d, %d, %d)\n", s, tab[s].to, tab[s].read, tab[s].save, tab[s].error);
		flag_fined = false;
		s_prev = s;
		t_prev = t;
// поиск позволяющих переход токенов
		for(i = 0; i < tab[s].N; i++)
		{
			//printf("(%d, %d) V (%d, %d)\n", t.table, t.i, tab[s].tok[i].table, tab[s].tok[i].i);
			if(token_equal(t, tab[s].tok[i]))
			{
				// читаем новый токен если нужно
				if(tab[s].read)
				{
					fscanf(tok_in, "%d%d", &t.table, &t.i);
				}
				// помещаем в стек номер текущего состояния если нужно
				if(tab[s].save)
				{
					stack_head++;
					if(stack_head >= STACK_LEN)
					{
						if(increace_stack() != 0)	return ERROR_FATAL;
					}
					stack[stack_head] = s;
				}
				// требуется переход в новое состояние либо возврат в состояние из вершины стека
				if(tab[s].to == -2)
				{// конец
					if(stack_head == -1)
					{
						goto end;
					}
					else
					{
						ERR("неожиданный конец программы\n", ERROR_FATAL);
					}
				}else
				if(tab[s].to != -1)
				{
					// переход в новое состояние
					s = tab[s].to;
				}else
				{
					// возврат в состояние из вершины стека
					s = stack[stack_head] + 1;
					stack_head--;
				}
				flag_fined = true;
				break;
			}
		}

// если не найден подходящий токен:
		if(!flag_fined)
		{
			if(!tab[s_prev].error)
			{
				// ничего страшного: ошибки нет, переходим в следующее состояние
				s++;
			}
			else
			{
				// беда
				fprintf(out_errors, "вместо %s ожидалось ", get_token_string(t_prev));
				for(i = 0; i < tab[s_prev].N; i++)
				{
					fprintf(out_errors, "%s", get_token_string(tab[s_prev].tok[i]));
					if(i < tab[s_prev].N - 1) fprintf(out_errors, " или ");
				}
				fprintf(out_errors, "\n");
				return ERROR_FATAL;
			}
		}

// описания переменных
	// если встречается int (состояние 16) значит начинается описание переменных
		if(s_prev == 16)
		{
			flag_define = true;
		}else
	// после ; (состояние 19) описание переменных заканчивается
		if(s_prev == 19)
		{
			flag_define = false;
		}
	// если идет описание переменных и встретился id то обновляем его атрибут defined
		if(flag_define && t_prev.table == 4)
		{
			if(id.el[t_prev.i].defined)
			{
				fprintf(out_errors, "повторное описание переменной %s\n", get_token_string(t_prev));
				return ERROR_FATAL;
			}
			else
			{
				id.el[t_prev.i].defined = true;
			}
		}

// вычисления
	// если встречается while | id (состояние 30) значит начинается использование переменных
		if(s_prev == 30)
		{
			flag_solving = true;
		}else
	// после } (состояние 9) использование переменных заканчивается
		if(s_prev == 9)
		{
			flag_solving = false;
		}
	// если идет использование переменных и встретилась id то проверяем его атрибут defined (вдруг не описана)
		if(flag_solving && t_prev.table == 4)
		{
			if(!id.el[t_prev.i].defined)
			{
				fprintf(out_errors, "не описана переменная %s\n", get_token_string(t_prev));
				return ERROR_FATAL;
			}
		}
// постфикизация
// тут уже выловлены все ошибки
		
		bool res_simple = state_simple(s_prev);	// обычные
		bool res_begin = state_begin(s_prev);	// начинающие
		bool res_end = state_end(s_prev);		// завершающие
		bool res_dont_write = state_dont_write(s_prev);		// не выводить токен?

		if(res_simple || res_begin || res_end)
		{
			// токен начинающий блок помещаем в стек.
			if(res_begin)
			{
				if(s_prev == 35)		//while
				{
					count_whiles++;
					// портим t_prev
					// сразу выводим метку конца начала цикла
					t_prev.table = WHILE_BEGIN_ID;
					t_prev.i = count_whiles;
					write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
					printf("%s\n", get_token_string(t_prev));
#endif
					// а в стек отправляем метку конца цикла
					t_prev.table = WHILE_END_ID;
					t_prev.i = count_whiles;					
				}
				stack_tokens_head++;
				if(stack_tokens_head >= STACK_TOKENS_LEN)
				{
					if(increace_stack() != 0)	return ERROR_FATAL;
				}
				stack_tokens[stack_tokens_head] = t_prev;
			}else
			// токен завершающий блок. Выводим его, если он не в черном списке, затем выводи токен начинающий блок из стека
			if(res_end)
			{
				if(!res_dont_write)
				{
					write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
					printf("%s\n", get_token_string(t_prev));
#endif
				}
				if(stack_tokens_head < 0) ERR("Критическая ошибка: стек токенов пуст\n", ERROR_FATAL);
				write_token(out, stack_tokens[stack_tokens_head].table, stack_tokens[stack_tokens_head].i);
#if defined(DEBUG)
				printf("%s\n", get_token_string(stack_tokens[stack_tokens_head]));
#endif
				stack_tokens_head--;
			}else
			// рядовой символ требующий отображения
			if(res_simple)
			{
				write_token(out, t_prev.table, t_prev.i);
#if defined(DEBUG)
				printf("%s\n", get_token_string(t_prev));
#endif
			}
		}
	}

end:;
// последним должен быть специальный завершающий токен
	fscanf(tok_in, "%d%d", &t.table, &t.i);
	if(t.table != -1 || t.i != -1)
	{
		ERR("лишний код после конца программы\n", ERROR_FATAL);
	}
	write_token(out, -1, -1);// завершающий токен
	fclose(out);
	fclose(tok_in);
	delete stack;
	delete stack_tokens;
	for(i = 1; i <= tab_size; i++)
	{
		delete tab[i].tok;
	}
	delete tab;
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ГЕНЕРАТОР КОДА
///////////////////////////////////////////////////////////////////////////////

int make_code(const char *file_name_tree, const char *file_name_listing)
{
	FILE *in, *out;
// стек для хранения токенов
	TOKEN t, t1, t2, temp;
	char s[STRING_LEN*2];
	int i;
	in = fopen(file_name_tree, "r");
	ERR_FILE(in, file_name_tree);
	out = fopen(file_name_listing, "w");
	ERR_FILE(out, file_name_listing);
// заголовок программы
	PUT(".386");
	PUT(".MODEL FLAT");
	PUT(".DATA");
// описание переменных
	for(i = 0; i < id.N; i++)
	{
		if(id.el[i].name != NULL)
		{
			sprintf(s, "_%s DD ?", id.el[i].name);
			PUT(s);
		}
	}
// сегмент кода
	PUT(".CODE");
	PUT("START:");
	for(;;)
	{
		// очередной токен
		fscanf(in, "%d%d", &t.table, &t.i);
		if(t.table == -1 && t.i == -1)
			break;
		else
// идентификатор значит дальше будут арифметические операции
		if(t.table == ID_ID)
		{
			// EAX = первое слагаемое
			fscanf(in, "%d%d", &temp.table, &temp.i);		// id | const
			if(temp.table == ID_ID)
				sprintf(s, "MOV EAX, _%s", get_token_string(temp));
			else
				sprintf(s, "MOV EAX, %s", get_token_string(temp));
			PUT(s);
			for(;;)
			{
				fscanf(in, "%d%d", &t1.table, &t1.i);		// id | const | =
				if(t1.table == OPER_ID && t1.i == 4) break;	//=
				//если не равно
				fscanf(in, "%d%d", &t2.table, &t2.i);		// + | -
				if(t2.table == OPER_ID && t2.i == 0)		// +
				{
					if(t1.table == ID_ID)
						sprintf(s, "ADD EAX, _%s", get_token_string(t1));
					else
						sprintf(s, "ADD EAX, %s", get_token_string(t1));
					PUT(s);
				}
				else										// -
				{
					if(t1.table == ID_ID)
						sprintf(s, "SUB EAX, _%s", get_token_string(t1));
					else
						sprintf(s, "SUB EAX, %s", get_token_string(t1));
					PUT(s);
				}
			}
			// приравниваем t = EAX
			sprintf(s, "MOV _%s, EAX", get_token_string(t));
			PUT(s);
		}else
//  начало цикла
		if(t.table == WHILE_BEGIN_ID)
		{
			// ставим метку
			sprintf(s, "WHILE_START%d:", t.i);
			PUT(s);
			// далее идут 2 операнда и знак операции  сравнения
			fscanf(in, "%d%d", &t1.table, &t1.i);		// id | const
			fscanf(in, "%d%d", &t2.table, &t2.i);		// id | const
			fscanf(in, "%d%d", &temp.table, &temp.i);	// < | > | <= | >=
			if(t1.table == ID_ID)
				sprintf(s, "MOV EAX, _%s:", get_token_string(t1));	// EAX = t1
			else
				sprintf(s, "MOV EAX, %s:", get_token_string(t1));
			PUT(s);
			if(t2.table == ID_ID)
				sprintf(s, "CMP EAX, _%s:", get_token_string(t2));	// (t1=EAX) VS t2
			else
				sprintf(s, "CMP EAX, %s:", get_token_string(t2));
			PUT(s);
			if(temp.i == 2)								// <
			{											
				sprintf(s, "JGE WHILE_END%d", t.i);		// >= - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 3)								// <=
			{											
				sprintf(s, "JG WHILE_END%d", t.i);		// > - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 5)								// >
			{											
				sprintf(s, "JLE WHILE_END%d", t.i);		// <= - условие выхода из цикла
				PUT(s);
			}else
			if(temp.i == 6)								// >=
			{											
				sprintf(s, "JL WHILE_END%d", t.i);		// < - условие выхода из цикла
				PUT(s);
			}			
		}else
//  конец цикла
		if(t.table == WHILE_END_ID)
		{
			// безусловный переход
			sprintf(s, "JMP WHILE_START%d", t.i);
			PUT(s);
			sprintf(s, "WHILE_END%d:", t.i);
			PUT(s);

		}

	}
	PUT("END START");
	fclose(in);
	fclose(out);
	return 0;
}

///////////////////////////////////////////////////////////////////////////////
// ГОЛОВНАЯ ПРОГРАММА
///////////////////////////////////////////////////////////////////////////////

unsigned CALLBACK timer_proc(void*)
{
	int count = 0, c;
    while (true)
    {
        Sleep(1*1000);
		count += 60;
        printf("Текущий этап трансляции: %s. Программа выполняется уже %d минут. Прекратить?Y/N ", PHASE_NAME[PHASE_ID], count/60);
		c = getchar();
		if(c == 'y' || c == 'Y') break;
    }
	fprintf(out_errors, "Процесс трансляции прерван по техническим причинам\n");
	_exit(0);
	return 0;
}

void main()
{
	SetConsoleCP(1251);
	SetConsoleOutputCP(1251);
	HANDLE hThread;
	int R;
	FILE *config;
	keys.el = NULL;
	oper.el = NULL;
	sep.el = NULL;
	id.el = NULL;
	consts.el = NULL;
	stack = NULL;
	stack_tokens = NULL;
	tab = NULL;
	config = fopen("config.txt", "r");
	if(config == NULL)
	{
		STACK_LEN			= 1024;
		STACK_TOKENS_LEN	= 1024;
		TABLE_ID_LEN		= 1024;
		TABLE_CONSTS_LEN	= 1024;
	}
	else
	{
		fscanf(config, "%d%d%d%d", &STACK_LEN, &STACK_TOKENS_LEN, &TABLE_ID_LEN, &TABLE_CONSTS_LEN);
		fclose(config);
	}

	PHASE_ID = 0;
	hThread = (HANDLE)_beginthreadex(NULL, 0, timer_proc, NULL, 0, NULL);
	if(keys.load("keys.txt") == ERROR_FATAL) return;
	if(oper.load("oper.txt") == ERROR_FATAL) return;
	if(sep.load("sep.txt") == ERROR_FATAL) return;
	if(id.init(TABLE_ID_LEN) == ERROR_MEMORY) return;
	if(consts.init(TABLE_CONSTS_LEN) == ERROR_MEMORY) return;
	
	PHASE_ID = 1;
m1:	R = make_tokens("code.cpp", "_tokens.txt");
	if(R == ERROR_FATAL) return; else
	if(R == ERROR_OVERFLOW) {if(increace_table() != 0) return; else goto m1;} else
	if(R == ERROR_MEMORY) return;
	id.save("_id.txt"); id.release();
	consts.save("_consts.txt");	consts.release();
		
	PHASE_ID = 2;
	id.load("_id.txt");
	consts.load("_consts.txt");
	R = make_tree("table.txt", "_tokens.txt", "_tree.txt");
	if(R == ERROR_FATAL) return;
	id.save("_id.txt"); id.release();
	consts.save("_consts.txt");	consts.release();
	
	PHASE_ID = 3;
	id.load("_id.txt");
	consts.load("_consts.txt");
	R = make_code("_tree.txt", "_listing.asm");
	if(R == ERROR_FATAL) return;

	PHASE_ID = 4;
	keys.release();
	oper.release();
	sep.release();
	id.release();
	consts.release();
	CloseHandle(hThread);
}

 

 

  картинка для ясности

MAnsXQo.png

 

jDx9OG2.png

вроду эту лабу ещё не скидывал, хз

 

сделано конечно хуёва, особенно хеш таблица

но эта хуета большего не заслуживала

 

Классно, хуйня которая отработает если файловая система будет добра.

Зачем писать поддерживаемый функциональный код который в любой момент можно научить работать не только с fs но и с http.

Зачем чекать возвращаемые коды от  io функций.

 

Хуйня на два экрана которая делает то, что у людей сделает 4 класса меньше 100 строк  причем с логами и ретраем.

Написать императивную хуйню большого ума не надо.

Завернуть бизнес-задачу в декларативный понятный поддерживаемый код,  с сохранением сложности, вот это сильно.

у меня от этого листинга if(!(BUKVA(c) || CIFRA(c)))

DnoInvokera написал 13 часов назад:

хотел загуглить но уже второй день руки не доходят

как выбрать рандомные 5 элемента из списка, если в списке миллион элементов, ну типа на скорость

 

Если random acces то просто генерируешь последовательность случайных чисел пока там не наберется 5 дистинктов.

На энтропию это вроде не должно влиять.

Потом берешь по индексу.

 

Если список связный, то последовательность случайных чисел сортируешь. И за обход до максимального индекса собираешь.

Можешь потом их обратно перемешать в том же порядке в котором были индексы до сортировки.

 

Как-то так. :zatrolka_tupostu:

E1azor и GoldRobot понравилось это

Поделиться сообщением


Ссылка на сообщение

если список двусвязный - можно разбить на подсписки так же само random(0,1) с начала или с конца, и рандомно собрать 5, если в одном из них не набралось 5 элементов distinct то идешь в другой подсписок

 

Поделиться сообщением


Ссылка на сообщение

не могу осилить что вы написали потому что надо убегать, но для рандома без повторов у меня такое получилось (т.е. я бы делал также как ((ne()))

const list = [...Array(12000000).keys()]
const randomIndex = () => Math.trunc(Math.random() * list.length);
const randomRange = (limit = 5) => {
  const data = [];

  const handleRandom = () =>
    (index = randomIndex(), data.push(list[index]), list.splice(index, 1));

  const youSpinMe = (round) => round > 0 ?
    (handleRandom(), youSpinMe(round-1)) : data;

  return youSpinMe(limit);
}

const items = randomRange()

 


have courage and be kind

  😈🫀💋 🩸👣🤌🏿🦄 🐝 ☄️❣️ 💕 💞❤️😈

 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖

220941652_Annotation2021-03-20123345.jpg.23dcff343d6a377badf433b20f5271fd.jpg

💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 💖 

Поделиться сообщением


Ссылка на сообщение
DnoInvokera написал 44 минуты назад:

не могу осилить что вы написали потому что надо убегать, но для рандома без повторов у меня такое получилось (т.е. я бы делал также как ((ne()))


const list = [...Array(12000000).keys()]
const randomIndex = () => Math.trunc(Math.random() * list.length);
const randomRange = (limit = 5) => {
  const data = [];

  const handleRandom = () =>
    (index = randomIndex(), data.push(list[index]), list.splice(index, 1));

  const youSpinMe = (round) => round > 0 ?
    (handleRandom(), youSpinMe(round-1)) : data;

  return youSpinMe(limit);
}

const items = randomRange()

 

серьезно? ты пишешь про самый быстрый способ нахождения на огромном массиве, но ты в процессе удаляешь элементы с массива что O(n)

 

func getRandomElementsFrom(array: [Int], resultingCount: Int = 5) -> [Int] {
    if array.count <= resultingCount {
        return array
    }

    var results = [Int]()
    var usedIndecies = Set<Int>()
    var currentIndex = Int.random(in: 0..<array.count)

    while results.count < resultingCount {
        while usedIndecies.contains(currentIndex) {
            currentIndex = Int.random(in: 0..<array.count)
        }

        results.append(array[currentIndex])
        usedIndecies.insert(currentIndex)
    }

    return results
}

если нужен порядок то сначала индексы получить, потом их сортануть и форлупом собрать элементы

Поделиться сообщением


Ссылка на сообщение

 

UPD:

Вот намного лучше функция, которая не юзает Set, гарантировано O(k), where k = resultingCount

func _getRandomElementsFrom(array: [Int], resultingCount: Int = 5) -> [Int] {
    if array.count <= resultingCount {
        return array
    }

    var currArray = array

    for i in 0..<resultingCount {
        let randomIndex = Int.random(in: 0..<currArray.count - i)
        let temp = currArray[randomIndex]
        currArray[randomIndex] = currArray[currArray.count - i - 1]
        currArray[currArray.count - i - 1] = temp
    }

    return Array(currArray[(currArray.count - resultingCount)..<currArray.count])
}

 

Поделиться сообщением


Ссылка на сообщение
Гость
Эта тема закрыта для публикации сообщений.

×
×
  • Создать...