На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (12) « Первая ... 7 8 [9] 10 11 ... Последняя » все  ( Перейти к последнему сообщению )  
> Сохранение и восстановление состояния обработки
    Wound, я спорил с конкретным тезисом о том, что такую ошибку легко допустить в C++. Я с этим не согласен, потому что при нормальной организации работы, тебе даст по рукам уже компилятор.
    Ни с чем другим я не спорил.
      Цитата D_KEY @
      Wound, я спорил с конкретным тезисом о том, что такую ошибку легко допустить в C++. Я с этим не согласен, потому что при нормальной организации работы, тебе даст по рукам уже компилятор.
      Ни с чем другим я не спорил.

      Ты с этим не согласен - это твое субъективное мнение или объективное? Если это твое субъективное мнение, то ты прав, потому что ты там что то используешь, что в принципе тебя может от этого спасти(с другой стороны конструкции такого плана, которые могут встретится в каких нибудь сторонних библиотеках - нужно как то исключать?). Но кроме тебя - еще полно людей, которые не используют то, что ты там у себя используешь, и объективно - то что ты приводишь, это не аргумент. Хотя применительно к тебе - аргумент да. Но мы не тебя же обсуждаем.
      А то тебя послушать - так при нормальной организации работы, при нормальных знаниях ЯП, и тд. вообще будет все в шоколаде, но на практике - это не так.

      Добавлено
      Ну и к слову - я на такие баги натыкался, когда вместо сравнения, было присваивание, причем натыкался случайно, и не один раз, в древнем, как говно мамонта коде, на тех же плюсах.
        Ну что, уважаемые, вижу - все кто мог участвовать, уже смогли. Перечислю тех, кто хотел бы поучаствовать, но не с мог по причине запарок на работе, или отсутствием времени по иным причинам:

        • D_KEY
        • Fester
        • OpenGL
        • Qraizer
        • ЫукпШ (не ответил)

        Про остальных - не знаю. Поэтому, считаю, что пора "вскрываться" :yes:

        Пароли к архивам

        • korvin: kjgfhm
        • Majestio: slava-buratine
        • Wound: P@ssw0rd

        user posted image

        Победила дружба!

        И спасибо всем за участие, особенно порадовал korvin многообразием вариантов. Што-то смотрю мне OCaml немного приглянулся :rolleyes: Ну а выводы, надеюсь, всем понятны - никуда с помощью GOTO "впрыгивать" не нужно, равно как и городить многовложенных циклов, коль впереди маячат долгие пересчеты с сохранением состояний. Будет просто супер, если каждый из участвующих в отдельном сообщении соберет все свои варианты, но уже в текстовом виде под спойлер, а рядом выложит ссылку исполнения в онлайн компиляторе.

        Peace! :victory:
          Вариант 1 (С++, без GOTO) Ссылка на онлайн-исполнение
          Скрытый текст
          ExpandedWrap disabled
            #include <iostream>
            #include <vector>
            #include <algorithm>
             
            using namespace std;
             
            std::vector<int> Arr {0,0,0,0};
            std::size_t Step = 0;
            std::size_t State = 0;
             
            void prn();
             
            // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
             
            bool process1() {
                Step++;
                Arr[0]++;
                int Summ = 0;
                std::for_each(Arr.begin(), Arr.end(), [&](int &n){Summ += n;});
                return Summ % 2 == 0;
            }
             
            bool process2() {
                Step++;
                Arr[1] += Arr[3] + 1;
                int Summ = 0;
                std::for_each(Arr.begin(), Arr.end(), [&](int &n){Summ += n;});
                return Summ % 7 > 0;
            }
             
            bool process3() {
                Step++;
                Arr[2] += ((Arr[0]+Arr[1]) % 3 == 0) ? 0 : 7;
                bool Flag = true;
                std::for_each(Arr.begin(), Arr.end(), [&](int &n){if (n % 2 >0) Flag = false;});
                return Flag;
            }
             
            bool process4() {
                Step++;
                Arr[3] += ((Arr[0]+Arr[2]) % 5 == 4) ? 0 : 1;
                int Summ = 0;
                std::for_each(Arr.begin(), Arr.end(), [&](int &n){Summ += n;});
                return Summ > 24;
            }
             
            // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
             
            void load(int pass) {
                if (pass == 1) {
                    State = 1;
                    prn();
                } else {
                    State = 4;
                    Arr = {3,3,14,1};
                    Step = 9;
                    prn();
                }
                return;
            }
             
            void prn() {
                std::cout << "Step: " << Step << "\t" << "Proc: " << State << "\t"
                          << Arr[0] << "\t" << Arr[1] << "\t"
                          << Arr[2] << "\t" << Arr[3] << "\n";
            }
             
            // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
             
            int main()
            {
                for (int i=1; i<3; i++) {
                    load(i);
                    bool cycle = true;
                    while (cycle) {
                        switch (State) {
                            case 1:
                                State = (process1()) ? 4:3; prn(); break;
                            case 2:
                                State = (process2()) ? 3:4; prn(); break;
                            case 3:
                                State = (process3()) ? 2:1; prn(); break;
                            case 4:
                                State = (process4()) ? 5:2; prn(); break;
                            default:
                                cycle = false; break;
                        }
                    }
                    std::cout << "----------------------------------------------------------------\n";
                }
                return 0;
            }

          Вариант 2 (С++, с прекрасным оператором GOTO) Ссылка на онлайн-исполнение
          Скрытый текст
          ExpandedWrap disabled
            #include <functional>
            #include <algorithm>
            #include <iterator>
            #include <iostream>
            #include <numeric>
            #include <vector>
             
            int main() {
              int Idx = 0;
              int Step = 0;
              bool Continue = true;
             
              std::vector<int>A =  {0, 0, 0, 0};
              std::vector<std::vector<int>> Matrix = {{3,2},{2,3},{1,0},{4,1},{4,4}};
             
              auto P1 = [&]() -> void { A[0]++; };
              auto P2 = [&]() -> void { A[1] += A[3] + 1; };
              auto P3 = [&]() -> void { A[2] += ((A[0] + A[1]) % 3 == 0) ? 0 : 7; };
              auto P4 = [&]() -> void { A[3] += ((A[0] + A[2]) % 5 == 4) ? 0 : 1; };
              auto Fp = [&]() -> void { };
              auto D1 = [&]() -> bool { return std::accumulate(A.begin(), A.end(), 0) % 2 == 0; };
              auto D2 = [&]() -> bool { return std::accumulate(A.begin(), A.end(), 0) % 7 > 0; };
              auto D3 = [&]() -> bool { return std::find_if(A.begin(), A.end(), [](int i){ return i % 2 > 0; }) == A.end(); };
              auto D4 = [&]() -> bool { return std::accumulate(A.begin(), A.end(), 0) > 24; };
              auto Fd = [&]() -> bool { Continue = false; return false; };
             
              auto Print = [&]() -> void {
                std::cout << "Step: " << Step << "\tProc: " << (Idx+1) << "\t";
                std::copy(A.begin(), A.end(), std::ostream_iterator<int>(std::cout, "\t"));
                std::cout << std::endl;
              };
             
              using Process = std::function<void()>;
              using Decision = std::function<bool()>;
             
              std::vector<Process> P = {P1, P2, P3, P4, Fp};
              std::vector<Decision> D = {D1, D2, D3, D4, Fd};
             
              // Проход с начала и до конца
             
              while(Continue) {
                Print();
                P[Idx]();
                Idx = Matrix[Idx][(D[Idx]()) ? 0:1];
                Step++;
              }
             
              std::cout << "----------------------------------------------------------------\n";
             
              // Эмуляция восстановления в точке перед Proc-4 и продолжение
             
              Continue = true;
              Step = 9;
              Idx = 3;
              A = {3, 3 ,14, 1};
             
              while(Continue) {
                Print();
                P[Idx]();
                Idx = Matrix[Idx][(D[Idx]()) ? 0:1];
                Step++;
              }
             
              std::cout << "----------------------------------------------------------------\n";
             
              // использование прекрасного оператора GOTO!
             
              label: if (true == false) goto label;
             
              return 0;
            }
            Цитата Majestio @
            Будет просто супер, если каждый из участвующих в отдельном сообщении соберет все свои варианты, но уже в текстовом виде под спойлер, а рядом выложит ссылку исполнения в онлайн компиляторе.

            Онлайн -> https://rextester.com/PKDT40835
            Код

            ExpandedWrap disabled
              using System;
              using System.Collections.Generic;
              using System.Linq;
              using Challenge.Interfaces;
               
              //! Interfaces
              namespace Challenge.Interfaces
              {
                  public interface IDecisionHandler
                  {
                      string HandleDecision(bool decision);
                  }
                  
                  public interface IProcess
                  {
                      void Execute(List<int> values);
                      bool Decision(List<int> values);
                  }
              }
               
               
              namespace Challenge
              {
              //! DecisionhandlerContext
                  public class DecisionHandlerContext
                  {
                      private Dictionary<string, IDecisionHandler> _handlers;
                      public DecisionHandlerContext()
                      {
                          _handlers = new Dictionary<string, IDecisionHandler>();
                      }
               
                      public void RegisterHandler(string processName, IDecisionHandler decisionHandler)
                      {
                          if (String.IsNullOrEmpty(processName) || decisionHandler == null)
                              throw new Exception("Argument can't be null");
               
                          _handlers.Add(processName, decisionHandler);
                      }
               
                      public string HandleDecisionAndGetNextStep(string processName, bool decision)
                      {
                          if (String.IsNullOrEmpty(processName))
                              throw new Exception("Invalid arguments");
               
                          if(_handlers.TryGetValue(processName, out var handler))
                          {
                              return handler.HandleDecision(decision);
                          }
                          throw new Exception("Handle error");
                      }
                  }
               
                  public class Process1DecisionHandler : IDecisionHandler
                  {
                      public string HandleDecision(bool decision)
                      {
                          if(decision)
                              return Process4.ProcessName;
                          return Process3.ProcessName;
                      }
                  }
               
                  public class Process2DecisionHandler : IDecisionHandler
                  {
                      public string HandleDecision(bool decision)
                      {
                          if (decision)
                              return Process3.ProcessName;
                          return Process4.ProcessName;
                      }
                  }
               
                  public class Process3DecisionHandler : IDecisionHandler
                  {
                      public string HandleDecision(bool decision)
                      {
                          if (decision)
                              return Process2.ProcessName;
                          return Process1.ProcessName;
                      }
                  }
               
                  public class Process4DecisionHandler : IDecisionHandler
                  {
                      public string HandleDecision(bool decision)
                      {
                          if (decision)
                              return Process5.ProcessName;
                          return Process2.ProcessName;
                      }
                  }
               
                  public class Process5DecisionHandler : IDecisionHandler
                  {
                      public string HandleDecision(bool decision)
                      {
                          return String.Empty;
                      }
                  }
                  
              //! Process1
                  public class Process1 : IProcess
                  {
                      private const int MaxSizeValues = 4;
                      public static string ProcessName => "1";
               
                      public void Execute(List<int> values)
                      {
                          if (values == null || values.Count > MaxSizeValues)
                              throw new InvalidOperationException("List of values is empty...");
                          ++values[0];
                      }
               
                      public bool Decision(List<int> values)
                      {
                          return (values.Sum() % 2) == 0;
                      }
               
                  }
               
              //! Process2
                  public class Process2 : IProcess
                  {
                      private const int MaxSizeValues = 4;
                      public static string ProcessName => "2";
               
                      public bool Decision(List<int> values)
                      {
                          return (values.Sum() % 7) > 0;
                      }
               
                      public void Execute(List<int> values)
                      {
                          if (values == null || values.Count > MaxSizeValues)
                              throw new InvalidOperationException("List of values is empty...");
               
                          values[1] += values[3] + 1;
                      }
                  }
               
              //! Process3
                  public class Process3 : IProcess
                  {
                      private const int MaxSizeValues = 4;
                      public static string ProcessName => "3";
               
                      public bool Decision(List<int> values)
                      {
                          var existOdd = values.Any(e => e % 2 != 0);
                          return !existOdd;
                      }
               
                      public void Execute(List<int> values)
                      {
                          if (values == null || values.Count > MaxSizeValues)
                              throw new InvalidOperationException("List of values is empty...");
               
                          if ( (values[0] + values[1]) % 3 > 0 )
                              values[2] += 7;
                      }
                  }
               
              //! Process4
                  public class Process4 : IProcess
                  {
                      private const int MaxSizeValues = 4;
                      public static string ProcessName => "4";
               
                      public bool Decision(List<int> values)
                      {
                          return values.Sum() > 24;
                      }
               
                      public void Execute(List<int> values)
                      {
                          if (values == null || values.Count > MaxSizeValues)
                              throw new InvalidOperationException("List of values is empty...");
               
                          if ((values[0] + values[2]) % 5 != 4)
                              ++values[3];
                      }
                  }
               
              //! Process5
                  public class Process5 : IProcess
                  {
                      public static string ProcessName => "5";
               
                      public bool Decision(List<int> values)
                      {
                          return true;
                      }
               
                      public void Execute(List<int> values)
                      {
                      }
                  }
               
              //! ProcessContext
                  public class ProcessContext
                  {
                      private Dictionary<string, IProcess> _processes;
                      private DecisionHandlerContext _handlerContext;
                      public ProcessContext()
                      {
                          _processes = new Dictionary<string, IProcess>();
                          _handlerContext = new DecisionHandlerContext();
                      }
               
                      public ProcessContext AddProcess(string proccesName, IProcess process, IDecisionHandler handler)
                      {
                          if (String.IsNullOrEmpty(proccesName) || process == null)
                              throw new Exception("Argument can't be null");
               
                          _processes.Add(proccesName, process);
                          _handlerContext.RegisterHandler(proccesName, handler);
               
                          return this;
                      }
               
                      public bool RunProcessAndCheckDecision(string processName, List<int> values)
                      {
                          if(_processes.TryGetValue(processName, out var proc))
                          {
                              if (proc == null)
                                  throw new Exception($"Process with name '{processName}' is null.");
               
                              proc.Execute(values);
               
                              return proc.Decision(values);
                          }
               
                          throw new Exception($"Process with name '{processName}' not found.");
                      }
               
                      public void RunAllProcesses(string startProcessName, List<int> values)
                      {
                          string currentProcessName = startProcessName;
                          int step = 0;
                          while (true)
                          {
                              Console.WriteLine($"Step {step}\t Proc: {currentProcessName}\t {String.Join(" ", values)}");
               
                              var result = RunProcessAndCheckDecision(currentProcessName, values);
                              currentProcessName = _handlerContext.HandleDecisionAndGetNextStep(currentProcessName, result);
                              if (String.IsNullOrEmpty(currentProcessName))
                                  break;
                              ++step;
                          }
                      }
                  }
                  
              //! Programm
                  public class Program
                  {
                      static void Main(string[] args)
                      {
                          try
                          {
                              List<int> values = new List<int> { 0, 0, 0, 0 };
               
                              ProcessContext processContext = new ProcessContext();
               
                              processContext
                                  .AddProcess(Process1.ProcessName, new Process1(), new Process1DecisionHandler())
                                  .AddProcess(Process2.ProcessName, new Process2(), new Process2DecisionHandler())
                                  .AddProcess(Process3.ProcessName, new Process3(), new Process3DecisionHandler())
                                  .AddProcess(Process4.ProcessName, new Process4(), new Process4DecisionHandler())
                                  .AddProcess(Process5.ProcessName, new Process5(), new Process5DecisionHandler());
               
                              processContext.RunAllProcesses(Process1.ProcessName, values);
               
                              Console.WriteLine("--------------------------");
                              List<int> savedValues = new List<int> { 3, 3, 14, 1 };
                              processContext.RunAllProcesses(Process4.ProcessName, savedValues);
                          }
                          catch(Exception error)
                          {
                              Console.WriteLine(error.Message);
                          }
                      }
                  }
              }

              Ocaml #1

              ExpandedWrap disabled
                module Memory =
                  struct
                    type cells = int array
                 
                    let size = 4
                    let alloc () = Array.make size 0
                  end
                 
                module type CPU =
                  sig
                    type process = Memory.cells -> unit
                 
                    val process_1 : process
                    val process_2 : process
                    val process_3 : process
                    val process_4 : process
                 
                    type decision = Memory.cells -> bool
                 
                    val decision_1 : decision
                    val decision_2 : decision
                    val decision_3 : decision
                    val decision_4 : decision
                  end
                 
                module Machine (CPU : CPU) =
                  struct
                    open CPU
                 
                    type cpu_state =
                      | Process_1
                      | Process_2
                      | Process_3
                      | Process_4
                      | Stop
                 
                    type machine =
                      { mutable cpu_state   : cpu_state
                      ; mutable cpu_counter : int
                      ;         memory      : Memory.cells }
                 
                    let new_machine ?(cpu_state=Process_1) ?(cpu_counter=0) ?(memory_init=[||]) () =
                      let memory = Memory.alloc () in
                      for i = 0 to min (Memory.size - 1) (Array.length memory_init - 1) do
                        memory.(i) <- memory_init.(i)
                      done ;
                      { cpu_state   = cpu_state
                      ; cpu_counter = cpu_counter
                      ; memory      = memory }
                 
                    let cpu process machine =
                      process machine.memory ;
                      { machine with cpu_counter = machine.cpu_counter + 1 }
                 
                    let branch decision machine =
                      (machine, decision machine.memory)
                 
                    let yes y ~no (machine, flag) =
                      { machine with cpu_state = if flag then y else no }
                 
                    let ( ==> ) = ( |> )
                 
                    let rec run machine =
                      describe machine ;
                      match machine.cpu_state with
                      | Process_1 -> machine ==> cpu process_1 ==> branch decision_1 ==> yes Process_4 ~no: Process_3 ==> run
                      | Process_2 -> machine ==> cpu process_2 ==> branch decision_2 ==> yes Process_3 ~no: Process_4 ==> run
                      | Process_3 -> machine ==> cpu process_3 ==> branch decision_3 ==> yes Process_2 ~no: Process_1 ==> run
                      | Process_4 -> machine ==> cpu process_4 ==> branch decision_4 ==> yes Stop      ~no: Process_2 ==> run
                      | Stop      -> ()
                 
                    and describe { cpu_state ; cpu_counter ; memory } =
                      Printf.printf "Step: %2d    %-8s %s\n" cpu_counter (state_string cpu_state) (mem_string memory)
                 
                    and state_string state =
                      match state with
                      | Process_1 -> "Proc: 1"
                      | Process_2 -> "Proc: 2"
                      | Process_3 -> "Proc: 3"
                      | Process_4 -> "Proc: 4"
                      | Stop      -> "Stop   "
                 
                    and mem_string mem =
                      let str  = ref "" in
                      for i = 0 to Memory.size - 1 do
                        str := !str ^ Printf.sprintf " %3d" mem.(i)
                      done ;
                      !str
                 
                  end
                 
                module Majestio_CPU : CPU =
                  struct
                    type process = Memory.cells -> unit
                 
                    let process_1 mem =
                      mem.(0) <- mem.(0) + 1
                 
                    let process_2 mem =
                      mem.(1) <- mem.(1) + mem.(3) + 1
                 
                    let process_3 mem =
                      let sum_0_1 = mem.(0) + mem.(1) in
                      if sum_0_1 mod 3 <> 0 then
                        mem.(2) <- mem.(2) + 7
                 
                    let process_4 mem =
                      let sum_0_2 = mem.(0) + mem.(2) in
                      if sum_0_2 mod 5 <> 4 then
                        mem.(3) <- mem.(3) + 1
                 
                    type decision = Memory.cells -> bool
                 
                    let sum = Array.fold_left (+) 0
                 
                    let decision_1 mem =
                      sum mem mod 2 = 0
                 
                    let decision_2 mem =
                      sum mem mod 7 > 0
                 
                    let decision_3 mem =
                      let is_even x = x mod 2 = 0 in
                      Array.for_all is_even mem
                 
                    let decision_4 mem =
                      sum mem > 24
                 
                  end
                 
                let main () =
                  let module M = Machine (Majestio_CPU) in
                 
                  M.new_machine () |> M.run ;
                  print_endline "----------------------------------------------------------------" ;
                 
                  M.new_machine
                    ~cpu_state:   M.Process_4
                    ~cpu_counter: 9
                    ~memory_init: [| 3; 3; 14; 1 |]
                    () |> M.run ;
                  print_endline "----------------------------------------------------------------"
                 
                let () = main ()

              https://rextester.com/YFHF41308


              Ocaml #2

              ExpandedWrap disabled
                module type Machine =
                  sig
                    type data = int array
                    val init : ?data:data -> unit -> unit
                    val dump : unit -> data
                 
                    type process = unit -> unit
                    val process_1 : process
                    val process_2 : process
                    val process_3 : process
                    val process_4 : process
                 
                    type decision = unit -> bool
                    val decision_1 : decision
                    val decision_2 : decision
                    val decision_3 : decision
                    val decision_4 : decision
                  end
                 
                module Program (M : Machine) =
                  struct
                 
                    type state =
                      | Proc_1
                      | Proc_2
                      | Proc_3
                      | Proc_4
                      | Stop
                 
                    let ( --> ) = ( |> )
                 
                    let yes y ~no:n decision = if decision then y else n
                 
                    let rec run count state =
                      log_state count state ;
                      let loop = run (count + 1) in
                      match state with
                      | Proc_1 -> () --> M.process_1 --> M.decision_1 --> yes Proc_4 ~no:Proc_3 --> loop
                      | Proc_2 -> () --> M.process_2 --> M.decision_2 --> yes Proc_3 ~no:Proc_4 --> loop
                      | Proc_3 -> () --> M.process_3 --> M.decision_3 --> yes Proc_2 ~no:Proc_1 --> loop
                      | Proc_4 -> () --> M.process_4 --> M.decision_4 --> yes Stop   ~no:Proc_2 --> loop
                      | Stop   -> ()
                 
                    and log_state count state =
                      let data = M.dump () in
                      Printf.printf "Step: %2d   %s   %s\n" count (state_string state) (data_string data)
                 
                    and state_string s =
                      match s with
                      | Proc_1 -> "Process 1"
                      | Proc_2 -> "Process 2"
                      | Proc_3 -> "Process 3"
                      | Proc_4 -> "Process 4"
                      | Stop   -> "Stop     "
                 
                    and data_string data =
                      data --> Array.map (Printf.sprintf " %2d") --> Array.to_list --> String.concat " "
                 
                  end
                 
                 
                module Majestio_machine : Machine =
                  struct
                 
                    let size = 4
                 
                    let cell = Array.make size 0
                 
                    type data = int array
                 
                    let init ?(data=[||]) () =
                      let n = min size (Array.length data) in
                      if n = 0
                        then Array.fill cell 0 size 0
                        else Array.blit data 0 cell 0 n
                 
                    let dump () = Array.copy cell
                 
                    type process = unit -> unit
                 
                    let process_1 () =
                      cell.(0) <- cell.(0) + 1
                 
                    let process_2 () =
                      cell.(1) <- cell.(1) + cell.(3) + 1
                 
                    let process_3 () =
                      let sum_0_1 = cell.(0) + cell.(1) in
                      if sum_0_1 mod 3 <> 0 then
                        cell.(2) <- cell.(2) + 7
                 
                    let process_4 () =
                      let sum_0_2 = cell.(0) + cell.(2) in
                      if sum_0_2 mod 5 <> 4 then
                        cell.(3) <- cell.(3) + 1
                 
                    type decision = unit -> bool
                 
                    let sum = Array.fold_left (+) 0
                 
                    let decision_1 () = sum cell mod 2 = 0
                 
                    let decision_2 () = sum cell mod 7 > 0
                 
                    let decision_3 () =
                      let is_even x = x mod 2 = 0 in
                      Array.for_all is_even cell
                 
                    let decision_4 () = sum cell > 24
                 
                  end
                 
                 
                let main () =
                  let module Machine = Majestio_machine in
                  let module Program = Program (Machine) in
                 
                  Machine.init () ;
                  Program.run 1 Program.Proc_1 ;
                  print_endline "----------------------------------------------------------------" ;
                 
                  Machine.init ~data:[| 3; 3; 14; 1 |] () ;
                  Program.run 9 Program.Proc_4 ;
                  print_endline "----------------------------------------------------------------" ;
                 
                  print_endline "done"
                 
                let () = main ()

              https://rextester.com/WPDD51431


              Ocaml #3

              ExpandedWrap disabled
                module Machine =
                  struct
                 
                    type memory   = int array
                    type process  = memory -> unit
                    type decision = memory -> bool
                 
                    type cpu =
                      { processes : process array
                      ; decisions : decision array }
                 
                    type program = (int * int * int) array
                 
                    let majestio : program = [|
                      1, 4, 3;
                      2, 3, 4;
                      3, 2, 1;
                      4, 5, 2
                    |]
                 
                    let rec run ?(count = 0) ?(proc = 1) cpu mem program =
                      log_state count proc mem ;
                      let proc = proc - 1 in
                      if 0 <= proc && proc < Array.length program then begin
                        let dec, yes, no = program .(proc)       in
                        let process      = cpu.processes.(proc)  in
                        let decision     = cpu.decisions.(dec-1) in
                        process mem ;
                        let next = if decision mem then yes else no in
                        run ~count:(count+1) ~proc:next cpu mem program
                      end
                 
                    and log_state count process mem =
                      let mem = mem |> Array.map (Printf.sprintf "%2d") |> Array.to_list |> String.concat " "
                      in Printf.printf "Step: %2d   Proc: %d   %s\n" count process mem
                 
                  end
                 
                module Majestio =
                  struct
                 
                    let process_1 cell =
                      cell.(0) <- cell.(0) + 1
                 
                    let process_2 cell =
                      cell.(1) <- cell.(1) + cell.(3) + 1
                 
                    let process_3 cell =
                      let sum_0_1 = cell.(0) + cell.(1) in
                      if sum_0_1 mod 3 <> 0 then
                        cell.(2) <- cell.(2) + 7
                 
                    let process_4 cell =
                      let sum_0_2 = cell.(0) + cell.(2) in
                      if sum_0_2 mod 5 <> 4 then
                        cell.(3) <- cell.(3) + 1
                 
                    let sum = Array.fold_left (+) 0
                 
                    let decision_1 cell = sum cell mod 2 = 0
                 
                    let decision_2 cell = sum cell mod 7 > 0
                 
                    let decision_3 cell =
                      let is_even x = x mod 2 = 0 in
                      Array.for_all is_even cell
                 
                    let decision_4 cell = sum cell > 24
                 
                    let cpu =
                      { Machine.
                 
                        processes =
                        [|
                          process_1;
                          process_2;
                          process_3;
                          process_4
                        |]
                      ; decisions =
                        [|
                          decision_1;
                          decision_2;
                          decision_3;
                          decision_4
                        |]
                      }
                 
                    let program =
                      [|
                       1, 4, 3;
                       2, 3, 4;
                       3, 2, 1;
                       4, 5, 2
                     |]
                 
                  end
                 
                let main () =
                  Machine.run Majestio.cpu [| 0; 0; 0; 0 |] Majestio.program ;
                  print_endline "----------------------------------------------------------------" ;
                 
                  Machine.run ~count:9 ~proc:4 Majestio.cpu [| 3; 3; 14; 1 |] Majestio.program ;
                  print_endline "----------------------------------------------------------------"
                 
                let () = main ()

              https://rextester.com/ARZ32340


              Racket

              ExpandedWrap disabled
                #lang racket
                 
                (define (sum v)
                  (for/sum ((x (in-vector v))) x))
                 
                (define (cell c1 c2 c3 c4)
                  (vector c1 c2 c3 c4))
                 
                (define (mod x y)
                  (remainder x y))
                 
                (define (div-by? n v)
                  (zero? (mod v n)))
                 
                (define (all v predicate?)
                  (for/and ((x (in-vector v)))
                    (predicate? x)))
                 
                (define (are-even? x)
                  (zero? (mod x 2)))
                 
                (define (f l n #:left? (left? #f))
                  (let* ((s (format "~a" n))
                         (m (string-length s)))
                    (cond ((>= m l)
                           s)
                          (left?
                           (string-append s (make-string (- l m) #\Space)))
                          (else
                           (string-append (make-string (- l m) #\Space) s)))))
                 
                (define-syntax-rule (state st) 'st)
                 
                (define (counter c) c)
                 
                (define-syntax define-machine
                  (syntax-rules (state -> -- < > yes no)
                    ((_ (name (counter counter-init) (state state-init) (cell c1 c2 c3 c4))
                        { -> [ proc-in
                               action ]
                          ->
                             <
                               post-cond
                             >
                          -- yes -> yes-proc-out
                          -- no  -> no-proc-out }
                        ...
                        )
                     (define (name (counter counter-init) (state 'state-init) (cells #(c1 c2 c3 c4)))
                       (define cs (vector-copy cells))
                       (define-syntax cell
                         (syntax-rules (<- ->)
                           ((_) cs)
                           ((_ i) (vector-ref cs i))
                           ((_ i <- op . vs)
                            (vector-set! cs i (op (cell i) . vs)))
                           ((_ op -> predicate?)
                            (let ((op (op cs)))
                              predicate?))))
                       (define (proc-in)
                         action
                         (if post-cond
                             'yes-proc-out
                             'no-proc-out))
                       ...
                       (let loop ((state state) (counter counter))
                         (printf "Step: ~a   ~a  ~a  ~a  ~a  ~a~n"
                                 (f 2 counter)
                                 (f 10 state #:left? #t)
                                 (f 2 (cell 0))
                                 (f 2 (cell 1))
                                 (f 2 (cell 2))
                                 (f 2 (cell 3)))
                         (case state
                           ((proc-in) (loop (proc-in) (+ counter 1)))
                           ...
                           (else 'done)))))))
                 
                 
                 
                (define-machine (majestio-machine (counter 0) (state process-1) (cell 0 0 0 0))
                  
                  { -> [ process-1
                         (cell 0 <- + 1) ]
                    ->
                       < (cell sum -> (div-by? 2 sum)) >
                    -- yes -> process-4
                    -- no  -> process-3 }
                  
                  { -> [ process-2
                         (cell 1 <- + (cell 3) 1) ]
                    ->
                       < (cell sum -> (positive? (mod sum 7))) >
                    -- yes -> process-3
                    -- no  -> process-4 }
                  
                  { -> [ process-3
                         (unless (div-by? 3 (+ (cell 0) (cell 1)))
                           (cell 2 <- + 7)) ]
                    ->
                       < (all (cell) are-even?) >
                    -- yes -> process-2
                    -- no  -> process-1 }
                  
                  { -> [ process-4
                         (let ((c0+c2 (+ (cell 0) (cell 2))))
                           (unless (= (mod c0+c2 5) 4)
                             (cell 3 <- + 1))) ]
                    ->
                       < (cell sum -> (> sum 24)) >
                    -- yes -> stop
                    -- no  -> process-2 } )
                 
                 
                 
                (define (main)
                  (majestio-machine)
                  (displayln "----------------------------------------------------------------")
                  (majestio-machine (counter 9) (state process-4) (cell 3 3 14 1))
                  (displayln "----------------------------------------------------------------"))
                 
                (main)

              https://onecompiler.com/racket/3ygbcbxe2


              Haskell

              ExpandedWrap disabled
                module Main (main) where
                 
                main :: IO ()
                main = do
                  machine (Run 0 Process 1 [0, 0, 0, 0])
                  putStrLn "----------------------------------------------------------------"
                  machine (Run 9 Process 4 [3, 3, 14, 1])
                  putStrLn "----------------------------------------------------------------"
                 
                ----------------------------------------------------------------
                 
                data CmdType = Process | Decision deriving (Show)
                type CmdAddr = Int
                type Counter = Int
                type Memory  = [Int]
                 
                data State
                  = Run Counter CmdType CmdAddr Memory
                  | Stop
                  | Fail String
                 
                instance Show State where
                  show Stop = "stop"
                  show (Fail err) = "failure: " ++ err
                 
                  show (Run c Process i cells) =
                    "Step: " ++ align2 c ++ "    Proc: " ++ show i ++ "   " ++ showCells cells
                    where
                      showCells []          = ""
                      showCells (cell:rest) = " " ++ align2 cell ++ showCells rest
                      align2 n
                        | n < 10     =  " " ++ show n
                        | otherwise  =  show n
                 
                  show (Run c t i cells) = "Step " ++ show c ++ " " ++ show t ++ " " ++ show i ++ " " ++ show cells
                 
                ----------------------------------------------------------------
                 
                cpu :: State -> State
                 
                cpu (Run c Process 1 [c0, c1, c2, c3]) = Run (c+1) Decision 1 [c0+1, c1, c2, c3]
                 
                cpu (Run c Decision 1 cells)
                  | even (sum cells)  =  Run c Process 4 cells
                  | otherwise         =  Run c Process 3 cells
                 
                cpu (Run c Process 2 [c0, c1, c2, c3]) = Run (c+1) Decision 2 [c0, c1+c3+1, c2, c3]
                 
                cpu (Run c Decision 2 cells)
                  | sum cells `mod` 7 > 0  =  Run c Process 3 cells
                  | otherwise              =  Run c Process 4 cells
                 
                cpu (Run c Process 3 [c0, c1, c2, c3])
                  | (c0+c1) `mod` 3 /= 0  =  Run (c+1) Decision 3 [c0, c1, c2+7, c3]
                  | otherwise             =  Run (c+1) Decision 3 [c0, c1, c2,   c3]
                 
                cpu (Run c Decision 3 cells)
                  | all even cells  =  Run c Process 2 cells
                  | otherwise       =  Run c Process 1 cells
                 
                cpu (Run c Process 4 [c0, c1, c2, c3])
                  | (c0+c2) `mod` 5 /= 4  =  Run (c+1) Decision 4 [c0, c1, c2, c3+1]
                  | otherwise             =  Run (c+1) Decision 4 [c0, c1, c2, c3]
                 
                cpu (Run c Decision 4 cells)
                  | sum cells > 24  =  Run c Process 5 cells
                  | otherwise       =  Run c Process 2 cells
                 
                cpu (Run _ Process 5 _) = Stop
                 
                cpu Stop       = Stop
                cpu (Fail err) = Fail err
                cpu state      = Fail (show state)
                 
                ----------------------------------------------------------------
                 
                machine :: State -> IO ()
                machine Stop                  = return ()
                machine s@(Fail _)            = print s
                machine s@(Run _ Process _ _) = print s >> machine (cpu s)
                machine s                     = machine (cpu s)

              https://rextester.com/EQGX38142


              Go

              ExpandedWrap disabled
                package main
                 
                import (
                    "context"
                    "fmt"
                )
                 
                var (
                    process1 = make(chan int)
                    process2 = make(chan int)
                    process3 = make(chan int)
                    process4 = make(chan int)
                 
                    stop  = make(chan int)
                    cell  = make(Cells, 4)
                )
                 
                func main() {
                    var ctx = context.Background()
                    robot(ctx)
                 
                    start(0, process1, 0, 0, 0, 0)
                    start(9, process4, 3, 3, 14, 1)
                }
                 
                func robot(ctx context.Context) {
                    go Block{
                        Name:     "Proc: 1",
                        Receive:  process1,
                        Process:  Process1,
                        Decision: Decision1,
                        IfYes:    process4,
                        IfNo:     process3,
                    }.Connect(ctx)
                 
                    go Block{
                        Name:     "Proc: 2",
                        Receive:  process2,
                        Process:  Process2,
                        Decision: Decision2,
                        IfYes:    process3,
                        IfNo:     process4,
                    }.Connect(ctx)
                 
                    go Block{
                        Name:     "Proc: 3",
                        Receive:  process3,
                        Process:  Process3,
                        Decision: Decision3,
                        IfYes:    process2,
                        IfNo:     process1,
                    }.Connect(ctx)
                 
                    go Block{
                        Name:     "Proc: 4",
                        Receive:  process4,
                        Process:  Process4,
                        Decision: Decision4,
                        IfYes:    stop,
                        IfNo:     process2,
                    }.Connect(ctx)
                }
                 
                func start(counter int, process chan<- int, c1, c2, c3, c4 int) {
                    cell[0], cell[1], cell[2], cell[3] = c1, c2, c3, c4
                 
                    process <- counter
                    counter = <-stop
                 
                    dump(counter, "Stop")
                    fmt.Println("----------------------------------------------------------------")
                }
                 
                type (
                    Cells []int
                 
                    Block struct {
                        Name     string
                        Receive  <-chan int
                        Process  Process
                        Decision Decision
                        IfYes    chan<- int
                        IfNo     chan<- int
                    }
                 
                    Process func()
                 
                    Decision func() bool
                )
                 
                func (b Block) Connect(ctx context.Context) {
                    for {
                        select {
                        case <-ctx.Done():
                            // may save here
                        case counter := <-b.Receive:
                            dump(counter, b.Name)
                            counter++
                            b.Process()
                            if b.Decision() {
                                b.yes(ctx, counter)
                            } else {
                                b.no(ctx, counter)
                            }
                        }
                    }
                }
                 
                func (b Block) yes(ctx context.Context, value int) {
                    send(ctx, b.IfYes, value)
                }
                 
                func (b Block) no(ctx context.Context, value int) {
                    send(ctx, b.IfNo, value)
                }
                 
                /* ---------------------------------------------------------------- */
                 
                func Process1() {
                    cell[0]++
                }
                 
                func Process2() {
                    cell[1] += cell[3] + 1
                }
                 
                func Process3() {
                    if (cell[0] + cell[1])%3 != 0 {
                        cell[2] += 7
                    }
                }
                 
                func Process4() {
                    if (cell[0] + cell[2])%5 != 4 {
                        cell[3] += 1
                    }
                }
                 
                /* ---------------------------------------------------------------- */
                 
                func Decision1() bool {
                    return cell.sum()%2 == 0
                }
                 
                func Decision2() bool {
                    return cell.sum()%7 > 0
                }
                 
                func Decision3() bool {
                    return cell.areAllEven()
                }
                 
                func Decision4() bool {
                    return cell.sum() > 24
                }
                 
                /* ---------------------------------------------------------------- */
                 
                func (xs Cells) sum() (s int) {
                    for _, x := range xs {
                        s += x
                    }
                    return s
                }
                 
                func (xs Cells) areAllEven() bool {
                    for _, x := range xs {
                        if x%2 != 0 {
                            return false
                        }
                    }
                    return true
                }
                 
                func send(ctx context.Context, ch chan<- int, v int) {
                    select {
                    case ch <- v:
                    case <-ctx.Done():
                    }
                }
                 
                func dump(c int, p string) {
                    fmt.Printf("Step: %2d    %-10s    %2d  %2d  %2d  %2d\n",
                        c, p, cell[0], cell[1], cell[2], cell[3])
                }

              https://go.dev/play/p/2AZ1MAlUaOp


              Common Lisp

              ExpandedWrap disabled
                (defparameter *data* (vector 0 0 0 0))
                 
                (defun run-machine (&key (state 1) (count 0))
                  (labels ((dump (state)
                             (format t "Step: ~2d    Proc: ~2d  ~{ ~2d~}~%" count state (coerce *data* 'list))
                             (incf count)))
                    (tagbody
                     (case state
                       (1 (go :proc-1))
                       (2 (go :proc-2))
                       (3 (go :proc-3))
                       (4 (go :proc-4))
                       (t (go :stop)))
                     :proc-1
                     (dump 1)
                     (process-1)
                     (if (decision-1) (go :proc-4) (go :proc-3))
                     :proc-2
                     (dump 2)
                     (process-2)
                     (if (decision-2) (go :proc-3) (go :proc-4))
                     :proc-3
                     (dump 3)
                     (process-3)
                     (if (decision-3) (go :proc-2) (go :proc-1))
                     :proc-4
                     (dump 4)
                     (process-4)
                     (if (decision-4) (go :stop) (go :proc-2))
                     :stop
                     (dump 5))))
                 
                (defun process-1 ()
                  (incf (cell 0)))
                 
                (defun process-2 ()
                  (incf (cell 1) (+ (cell 3) 1)))
                 
                (defun process-3 ()
                  (unless (divisible (sum-cells 0 1) :by 3)
                    (incf (cell 2) 7)))
                 
                (defun process-4 ()
                  (unless (= 4 (rem (sum-cells 0 2) 5))
                    (incf (cell 3))))
                 
                (defun decision-1 ()
                  (divisible (cells-sum) :by 2))
                 
                (defun decision-2 ()
                  (plusp (rem (cells-sum) 7)))
                 
                (defun decision-3 ()
                  (all-cells #'evenp))
                 
                (defun decision-4 ()
                  (> (cells-sum) 24))
                 
                ;------------------------------------------------
                 
                (defun cell (i)
                  (aref *data* i))
                 
                (defun (setf cell) (v i)
                  (setf (aref *data* i) v))
                 
                (defun divisible (v &key by)
                  (zerop (rem v by)))
                 
                (defun sum-cells (&rest indexes)
                  (loop for i in indexes summing (cell i)))
                 
                (defun cells-sum ()
                  (loop for x across *data* summing x))
                 
                (defun all-cells (predicate)
                  (loop for x across *data*
                        unless (funcall predicate x)
                          do (return-from all-cells nil))
                  t)
                 
                ;------------------------------------------------
                 
                (defun main ()
                  (run-machine)
                  (format t "----------------------------------------------------------------~%")
                  (let ((*data* (vector 3 3 14 1)))
                    (run-machine :count 9 :state 4))
                  (format t "----------------------------------------------------------------~%"))
                 
                (main)

              https://rextester.com/RRI70257
              Сообщение отредактировано: korvin -
                Цитата Majestio @
                label: if (true == false) goto label;

                :bad:

                Добавлено
                Цитата Majestio @
                Вариант 1 (С++, без GOTO)

                Видишь, ты даже в синтетической задаче не нашел применение этому оператору.
                  Ну тогда и я вскроюсь. В главном цикле приложения: конечный автомат для решений и переходов + сериализация для хранения состояний. Сохранение/восстановление тоже состояния автомата. Всё.
                    Цитата Wound @
                    Видишь, ты даже в синтетической задаче не нашел применение этому оператору.

                    Ну в моем первом варианте - использование switch-case только это маскирует формально, а по сути - тот же if-goto, только вид сбоку :rolleyes:
                      Цитата Qraizer @
                      конечный автомат

                      Гм, тогда к чему было:
                      Цитата Qraizer @
                      кажись, я слегка погорячился, прованговав всем известный паттерн.

                      ?

                      Или ты про конкретно этот паттерн?
                        Цитата korvin @
                        Или ты про конкретно этот паттерн?

                        Скорее он про switch в цикле, ИМХО.

                        Добавлено
                        Я так предполагаю что то типа этого: http://www.devexp.ru/2011/02/konechnye-avtomaty-v-c/
                        Хотя могу ошибаться. В плюсах я только про такие автоматы слышал.
                        Сообщение отредактировано: Wound -
                          Цитата Qraizer @
                          Ну тогда и я вскроюсь. В главном цикле приложения: конечный автомат для решений и переходов + сериализация для хранения состояний. Сохранение/восстановление тоже состояния автомата. Всё.

                          Да, у всех один и тот же подход. А вот при постановке задачи "пересчеты-с-сохранением" - многовложенные циклы в 17 раз хуже использования прекрасного оператора GOTO :rolleyes:
                            Цитата Majestio @
                            А вот при постановке задачи "пересчеты-с-сохранением" - многовложенные циклы в 17 раз хуже использования прекрасного оператора GOTO :rolleyes:

                            Ты нигде его не использовал свой goto. Твой ивент - профанация. Я почти неделю ждал решения на goto, чтоб его обосрать и где оно? Только korvin, то что у тебя на языке было, написал сегодня или вчера кодом. И все.
                            Короче blah-blah-blah... goto, goto, и где он этот goto в твоих исходниках? Я не вижу его. <_<

                            Добавлено
                            Я тебе больше скажу - давай расширим ивент до 50 процессов. Только мне лень придумывать им решения. Я хочу посмотреть как распухнут твои исходники на плюсах.
                            Сообщение отредактировано: Wound -
                              Цитата Wound @
                              Я хочу посмотреть как распухнут твои исходники на плюсах.

                              На одно распухание: 2 лямбды + 1 пара значений в таблицу переходов :rolleyes:

                              Добавлено
                              Цитата Wound @
                              Я почти неделю ждал решения на goto, чтоб его обосрать и где оно?

                              Прости!!! :lool:
                                Цитата Majestio @
                                На одно распухание: 2 лямбды + 1 пара значений в таблицу переходов :rolleyes:

                                Именно, оно уже выглядит пугающим. Когда там будет 100 лямбд - то уже будет на что посмотреть.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0943 ]   [ 15 queries used ]   [ Generated: 6.12.23, 20:55 GMT ]