1. ActionScript / Говнокод #9195

    −116

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    /*
    Часть библиотеки MathUtilsLib  (c) Sergey ( FlexMaster ), 2008
    */
    function shuffle( a:Array ):void{
       if( a ){
           a.map( function ( val:*, index:int, o:Array ){ o[index] = {v:val, r:int( 1000*Math.random())} }, a );
           a.sortOn( 'r');
           a.map(  function ( val:*, index:int, o:Array ){ o[index] = val['v']} );
       }
    }

    К сожалению, в Actionscript нет функции, которая позволила бы получить случайным образом перестановку массива. Иногда это бывает очень нужно.
    функция shuffle перемешивает содержимое исходного массива случайным образом.

    Запостил: kyzi007, 22 Января 2012

    Комментарии (48) RSS

    • Вероятность того, что два элемента не будут переставлены, чуть выше, чем что будут, потому что рандом может выдать одинаковые значения.
      Ответить
    • Код вообще нечитаемый. Shaffle массива - операция O(n), а тут умудрились сделать O(n * log(n)). Хоть бы погуглил прежде чем писать, математик хренов.
      фи, какой императивный map.
      Ответить
    • Фишка еще в том что map это грабля которая работает в десятки раз медленнее чем прямой перебор в цикле.
      Ответить
      • Странно, а почему так?
        Ответить
        • Не знаю, потому что гладиолус.
          А try catch в анонимной функции крешит плеер одним своим присутствием, есть методы play и play1 у видео, для того чтобы заработали вызовы шелл скриптов в air в linex надо собирать установщик из под целевой сборки (то есть под федору там собирать отдельно), официальные мануалы часто врут и тд и тп, стандартный набор граблей о который долбаются даже старички.
          Ответить
          • Чудесная иллюстрация, как мыши продолжают есть проприетарный кактус.
            Говорят, что хтмл 5 окончательно убьёт флещи.
            Ответить
            • А там кактус еще более колючий.
              Ответить
            • а кто убьёт IE6?
              Ответить
              • Что то там говорили про насильное обновление осла...
                Хотя сводная табличка того что работает / не работает / глючит на разных платформах даже без учета ослов меня не так давно впечатляла.
                Ответить
              • А зачем его убивать? Просто сайт однажды в нём не откроется. Это уже проблемы пользователей.
                Я в данном вопросе полностью стою за политику Ein Volkодного браузера. Браузерные войны - бич современности. Ладно они бы хоть стандартам соответствовали одинаково, ан нет.
                Ответить
                • Особенно весело если этот пользователь - самый главный босс.
                  А вот в мерзком адобе - один плеер:)
                  Ответить
                  • Увы, разумного компромисса найти невозможно.
                    Ответить
                    • Можно нагишом бегать по площади и орать «Фалуньгун! Фалуньгун!» «Обнови IE! Обнови IE!». Всегда выход есть.
                      Ответить
                  • да-да, как правило IE6 стоит именно у клиентов. так что пока приходится прогибаться нам под IE. слава Б-гу, я уже отхожу от этой кухни.
                    Ответить
                    • Ну и отлично. Просто сайт будет не на хтмл 5, невелика потеря.
                      Ответить
              • я
                Ответить
        • Потому что http://govnokod.ru/8865
          Ответить
    • Призвала автора в тред, а то скушно...
      Ответить
    • Тут оочень много чего хорошего :) sortOn() кроме всего прочего понасоздает экземпляров строки "r" по одному, на каждый перебираемый элемент... Каждый вызов функции - это как минимум создание динамического массива, в котором находятся ее аргументы. Не говоря уже о том, что создание объекта для каждого элемента массива - это ну даже не знаю, как такое в голову пришло... тут оооочень далеко до n * log(n), в том смысле, что кроме сложности тут есть много дополнительных накладных расходов, которые очень сильно превышают расходы связанные с неоптимальностью алгоритма... Ну и напоследок, сами вложенные функции будут создаваться каждый раз как shuffle() вызовется.
      Ответить
      • Мне больше всего нравиться что над этим бредом гордый цопирайт )
        Ответить
        • Ах, да, еще забыл. Array.map() вобщем-то создает новый массив, т.е. эти вложенные функции должны были бы, в идеале, что-то возвращать, а так создаются еще 2 невостребованных массива заполненых undefined.

          Ну, копирайт - это единственное, что в коде хорошо :) Код с копирайтом лучше кода без копирайта.
          Ответить
          • Массив то из 1000000 (или даже 100000, не помню) элементов у меня прогонялся 4 секунды им:)
            Ответить
      • Все накладные расходы линейты, O(n * log(n)) всё побъёт на больших массивах. А на небольших массивах накладные расходы будут отнимать бОльшую часть операций.
        Ответить
        • Кстати, по поводу map() - не такая уж и большая разница... (хотя, логично ожидать, что разница будет, т.как вызов функции сам по себе не дешевый).

          private function speedTest():void
          {
          	var tested:Array = [1, 2, 3, 4, 5];
          	var i:int;
          	var start:int = getTimer();
          	
          	for (i = 0; i < 100000; i++)
          		tested = this.mapShuffle(tested);
          	trace("mapShuffle", getTimer() - start);
          	
          	start = getTimer();
          	for (i = 0; i < 100000; i++)
          		tested = this.shuffle(tested);
          	trace("shuffle", getTimer() - start);
          	
          //	mapShuffle 693
          //	shuffle 368
          }
          		
          private function shuffle(array:Array):Array
          {
          	var result:Array = array.concat();
          	var helper:*;
          	var offset:int;
          	
          	for (var i:int = result.length; i; i--)
          	{
          		offset = Math.random() * i;
          		helper = result[offset];
          		result[offset] = result[i - 1];
          		result[i] = helper;
          	}
          	result.shift();
          	return result;
          }
          
          private function mapShuffle(array:Array):Array
          {
          	return array.concat().map(this.mapShuffleHelper);
          }
          
          private function mapShuffleHelper(element:*, index:int, all:Array):*
          {
          	var offset:uint = Math.random() * all.length;
          	var result:* = all[offset];
          	
          	all[offset] = all[all.length - 1];
          	all.length--;
          	return result;
          }


          А по поводу линейности - ну да, естесственно, просто я имел в виду, что эта формула не говорит о том, на сколько действительно эффективно работает реализация (выше 2 алгоритма, в принципе практически одинаковые, но одна реализация в принципе не может быть быстрее другой).
          Ответить
          • И правда, может мои знания устарели в новой версии плеера...
            Зы, а так в разы рандомнее
            private function shuffle (array:Array):Array
            {
            	var result:Array = array.concat();
            	var helper:*;
            	var offset:int;
            	var count:int = result.length;
            
            	for (var i:int = count; i; i--)
            	{
            		offset = Math.random() * count;
            		if(offset == i) offset = Math.random() * count;
            		if(offset == i) continue;
            		helper = result[offset];
            		result[offset] = result[i - 1];
            		result[i] = helper;
            	}
            	result.shift();
            	return result;
            }
            Ответить
            • > в разы рандомнее
              > в разы
              no comments
              Ответить
              • Прицепилось
                Ответить
              • Вспомнился код, где к массиву применяли три раза один и тот же метод shuffle. Для большей рандомности, так сказать.
                Ответить
              • Эх раз, ишшо раз
                рандомнее, еще рандомнее!
                Ответить
                • Возьми трубку нигодяй, домой же не попадешь
                  Ответить
                  • русский чатик, бессмысленный и беспощадный.
                    Ответить
                  • Зачем домой попадать? Ему и на говнокоде хорошо.
                    Пиздец. Какой пиздец.
                    Ответить
                    • Говнокод - сайт для всей семьи! ©
                      Ответить
                    • хорошо-то хорошо, но чичас почти времени нет тут бывать, в контраст с прошлым.
                      на работе даже гмайл заблочен (говнокодик не заблочили только потому, что одмины не в курсе)
                      а дома много других дел, а сил маловато )
                      Ответить
                • Никто не увидел в фразе сексюальной подоплеки? О_о
                  Ответить
            • Ну как бы вообще-то цель не совсем абсолютно рандомый результат... идея заключается в том, что любая пермутация элементов массива должна выпасть в равной степени вероятности :) А у вас тут даже не пермутации, довольно таки непредсказуемая штука :)
              Ответить
    • собственно говоря, я написал обсуждаемый код. Он применялся для генерации карточной колоды ( 36 - 52 элемента ). Основным требованием было получение непрерывного равномерного распределения вероятностей раскладок. Данный вариант показал наиболее стабильный результат. Скорость работы - не критично... в данном случае ( 1 перемешивание 52 карт 1 раз в 2-3 минуты... )...

      Всем спасибо за обсуждение.
      Ответить
      • Все свободны.
        Ответить
      • Отложив в сторону все остальные претензии, если в колоде максимум 52 карты - зачем вы рандом на 1000 умножали? Да и вообще, зачем вы его на что-то умножали...
        Ответить
        • > зачем вы его на что-то умножали
          "так в разы рандомнее"(ц)
          Ответить
        • число красивое...
          а если серьезно, - не помню что я конкретно думал в течении тех трех-четырех минут, почти 5 лет назад, когда писал эту функцию. Одна из идей реализации была простой : присвоить элементам рандомные весовые коэф. и отсортировать.. тем самым получить перестановку- .... либо переставлять элементы...
          в итоге было несколько вариантов, и в том контексте, более подходящим оказался тот, который обсуждается.
          Ответить
        • > зачем вы рандом на 1000 умножали?
          const TbMA = 1000;

          и десятичная система головного мозга
          Ответить
      • Да, и, если уже померять оптимальность - при размере массива в 52 элемента, ваш вариант примерно в 13 раз хуже тривиальной реализации. Как же вы так померяли?
        Ответить
        • еще раз... время выполнения не являлось главным критерием.
          Ответить

    Добавить комментарий