1. C# / Говнокод #20137

    +2

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    static void generatorPass()
            {
                string letters = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ1234567890";
                StringBuilder initPass = new StringBuilder("", 6);
    
                for (int i = 0; i < 6; i++)
                {
                    initPass.Append(0);
                }
    
                int count = 0;
    
                for (int i = 0; i < 6; i++)
                {
                    for (int a = 0; a < letters.Length; a++)
                    {
                        initPass[i] = letters[a];
    
                        for (int b = 0; b < letters.Length; b++)
                        {
                            initPass[i + 1] = letters[b];
    
                            for (int c = 0; c < letters.Length; c++)
                            {
                                initPass[i + 2] = letters[c];
    
                                for (int d = 0; d < letters.Length; d++)
                                {
                                    initPass[i + 3] = letters[d];
    
                                    for (int e = 0; e < letters.Length; e++)
                                    {
                                        initPass[i + 4] = letters[e];
    
                                        for (int f = 0; f < letters.Length; f++)
                                        {
                                            initPass[i + 5] = letters[f];
    
                                            Console.WriteLine(count++ + "]----> Проверяется пароль: [" + initPass.ToString() + "]");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

    Кажется, что то пошло не так . Как можно сделать это проще ?

    Запостил: partizanes, 06 Июня 2016

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

    • почитай как длинная арифметика делается, и используй тот же прием для перебора строки, в n-ричной системе счисления, где n - то, сколько может быть вариантов одного символа, и так можно перебирать все кобенации
      Ответить
    • Кобенации (они же пермутации) можно определить рекурсивно:
      1. Все пермутации строки из одного символа - список содержащий данную строку.
      2. Все пермутации строки из N символов - пермутации строки из N-1 символов где перед каждым символом добавлен N-ный символ из исходной строки + этот же символ добавлен в конце.
      Ответить
      • А не проще строить выборки длиной M из строки длиной N?
        Ответить
      • Но тут же не пермутации автор хотел?
        Ответить
        • Да, поэтому тут надо циклом перебирать от aaaaaa до 000000 таким же способом, как и бигинты, перенос в новый разряд короче
          Ответить
      • > пермутации) можно определить рекурсивно

        Можно, только это не пермутации, а декартово возведение в степень.
        Ответить
        • Тогда можно здействовать SQL кросс-продакт.
          Ответить
          • В этом ихнем c# linq есть. Может там как-то можно декартово произведение замутить в одну строчку?
            Ответить
            • Но наверное можно проще.
              cross(L, X) :-
                  findall(W, between(0, L, W), V),
                  findall(Z, maplist(between(0), V, Z), X).
              Ответить
            • > Может там как-то можно декартово произведение замутить в одну строчку?

              Всё равно геммор, нужно же n раз заджоинить, врядли в одно строчку получится. Я даже в хаски в одну не могу... Две надо.
              passwords :: String -> Int -> [String]
              passwords _ 0 = [""]
              passwords alphabet chars = map (:) alphabet <*> passwords alphabet (chars - 1)
              Ответить
              • UPD: таки могу
                passwords alphabet n = iterate (map (:) alphabet <*>) [""] !! n


                Вот что лямбда-зонд животворящий делает
                Ответить
                • смотрю на это и сразу цитату из хаскелевого туториала вспоминаю: "интуитивный и выразительный язык".
                  Ответить
                  • > смотрю на это
                    > интуитивный и выразительный язык
                    Только для осиляторов
                    Ответить
                    • а как будет слово "кому это нужно"?

                      я просто дальше туториала и пошел потому что фокус языка/этц мне не подходил. erlang мне намного привлекательней.
                      Ответить
                      • > кому это нужно
                        > кококо
                        Ответить
                        • Ниасилил язык?

                          Скажи что он не нужен.
                          Ответить
                          • Да, так конечно проще. "Я не осилел, потому что он не нужен. Мол не виноватая я, просто язык говно"
                            Ответить
                      • > erlang
                        въебал минус
                        Erlang is shit, SHIT!
                        Ответить
                        • динамическая питухизация
                          компилятор сожрёт даже сладкий хлеб, и принесёт его на тарелочке в рантайм
                          пирфоманс
                          records-хуекордс
                          guards -- говно
                          отсутствие чистоты
                          типичная архитектура -- спагетти из кучи процессов, ожидающих невесть что, невесть откуда
                          нельзя инфиксные операторы определять, а значит хуй вам, а не управление control flow
                          VM, которой чуть-чуть не хватает проца -- обречённая VM
                          строки
                          иерархических модулей не завезли
                          ебанатский синтаксис
                          Ответить
                • нахуя всё это???

                  sequence $ replicate n alphabet
                  Ответить
                  • Да, действительно, красиво. Я думал о чём-то таком, но почему-то вместо монад на аппликативные функторы потянуло.
                    Спасибо.
                    Ответить
              • Ну это старое правило, что если ты достал <*> и или <$> или пишешь декартово произведение, то скорее всего тебе нужна sequence или её братия
                Ответить
            • https://ideone.com/6d98tJ

              монады в моем сишарпике
              Ответить
              • ниет
                Ответить
              • Хуита ваши шарпики, то ли дело Си:

                http://melpon.org/wandbox/permlink/VXUNyy9R4lBf5sek
                Ответить
                • Вообще хуита, надо конечно typedef всунуть для функции, но там жопа с рекурсивным определением функции X = (int()(char **, X **))

                  По сути, надо чтобы функция в качестве аргумента принимала указатель того же типа, что и та сама функция, а такое рекурсивное определение типа в Си нельзя делать
                  Ответить
                • Такое надо отдельным пстом накладывать
                  Ответить
                • Кастовать указатель на функцию - УБ.
                  Ответить
                  • А как в функцию передать указатель на функцию, которая того же самого типа, и чтобы вызвать ее оттуда? Сигнатура функции будет рекурсивной. Каст из функции которая void()(void) в функцию с любой другой сигнатурой это хоть не UB?

                    Или может еще нужны какие-то извраты с memcpy или union?
                    Ответить
                    • Если честно, то я вижу, что это делают сплошь и рядом, но в стандарте пук такой есть.
                      Ответить
                    • > Или может еще нужны какие-то извраты с memcpy или union?

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

                      правда даже если так можно, выглядит как то малоюзабельно
                      Ответить
                  • да, там наверное сделали УБ потому что есть контроллеры с гарвардской архитектурой всякой, где адресация для функций отличается от адресаций на данные
                    Ответить
                    • щито?)) причем тут UB от кастинга функций с разными сигнатурами и раздельная память для кода и данных?
                      Ответить
                      • Под функции у тебя может быть 32-битные указатели, а под данные другие
                        http://stackoverflow.com/a/12358902 на стековерфлоу именно так и объясняют
                        Ответить
                        • Это объясняет почему нельзя кастить указатель на данные в указатель на функцию. А два указателя-то на функции между собою можно кастить, если они указывают на фукнции с одинаковыми сигнатурами
                          Ответить
                          • Ну если подумать... В том же досе в риалмоде например была говносегментная адресация памяти, там вообще адресное пространство процессора могло быть меньше, чем фактический объем ОЗУ (640 килобайт хватит всем, ага), и там была эта питушня с near far huge указателями, там даже huge указатель в near не запихнуть (даже просто указатель на данные, без всяких там функций). Но я это говно не застал практически https://stackoverflow.com/questions/1749904/what-is-the-difference-between-far-pointers-and-near-pointers
                            Ответить
                            • Сегментная адресация есть не только в ДОСе в риалмоде, но и в Виндовсе/Линухе в протектедмоде, если используется PAE (page address extension). В этом случае на 32-битной машине можно использовать 36-битные указатели и адресовать 64 гига памяти вместо четырёх.

                              Так что кто знает, где ещё можно столкнуться с far-указателями.
                              Ответить
                              • но формат указателей на функцию то и указателей от этого того не изменится, что заюзали сегменты.

                                хотя теоретически на какой-то говноплатформе может быть call far запрещен

                                > 36-битные указатели и адресовать 64 гига памяти вместо четырёх.
                                а как это реализоано в тулчейне? 64битными становятся указательки и оттуда выдергивается сегмент?
                                Ответить
                                • Не приходилось пользоваться этой фичей. В защищённом режиме x86 есть селекторы и смещения. Смещение — это near-адрес, к которому все привыкли.

                                  В регистрах CS, DS, ES, FS, GS хранится селектор (16-битное значение). Селектор — это номер записи в таблице селекторов. Запись содержит базовый адрес сегмента и лимит (в обычном режиме они 32-разрядные, в PAE имеют большую длину).

                                  Чтобы получить far-указатель, нужно указать и селектор, и смещение, итого на 32-битной машине 16+32 бит = 48 бит. Т. е. far-указатель — это фактически запись с двумя полями.

                                  near-указатель можно скастить в far, добавив к нему значение селектора текущего сегмента. В Винде обычно CS=DS, потому что используется «плоская» модель памяти, но в окружении с сегментированной моделью памяти селектор текущего сегмента кода и селектор сегмента данных могут не совпадать (более того, одна программа может использовать несколько сегментов), поэтому преобразование будет зависеть от контекста.

                                  Наоборот же far в near можно преобразовать только в том случае, если селектор, записанный в far-указатель, совпал селектором «текущего» контекста. В общем случае преобразование far в near невозможно. Это как у плавающего питуха порядок отрезать.

                                  https://en.wikipedia.org/wiki/Physical_Address_Extension
                                  https://ru.wikipedia.org/wiki/Дескрипторные_таблицы
                                  Ответить
                                  • Зачем ты базовые вещи рассказываешь? Я сам это юзал. Только вот на асме. Я спросил как обычно юзают в сишке сегменты смещение? Указатель всегда фар, либо чтоб юзать указатель надо юзать пару селектор:смещение? Я склоняюсь к атрибутам указателя void __FAR *, void __NEAR *, void __TINY * и тд. А вот это реально бажная нестандартная хрень, за которую хотелось бы долбить во все щели.
                                    Ответить
                                    • > Зачем ты базовые вещи рассказываешь?

                                      Чтобы набить ГК ключевыми словами и сюда пришли 15 троллей-ассемблерщиков.

                                      > Указатель всегда фар, либо чтоб юзать указатель надо юзать пару селектор:смещение?

                                      В известных реализациях были атрибуты. В Watcom C было void __far *, void __near * и void __huge *. Слово __huge использовалось только в 16-битном компиляторе и только для массивов, использующих более одного сегмента. Было ещё слово __far16, позволяющее из 32-битного кода поставить указатель на 16-битный сегмент.

                                      Наконец, были ещё «based pointers» — когда указатель хранился как near, но в декларации был указан сегмент, так что компилятор при использовании подставлял нужный сегмент. Пример:
                                      int __based(__segname("_CODE")) * iptr;

                                      В самом iptr хранится только смещение, как в near-указателе, но при использовании в сегментный регистр подставится адрес секции _CODE экзешника.

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

                                      В Борманд Си и в MSVC были аналогичные атрибуты (только у MS знаков подчёркивания было поменьше).

                                      А ещё был оператор :> для склеивания сегмента со смещением в один указатель. Обычно использовался не напрямую, а посредством макроса:
                                      #define MK_FP(__s,__o) (((unsigned short)(__s)):>((void __near *)(__o)))


                                      Но самое страшное, что __FAR и __NEAR — это макросы, которые в бессегментной модели памяти flat определены как пустое значение, чтобы код, написанный под сегментированную модель, компилировался без доработки.
                                      Ответить
                                      • > Чтобы набить ГК ключевыми словами и сюда пришли 15 троллей-ассемблерщиков.
                                        А потом придёт ещё 1 и на ГК снова не будет троллей-ассемблерщиков.
                                        Ответить
                                • В общем, если архитектура не гарвардская, то могут быть несовместимые указатели near/far, но внутри класса near или внутри класса far все указатели совместимы. Ах, да, near несовместим с near (по использованию, а не по формату/размеру), если сегмент не совпал.
                                  Ответить
                        • Короче ждем пока в стандарт завезут void*, но для функций ака func*
                          Ответить
                          • Думается мне, как бы да - насчет гарвардской архитектуры, это конечно значит, что void* может быть не совместим с void(*)(void), но это никак не говорит нам о том, что void(*)(void) не совместим с int(_cdecl*)(int), так что вместо func* можно и нужно юзать void(*)(void). Само собой там должна быть верная сигнатура с которой ты потом будешь вызывать, но это уж из другой оперы. Временно хранить int(_cdecl*)(int) в void(*)(void) вполне себе можно
                            Ответить
                            • Но в данном случе проблема как раз в том что верной сигнатуры быть не может, т.к. она рекурсивная.
                              ---
                              а хотя да, и проблемы нет. Просто надо вместо void** указатель на функцию сделать.
                              Ответить
                              • > Но в данном случе проблема как раз в том что верной сигнатуры быть не может, т.к. она рекурсивная.

                                с точки зрения гарвардской рахитектуры и сишки может.
                                Раз мы void(*)(void) юзаем вместо func*, то
                                например int (*)(int, func* recArg) записываем как int (*)(int, void(*recArg)(void)). Размеры там одинаковые, а перед вызовом arg мы все равно скастим к верной сигнатуре int (*)(int, func*), а именно к int (*)(int, void(*)(void)).
                                С точки зрения стандарта это может и лажа, но уб не бомбанет.
                                Ответить
                                • Да и с точки зрения стандарта по-моему все нормально. Там запрещено только вызывать функцию по неправильной сигнатуре, а мы вызываем по правильной.
                                  Ответить
                                  • Нет, с точки зрения стандарта мы вызываем по неправильной, ибо int (*)(int, void(*)(void)) неправильная, в отличии от int (*)(int, SomeAccuracyFunctionType*)
                                    Ответить
                                    • Если она объявлена как int (*)(int, void(*)(void)) то это и есть правильная сигнатура. А внутри она конвертит void(*)(void) в (*)(int, void(*)(void)) и тоже вызывает по правильной.
                                      Ответить
                    • На правах вброса.

                      Стандартный Паскаль совместим с гарвардской моделью, а Object Pascal (Turbo Pascal, Delphi, FPC etc) нет.

                      Почему? В стандартном Паскале тип указатель (включая pointer, который является аналогом сишного void *) мог указывать только на данные. Функцию можно было передавать в функцию, но с этим аргументом нельзя было ничего делать, кроме вызова. Пример:
                      function Integral(a, b: Real; function F(x: Real): Real): Real;
                        var x, result: Real;
                        begin
                          result := 0;
                          x := a;
                          while x <= b - step do
                            begin
                              result := result + F(x + step/2) * step;
                              x := x + step
                            end;
                          Integral := result
                        end;
                      begin
                        Writeln(Integral(5, 10, sin))
                      end.

                      То есть вроде как и можно было сослаться на функцию (мы сослались на sin), но поместить её адрес в переменную типа pointer нельзя. И нельзя объявить переменную, указывающую на функцию, хотя параметр функции, указывающий на функцию, объявить можно (в данном случае мы объявили F). Данный и код надёжно разделены, враг не пройдёт.

                      А как сделано в Object Pascal? Ключевое слово function/procedure у параметра функции теперь использовать нельзя, но его можно использовать в декларации типа.
                      type
                        myfunc = function (x: Real): Real;
                      function Integral(a, b: Real; F: myfunc): Real;
                        var x, result: Real;
                        begin
                          result := 0;
                          x := a;
                          while x <= b - step do
                            begin
                              result := result + F(x + step/2) * step;
                              x := x + step
                            end;
                          Integral := result
                        end;
                      begin
                        Writeln(Integral(5, 10, sin))
                      end.

                      Мы сделали тайпдеф и у нас F можно использовать как любую переменную. Мы можем значение параметра F скопировать в «несемантический» указатель типа pointer и наоборот:
                      var
                        p: ponter;
                        i: integer;
                        f: myfunc;
                      begin
                        f := sin;
                        p := @i;
                        p := f;
                        f := p;
                      end.

                      Pointer может хранить и указатели на данные, и указатели на код. Совместимость с гарвардской архитектурой в Object Pascal утеряна.
                      Ответить
                  • а в каком месте стандарта это написано?
                    Ответить
                    • The behavior is undefined in the following circumstances:
                          A pointer is used to call a function whose type is not
                          compatible with the pointed-to type (6.3.2.3).
                      Ответить
                      • Так это если "is not compatible with the pointed-to type ".

                        Довольно логично иметь UB в случае каста указателя на функцию void foo(int) к указателю на функцию int bar(const char*) с последующим вызовом последней.
                        Ответить
                        • For two function types to be compatible, both shall specify compatible return types.

                          Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types. If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)


                          В коде по ссылке - там вообще даже не указатель на функцию, а void**. Т.е. компилятор вправе форматнуть Ц, если захочет.
                          Ответить
                          • dlsym кстати возвращает void *
                            http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html
                            Так что позиксу срать на сишные стандарты
                            Ответить
                            • > позиксу срать на сишные стандарты
                              Конечно. Си же кроссплатформенный, а позикс только на никсах.
                              Ответить
                          • >В коде по ссылке - там вообще даже не указатель на функцию, а void**.

                            В коде по ссылке там void** - дважды указатель на void - но вот тут
                            ( *(int(*)(char **, void **)) *(func_ptr-1) )(arr_ptr-1,func_ptr-1);
                                                          ^^^^^^^^^^^^^
                                                          |

                            от него отнимаем 1 и он единожды разыменовывается, в итоге получается просто void*
                            который потом тут
                            ( *(int(*)(char **, void **)) *(func_ptr-1) )(arr_ptr-1,func_ptr-1);
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^

                            Кастуется в указатель на функцию, принимающую char **, void ** и возвращающую int. Ну и потом я это дело вызываю с аргументами arr_ptr-1,func_ptr-1 Так что в функцию я кастую не void** а void*
                            Ответить
            • Как-то так:
              string letters = "abc";
              int passwordLength = 3;
              
              var passwords = letters.Select(c => c.ToString());
              for (int i = 1; i < passwordLength; i++)
              {
                  passwords = passwords.SelectMany(c1 => letters, (c1, c2) => c1 + c2);
              };

              В одну строчку не сделать.
              Ответить
    • def generate_parol(bukvi, size):
          return "".join(random.choice(bukvi) for _ in xrange(size))
      
      def generate_parols(na):
          piton = set()
          pidar = string.ascii_letters
      
          while len(piton) < len(pidar) ** na:
              piton.add(generate_parol(pidar, na))
      
          return piton
      
      for parol in generate_parols(6):
          print parol
      Ответить
    • Array(64).join(".").split("").map((a, b) => b).map((a) => ("0000" + a.toString(32)).replace(/0+(.{5})$/, "$1"));

      Тоже в одну строчку.
      Ответить
    • O(n^7)? Ого, больше только O(n!), пожалуй.
      Ответить
      • Опять хвастаетесь у кого больше?
        Ответить
        • У гипероператора всё равно больше.

          https://ru.wikipedia.org/wiki/Гипероператор

          https://ru.wikipedia.org/wiki/Быстрорастущая_иерархия
          Ответить
    • К слову, какие вообще бывают способы реализации циклов второго порядка в императивных ЯП? Ну как тут, когда цикл вложен в цикл N раз?

      Сходу такие варианты:
      1. Рекурсивный вызов функции.
      2. Редукция до одного цикла. Общий счётчик, из которого частичные счётчики получаются делением с остатком (если диапазоны фиксированы и известны).

      Что ещё можно придумать?

      И ещё вопрос. Бывают циклы высших порядков?
      Ответить
      • Yield какой-нибудь?

        Ну и перевод на конечный автомат никто не отменял. Yield это просто сахарок для этого.
        Ответить
      • for(size_t i = 0; i < len; ++i)
        {
          size_t j[len];
          for(j[i] = 0; j[i] < len2; ++j[i])
          {
            ...
          }
        }
        Ответить
        • Чего-то тут не хватает... Этот цикл просто каждую "цифру" крутит.

          O(len*len2) вместо O(len2^len).
          Ответить
          • А, ну да. Тут надо стек с хренью делать. Это будет по-сути рекурсия
            Ответить
          • https://wandbox.org/permlink/JbjrIlMNMPEZfoJ4 вот так можно
            Ответить
      • А можно в «Nim» наметушить цикл, который раскрывается во вложенные циклы, если есть доступ к «AST» и можно использовать шаблоны, которые типа как дефайны в сишке.
        Ответить
        • Я думаю, что можно.

          Сделать какую-нибудь компайл-тайм питушню, которая принимает массив интервалов для каждого счётчика и массив блоков кода / функций, которые будут выполняться на каждой итерации... и потом всё это будет раскрываться хитрым способом в цикл высшего порядка.
          Ответить
        • > А можно в «Nim» наметушить цикл, который раскрывается во вложенные циклы, если есть доступ к «AST»

          Хуйня этот ваш "доступ к \"AST\"", надо чтоб гомоиконность. Вот в D честно признались https://govnokod.ru/27615#comment664409 что им нехватает гомоиконности как в LISP. Признались ли в этом разрабы "Nim"?
          Ответить
          • Зачем гомоиконность, если есть доступ к «AST» и вычисления на этапе компиляции?
            Ответить
            • Потому что если просто доступ к AST то тогда хуй поймешь, как синтаксис отображается в AST. Т.е. нельзя удобно работать с этим вот AST потому что неочевидно, что вот этот синтаксис соответствует такому-то AST
              Ответить
              • Не вижу и не понимаю такую проблему. Или ты хочешь WYSIWYG?
                Ответить
                • В гомоиконщине у тебя код и данные выглядят одинаково, ты можешь его обработать обычными функциями для данных, вывести для отладки и т.п.

                  В случае с трансформацией AST тебе надо заучивать в какую AST ноду превращается каждый элемент синтаксиса.
                  Ответить
    • Какая комбинаторика ))
      Ответить

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