1. C++ / Говнокод #20365

    +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
    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
    // p2.cpp : Defines the entry point for the console application.
    //   Язык Visual C++ 7.0
    //   Консольное приложение
    //   13.07.2016
    
    #include "stdafx.h"
    #include <conio.h>
    
    int aa (int, int, int);
    void ab (int);
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int a, b, c, d, e;
    	int f;
    
    	for (a = 0; a < 4; a++)
    		for (b = 0; b < 4; b++)
    			for (c = 0; c < 4; c++)
    				for (d = 0; d < 4; d++)
    					for (e = 0; e < 4; e++)
    					{
    						f = aa (1, a, 2);
    						f = aa (f, b, 3);
    						f = aa (f, c, 4);
    						f = aa (f, d, 5);
    						f = aa (f, e, 6);
    
    						if (f == 35)
    						{
    							printf ("((((1 "); ab (a);
    							printf ("2) "); ab (b);
    							printf ("3) "); ab (c);
    							printf ("4) "); ab (d);
    							printf ("5) "); ab (e);
    							printf ("6 = 35.\n");
    						}
    					}
    
    	getch ();
    	return 0;
    }
    
    
    int aa (int a, int b, int c)
    {
    	switch (b)
    	{
    		case 0: return a + c;
    		case 1: return a - c;
    		case 2: return a * c;
    		case 3: return a / c;
    	}
    
    	return 0;
    }
    
    void ab (int a)
    {
    	switch (a)
    	{
    		case 0: printf ("+ "); break;
    		case 1: printf ("- "); break;
    		case 2: printf ("* "); break;
    		case 3: printf ("/ "); break;
    	}
    }

    Задача: В написанном выражении ((((1 ? 2) ? 3) ? 4) ? 5) ? 6 вместо каждого знака ? вставить знак одного из четырёх арифметических действий: +, -, *, / так, чтобы результат вычислений равнялся 35.

    Запостил: FrontlineReporter, 13 Июля 2016

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

    • int aa (int a, int b, int c)

      А у автора богатое воображение.
      Ответить
      • fixed:
        namespace Enterprise
        {
        enum SimpleArithmeticOperation {
        	Operation_Addition = 0,
        	Operation_Substraction,
        	Operation_Multiplication,
        	Operation_Division,
        };
        
        class SimpleArithmeticOperand
        {
        public:
        	SimpleArithmeticOperand( int Operand );
        	virtual ~SimpleArithmeticOperand();
        private:
        	int m_Operand;
        };
        
        class SimpleArithmeticOperation
        {
        public:
        	SimpleArithmeticOperand( SimpleArithmeticOperation Operation );
        	virtual ~SimpleArithmeticOperation();
        private:
        	SimpleArithmeticOperation m_Operation;
        };
        
        typedef ::Advanced::Primitive::Simple::Enhanced::AbstractFactoryTemplateType<SimpleArithmeticOperand> SimpleArithmeticOperandFactory;
        typedef ::Advanced::Primitive::Simple::Enhanced::AbstractFactoryTemplateType<SimpleArithmeticOperation> SimpleArithmeticOperationFactory;
        
        enum BinaryOperationOperandType {
        	Operand_Left = 0,
        	Operand_Right = 1,
        	Operand_Max = 2,
        };
        
        class AdvancedDynamicOperationCalculator : public IRunnable, public IASyncSafe, public ISerializable
        {
        public:
        	AdvancedDynamicOperationCalculator();
        	virtual ~AdvancedDynamicOperationCalculator();
        	AdvancedDynamicOperationCalculator( const SimpleArithmeticOperand& OperandLeft, const SimpleArithmeticOperand& OperandRight );
        	AdvancedDynamicOperationCalculator( const SimpleArithmeticOperand& OperandLeft, const SimpleArithmeticOperation& Operation, const SimpleArithmeticOperand& OperandRight );
        	void SetOperand( BinaryOperationOperandType OperandType, const SimpleArithmeticOperand& OperandLeft );
        	void SetOperation( const SimpleArithmeticOperation& Operation );
        	const SimpleArithmeticOperand& GetResult() throw(ResultNotReadyException, DivisionByZero);
        	virtual void Execute();
        private:
        	bool m_HasResult;
        	bool m_DivisionByZero;
        	std::vector<SimpleArithmeticOperand> m_OperandVec;
        	SimpleArithmeticOperand m_Result;
        	SimpleArithmeticOperation m_Operation;
        };
        
        }
        Ответить
        • в каком ебучем стандарте пространства имен, классы и методы начинаются с заглавной?
          Ответить
          • Qt.

            > методы
            З.Ы. А ну раз ещё и методы - то майкрософт и его друзья.
            Ответить
            • Qt-шный слизан подчистую с какого-то другого, найти только не могу. Только там настоятельно рекомендуют начинать функции и имена переменных с маленькой буквы.
              Ответить
            • Не гони, там с заглавной начинаются свойства.
              Ответить
          • В го всё экспортящееся начинается с заглавной.
            Ответить
          • FLTK
            Ответить
        • Где найти реализацию?
          Ответить
          • у меня же. лицензия стоит $200 в месяц per seat. но для друзей с ГК я так и быть сделаю скидку - всего лишь $150! не упускайте шанса!!
            Ответить
      • Учился на обфусцированном коде.
        Ответить
    • Деление в условиях задачи по каким правилам работает? Как в сишке возвращает частное, или как в математике возвращает дробь?
      Ответить
    • #include "stdafx.h"
      #include <conio.h>
      
      int _tmain(int argc, _TCHAR* argv[])
      {
      	printf("((((1 + 2) + 3) * 4) + 5) + 6 = 35.\n");
      	getch ();
      	return 0;
      }

      я сделялъ
      Ответить
    • ... я уже боюсь спрашивать как JSники это решат. догадываюсь что будет возвращать 35 даже если не вызывать эту функцию.
      Ответить
      • Да как обычно. Monkey-patching прототипа, хуяк-хуяк - готовенько!
        Ответить
    • Где здесь С++? Где перегрузка функций, функторы, использование стандартной библиотеки (std::plus...), контейнеры, алгоритмы, шаблоны? Где буст, в конце-концов?
      Ответить
      • ...и шаблоны с auto

        (вспомнился анекдот "и шапочку")
        Ответить
      • Ну ты б еще спросил где GUI в Visual C++
        Ответить
      • > где здесь С++?
        я зделяль
        #include <algorithm>
        #include <functional>
        #include <iostream>
        #include <vector>
        #include <string>
        
        int main() {
            std::vector<int> nums = {1, 2, 3, 4, 5, 6};
            std::vector<std::pair<std::function<int(int, int)>, std::string>> all_ops = {
                {std::plus<int>(),       "+"},
                {std::minus<int>(),      "-"},
                {std::multiplies<int>(), "*"},
                {std::divides<int>(),    "/"},
            };
            std::vector<std::string> ops;
            std::function<void(int, size_t)> find = [&](int r, size_t i) {
                if (i == nums.size()) {
                    if (r == 35) {
                        std::cout << std::string(ops.size(), '(') << nums[0];
                        for (size_t i = 0; i < ops.size(); i++) {
                            std::cout << " " << ops[i] << " " << nums[i + 1] << ")";
                        }
                        std::cout << std::endl;
                    }
                    return;
                }
                for (const auto& op : all_ops) {
                    ops.push_back(op.second);
                    find(op.first(r, nums[i]), i + 1);
                    ops.pop_back();
                }
            };
            find(nums[0], 1);
            return 0;
        }
        Ответить
    • op(A, '+', B, Res) :- Res is A + B.
      op(A, '-', B, Res) :- Res is A - B.
      op(A, '*', B, Res) :- Res is A * B.
      op(A, '/', B, Res) :- Res is A / B.
      
      place_ops((((((1, A, 2), B, 3), C, 4), D, 5), E, 6)) :-
          op(1, A, 2, A1),
          op(A1, B, 3, B1),
          op(B1, C, 4, C1),
          op(C1, D, 5, D1),
          op(D1, E, 6, 35).
      
      ?- place_ops(X).
      X = (((((1, (+), 2), (+), 3), (*), 4), (+), 5), (+), 6) ;
      X = (((((1, (+), 2), (*), 3), (*), 4), (+), 5), (-), 6) ;
      X = (((((1, (*), 2), (*), 3), (*), 4), (+), 5), (+), 6) ;
      false.
      Ответить
      • `:-` - пролог что ли?
        Ответить
        • В каком ещё языке есть такая пиписька?
          Ответить
          • > В каком ещё языке есть такая пиписька?

            В сишечке же.
            ops :- 1;
            Вы что, не знали, что сишечка испокон веков поддерживала логическое программирование?
            http://ideone.com/ByOjSC
            Ответить
      • Prolog Curry

        ops = ("+", (+))
        ops = ("-", (-))
        ops = ("*", (*))
        ops = ("/", div)
        
        f (s, v) b = ("(" ++ s ++ op ++ show b ++ ")", f v b)
          where (op, f) = ops
        
        main | v == 35 = s 
          where (s, v) = foldl f ("1", 1) [2..6]


        "(((((1+2)+3)*4)+5)+6)"
        "(((((1*2)*3)*4)+5)+6)"
        "(((((1+2)*3)*4)+5)-6)"
        Ответить
    • ops = [("+", (+)), ("-", (-)), ("*", (*)), ("/", quot)]
      
      display nums ops = glue (map show nums) (map fst ops)
        where glue (x:xs) ys = (replicate (length ops) '(') ++ x ++ " " ++ glueRest xs ys
              glue _ _ = ""
              glueRest (x:xs) (y:ys) = y ++ " " ++ x ++ ") " ++ glueRest xs ys
              glueRest _ _ = ""
      
      solutions nums target = map (\f -> display nums f) fs
        where cs = sequence $ replicate (length nums - 1) ops
              fs = filter (\o -> apply nums o == target) cs
              apply (x:y:xs) ((_, op):fs) = apply ((op x y):xs) fs
              apply [x] [] = x
      
      
      main = sequence_ $ map putStrLn $ solutions [1..6] 35
      Самое сложное — правильно отобразить результат.
      Ответить
      • def decompose_35():
            ops = ['+', '-', '*', '/']
            mask = "((((1 %s 2) %s 3) %s 4) %s 5 %s 6)"
            for perm in itertools.product(ops, ops, ops, ops, ops):
                if eval(mask % perm) == 35:
                        print mask % perm, "= 35"

        Даже на Питоне, и то лучше выглядит.
        Ответить
        • Пф, такой хардкодный анскилл я тоже могу запилить
          import Text.Printf
          
          ops = [("+", (+)), ("-", (-)), ("*", (*)), ("/", quot)]
          
          solve = map (display . map fst) $ filter (ok . map snd) $ sequence $ replicate 5 ops
            where ok      [a, b, c, d, e] = 1 `a` 2 `b` 3 `c` 4 `d` 5 `e` 6 == 35
                  display [a, b, c, d, e] = printf "(((((1 %s 2) %s 3) %s 4) %s 5) %s 6)" a b c d e
          
          main = sequence_ $ map putStrLn solve
          Предыдущий вариант принимает произвольное кол-во произвольных чисел, потому менее прозрачен.
          Ответить
    • > conio.h
      > printf
      Пожалуй, это самый сишный говнокод, который я видел в разделе C++. Где, ну вот где, во имя всех святых хуёв, здесь C++, FrontlineReporter?!
      Ответить
    • <yaomingface> ((((1+2)*3)*4)+5)-6 </yaomingface>
      Ответить
    • Ну и как же без
      (defun decompose-35 ()
        (let ((ops #(+ - * /)))
          (labels ((%test (a b c d e) (eval `(,e (,d (,c (,b (,a 1 2) 3) 4) 5) 6))))
            (loop :for i :below (expt 4 5)
               :for args = (loop :for j :from -8 :upto 0 :by 2
                              :collect (aref ops (logand (ash i j) 3)))
               :when (= (apply #'%test args) 35)
               :do (apply 'format t "~&(((((1 ~s 3) ~s 3) ~s 4) ~s 5) ~s 6)" args)))))
      Ответить
    • генетический алгоритм надо.
      Ответить
      • Немного думал вчера над этим, но если как геном использовать вектор операций, а как фитнесс-функцию, например -- квадрат разности с 35, то пространство поиска будет шибко негладким, так что генетика скорее всего выродится в простой random walking, либо остановится где-то в локальном минимуме. Кроссинговер точно будет неэффективен: две половинки, более-менее близких к искомому значению, при кобенации всегда дадут нечто худшее.
        Хотя это чистая интуиция, пруфов не будет.
        Ответить
    • Блок-схемку ещё, бывает, к таким задачам надо
      ┌─────────┐
      │ начало  │
      └────┬────┘
      ┌────┴────┐
      │ ввод    │
      │ данных  │
      └────┬────┘
      ┌────┴────┐
      │ хуяк-   │
      └────┬────┘
      ┌────┴────┐
      │  -хуяк  │
      └────┬────┘
      ┌────┴────┐
      │ вывод   │
      │ решения │
      └────┬────┘
      ┌────┴────┐
      │  конец  │
      └─────────┘
      Ответить
    • Через SMT солвер лучше б сделали, там это легко
      Ответить
      • Хеш тоже смогут обратить?
        Ответить
        • Если очень долго ждать и памяти хватит - смогут. Оно там вообщет Тьюринг-полное по идее. Ну т.е. можно на этом написать определение брейнфака и потом программировать на брейнфаке
          Ответить
          • > и потом программировать на брейнфаке
            Фи! Не барское это дело. Пускай сольвер сам программирует на брейнфаке (подбирая код под тесткейсы).
            Ответить
          • Задача: В написанном выражении ?????????????????????????? вместо каждого знака ? вставить один из восьми операторов брейнфака так, чтобы результат вычислений равнялся 42.
            Ответить
            • Т.е. нужно просто вывести число 42?
              Ответить
              • Ну да. Либо доказать, что задача неразрешима :3
                Ответить
            • ++++[->+++++++++++++<].--.
              26 символов, как заказано.
              Ответить
              • Возможно ты имел в виду ++++[->+++++++++++++<]>.--.?
                Ответить
                • Ччёрт, да. Тогда вылезаю.
                  Ответить
                  • А если найду? А вдруг решение всё-таки существует?

                    З.Ы. И я его таки нашёл: ????????????????? но ideone на нём таймаутится. Есть где-нибудь на примете ещё интерпретаторы?
                    Ответить
                  • [spoiler]-[----->+<]>+.--.[/spoiler]

                    З.Ы. Я там количество вопросиков от балды вбивал, не подумайте, что я специально забрил большинство наивных решений (которые почему-то получаются по 27 символов, как назло).
                    Ответить
                    • А поведение брейнфак-машины по integer underflow определено? Я что-то не уверен.
                      Ответить
                      • Ну на вики было определено. bf тоже схавал. На Ideone тоже ведёт себя как uint8_t, просто не успевает цикл докрутить до конца (чем они его там интепретируют?!).

                        Ткни меня носом в строчку в стандарте брейнфака, где написано, что это UB.
                        Ответить
            • Унёс задачку на летнюю школу.
              Ответить
      • theory Test "Why3 test"
        use import int.Int
        use import int.EuclideanDivision
        
        type operator = Plus | Minus | Mult | Divid
        
        function myf (x y : int) (z : operator) : int = match z with
          | Plus  -> x + y
          | Minus -> x - y
          | Mult  -> x * y
          | Divid -> div x y
          end
        
          goal G1: exists y : operator. (myf 2 2 Plus = myf 2 2 y) /\ (y <> Plus)
          (* тут exist - квантор существования(есть еще forall - квантор всеобщности).
          Вот  эта штука '/\' https://ru.wikipedia.org/wiki/Конъюнкция .
          Пытаемся доказать, что 2 + 2 = 2 ? 2 где '?' это может быть '-' '*' '/' но не '+'.
          *)
        
          goal G2: exists b1,b2,b3,b4,b5 : operator. (myf (myf (myf (myf (myf 1 2 b1) 3 b2) 4 b3) 5 b4) 6 b5) = 35
          (* ну а это сама задача задача *)
        
        end


        Эта хрень с ML синтаксисом (типа всяких там хачкелей). http://why3.lri.fr/stdlib-0.87.1/ можно довольно легко разобраться синтаксисом к этой хрени, если ковырялись с ML-ями (хачкель, F#, Standard ML, OCaml и проч)
        Оно эту свою хрень переводит в язык для всяких разных SMT солверов. Еще умеет в Coq транслировать это говно (в Agda вроде нет).
        Ответить
        • Вот еще скобковый SMT-LIB язычок http://smtlib.cs.uiowa.edu/language.shtml
          (declare-datatypes () ((operator (Plus) (Minus) (Mult) (Divid))))
          
          (define-fun myf ((x Int) (y Int) (z operator)) Int
                (ite (= z Plus) (+ x y)
                   (ite (= z Minus) (- x y)
                     (ite (= z Mult) (* x y)
                         (div x y)))))
          
          
          (assert
            (exists ((b1 operator) (b2 operator) (b3 operator) (b4 operator)
            (b5 operator))
            (= (myf (myf (myf (myf (myf 1 2 b1) 3 b2) 4 b3) 5 b4) 6 b5) 35)))
          
          (check-sat)
          (get-model)
          (exit)

          Z3 выдает ответ
          sat
          (model 
            (define-fun b3!2 () operator
              Mult)
            (define-fun b2!3 () operator
              Mult)
            (define-fun b5!0 () operator
              Plus)
            (define-fun b1!4 () operator
              Mult)
            (define-fun b4!1 () operator
              Plus)
          )

          http://rise4fun.com/Z3/luIN

          ite это if then else, остальное думаю и так понятно
          Ответить
    • Обратный алгоритм на Питоне:

      res = 35
      nums = [6, 5, 4, 3, 2]
      
      ops = [
          ('*', operator.div),
          ('/', operator.mul),
          ('-', operator.add),
          ('+', operator.sub)
      ]
      
      solutions = [('', res)]
      
      for n in nums:
          old_solutions, solutions = solutions, []
          for order, res in old_solutions:
              for opname, op in ops:
                  r = op(res, n)
                  if opname == '*' and (res % n) != 0:
                      continue
                  
                  solutions.append((opname + order, r))
      
      for order, _ in filter(lambda x: x[1] == 1, solutions):
          print '(((((1 {0} 2) {1} 3) {2} 4) {3} 5) {4} 6)'.format(*order)
      Ответить
      • Я нихуя не понял
        Ответить
      • А есть ли смысл обходить в ширину, а не в глубину? Расход памяти больше, а эффект вроде тот же.
        Ответить
    • комплай-тайм версию на кресто шаблонах кто нибудь осилит?

      мне чет это сразу в голову пришло, но не могу придумать как заанролить весь набор комбинаций =\
      Ответить
      • через std::index_sequence, вариадик шаблоны и std::enable_if
        Ответить
        • Имхо, лучше как-нибудь через SFINAE - пусть выживет та специализация, у которой результат будет 35.
          Ответить
          • Дык enable_if и есть удобно завёрнутое SFINAE
            Ответить
          • так оно так и будет. std::enable_if_t<result</*какие-то шаблонные аргументы*/>() == 35, void> func() { /*что-то там с этими аргументами*/};

            Функция скомпилится только если будет существовать какой-то вариант реализации, выдающий 35, а остальные варианты попросту откинет
            Ответить
          • > пусть выживет та специализация, у которой результат будет 35

            интересная штука, но я пока по быстрому сделал в лоб через рекурсию и специализацию
            https://ideone.com/AVSQa6
            раскрывается в 3 вызова Print и ужасное количество кода (сборку строки выхлопа бы в комплай-тайм вынести, на макросах как нибудь, но хз)
            Ответить
          • > пусть выживет та специализация, у которой результат будет 35

            http://rextester.com/TPMIJ98478 - даже печать на этапе конпиляции.
            Ответить
            • Хоть бы в макросы завернул для приличия...
              Ответить
      • Компайл-тайм на крестошаблонах - это уже прошлый век. Сейчас надо на constexpr.
        Ответить

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