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

Статус: Offline
Реєстрація: 10.10.2007
Повідом.: 13141
Вы смотрите телепередачу "А нука, гуру!"

Необходимо случайным образом распределеть заданное количество карточек (например 30) по 7 ящикам, да так чтобы в каждом получилось не меньше заданного минимума (например 2) и не больше заданного максимума (например 6). То есть нужна функция, которая будет принимать количество карточек, минимум и максимум, а отдавать массив из 7 чисел (количества карточек по ящичкам).
Возможен вариант, когда количество карточек равно 1, минимум 0, максимум 1. Фукция должна отрабатывать его коректно: класть единственную карточку в случайный ящичек.

АПДЕЙТ!
конкурс завершен.
наше уважаемое жюри посовещалось и я решил распределить призовые баллы следующим образом:
  • приз "За волю к победе" как первый приславший вариант решения получает AS0kol. 2 балла.
    appl.gif
  • приз "Открытие Века" получает Achenar. 2 балла.
    appl.gif
  • приз "Говнокодер Года" за переменную mas и нежелание решить проблему "затыкания" получает Orshansky. 1 балл.
    appl.gif
  • приз "Обманул Судьбу" за хитровывернутое решение получает Stqs. 2 балла.
    appl.gif
  • и наконец, приз "Тролололо/Шарманщик Века" и по дисквалификации получает strenzer. -1 балл.
    bud.gif
(надо будет придумать гран-при...)

следующий выпуск выйдет в эфир где-то после девятого числа. следите за новостями.
всем большое спасибо! до свиданья, до новых встреч!
 
Останнє редагування:
пару циклов с условными операторами и рендомайзер. На С++ можно накидать под кофе и сигаретку.
 
пару циклов с условными операторами и рендомайзер. На С++ можно накидать под кофе и сигаретку.

та это понятно. сам алгоритм? особенно интересно, как в си-плюсах.
уж и забыл как оно было ужасно, когда нельзя удалять элементы из массива..
 
Вариантов много. Вот один накропал на скорую руку.

Код:
<html>
  <head>
    <style type="text/css">
      .label {
        text-align: right;
      }
    </style>
    <script type="text/javascript">
      function splitCards(aCardCount, aBoxCount, aMinCount, aMaxCount) {
        if (aMinCount.valueOf() > aMaxCount.valueOf()) {
          throw("Минимальное количество карточек не должно превышать максимальное.");
        }
        
        var lCardsRest = aCardCount - (aBoxCount * aMinCount);
                
        if (lCardsRest.valueOf() < 0) {
          throw("Не хватает карточек для заполнения коробок по минимуму.");
        }
        
        var lResult = [];
                
        if ((lCardsRest.valueOf() == 0) || (aMinCount.valueOf() == aMaxCount.valueOf())) {
          for (var lBoxIndex = 0; lBoxIndex < aBoxCount; lBoxIndex++) {
            lResult[lBoxIndex] = aMinCount;
          }
        }
        else {
          for (var lIndex = 0; lIndex < aBoxCount; lIndex++) {
            var lMax = Math.min(aMaxCount, lCardsRest);
            var lCardCount = Math.min(Math.round(lMax * Math.random()), lMax);
            lCardsRest -= lCardCount;
            
            var lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            while (lResult[lBoxIndex] != null) {
              lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            }
            lResult[lBoxIndex] = lCardCount + aMinCount;
          }
        }
        return lResult;
      }
      
      function onButtonGoClick() {
        var lCardCount = new Number(document.getElementById("inputCardCount").value);
        var lBoxCount =  new Number(document.getElementById("inputBoxCount").value);
        var lMinCount =  new Number(document.getElementById("inputBoxCardMinCount").value);
        var lMaxCount =  new Number(document.getElementById("inputBoxCardMaxCount").value);
        var lResultString = "";
        
        try {
          var lArray = splitCards(lCardCount, lBoxCount, lMinCount, lMaxCount);      
          var lSum = 0;
          for (var lIndex = 0; lIndex < lArray.length; lIndex++) {
            lResultString += lArray[lIndex] + " ";
            lSum += lArray[lIndex];
          }
          document.getElementById("spanResults").innerHTML = lResultString + " сумма = " + lSum;
        }
        catch (lException){
          document.getElementById("spanResults").innerHTML = lException;
        }
      }      
    </script>
  </head>
  <body>
    <table>
      <tr>
        <td class="label">
          <label for="inputCardCount">Количество карточек</>
        </td>
        <td>
          <input type="text" id="inputCardCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCount">Количество коробок</>
        </td>
        <td>
          <input type="text" id="inputBoxCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMinCount">Минимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMinCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMaxCount">Максимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMaxCount">
        </td>
      </tr>
      <tr>
        <td class="label" colspan="2">
          <input type="button" value="Go" onClick="onButtonGoClick();">
        </td>
      </tr>
    </table>
    <span id="spanResults"></span>
  </body>
</html>
 
Вариантов много. Вот один накропал на скорую руку.

Код:
<html>
  <head>
    <style type="text/css">
      .label {
        text-align: right;
      }
    </style>
    <script type="text/javascript">
      function splitCards(aCardCount, aBoxCount, aMinCount, aMaxCount) {
        if (aMinCount.valueOf() > aMaxCount.valueOf()) {
          throw("Минимальное количество карточек не должно превышать максимальное.");
        }
        
        var lCardsRest = aCardCount - (aBoxCount * aMinCount);
                
        if (lCardsRest.valueOf() < 0) {
          throw("Не хватает карточек для заполнения коробок по минимуму.");
        }
        
        var lResult = [];
                
        if ((lCardsRest.valueOf() == 0) || (aMinCount.valueOf() == aMaxCount.valueOf())) {
          for (var lBoxIndex = 0; lBoxIndex < aBoxCount; lBoxIndex++) {
            lResult[lBoxIndex] = aMinCount;
          }
        }
        else {
          for (var lIndex = 0; lIndex < aBoxCount; lIndex++) {
            var lMax = Math.min(aMaxCount, lCardsRest);
            var lCardCount = Math.min(Math.round(lMax * Math.random()), lMax);
            lCardsRest -= lCardCount;
            
            var lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            while (lResult[lBoxIndex] != null) {
              lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            }
            lResult[lBoxIndex] = lCardCount + aMinCount;
          }
        }
        return lResult;
      }
      
      function onButtonGoClick() {
        var lCardCount = new Number(document.getElementById("inputCardCount").value);
        var lBoxCount =  new Number(document.getElementById("inputBoxCount").value);
        var lMinCount =  new Number(document.getElementById("inputBoxCardMinCount").value);
        var lMaxCount =  new Number(document.getElementById("inputBoxCardMaxCount").value);
        var lResultString = "";
        
        try {
          var lArray = splitCards(lCardCount, lBoxCount, lMinCount, lMaxCount);      
          var lSum = 0;
          for (var lIndex = 0; lIndex < lArray.length; lIndex++) {
            lResultString += lArray[lIndex] + " ";
            lSum += lArray[lIndex];
          }
          document.getElementById("spanResults").innerHTML = lResultString + " сумма = " + lSum;
        }
        catch (lException){
          document.getElementById("spanResults").innerHTML = lException;
        }
      }      
    </script>
  </head>
  <body>
    <table>
      <tr>
        <td class="label">
          <label for="inputCardCount">Количество карточек</>
        </td>
        <td>
          <input type="text" id="inputCardCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCount">Количество коробок</>
        </td>
        <td>
          <input type="text" id="inputBoxCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMinCount">Минимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMinCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMaxCount">Максимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMaxCount">
        </td>
      </tr>
      <tr>
        <td class="label" colspan="2">
          <input type="button" value="Go" onClick="onButtonGoClick();">
        </td>
      </tr>
    </table>
    <span id="spanResults"></span>
  </body>
</html>

спасибо за попытку, но...
это что еще за выкрутасы? я заказывал 30...

какбе lResult[lBoxIndex] = lCardCount + aMinCount может произойти с одним ящиком дважды.

ЗЫ. проверкой валидности параметров можно не заморачиваться. количество ящиков тоже фиксированное. это какбе дни недели на самом деле.
 
Там не было сказано распределить без остатка. :) Поправлю.
 
какбе lResult[lBoxIndex] = lCardCount + aMinCount может произойти с одним ящиком дважды.

Если ты посмотришь внимательно, то поймешь, что не может.

а одна карточка усохла в ходе распределения? ))))

Это откат. :)
 
Останнє редагування:
Вариантов много. Вот один накропал на скорую руку.

Код:
<html>
  <head>
    <style type="text/css">
      .label {
        text-align: right;
      }
    </style>
    <script type="text/javascript">
      function splitCards(aCardCount, aBoxCount, aMinCount, aMaxCount) {
        if (aMinCount.valueOf() > aMaxCount.valueOf()) {
          throw("Минимальное количество карточек не должно превышать максимальное.");
        }
        
        var lCardsRest = aCardCount - (aBoxCount * aMinCount);
                
        if (lCardsRest.valueOf() < 0) {
          throw("Не хватает карточек для заполнения коробок по минимуму.");
        }
        
        var lResult = [];
                
        if ((lCardsRest.valueOf() == 0) || (aMinCount.valueOf() == aMaxCount.valueOf())) {
          for (var lBoxIndex = 0; lBoxIndex < aBoxCount; lBoxIndex++) {
            lResult[lBoxIndex] = aMinCount;
          }
        }
        else {
          for (var lIndex = 0; lIndex < aBoxCount; lIndex++) {
            var lMax = Math.min(aMaxCount, lCardsRest);
            var lCardCount = Math.min(Math.round(lMax * Math.random()), lMax);
            lCardsRest -= lCardCount;
            
            var lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            while (lResult[lBoxIndex] != null) {
              lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            }
            lResult[lBoxIndex] = lCardCount + aMinCount;
          }
        }
        return lResult;
      }
      
      function onButtonGoClick() {
        var lCardCount = new Number(document.getElementById("inputCardCount").value);
        var lBoxCount =  new Number(document.getElementById("inputBoxCount").value);
        var lMinCount =  new Number(document.getElementById("inputBoxCardMinCount").value);
        var lMaxCount =  new Number(document.getElementById("inputBoxCardMaxCount").value);
        var lResultString = "";
        
        try {
          var lArray = splitCards(lCardCount, lBoxCount, lMinCount, lMaxCount);      
          var lSum = 0;
          for (var lIndex = 0; lIndex < lArray.length; lIndex++) {
            lResultString += lArray[lIndex] + " ";
            lSum += lArray[lIndex];
          }
          document.getElementById("spanResults").innerHTML = lResultString + " сумма = " + lSum;
        }
        catch (lException){
          document.getElementById("spanResults").innerHTML = lException;
        }
      }      
    </script>
  </head>
  <body>
    <table>
      <tr>
        <td class="label">
          <label for="inputCardCount">Количество карточек</>
        </td>
        <td>
          <input type="text" id="inputCardCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCount">Количество коробок</>
        </td>
        <td>
          <input type="text" id="inputBoxCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMinCount">Минимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMinCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMaxCount">Максимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMaxCount">
        </td>
      </tr>
      <tr>
        <td class="label" colspan="2">
          <input type="button" value="Go" onClick="onButtonGoClick();">
        </td>
      </tr>
    </table>
    <span id="spanResults"></span>
  </body>
</html>
УГ
Тільки зареєстровані користувачі бачать весь контент у цьому розділі
 
Вот. Функция пытается полностью использовать все карточки, если максимальное кол-во карточек * кол-во коробок <= кол-во карточек, то все коробки заполняются по максимуму. Если заранее известно, что карточек немного, то добавленный код можно использовать как самостоятельное решение.
Код:
<html>
  <head>
    <style type="text/css">
      .label {
        text-align: right;
      }
    </style>
    <script type="text/javascript">
      function splitCards(aCardCount, aBoxCount, aMinCount, aMaxCount) {
        if (aMinCount.valueOf() > aMaxCount.valueOf()) {
          throw("Минимальное количество карточек не должно превышать максимальное.");
        }
        
        var lCardsRest = aCardCount - aBoxCount * aMinCount;
                
        if (lCardsRest.valueOf() < 0) {
          throw("Не хватает карточек для заполнения коробок по минимуму.");
        }
        
        var lResult = [];
                
        if ((lCardsRest.valueOf() == 0) || (aMinCount.valueOf() == aMaxCount.valueOf())) {
          for (var lBoxIndex = 0; lBoxIndex < aBoxCount; lBoxIndex++) {
            lResult[lBoxIndex] = aMinCount;
          }
        }
        else if (aMaxCount * aBoxCount <= aCardCount) {
          for (var lBoxIndex = 0; lBoxIndex < aBoxCount; lBoxIndex++) {
            lResult[lBoxIndex] = aMaxCount;
          }
        }
        else {
          var lCardsUsed = 0;
          for (var lIndex = 0; lIndex < aBoxCount; lIndex++) {
            var lMax = Math.min(aMaxCount, lCardsRest);
            var lCardCount = Math.round(lMax * Math.random());
            lCardsRest -= lCardCount;
            
            var lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            while (lResult[lBoxIndex] != null) {
              lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            }
            lResult[lBoxIndex] = Math.min(lCardCount + aMinCount, aMaxCount);
            lCardsUsed += lResult[lBoxIndex];
          }
          
          var lCardsToSplit = Math.min(aMaxCount * aBoxCount, aCardCount) - lCardsUsed;
          while (lCardsToSplit.valueOf() > 0) {
            var lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            while (lResult[lBoxIndex].valueOf() >= aMaxCount) {
              lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
            }
            lResult[lBoxIndex] += 1;
            lCardsToSplit--;
          }
        }
        return lResult;
      }
      
      function onButtonGoClick() {
        var lCardCount = new Number(document.getElementById("inputCardCount").value);
        var lBoxCount =  new Number(document.getElementById("inputBoxCount").value);
        var lMinCount =  new Number(document.getElementById("inputBoxCardMinCount").value);
        var lMaxCount =  new Number(document.getElementById("inputBoxCardMaxCount").value);
        var lResultString = "";
        
        try {
          var lArray = splitCards(lCardCount, lBoxCount, lMinCount, lMaxCount);      
          var lSum = 0;
          for (var lIndex = 0; lIndex < lArray.length; lIndex++) {
            lResultString += lArray[lIndex] + " ";
            lSum += lArray[lIndex];
          }
          document.getElementById("spanResults").innerHTML = lResultString + " сумма = " + lSum;
        }
        catch (lException){
          document.getElementById("spanResults").innerHTML = lException;
        }
      }      
    </script>
  </head>
  <body>
    <table>
      <tr>
        <td class="label">
          <label for="inputCardCount">Количество карточек</>
        </td>
        <td>
          <input type="text" id="inputCardCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCount">Количество коробок</>
        </td>
        <td>
          <input type="text" id="inputBoxCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMinCount">Минимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMinCount">
        </td>
      </tr>
      <tr>
        <td class="label">
          <label for="inputBoxCardMaxCount">Максимальное количество</>
        </td>
        <td>
          <input type="text" id="inputBoxCardMaxCount">
        </td>
      </tr>
      <tr>
        <td class="label" colspan="2">
          <input type="button" value="Go" onClick="onButtonGoClick();">
        </td>
      </tr>
    </table>
    <span id="spanResults"></span>
  </body>
</html>

УГ
Тільки зареєстровані користувачі бачать весь контент у цьому розділі

Буду краток: ПНХ.
 
тот же комментарий.
Кстати у меня тоже есть такая задача, только более общая имеется массив записей в БД, кол-во больше 100.
Необходимо выбирать в течение недели все записи случайным образом, так, чтобы в сутки примерно равномерно. Следуя
Тільки зареєстровані користувачі бачать весь контент у цьому розділі
миниум и максимум принебрегаем. Решения длинной пол страницы можете не писать. HTML тоже не интересует.

Так, один признал, что не способен решить задачу нормально.
 
Вот. Функция пытается полностью использовать все карточки, если максимальное кол-во карточек * кол-во коробок <= кол-во карточек, то все коробки заполняются по максимуму. Если заранее известно, что карточек немного, то добавленный код можно использовать как самостоятельное решение.

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

вот тока...
while (lResult[lBoxIndex].valueOf() >= aMaxCount) {
lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
}
а нето, что?
а если рандомайзер погонит серию одинаковых чисел?
 
Останнє редагування:
тот же комментарий.
Кстати у меня тоже есть такая задача, только более общая имеется массив записей в БД, кол-во больше 100.
Необходимо выбирать в течение недели все записи случайным образом, так, чтобы в сутки примерно равномерно. Следуя
Тільки зареєстровані користувачі бачать весь контент у цьому розділі
миниум и максимум принебрегаем. Решения длинной пол страницы можете не писать. HTML тоже не интересует.


Так, один признал, что не способен решить задачу нормально.

Задача как минимум решена. При чем двумя способами. Так как пиздеть - не мешки ворочать, то предложи свой вариант. Ну а пока ПНХ.
 
вот тапереча работает!
да, карточек немного, так что я сразу использовал то самое решение.

вот тока...
while (lResult[lBoxIndex].valueOf() >= aMaxCount) {
lBoxIndex = Math.round(Math.random() * (aBoxCount - 1));
}
а нето, что?
а если рандомайзер погонит серию одинаковых чисел?

Будет рандомайзить до тех пор, пока не найдет "рандомный" ящик с нужным количеством карточек. Это самое тормознутое место в алгоритме. Но у меня пока нет времени на оптимизацию.

давайте "первый способ" (с усушкой) считать не будем.

А я его и не считаю. Из моей большой функции можно выдрать мелкий кусок и использовать его как второе решение. О чем я уже говорил.
 
Будет рандомайзить до тех пор, пока не найдет "рандомный" ящик с нужным количеством карточек. Это самое тормознутое место в алгоритме. Но у меня пока нет времени на оптимизацию.

"оптимизация" там очень простая.
ящичек набравший максимум надо выкинуть из раздачи.
но для этого массив раздач и массив результатов должны быть разные и немного по-разному устроены.
 
Задача как минимум решена. При чем двумя способами. Так как пиздеть - не мешки ворочать, то предложи свой вариант. Ну а пока ПНХ.

Герцог тоже решил задачу ферокса. Говнокодом на 100500 строк.

Мой вариант рандомизировать по дню недели. прогнал массив карточек - назнчаил каждой день рандомно. всё
если заказчик мудак и ставит еще условия решай их дальше отдельно!
выбрал кол-во карточек в день, проверил. отвечает условию - дальше, нет - корректируй.
Профессионалы.... Звезда

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

Это все говнокод, совершенно непонятный стороннему наблюдателю.
Чем больше пытаешь решить за раз тем более заоптимизированым получается решение.
https://www.kharkovforum.com/showpost.php?p=18469069&postcount=19
но
Тільки зареєстровані користувачі бачать весь контент у цьому розділі
:іржач::іржач::іржач:
да и в посылах НХ чувствуется горечь и недоврольство тем, что не способен решить задачу лучше
Тільки зареєстровані користувачі бачать весь контент у цьому розділі
 
девочки не ссорьтесь
ждем преподов
 
Назад
Зверху Знизу