1. Ruby / Говнокод #18439

    −114

    1. 1
    2. 2
    3. 3
    def days(index)
      ((15662003>>(2*(index-1)))&3) + 28
    end

    Вычисление количества дней в месяце по индексу.

    Запостил: yuryroot, 06 Июля 2015

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

    • олимпиадник писал
      Ответить
      • Какой к чёрту олимпиадник?
        ЦарьПрограммист на Си может писать на любом языке как на Си.
        Ответить
        • это какой-то или очень старый сишник, или сишник микроконтроллерщик
          Ответить
          • Знаешь чем отличается микроконтроллерщик он контроллерщика?
            Ответить
            • я так спизданул, ради красного словца

              а в чем разница? микроконтроллерщик пишет на VHDL/Verilog?
              Ответить
              • Микроконтроллерщик пишет ((15662003>>(2*(index-1)))&3) + 28, контроллерщик пишет UndoRedoSubTabMicroWrapperRolrollerContr oller (мой говнокод такой потёрли)
                Ответить
                • Это контроллерщик это какой-то ни то Win32API, ни то Cocoa ни то Java программист
                  Ответить
    • Надо будет вызывать days(10_000_000_000_000), просто из принципа.
      Ответить
      • А что не так? Разве не 28 будет?
        Ответить
        • Ох, слепое я говно. Я сначала подумал, что там bignum взорвётся, но нет.
          Ответить
    • Number(15662003).toString(4)
      "323233232303"  //radix 4

      Думаю в такой записи код становится понятным и самоочевидным.
      Ответить
    • Думаю этот код слишком понятен и даже сопровождаем, если записать lookup table in base-4.

      Пока лень думать, но вот прототип, с возможностью оптимизации
      !!(i-2)*(2+!!(5546&(1<<i)))+28
      Ответить
    • v2. Убираем ненужную константу
      !!(i-2)*(2+(i>>3^i&1))+28
      Ответить
    • v3. Как бы получше записать последнюю часть с минусом?
      30+(i>>3^i&1)-!(i-2)*i

      Тернарник будет короче, но это читерство, ибо БРАНЧИНГ
      Ответить
      • Что-то слишком легко читаться стало. Логика насквозь просвечивает.
        Ответить
        • >Что-то слишком легко читаться стало.
          :))

          v4. Избавился от умножения.
          30+(i>>3^i&1)-((1<<(i-1))&2)


          Хотел сделать красивее: 32-((1<<i)&4)-...
          Февраль становится проще, но троеточие сильно усложняется.
          f=(1<<i)&4;
          32-f-((2-(i>>3^i&1))^(f>>1))
          Ответить
        • > Что-то слишком легко читаться стало

          Добавьте поддержку високосного года.
          Ответить
          • 30+(m>>3^m&1)-((1<<(m-1))&2)*(((y|(y>>1))&1)^1&(+!(y%100)^(!!(y%400))))
            Ответить
            • Ну вот. Пишем тесты, катим в прод.
              Ответить
              • Не по-царски же. И по-прежнему слишком очевидно.
                Надо сначала деление на константы убрать, а то будет тупить!
                Ответить
            • fix
              30+(m>>3^m&1)-( ((1<<(m-1))&2) >> (((y|(y>>1))&1)^1&(!(y%100)^(!!(y%400)))) )
              Ответить
              • https://godbolt.org/g/qY65pV
                Ответить
                • Эх, я сначала подумал конпелятор анроллнул формулу в lookup.
                  Ответить
                  • Хах! До меня не сразу дошло что f(int,int) на 1 строчку короче чем f2 (int,int)+ lookup table.
                    Ответить
                    • https://godbolt.org/g/SZnb7u
                      Хм, интересно, можно ли существенно зожать асмовыхлоп с учётом високосного года?
                      Ответить
                      • По ссылке дизасм не обновился
                        Ахаха, смотрите свищ таки в lookup-константу запихунл как и у меня в v1 http://govnokod.ru/18439#comment402263

                        >!!(i-2)*(2+!!(5546&(1<<i)))+28
                        sal     rdx, cl
                                test    edx, 2773
                        
                        2773*2=5546
                        
                        Number(2773).toString(2)
                        "101011010101"
                        Ответить
                • > jne .L4
                  > jne .L3
                  > jne .L4
                  Говорю же: намеренно избегал тернарников => условных переходов. БРАНЧИНГ
                  Ответить
                  • А он не сможет запредиктить такие джампы, или хотя-бы выполнить их в OOE чтобы не сильно угробить перформанс?
                    Ответить
                    • Сможет, в этом и ржака.
                      Причём за счёт раннего выхода jmpы наверняка будут работать лучше (много инструкций скипаем).
                      Ответить
                      • и тут надо обратить внимание на то, что это код на руби

                        MRI наверняка умеет JIT, но я не знаю не перефигачит ли он ваш код
                        Ответить
              • Интересно было бы что-то вроде компилятора Malbolge использовать для таких штук. Или какие-нибудь квантовые питухи. На входе нормальная программа, на выходе - её оптимизированный криптоэквивалент.
                Ответить
                • Дык нужно просто компилировать в какой-нить тьюринг-полный брейнфак#, где не будет условных переходов, делений и прочей питушни, замедляющей программы.

                  По сути это может быть даже какой-то ранний RISC-асм со сдвигами, сложениямии и побитовыми инструкциями.

                  Вот пидорасить lookup-таблицы в нечитаемый формульный вид — тут вопрос, и это основная часть творчества. Но и это автоматизируется.

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

                  i+((i&(i>>1))&1)*i+(((i>>2)&1)<<4)+(i&4)+((((i>>2)&i)<<5))*3+((i&(i>>1))&2)*347+((i&(i>>1)&(i>>2))&1)*4217-((i>>2)&i)

                  Осторожно! Данные формулы могут быть опасны для вашего здоровья
                  Ответить
                  • Упрлс, нпрмер
                    f1= i=> i+((i&(i>>1))&1)*i+(((i>>2)&1)<<4)+(i&4)+((((i>>2)&i)<<5))*3+((i&(i>>1))&2)*347+((i&(i>>1)&(i>>2))&1)*4217-((i>>2)&i)
                    f2= i => f1(i) *!(i>>3)+(f1((i&8)-1))*(i&8)*((i>>3)+((i&1)<<3))

                    for (i=1;i<10;++i){console.log(i,f2(i))}
                    Ответить
                    • Ты за размер кода упарываешься? А если в плавающем питухе попробовать?
                      Ответить
                      • Нет, это просто упоротая branchless-хуита.

                        Давным-давно, когда я учился в универе, нам препод рассказывал историю.
                        Будто в 70х или 80х был у него был какой знакомый, который по идейным соображениям начисто отвергал циклы.
                        То ли он считал что "они замедляют программы", то ли хз. Короче loop considered harmful.

                        Мы еще тогда знатно поржали с него. Но я вот подумал: можно же написать программу не только без циклов (джампов назад), но и вообще без условных переходов.
                        Ответить
                      • Что такое программа? Грубо говоря операция, которая как-то модифицирует вектор ОЗУ.

                        Фактически её можно рассматривать как функцию, считывающую ооочень длинное число a и записывающее вместо него b.

                        RAM_state=program(RAM_state)

                        Потому любой конечный алгоритм (с остановом), наверянка можно превратить в длииииную формулу, которая преобразует память.
                        Ответить
                        • Ну ты осторожнее, а то тезис Черча-Тьюринга случайно выведешь
                          Ответить
                          • Вывел тебе за щеку, проверь.
                            Ответить
                          • > а то тезис Черча-Тьюринга случайно выведешь

                            Хаха! Как раз и подумал что в итоге редуцирования и обфускации кода прийду к чему-то похожему на нумералы Чёрча.

                            Однако проблема всех этих лямбда-питухов в замене циклов на рекурсию. Y-кобенатор цикла не слаще.
                            Ответить
                            • Моё понимание всей этой еботни закончилось с появлением оператора минимизации. До сих пор хз как в здравом уме такое можно было придумать.
                              Ответить
                              • typedef unsigned long uint;
                                
                                uint inc(uint i) {
                                    return i+1;
                                }
                                uint dec(uint i) {
                                    return i-1;
                                }
                                uint add(uint a, uint b) {
                                    return 0==b ? a : add(inc(a),dec(b));
                                }
                                
                                inline uint _mul(uint a, uint b, uint r) {
                                    return 0==b ? r : _mul(a,b-1,r+a);
                                }
                                
                                uint dec_mul(uint a, uint b, uint r) {
                                    return 0==b ? r : _mul(a,dec(b),r+a);
                                }
                                
                                uint mul(uint a, uint b) {
                                    return _mul(a,b,0);
                                }
                                Ответить
                                • Это примитивно-рекурсивные функции.
                                  Реализуй минимизацию.

                                  P.S. Или mul - это оно и есть?
                                  Ответить
                                  • >Или mul - это оно и есть?

                                    Мне нравится как в лямбдопитушатной теории из мельчайшей, простейшней, базовой функции и капельки рекурсии выводят всю арифметику.

                                    И еще как шланг это хавает и превращает в оптимизированный x64.
                                    Ответить
                    • Вот что бывает, когда выпиваешь с Настенькой.
                      Ответить
                      • Вообще по уму должен быть компилятор на уровне искусственного интеллекта. Чтоб циклы и рекурсии преобразовались в прямые формулы.

                        Ты ему цикл
                        var i,k=10000000,s=0;for (i=1;i<k;s+=i,i++); 
                        //оно - формулу
                        console.log(s,(k*k-k)/2)

                        Причём без эвристик и заранее заложенных случаев.
                        Ты ему цикл
                        var i1,i2; 
                        for (i1=1,i2=1;i2<1000000000;i2+=i1,i1+=i2); console.log(i2);

                        Оно тебе формулу Бине
                        n=45,phi=(1+Math.sqrt(5))/2,Math.round ( (Math.pow(phi,n)-Math.pow(-phi,-n))/(2*phi-1))


                        Ты ему факториал, оно тебе гамма-функцию.
                        Ответить

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