Змінюй хід війни! Допомагай ЗСУ!
  • Знижка на баннерну рекламу 30%! Банер на всіх сторінках сайту, в мобільній та десктопній версії за 14 тис. грн на місяць. Статистика сайту. Контакт: [email protected]

Вы смотрите телепередачу "А нука, гуру!"

  • Автор теми Автор теми dr_mousefly
  • Дата створення Дата створення
Здравствуйте,
мне задача понравилась, но обидно что к ее решению был трижды выбран примитывный железный подход.
Помнится, Наташа решала задачу, первое лиш бы что написать,непротиворечащее условию,потом ей говорят,тут их семь,она вставляет проверочку,потом ей говорят,по минимуму, он вставляет проверочку,потом и по максимуму ,она еще добовляет проверочку,и так горем пополам дошли до логического завершения.
Это не работа, да вроде как и требовалось определить математическое разрешение через одну функцию.
 
Здравствуйте,
мне задача понравилась, но обидно что к ее решению был трижды выбран примитывный железный подход.
Помнится, Наташа решала задачу, первое лиш бы что написать,непротиворечащее условию,потом ей говорят,тут их семь,она вставляет проверочку,потом ей говорят,по минимуму, он вставляет проверочку,потом и по максимуму ,она еще добовляет проверочку,и так горем пополам дошли до логического завершения.
Это не работа, да вроде как и требовалось определить математическое разрешение через одну функцию.

покажите Ваше решение. хотя бы алгоритм
****еть умельцев много и без Вас.
 
Но и короткого алгоритма пока нет. УГ на полстранцы не обсуждаемо. Вот Тыемураз хотя бы смотрит горизонтально.
 
Прежде всего необходимо повязать числа (их три) , придавая им свойства ,удовлетворяющие условию.Далее разрешить их взаимодействие в одной плоскости.Подходы общеизвестны ,соответствуют учебному курсу 7-8 классов средних школ 80 -х.Могу подсказать действо деления и факторилала.
 
Прежде всего необходимо повязать числа (их три) , придавая им свойства ,удовлетворяющие условию.Далее разрешить их взаимодействие в одной плоскости.Подходы общеизвестны ,соответствуют учебному курсу 7-8 классов средних школ 80 -х.Могу подсказать действо деления и факторилала.

это не алгоритм.
числа не взаимодействуют в плоскости.
ни деление, ни факториал тут ни разу не нужны.
садись, два--.

Но и короткого алгоритма пока нет.

ну так и задача с подвохом...
надо запостить в тему про техноцирк. ануко как грамотным планированием заставить "клавиатурных рабов" щелкать подобные задачи с 1 раза,
а не пытаться что-то куда-то, а потом допиливать напильником до кондиции (если получится).
 
Спасибо за задачу, приятное разнообразие среди всех этих "если пользователь *****, вывести вежливый намек на это обстоятельство" :)

Код:
private static IEnumerable<int> GetCards( int cards, int boxes, int minCards, int maxCards, Random random  )
		{
			if ( boxes < 2 )
			{
				return new List<int> {cards};
			}
			var tolMin = cards - (boxes - 1) * maxCards;
			var tolMax = cards - (boxes - 1)*minCards;
			minCards = tolMin > minCards ? tolMin : minCards;
			maxCards = tolMax < maxCards ? tolMax : maxCards;
			var layInBox = minCards + random.Next(maxCards - minCards + 1);
			var temp = new List<int> {layInBox };
			temp.AddRange(GetCards(cards - layInBox, boxes - 1, minCards, maxCards, random));
			var result = new List<int>();
			while( temp.Count() > 0 )
			{
				var ix = random.Next(temp.Count());
				result.Add(temp[ix]);
				temp.RemoveAt(ix);
			}
			return result;
		}
 
Но и короткого алгоритма пока нет. УГ на полстранцы не обсуждаемо. Вот Тыемураз хотя бы смотрит горизонтально.

Так нужен "короткий" или быстрый? :D

Начнем с самого не оптимального варианта "O(n)":
Код:
void fun(int count, int min, int max, int* mas, int size)
{
	assert(min*size<=count);

	for(int i = 0; i<size; i++)
		mas[i] = min;

	for(int i=min*size; i<count; i++)
	{
		int j = rand()%size;
		if(mas[j]<max) 
			mas[j]++;
		else
			i--;
	}
}
 
Такой алгоритм разместит 1000 карточек в 4 ящика по 250 +/- 10, варианта 600-200-50-150 он не даст :) То есть при очень большом количестве карточек можно просто разделить на количество ящиков.
 
Такой алгоритм разместит 1000 карточек в 4 ящика по 250 +/- 10, варианта 600-200-50-150 он не даст :) То есть при очень большом количестве карточек можно просто разделить на количество ящиков.

Да это и ёжику понятно. Зато "ТЗ" такой алгоритм соответствует! :D
 
и протормаживает на сериях одинаковых случайных номеров ящичков.

Естественно, он же основан на переборе, а значит "O(n)". Но это скажем так, не пример, а контрпример немножко по-*****ьному написанному "ТЗ".
 
Такой алгоритм разместит 1000 карточек в 4 ящика по 250 +/- 10, варианта 600-200-50-150 он не даст :) То есть при очень большом количестве карточек можно просто разделить на количество ящиков.

количество не больше 30.

Но это скажем так, не пример, а контрпример немножко по-*****ьному написанному "ТЗ".

что Вас не устраивает в условиях задачи?
ответьте, пожалуйста, конкретно.
 
что Вас не устраивает в условиях задачи?
ответьте, пожалуйста, конкретно.

количество не больше 30.

Не устраивает то, что ограничения на исходные данные всплывают после 3-го варианта решения.
 
Ну, формальный подход к ТЗ обычно чреват уточнениями и переделками :) Понятно, что хочется как можно быстрее получить набор из "как можно более случайных" карточек, при этом количество карточек в заданных пределах, сумма строго равна. Исходя из этой "как можно большей случайности" я и добавил тасование ящиков, потому что по мере рекурсии свобода "минимум-максимум" уменьшается и последние числа уже предсказуемы. Еще можно/нужно добавить валидацию и обойти вызов random, если уже minCards = maxCards. А также не тасовать при рекурсивном вызове, для чего еще аргументик добавить, тогда тратить ценное время на пробежку по всему списку можно только один раз.
 
Для обоих, конечно.
 
PHP:
import random

def fill_boxes(cards_count=30, box_count=7, min_cards=2, max_cards=7):
    box_range = range(1, box_count+1)
    is_enough_cards = cards_count >= box_count*min_cards
    cards_to_fill = is_enough_cards and cards_count-min_cards*box_count or cards_count
    boxes = dict([(i, is_enough_cards and min_cards or 0) for i in box_range])
    full_boxes = {}
    for j in range(0, cards_to_fill):        
        rnd = random.choice(list(set(box_range)-set(full_boxes.keys())))
        boxes.update({rnd: boxes[rnd]+1})
        if boxes[rnd]==(is_enough_cards and max_cards or min_cards):
            full_boxes.update({rnd: boxes.pop(rnd)})
    boxes.update(full_boxes)
    return boxes

if __name__ == '__main__':
    print "Enough cards:"
    for i in range(0, 3): print fill_boxes()
    print "More boxes:"
    for i in range(0, 3): print fill_boxes(30, 10, 2, 7)
    print "Not enough cards to fill minimal count:"
    for i in range(0, 3): print fill_boxes(18, 10, 2, 7)
    print "Not enough cards:"
    for i in range(0, 3): print fill_boxes(5, 7, 2, 7)
    print "1 card:"
    for i in range(0, 3): print fill_boxes(1, 7, 0, 1)

output:

PHP:
Enough cards:
{1: 6, 2: 5, 3: 4, 4: 3, 5: 4, 6: 4, 7: 4}
{1: 5, 2: 4, 3: 3, 4: 7, 5: 4, 6: 4, 7: 3}
{1: 6, 2: 5, 3: 5, 4: 3, 5: 5, 6: 4, 7: 2}
More boxes:
{1: 3, 2: 2, 3: 4, 4: 2, 5: 3, 6: 3, 7: 2, 8: 2, 9: 4, 10: 5}
{1: 3, 2: 3, 3: 2, 4: 5, 5: 2, 6: 5, 7: 3, 8: 2, 9: 2, 10: 3}
{1: 4, 2: 2, 3: 3, 4: 5, 5: 3, 6: 3, 7: 2, 8: 3, 9: 2, 10: 3}
Not enough cards to fill minimal count:
{1: 1, 2: 2, 3: 2, 4: 1, 5: 2, 6: 2, 7: 2, 8: 2, 9: 2, 10: 2}
{1: 1, 2: 1, 3: 2, 4: 2, 5: 2, 6: 2, 7: 2, 8: 2, 9: 2, 10: 2}
{1: 2, 2: 2, 3: 2, 4: 2, 5: 1, 6: 2, 7: 1, 8: 2, 9: 2, 10: 2}
Not enough cards:
{1: 1, 2: 0, 3: 2, 4: 0, 5: 0, 6: 1, 7: 1}
{1: 1, 2: 1, 3: 0, 4: 1, 5: 1, 6: 1, 7: 0}
{1: 1, 2: 1, 3: 1, 4: 0, 5: 1, 6: 0, 7: 1}
1 card:
{1: 0, 2: 0, 3: 1, 4: 0, 5: 0, 6: 0, 7: 0}
{1: 0, 2: 0, 3: 1, 4: 0, 5: 0, 6: 0, 7: 0}
{1: 0, 2: 0, 3: 0, 4: 0, 5: 1, 6: 0, 7: 0}

вроде верно считается.
хорошая задачка.. интересная

не за что
 
Не устраивает то, что ограничения на исходные данные всплывают после 3-го варианта решения.

Бред (ц)
какие еще ограничения..

Ну, формальный подход к ТЗ обычно чреват уточнениями и переделками :)

не рассказывайте преподу о реальных ТЗ....
 
Естественно, он же основан на переборе, а значит "O(n)". Но это скажем так, не пример, а контрпример немножко по-*****ьному написанному "ТЗ".

Вот когда прав, то прав. Я тоже ТС сказал - ТЗ по-*****ьному написано.
 
Понятно, что хочется как можно быстрее получить набор из "как можно более случайных" карточек, при этом количество карточек в заданных пределах, сумма строго равна. Исходя из этой "как можно большей случайности" я и добавил тасование ящиков, потому что по мере рекурсии свобода "минимум-максимум" уменьшается и последние числа уже предсказуемы. Еще можно/нужно добавить валидацию и обойти вызов random, если уже minCards = maxCards. А также не тасовать при рекурсивном вызове, для чего еще аргументик добавить, тогда тратить ценное время на пробежку по всему списку можно только один раз.

Вариантов решения этой задачи масса. Можно даже собственный генератор псевдо-случайных чисел написать...
 
Назад
Зверху Знизу