1. Python / Говнокод #18239

    −123

    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
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    88. 88
    89. 89
    90. 90
    91. 91
    92. 92
    93. 93
    94. 94
    def run(code):
        
        def func(operator):
            from functools import reduce
            
            add    = lambda a, b: float(a) + float(b)
            mul    = lambda a, b: float(a) * float(b)
            div    = lambda a, b: float(a) / float(b)
            deduct = lambda a, b: float(a) - float(b)
            
            d = {
                '+': lambda arr: reduce(add,    arr),
                '*': lambda arr: reduce(mul,    arr),
                '/': lambda arr: reduce(div,    arr),
                '-': lambda arr: reduce(deduct, arr)
            }
            
            return d[operator]
        
        def lex(token):
            if token in ('+', '-', '/', '*', '%'):
                return "operator"
            elif token == '(':
                return "lbracket"
            elif token == ')':
                return "rbracket"
            elif token[0].isalpha():
                return "name"
            elif token[0] == token[-1] and token[0] in ('"', "'"):
                return "string"
            else:
                try:
                    float(token)
                    return "number"
                except:
                    raise ValueError
                
        def getArgs(words):
            args = []
            arg = []
            i = 0
            for word in words[2:]:
                if word == '(':
                    i += 1
                    arg.append(word)
                elif word == ')':
                    i -= 1
                    arg.append(word)
                    if i == 0:
                        args.append(arg)
                        arg = []
                elif i == 0:
                    arg.append(word)
                    args.append(arg)
                    arg = []
                else:
                    arg.append(word)
            return args
        
        def expr(words):
            args = getArgs(words)
            args_ = []
            for arg in args:
                if len(arg) == 1:
                    args_.append(arg)
                else:
                    args_.append(expr(arg))
            
            if lex(words[1]) == "operator":
                return func(words[1])(list(map(lambda a: (type(a) in (list, tuple) and a[0]) or a, args_)))
    
        lines = code.split("\n")
        for line in lines:
            word = ''
            words = []
            chars = tuple(line)
            
            for i in tuple(line):
                
                if i in ('(', ')'):
                    if word: words.append((word, lex(word)))
                    words.append((i, lex(i)))
                    word = ''
                
                elif i == ' ':
                    if word: words.append((word, lex(word)))
                    word = ''
                    
                else:
                    word += i
                    
            if word: words.append((word, lex(word)))
        words_ = list(map(lambda arr: arr[0], words))
        print(expr(words_))

    функция считает лиспоподобные арифметические выражения, например так:

    run("(+ 2 (* 3 4))") # 14

    в своё оправдание могу лишь сказать, что писал это в электричке на планшете

    Запостил: KolesnichenkoDS, 27 Мая 2015

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

    • А чо? Если оставить в стороне вопрос о применении этого кода, учесть что кодилось в электричке, даже приятно читать. Уберите это с ГК, это не ГК!
      Ответить
    • Хоть и говнокод, но форматирование мемберов прикольное. Питон, в таком исполнении, будто бы даже и не говно.
      Ответить
    • Можешь прокачать до простейшего лиспоподобного языка ;)
      Ответить
    • в null написал:
      >> в своё оправдание могу лишь сказать, что писал это в электричке на планшете

      Ой ты моя лапочка, давай я тебя обниму да поглажу...

      Боже мой, да всем на тебя насрать
      Ответить
      • > в null написал:
        Пофиксил Подавил в v 1.2.1.
        Ответить
        • С тебя бутылка кетчупа за тестирование
          Ответить
          • У меня есть только кусок говнокодика в функци анальном стиле. Рекурсия, ФВП и ни грамма переменных:
            function run(expr, old) {
              return old === expr ?
                +expr :
                run(expr.
                  replace(/\(([-+*/%])\s*(\d+(?:\s+\d+)*)\s*\)/g, function(_, op, args){
                    return ' ' + args
                      .split(/\s+/)
                      .reduce({
                        '+': function(a, b){ return +a + +b; },
                        '-': function(a, b){ return +a - +b; },
                        '*': function(a, b){ return +a * +b; },
                        '/': function(a, b){ return +a / +b; },
                        '%': function(a, b){ return +a % +b; }
                      }[op]) + ' ';
                  }), expr);
            }
            
            console.log(['(+ 2 2 2)', '(*(+4 4)(+ 6 6))'].map(run)); // [6, 96]
            Ответить
            • Я не понял вот эту строчку:
              /\(([-+*/%])\s*(\d+(?:\s+\d+)*)\s*\)/g
              Ответить
              • http://govnokod.ru/18240#comment287483
                Матчит подстроку, начинающуяся на скобку, после которой идёт один из символов -+*/% (1), затем пробелы по вкусу, затем последовательности цифр, разделённые более, чем одним пробелом (2), затем пробелы по вкусу и закрывающая скобка. Это регулярное выражение также захватывает символ (1) и строку из чисел, разделённую пробелами (2).
                Ответить
                • > более, чем одним пробелом
                  не менее, чем одним пробелом

                  > пробелы по вкусу
                  т.е. если невкусно, их может и не быть

                  bormand в http://govnokod.ru/18239#comment287489 написал:
                  > несколько натуральных десятичных чисел (возможно, что ни одного)
                  как минимум одно должно быть
                  Ответить
              • Открывающая круглая скобка, за которой следует первое захватываемое выражение, представляющее собой один из следующих символов: плюс, минус, звёздочка, косая черта, процент; за которым могут следовать пробельные символы; за которыми следует второе захватываемое выражение, которое представляет собой несколько натуральных десятичных чисел (возможно, что ни одного), разделённых одним или несколькими пробельными символами; за которым могут следовать пробельные символы; за которыми следует закрывающая круглая скобка.
                Ответить
            • Раз уж все кидаются своим говном - смотрите какую какаху откопал!

              http://ideone.com/3GxzkY


              Самое примечательное, что проверок на ошибки нет в принципе
              Ответить
            • Хреновые у вас парсеры, даже (~=#$хуй-+-пизда-+-джигурда$#=~ 42 100500) не разберут ;)

              Вот как в настоящей scheme: Identifiers may denote variables, keywords, or symbols, depending upon context. They are formed from sequences of letters, digits, and special characters. With three exceptions, identifiers cannot begin with a character that can also begin a number, i.e., they cannot begin with ., +, -, or a digit. The three exceptions are the identifiers ..., +, and -.
              Ответить
    • Я пересел на сиденье рядом с ним, он взял мою руку и положил ее на упакованный, пока ещё, в джинсы член. Ладонь почувствовала, как под ней что-то стремительно набухает, второй рукой я начал гладить его волосатую грудь спускаясь все ниже и ниже. И, наконец, мои пальцы скользнули под пояс джинсов. Я уже капитально завёлся, да и он начал постанывать, откинув голову назад.
      Ответить

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