Змея / Говнокод #18239 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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 KolesnichenkoDS, (Updated )

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

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

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

    Боже мой, да всем на тебя насрать
    Ответить
        • У меня есть только кусок говнокодика в функци анальном стиле. Рекурсия, ФВП и ни грамма переменных:
          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 -.
            Ответить
  • Я пересел на сиденье рядом с ним, он взял мою руку и положил ее на упакованный, пока ещё, в джинсы член. Ладонь почувствовала, как под ней что-то стремительно набухает, второй рукой я начал гладить его волосатую грудь спускаясь все ниже и ниже. И, наконец, мои пальцы скользнули под пояс джинсов. Я уже капитально завёлся, да и он начал постанывать, откинув голову назад.
    Ответить

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

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8