
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.238.180.174] |
![]() |
|
Страницы: (12) « Первая ... 7 8 [9] 10 11 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#121
,
|
|
|
Wound, я спорил с конкретным тезисом о том, что такую ошибку легко допустить в C++. Я с этим не согласен, потому что при нормальной организации работы, тебе даст по рукам уже компилятор.
Ни с чем другим я не спорил. |
Сообщ.
#122
,
|
|
|
Цитата D_KEY @ Wound, я спорил с конкретным тезисом о том, что такую ошибку легко допустить в C++. Я с этим не согласен, потому что при нормальной организации работы, тебе даст по рукам уже компилятор. Ни с чем другим я не спорил. Ты с этим не согласен - это твое субъективное мнение или объективное? Если это твое субъективное мнение, то ты прав, потому что ты там что то используешь, что в принципе тебя может от этого спасти(с другой стороны конструкции такого плана, которые могут встретится в каких нибудь сторонних библиотеках - нужно как то исключать?). Но кроме тебя - еще полно людей, которые не используют то, что ты там у себя используешь, и объективно - то что ты приводишь, это не аргумент. Хотя применительно к тебе - аргумент да. Но мы не тебя же обсуждаем. А то тебя послушать - так при нормальной организации работы, при нормальных знаниях ЯП, и тд. вообще будет все в шоколаде, но на практике - это не так. Добавлено Ну и к слову - я на такие баги натыкался, когда вместо сравнения, было присваивание, причем натыкался случайно, и не один раз, в древнем, как говно мамонта коде, на тех же плюсах. |
Сообщ.
#123
,
|
|
|
Ну что, уважаемые, вижу - все кто мог участвовать, уже смогли. Перечислю тех, кто хотел бы поучаствовать, но не с мог по причине запарок на работе, или отсутствием времени по иным причинам:
Про остальных - не знаю. Поэтому, считаю, что пора "вскрываться" ![]() Пароли к архивам ![]() Победила дружба! И спасибо всем за участие, особенно порадовал korvin многообразием вариантов. Што-то смотрю мне OCaml немного приглянулся ![]() Peace! ![]() |
Сообщ.
#124
,
|
|
|
Вариант 1 (С++, без GOTO) Ссылка на онлайн-исполнение
Скрытый текст ![]() ![]() #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) Ссылка на онлайн-исполнение Скрытый текст ![]() ![]() #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; } |
Сообщ.
#125
,
|
|
|
Цитата Majestio @ Будет просто супер, если каждый из участвующих в отдельном сообщении соберет все свои варианты, но уже в текстовом виде под спойлер, а рядом выложит ссылку исполнения в онлайн компиляторе. Онлайн -> https://rextester.com/PKDT40835 Код ![]() ![]() 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); } } } } |
![]() |
Сообщ.
#126
,
|
|
Ocaml #1 ![]() ![]() 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 ![]() ![]() 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 ![]() ![]() 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 ![]() ![]() #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 ![]() ![]() 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 ![]() ![]() 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 ![]() ![]() (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 |
Сообщ.
#127
,
|
|
|
Цитата Majestio @ label: if (true == false) goto label; ![]() Добавлено Цитата Majestio @ Вариант 1 (С++, без GOTO) Видишь, ты даже в синтетической задаче не нашел применение этому оператору. |
![]() |
Сообщ.
#128
,
|
|
Ну тогда и я вскроюсь. В главном цикле приложения: конечный автомат для решений и переходов + сериализация для хранения состояний. Сохранение/восстановление тоже состояния автомата. Всё.
|
Сообщ.
#129
,
|
|
|
Цитата Wound @ Видишь, ты даже в синтетической задаче не нашел применение этому оператору. Ну в моем первом варианте - использование switch-case только это маскирует формально, а по сути - тот же if-goto, только вид сбоку ![]() |
![]() |
Сообщ.
#130
,
|
|
Сообщ.
#131
,
|
|
|
Цитата korvin @ Или ты про конкретно этот паттерн? Скорее он про switch в цикле, ИМХО. Добавлено Я так предполагаю что то типа этого: http://www.devexp.ru/2011/02/konechnye-avtomaty-v-c/ Хотя могу ошибаться. В плюсах я только про такие автоматы слышал. |
Сообщ.
#132
,
|
|
|
Цитата Qraizer @ Ну тогда и я вскроюсь. В главном цикле приложения: конечный автомат для решений и переходов + сериализация для хранения состояний. Сохранение/восстановление тоже состояния автомата. Всё. Да, у всех один и тот же подход. А вот при постановке задачи "пересчеты-с-сохранением" - многовложенные циклы в 17 раз хуже использования прекрасного оператора GOTO ![]() |
Сообщ.
#133
,
|
|
|
Цитата Majestio @ А вот при постановке задачи "пересчеты-с-сохранением" - многовложенные циклы в 17 раз хуже использования прекрасного оператора GOTO ![]() Ты нигде его не использовал свой goto. Твой ивент - профанация. Я почти неделю ждал решения на goto, чтоб его обосрать и где оно? Только korvin, то что у тебя на языке было, написал сегодня или вчера кодом. И все. Короче blah-blah-blah... goto, goto, и где он этот goto в твоих исходниках? Я не вижу его. ![]() Добавлено Я тебе больше скажу - давай расширим ивент до 50 процессов. Только мне лень придумывать им решения. Я хочу посмотреть как распухнут твои исходники на плюсах. |
Сообщ.
#134
,
|
|
|
Цитата Wound @ Я хочу посмотреть как распухнут твои исходники на плюсах. На одно распухание: 2 лямбды + 1 пара значений в таблицу переходов ![]() Добавлено Цитата Wound @ Я почти неделю ждал решения на goto, чтоб его обосрать и где оно? Прости!!! ![]() |
Сообщ.
#135
,
|
|
|
Цитата Majestio @ На одно распухание: 2 лямбды + 1 пара значений в таблицу переходов ![]() Именно, оно уже выглядит пугающим. Когда там будет 100 лямбд - то уже будет на что посмотреть. |