{"id":319776,"date":"2021-03-17T21:00:13","date_gmt":"2021-03-17T21:00:13","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=319776"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=319776","title":{"rendered":"\u201c\u0421\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c\u201d \u043a\u043e\u0434\u0430 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 ASCII \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432, \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430\u043c\u0438 \u0438 demo \u043d\u0430 Blazor WebAssembly"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0430\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u043e\u0439. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0418 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u044b, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043f\u043e \u0433\u0440\u0430\u0444\u0438\u043a\u0443 \u201c2 \u0447\u0435\u0440\u0435\u0437 2\u201d \u0434\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u0437\u0430\u0440\u043f\u043b\u0430\u0442\u044b. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0442\u043f\u0443\u0441\u043a\u0430, \u0441\u043c\u0435\u043d\u044b \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b, \u0443\u0432\u043e\u043b\u044c\u043d\u0435\u043d\u0438\u044f\/\u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044b \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043a\u0430\u0434\u0440\u043e\u0432\u044b\u0435 \u043c\u0435\u0440\u043e\u043f\u0440\u0438\u044f\u0442\u0438\u044f. \u042d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u0438\u043a\u0430\u0437\u043e\u0432, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u201c\u0414\u0430\u0442\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u201d \u0438 \u201c\u0414\u0430\u0442\u0430 \u043a\u043e\u043d\u0446\u0430\u201d, \u0442.\u0435. \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u0439\u0442\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432:<\/p>\n<pre><code class=\"cs\">          2              5         7         9                   |--------------|         |---------|         0              3    4         6    7              10   |--------------|    |---------|    |--------------|         1              4    5              8                   |--------------|    |--------------|              Result           2    3                   7    8                        |----|                   |----|  \/\/ \u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u044f \u0434\u0430\u0442\u044b \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u044b \u043d\u0430 \u0447\u0438\u0441\u043b\u0430<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0438 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0430\u043d\u043e\u043d\u0441\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0430\u043c\u0438 \u0432 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (\u043d\u0430\u0431\u043e\u0440 \u0442\u0435\u0441\u0442\u043e\u0432 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c) \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0443\u044e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e ASCII \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u044b\u0448\u0435.<\/p>\n<p>\u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 ASCII \u0433\u0435\u043d\u0435\u0440\u0438\u043b\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0435 \u0438 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 y=f(x).<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/de0\/d09\/f2a\/de0d09f2a265b3993e5e7ac344ca49a7.png\" width=\"1169\" height=\"784\"><figcaption><\/figcaption><\/figure>\n<p><em>\u0420\u0438\u0441 1. \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 ASCII \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432 \u043d\u0430 Blazor WebAssembly. \u041c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 y \u043e\u0442 x.<\/em><\/p>\n<h2>\u0410\u043d\u043e\u043d\u0441 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430\u043c\u0438 IntervalUtility  <\/h2>\n<p><a href=\"https:\/\/github.com\/AlexeyBoiko\/IntervalUtility\" rel=\"noopener noreferrer nofollow\"><u>GitHub<\/u><\/a>, <a href=\"https:\/\/www.nuget.org\/packages\/IntervalUtility\/\" rel=\"noopener noreferrer nofollow\"><u>NuGet<\/u><\/a>, \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 <a href=\"https:\/\/alexeyboiko.github.io\/IntervalUtility\/\" rel=\"noopener noreferrer nofollow\"><u>demo<\/u><\/a> \u043d\u0430 Blazor WebAssembly.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0430\u0440\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u0443\u0442\u0438\u043b\u0438\u0442\u044b. \u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043d\u0430 <a href=\"https:\/\/github.com\/AlexeyBoiko\/IntervalUtility\" rel=\"noopener noreferrer nofollow\"><u>GitHub<\/u><\/a>.<\/p>\n<p><strong>\u041d\u0430\u0439\u0442\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432<\/strong><\/p>\n<pre><code class=\"cs\">var arrayOfArrays = new[] {     new[] { new Interval&lt;int&gt;(2,5), new Interval&lt;int&gt;(7, 9) },     new[] { new Interval&lt;int&gt;(0,3), new Interval&lt;int&gt;(4, 6),              new Interval&lt;int&gt;(7, 10) },     new[] { new Interval&lt;int&gt;(1,4), new Interval&lt;int&gt;(5, 8) }, };  var intervalUtil = new IntervalUtil(); var res = intervalUtil.Intersections(arrayOfArrays); \/\/ =&gt; [2,3], [7,8]             2              5         7         9                  |--------------|         |---------|        0              3    4         6    7              10  |--------------|    |---------|    |--------------|        1              4    5              8                  |--------------|    |--------------|             Result           2    3                   7    8                       |----|                   |----| <\/code><\/pre>\n<p><strong>\u0412\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432<\/strong><\/p>\n<pre><code class=\"cs\">var intervalsA = new[] { new Interval&lt;int&gt;(1, 5), new Interval&lt;int&gt;(7, 10) }; var intervalsB = new[] { new Interval&lt;int&gt;(0, 2), new Interval&lt;int&gt;(3, 5),                           new Interval&lt;int&gt;(8, 9) };  var intervalUtil = new IntervalUtil(); var res = intervalUtil.Exclude(intervalsA, intervalsB); \/\/ =&gt; [2,3], [7,8], [9,10]        1                   5         7              10      |-------------------|         |--------------| 0         2    3         5              8    9 |---------|    |---------|              |----| Result           2    3                   7    8    9    10           |----|                   |----|    |----|<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0414\u0430\u043b\u044c\u0448\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 ASCII \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432.<\/p>\n<h2>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 ASCII \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432<\/h2>\n<p>\u0418\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 <a href=\"https:\/\/alexeyboiko.github.io\/AsciiDrawerSite\/\" rel=\"noopener noreferrer nofollow\"><u>demo<\/u><\/a> \u043d\u0430 Blazor WebAssembly.<\/p>\n<p>\u0412 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u201c<strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>\u201d. \u042d\u0442\u0438 \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u0438\u0435\u043c\/\u043f\u0430\u0442\u0442\u0435\u0440\u043d. \u041f\u043e \u0437\u0430\u0434\u0443\u043c\u043a\u0435, \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u201c\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e\u201d, \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u201c\u0443\u043c\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0441\u043a\u0438\u0435\u201d \u0442\u0435\u0440\u043c\u0438\u043d\u044b &#8212; \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0440\u0430\u0442\u043a\u0438\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0438\u0434\u0435\u0439.<\/p>\n<h3>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f: \u201c\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c ASCII\u201d \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u043c\u0438<\/h3>\n<p>\u041d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (\u0438\u043b\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432). \u041f\u0443\u0441\u0442\u044c \u201c\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u201d \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u0434\u043b\u0438\u043d\u044b. \u0422\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u041c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0431\u043b\u043e\u043a &#8212; \u043e\u0434\u0438\u043d \u043f\u0438\u043a\u0441\u0435\u043b\u044c. \u041f\u0438\u043a\u0441\u0435\u043b\u0438 \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430\u043c\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f. \u0412\u044b\u0441\u043e\u0442\u0430 \u0431\u043b\u043e\u043a\u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0430 &#8212; \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430.<\/p>\n<p>\u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u0443 \u043f\u0438\u043a\u0441\u0435\u043b\u044f, \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438,<\/p>\n<\/li>\n<li>\n<p>\u043d\u043e\u043c\u0435\u0440 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438\u043b\u0438, \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043d\u043e\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\/\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u043d\u043e\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435.<\/p>\n<pre><code class=\"cs\">public class DrawerProcessor {     public void Draw(         \/\/ \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0431\u043b\u043e\u043a \u043f\u043e \u043d\u043e\u043c\u0435\u0440\u0443 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u043d\u043e\u043c\u0435\u0440\u0443 \u0431\u043b\u043e\u043a\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435         Func&lt;int, int, DrawerBlock&gt; blockDraw,          \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u0433\u0434\u0430 \u0431\u043b\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c         Action&lt;string, bool&gt; onBlockDraw) {          int row = 0;         int blockIndex = 0;          var done = false;         while (!done) {             var block = blockDraw(row, blockIndex);              switch (block.Command) {                 case DrawerCommand.Continue:                     blockIndex = blockIndex + block.Displacement;                     break;                 case DrawerCommand.NewLine:                     row = row + 1;                     blockIndex = 0;                     break;                 case DrawerCommand.End:                     done = true;                     break;             }              onBlockDraw(block.Value, done);         }     } }  public class DrawerBlock {     public string Value { get; set; }     public DrawerCommand Command { get; set; }      \/\/ \u0421\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0431\u043b\u043e\u043a\u0430,     \/\/ Value \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u043b\u043e\u043a\u043e\u0432     \/\/ \u0415\u0441\u043b\u0438 \u0432 Value \u0434\u0432\u0430 \u0431\u043b\u043e\u043a\u0430 \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043d\u0430\u0434\u043e \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 2     public int Displacement { get; set; } = 1; }<\/code><\/pre>\n<p>DrawerProcessor \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439 \u0431\u043b\u043e\u043a\u0430. DrawerProcessor \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439:<\/p>\n<ul>\n<li>\n<p>\u043e\u043d \u043d\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u043b\u043e\u043a\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u043b\u0438 \u043d\u0435\u0442,<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u0438\u043b\u0438 \u043f\u0440\u0435\u0440\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 DrawerProcessor:<\/p>\n<pre><code class=\"cs\">var drawer = new DrawerProcessor(); drawer.Draw(     (row, blockIndex) =&gt; {         \/\/ \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0443\u0441\u043a\u0435 \u043a\u043e\u0434\u0430          if (row == 3)             return new DrawerBlock {                  Command = DrawerCommand.End              };          if(blockIndex == 3)             return new DrawerBlock {                 Value = Environment.NewLine,                 Command = DrawerCommand.NewLine             };          return new DrawerBlock {             Value = $\"[{row},{blockIndex}]\",             Command = DrawerCommand.Continue         };     },     (blockStr, isEnd) =&gt; Console.Write(blockStr) );  \u0412\u044b\u0432\u043e\u0434 [0,0][0,1][0,2] [1,0][1,1][1,2] [2,0][2,1][2,2]  \/\/ \u041b\u0438\u0441\u0442\u0438\u043d\u0433 1. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 DrawerProcessor. \/\/ \u041d\u0435 \u043b\u0443\u0447\u0448\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f - \u0432\u0441\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \/\/ \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0443\u0441\u043a\u0435 \u043a\u043e\u0434\u0430 (\u0432 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0435  (row, blockIndex) =&gt; { .. }), \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0441\u0442\u0430\u0442\u044c\u0441\u044f.<\/code><\/pre>\n<p>\u0417\u0430\u0447\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u043e\u0439\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438, \u0438 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0437\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e DrawerBlock.Displacement? \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c &#8212; \u0434\u043b\u0438\u043d\u0430 \u0431\u043b\u043e\u043a\u0430 1 \u0441\u0438\u043c\u0432\u043e\u043b, \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b \u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u0438 \u043a \u043a\u043e\u043d\u0446\u0430\u043c:<\/p>\n<pre><code class=\"cs\">8         11 |---------|<\/code><\/pre>\n<p>\u201c11\u201d &#8212; \u044d\u0442\u043e \u0434\u0432\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u0430. \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u201c11\u201d \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0441\u043b\u043e\u0436\u043d\u043e &#8212; \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u201c\u043f\u0438\u0448\u0435\u043c \u201c11\u201d, \u201c1\u201d \u0443\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 &#8212; \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0435\u0449\u0435 \u201c1\u201d \u201d. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0440\u0435\u0445\u0437\u043d\u0430\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e? \u041f\u0440\u043e\u0449\u0435 \u0441\u0440\u0430\u0437\u0443 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u201c11\u201d \u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430: \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c DrawerBlock.Displacement = 2.<\/p>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>: \u0435\u0441\u043b\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u201c11\u201d \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438, \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u043b \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0431\u043b\u043e\u043a \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434-\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439). \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 (\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0431\u043b\u043e\u043a \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b \u201c1\u201d &#8212; \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0434\u043e \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0435 \u201c1\u201d), \u0442.\u0435. \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f &#171;\u0441\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430&#187;. \u0421\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044e.<\/p>\n<\/blockquote>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430:<\/p>\n<pre><code class=\"cs\">static class Block {     public static DrawerBlock Continue(string val, int displacement = 1)                  =&gt; new() {             Command = DrawerCommand.Continue,             Value = val,             Displacement = displacement         };      public static DrawerBlock End() =&gt;         new() { Command = DrawerCommand.End };      public static DrawerBlock NewLine() =&gt;         new() {              Command = DrawerCommand.NewLine,              Value = Environment.NewLine          }; }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">return new DrawerBlock {     Value = Environment.NewLine,     Command = DrawerCommand.NewLine };<\/code><\/pre>\n<p>\u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0440\u043e\u0447\u0435:<\/p>\n<pre><code class=\"cs\">return Block.NewLine();<\/code><\/pre>\n<h3>\u0420\u0438\u0441\u0443\u0435\u043c \u043d\u0435\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0431\u043b\u043e\u043a\u0430\u043c\u0438<\/h3>\n<p>\u0412 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 1 \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0443\u0441\u043a\u0435 \u043a\u043e\u0434\u0430 (\u0432 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0435 (row, blockIndex) =&gt; { .. }). \u041f\u043e\u043a\u0430 \u044d\u0442\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043d\u0435 \u043c\u043d\u043e\u0433\u043e, \u044d\u0442\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e. \u041d\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0441\u0442\u0430\u043d\u0438\u0438, \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u044b\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439\/\u0443\u0441\u043b\u043e\u0432\u0438\u0439 &#8212;&nbsp; \u043a\u043e\u0434 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430 (row, blockIndex) =&gt; { .. } \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: \u0432 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 1 \u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0438 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0438 \u0441 \u0446\u0438\u0444\u0440\u0430\u043c\u0438:<\/p>\n<pre><code class=\"cs\">[0,0][0,1][0,2] [1,0][1,1][1,2] [2,0][2,1][2,2]<\/code><\/pre>\n<p>\u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u0444\u0440\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0430\u0445 \u0432 \u0448\u0430\u0445\u043c\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435:<\/p>\n<pre><code class=\"cs\">[   ][0,1][   ] [1,0][   ][1,2] [   ][2,1][   ]<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c \u043a\u043e\u0434 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430 (row, blockIndex) =&gt; { .. }.<\/p>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>: \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u201c\u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438\/\u0437\u0430\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438\u201d &#8212; \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u043e\u0432\u043e\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u043b\u0435\u0447\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u043d\u0435\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0442.\u0435. \u043a\u043e\u0434 \u201c\u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u0442 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f\u201d &#8212; \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u0418 \u043a\u043e\u0434 \u201c\u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0442 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439\u201d &#8212; \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0443\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>\u0422.\u0435. \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434, \u043a\u0430\u043a \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u0441\u043c. \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u0434\u0435\u043b), \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430. \u0421\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044e.<\/p>\n<\/blockquote>\n<p>\u041f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041f\u0443\u0441\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 (\u201c\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a \u0441 \u0446\u0438\u0444\u0440\u0430\u043c\u0438\u201d, \u201c\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a \u0431\u0435\u0437 \u0446\u0438\u0444\u0440\u201d, \u201c\u0431\u043b\u043e\u043a \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438\u201d, \u201c\u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0438\u0439 \u0431\u043b\u043e\u043a\u201d) \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f (\u0434\u0435\u043b\u0435\u0433\u0430\u0442).<\/p>\n<pre><code class=\"cs\">\/\/ \u0431\u043b\u043e\u043a \"\u043a\u043e\u043d\u0435\u0446\" DrawerBlock end(int row, int blockIndex) =&gt;     row == 3 ? Block.End() : null;  \/\/ \u0431\u043b\u043e\u043a \"\u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430\" DrawerBlock newLine(int row, int blockIndex) =&gt;     blockIndex == 3 ? Block.NewLine() : null;  \/\/ \u0431\u043b\u043e\u043a \"\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a \u0441 \u0446\u0438\u0444\u0440\u0430\u043c\u0438\" DrawerBlock brick(int row, int blockIndex) =&gt;      Block.Continue($\"[{row},{blockIndex}]\");<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u043b\u043e\u043a\u043e\u0432:<\/p>\n<pre><code class=\"cs\">public class BlockDrawer {     readonly DrawerProcessor _DrawerProcessor;     public BlockDrawer(DrawerProcessor drawerProcessor) {         _DrawerProcessor = drawerProcessor              ?? throw new ArgumentNullException(nameof(drawerProcessor));     }      public void Draw(         IReadOnlyCollection&lt;Func&lt;int, int, DrawerBlock&gt;&gt; blockDrawers,          Action&lt;string, bool&gt; onBlockDraw) {          _DrawerProcessor.Draw(                 (row, blockIndex) =&gt; {                     foreach (var bd in blockDrawers) {                         var block = bd(row, blockIndex);                         if (block != null)                             return block;                     }                     return                          new DrawerBlock { Command = DrawerCommand.End };                 },                 onBlockDraw             );     } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cs\">\/\/ \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0431\u043b\u043e\u043a\u043e\u0432 \u0432\u0430\u0436\u0435\u043d var blockDrawers = new Func&lt;int, int, DrawerBlock&gt;[] {      end,     newLine,     brick };  var drawer = new DrawerProcessor(); var blockDrawer = new BlockDrawer(drawer);  blockDrawer.Draw(     blockDrawers,     (blockStr, isEnd) =&gt; Console.Write(blockStr));<\/code><\/pre>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0440\u0438\u0441\u0443\u0435\u0442 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0432 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 1 &#8212; \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0438 \u0441 \u0446\u0438\u0444\u0440\u0430\u043c\u0438.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0438 \u0431\u0435\u0437 \u0446\u0438\u0444\u0440:<\/p>\n<pre><code class=\"cs\">static void Main(string[] args) {      DrawerBlock end(int row, int blockIndex) =&gt; ...;     DrawerBlock newLine(int row, int blockIndex) =&gt; ...;     DrawerBlock brick(int row, int blockIndex) =&gt; ...;      \/\/ \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a \u0431\u0435\u0437 \u0446\u0438\u0444\u0440     DrawerBlock brickEmpty(int row, int blockIndex) =&gt;         ((row + blockIndex) % 2 == 0) ? Block.Continue($\"[   ]\") : null;      var blockDrawers = new Func&lt;int, int, DrawerBlock&gt;[] {          end,         newLine,         brickEmpty, \/\/ \u0432\u0430\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0434 brick         brick     };      var drawer = new DrawerProcessor();     var blockDrawer = new BlockDrawer(drawer);      blockDrawer.Draw(         blockDrawers,         (blockStr, isEnd) =&gt; Console.Write(blockStr)); }  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 [   ][0,1][   ] [1,0][   ][1,2] [   ][2,1][   ]    \/\/ \u041b\u0438\u0441\u0442\u0438\u043d\u0433 2. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 DrawerProcessor. \/\/ \u0417\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f. \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0436\u0435\u043d\u044b \u0432 main - \u043d\u0435 \u043b\u0443\u0447\u0448\u0438\u0439 \u0432\u0430\u0440\u0438\u043d\u0442, \/\/ \u0435\u0441\u043b\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435.<\/code><\/pre>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u201c\u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u043e\u0431\u044f\u0437\u0430\u043d\u043d\u043e\u0441\u0442\u0435\u0439\u201d. \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u043e\u0432 \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0446\u0435\u043f\u043e\u0447\u043a\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439. \u041c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0431\u043b\u043e\u043a\u0438, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u0441\u043b\u0430\u0431\u0430\u044f \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u0442\u044c &#8212; \u0432\u0430\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043d\u0443\u0436\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.  <\/p>\n<\/blockquote>\n<p>\u0412 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 2 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0436\u0435\u043d\u044b \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 Main. \u041d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0430 Main. \u0418\u0441\u043f\u0440\u0430\u0432\u0438\u043c. \u041f\u0443\u0441\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441.<\/p>\n<pre><code class=\"cs\">public interface IContextDrawerBlock&lt;TDrawerContext&gt; {     int Priority { get; }     DrawerBlock Draw(int row, int blockIndex, TDrawerContext context); }<\/code><\/pre>\n<p>\u0412 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u043b\u043e\u043a\u043e\u0432 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d context, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043d\u0438\u0436\u0435 \u043a\u043b\u0430\u0441\u0441 \u0431\u043b\u043e\u043a\u0430 \u043a\u043e\u043d\u0446\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0443\u0437\u043d\u0430\u0435\u0442 \u043e \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u043b-\u0432\u0435 \u0441\u0442\u0440\u043e\u043a \u0447\u0435\u0440\u0435\u0437 context.RowCount:<\/p>\n<pre><code class=\"cs\">class EndDrawer : IContextDrawerBlock&lt;SampleDrawContext&gt; {     public int Priority =&gt; 10;     public DrawerBlock Draw(int row, int blockIndex,         SampleDrawContext context)                 =&gt; row == context.RowCount ? Block.End() : null; }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0438 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438, \u043a\u043b\u0430\u0441\u0441\u044b \u0431\u043b\u043e\u043a\u043e\u0432 \u043d\u0430\u0434\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0442\u044c:<\/p>\n<pre><code class=\"cs\">public class ContextBlockDrawer&lt;TDrawerContext&gt; {     readonly IReadOnlyCollection&lt;IContextDrawerBlock&lt;TDrawerContext&gt;&gt; _BlockDrawers;     readonly BlockDrawer _Drawer;      public ContextBlockDrawer(         BlockDrawer drawer,          IReadOnlyCollection&lt;IContextDrawerBlock&lt;TDrawerContext&gt;&gt; blockDrawers) {          _Drawer = drawer ?? throw ...          _BlockDrawers = blockDrawers?.Any() == true             ? blockDrawers.OrderBy(bd =&gt; bd.Priority).ToArray()             : throw ...     }      public void Draw(TDrawerContext drawerContext,         Action&lt;string, bool&gt; onBlockDraw) {          var drawers = _BlockDrawers.Select(bd =&gt; {             DrawerBlock draw(int row, int blockIndex) =&gt;                  bd.Draw(row, blockIndex, drawerContext);              return (Func&lt;int, int, DrawerBlock&gt;)draw;         })         .ToArray();          _Drawer.Draw(drawers, onBlockDraw);     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0430\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">\/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 ContextBlockDrawer  var drawer = new DrawerProcessor(); var blockDrawer = new BlockDrawer(drawer);   var blockDrawers = new IContextDrawerBlock&lt;SampleDrawContext&gt;[] {     new EndDrawer(),     new EndLineDrawer(),     new BrickEmptyDrawer(),     new BrickDrawer(), };  var ctxBlockDrawer = new ContextBlockDrawer&lt;SampleDrawContext&gt;(     blockDrawer,      blockDrawers);   \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 ContextBlockDrawer  ctxBlockDrawer.Draw(     new SampleDrawContext {         RowCount = 3,         BlockCount = 3     },     (blockStr, isEnd) =&gt; Console.Write(blockStr));  \/\/ \u041b\u0438\u0441\u0442\u0438\u043d\u0433 3. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 ContextBlockDrawer. \/\/ \u041a\u0430\u0436\u0434\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u0435. \/\/ \u0412\u0432\u0435\u0434\u0435\u043d \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f. \/\/ \u041a\u043b\u0430\u0441\u0441\u044b \u0431\u043b\u043e\u043a\u043e\u0432 \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u043d\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439, \/\/ \u043e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0430\u043a - \u043c\u0435\u0448\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c Priority.<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0431\u043b\u043e\u043a\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e Priority, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a\u0438\u0435 Priority \u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u0431\u043b\u043e\u043a\u043e\u0432. \u041f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442 \u043d\u043e\u0432\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0432\u044b\u0448\u0435 \u201c\u0431\u043b\u043e\u043a\u0430 \u043a\u043e\u043d\u0446\u0430\u201d. \u0422.\u0435. \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u0435\u0436\u0434\u0443 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0435\u0441\u0442\u044c \u0441\u0432\u044f\u0437\u044c (\u0445\u043e\u0442\u044f \u0438 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u0430\u044f).<\/p>\n<h3>\u041d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0442\u0430\u0440\u044b\u0439 \u043a\u043e\u0434, \u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u0438<\/h3>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f ContextBlockDrawer \u0432 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 3. ContextBlockDrawer \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 (\u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442) \u0432 \u0441\u0432\u043e\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 BlockDrawer \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440. BlockDrawer, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 (\u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442) DrawerProcessor, \u0438 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0435\u0433\u043e \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440.<\/p>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>:<\/p>\n<p>ContextBlockDrawer -&gt;\u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 (\u0447\u0438\u0442\u0430\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442)-&gt; BlockDrawer -&gt; \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 -&gt; DrawerProcessor.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u201c\u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0435\u0439\u201d.<\/p>\n<p>\u0412 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 3 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 ContextBlockDrawer \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u201c\u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439\u201d. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0430\u043c\u044b\u0439 \u044f\u0432\u043d\u044b\u0439 (\u0447\u0438\u0442\u0430\u0439 \u043b\u0443\u0447\u0448\u0438\u0439) \u0432\u0430\u0440\u0438\u0430\u043d\u0442: \u201c\u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u201d:<\/p>\n<p>&#8212; \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044f \u043a\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430, \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u043d\u043e \u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 (\u0432\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u0435\u0441\u0442\u0435 &#8212; \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435)<\/p>\n<p>&#8212; \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u043d\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<\/blockquote>\n<p>\u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f: \u0435\u0449\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u0435 \u0438\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u201c\u0441\u0435\u0440\u0432\u0438\u0441 \u043b\u043e\u043a\u0430\u0442\u043e\u0440\u201d:<\/p>\n<pre><code class=\"cs\">\/\/ \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u0435  \/\/ (\u0445\u0443\u0436\u0435 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440) var ctxBlockDrawer = new ContextBlockDrawer(); ctxBlockDrawer.BlockDrawer = blockDrawer;   \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0440\u0432\u0438\u0441 \u043b\u043e\u043a\u0430\u0442\u043e\u0440 \/\/ (\u0445\u0443\u0436\u0435 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440) public class ContextBlockDrawer&lt;TDrawerContext&gt; {     ...     public void Draw(TDrawerContext drawerContext,          Action&lt;string, bool&gt; onBlockDraw) {                     ...         var blockDrawer = ServiceLocator.Get&lt;BlockDrawer&gt;();         ...     } }  \/\/ \u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043b\u0443\u0447\u0448\u0435 \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c<\/code><\/pre>\n<p>\u041a\u0440\u043e\u043c\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 BlockDrawer \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 (\u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f), \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u0432 ContextBlockDrawer \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 BlockDrawer (\u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044e):<\/p>\n<pre><code class=\"cs\">public class ContextBlockDrawer&lt;TDrawerContext&gt; {     readonly IReadOnlyCollection&lt;IContextDrawerBlock&lt;TDrawerContext&gt;&gt;  _BlockDrawers;     readonly BlockDrawer _Drawer;      public ContextBlockDrawer(         IReadOnlyCollection&lt;IContextDrawerBlock&lt;TDrawerContext&gt;&gt; blockDrawers) {          \/\/ \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f         var drawer = new DrawerProcessor();         _Drawer = new BlockDrawer(drawer);         ...     }<\/code><\/pre>\n<p>\u0442\u043e\u0433\u0434\u0430 \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 ContextBlockDrawer \u0438 BlockDrawer \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u0441\u0438\u043b\u044c\u043d\u043e\u0439: ContextBlockDrawer \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c BlockDrawer, \u043d\u043e \u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c BlockDrawer. \u0418 \u0437\u043d\u0430\u0442\u044c \u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044f\u0445 BlockDrawer(\u043e DrawerProcessor). \u0422.\u0435. \u0441\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0435\u0442, \u0430 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0435\u0439 \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0435\u0442 \u0438 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0433\u043e\u0442\u043e\u0432 ASCII \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0441\u0445\u0435\u043c &#8212; <a href=\"https:\/\/alexeyboiko.github.io\/IntervalUtility\/\" rel=\"noopener noreferrer nofollow\"><u>\u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432<\/u><\/a>.<\/p>\n<h3>\u0414\u0435\u043a\u0430\u0440\u0442\u043e\u0432\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442<\/h3>\n<p>\u0420\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u043a\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 y \u043e\u0442 x \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ContextBlockDrawer \u043c\u043e\u0436\u043d\u043e, \u043d\u043e \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e:<\/p>\n<pre><code class=\"cs\">public interface IContextDrawerBlock&lt;TDrawerContext&gt; {     int Priority { get; }     DrawerBlock Draw(int row, int blockIndex, TDrawerContext context); }<\/code><\/pre>\n<p>Draw \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 row \u0438 blockIndex. \u0420\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0434\u0435\u0442 \u0441\u043f\u0440\u0430\u0432\u0430 \u043d\u0430\u043b\u0435\u0432\u043e \u0438 \u0441\u0432\u0435\u0440\u0445\u0443 \u0432\u043d\u0438\u0437. \u0414\u043b\u044f \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432 y \u043e\u0442 \u0445 \u0431\u044b\u043b\u043e \u0431\u044b \u0443\u0434\u043e\u0431\u043d\u0435\u0439:<\/p>\n<pre><code class=\"cs\">public interface I\u0421artesianDrawerBlock&lt;TDrawerContext&gt; {     int Priority { get; }     DrawerBlock Draw(float x, float y, TDrawerContext context); }<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u044d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a \u0440\u0438\u0441\u0443\u0435\u0442 \u043f\u0440\u044f\u043c\u0443\u044e:<\/p>\n<pre><code class=\"cs\">class LineDrawer : I\u0421artesianDrawerBlock&lt;\u0421artesianDrawerContext&gt; {     public int Priority =&gt; 40;      public DrawerBlock Draw(float x, float y,         \u0421artesianDrawerContext context) {          var y1 = x; \/\/ \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u044f\u043c\u043e\u0439 y=x                  \/\/ \u0435\u0441\u043b\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 y1 \u0440\u0430\u0432\u043d\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 y         \/\/ (c \u0443\u0447\u0435\u0442\u043e\u043c \u043e\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f)         if (Math.Abs(y1 -y) &lt;= context.Rounding)             return Block.Continue(\"#\");                      return null;     } }<\/code><\/pre>\n<p>\u041d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 I\u0421artesianDrawerBlock \u0441 \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c ContextBlockDrawer. \u041d\u0443\u0436\u0435\u043d \u0430\u0434\u0430\u043f\u0442\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u044b\u043a\u0443\u0435\u0442 \u201cDraw(int row, int blockIndex, TDrawerContext context)\u201d \u0438 \u201cDrawerBlock Draw(float x, float y, TDrawerContext context)\u201d:<\/p>\n<pre><code class=\"cs\">public class \u0421artesianDrawerAdapter&lt;TDrawerContext&gt; :      IContextDrawerBlock&lt;TDrawerContext&gt;     where TDrawerContext : I\u0421artesianDrawerAdapterContext {      readonly I\u0421artesianDrawerBlock&lt;TDrawerContext&gt; _cartesianDrawer;     public \u0421artesianDrawerAdapter(     \t\tI\u0421artesianDrawerBlock&lt;TDrawerContext&gt; cartesianDrawer) {          _cartesianDrawer = cartesianDrawer ?? throw ...     }          public int Priority =&gt; _cartesianDrawer.Priority;      public DrawerBlock Draw(int row, int blockIndex, TDrawerContext context) {          float x = blockIndex \/ context.Scale + context.XMin;         float y = context.YMax - row \/ context.Scale;         return _cartesianDrawer.Draw(x, y, context);     } }  public interface I\u0421artesianDrawerAdapterContext {     public float Scale { get; }     public float XMin { get; }     public float YMax { get; } }<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0421artesianDrawerAdapter &#8212; \u0433\u0440\u0430\u0444\u0438\u043a \u043f\u0440\u044f\u043c\u043e\u0439:<\/p>\n<pre><code class=\"cs\">\/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 ctxBlockDrawer \u0434\u043b\u044f \u0434\u0435\u043a\u0430\u0440\u0442\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442  var drawer = new DrawerProcessor(); var blockDrawer = new BlockDrawer(drawer);   var blockDrawers = new I\u0421artesianDrawerBlock&lt;\u0421artesianDrawerContext&gt;[] {         new EndDrawer(),         new EndLineDrawer(),         new LineDrawer(),         new EmptyDrawer()     }     .Select(dd =&gt;          \/\/ \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0430\u0434\u0430\u043f\u0442\u0435\u0440\u0430         new \u0421artesianDrawerAdapter&lt;\u0421artesianDrawerContext&gt;(dd))     .ToArray();  var ctxBlockDrawer = new ContextBlockDrawer&lt;\u0421artesianDrawerContext&gt;(     blockDrawer,     blockDrawers);   \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 ctxBlockDrawer  ctxBlockDrawer.Draw(new \u0421artesianDrawerContext {     XMin = -2,     XMax = 30,     YMin = -2,     YMax = 8,     Scale = 5,     Rounding = 0.1F }, (blockStr, isEnd) =&gt; Console.Write(blockStr));<\/code><\/pre>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>: \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043e\u0442 IContextDrawerBlock \u043a I\u0421artesianDrawerBlock \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043f\u0430\u0442\u0442\u0435\u0440\u043d \u201c\u0430\u0434\u0430\u043f\u0442\u0435\u0440\u201d &#8212; \u0421artesianDrawerAdapter.  <\/p>\n<\/blockquote>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u0435\u0435:<\/p>\n<pre><code class=\"cs\">\/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435  ... var ctxBlockDrawer = ...  var asciiDrawer =      new AsciiDrawer&lt;\u0421artesianDrawerContext&gt;(ctxBlockDrawer);   \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435  asciiDrawer     \/\/ \u0432\u043e\u0442 \u0442\u0443\u0442 \u0441\u0442\u0430\u043b\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u0435\u0435     .OnBlockDraw((blockStr, isEnd) =&gt; Console.Write(blockStr))     .Draw(new \u0421artesianDrawerContext {         XMin = -2,         XMax = 30,         ...     });  \/\/ \u041b\u0438\u0441\u0442\u0438\u043d\u0433 4. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 AsciiDrawer.<\/code><\/pre>\n<p>\u041a\u043e\u0434 AsciiDrawer: <\/p>\n<pre><code class=\"cs\">public class AsciiDrawer&lt;TDrawerContext&gt; {     readonly ContextBlockDrawer&lt;TDrawerContext&gt; _ContextBlockDrawer;     readonly Action&lt;string, bool&gt; _onBlockDraw;     public AsciiDrawer(         ContextBlockDrawer&lt;TDrawerContext&gt; contextBlockDrawer,          Action&lt;string, bool&gt; onBlockDraw = null) {          _ContextBlockDrawer = contextBlockDrawer ?? throw ...         _onBlockDraw = onBlockDraw;     }      public AsciiDrawer&lt;TDrawerContext&gt; OnBlockDraw(         Action&lt;string, bool&gt; onBlockDraw) {          \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440         \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c this (return this) \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043f\u0440\u0438 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438         return new AsciiDrawer&lt;TDrawerContext&gt;(             _ContextBlockDrawer,              onBlockDraw);     }      public void Draw(TDrawerContext context) {         if (_onBlockDraw == null)                 throw new InvalidOperationException(\"Use .OnBlockDraw to set up draw output\");          _ContextBlockDrawer.Draw(context, _onBlockDraw);     } }<\/code><\/pre>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>: AsciiDrawer \u0441\u0434\u0435\u043b\u0430\u043d \u201c\u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u044b\u043c\u201d &#8212; \u043d\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b \u0438\u0437\u043c\u0435\u043d\u044f\u043b\u0438 \u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435. OnBlockDraw \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 (\u0430 \u043d\u0435 this). \u201c\u041d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u201d \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u0441\u0442\u0438.<\/p>\n<\/blockquote>\n<h3>\u0412\u0441\u0435 SingleInstance<\/h3>\n<p>\u0412 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 4 \u0432\u0441\u0435, \u0447\u0442\u043e \u043f\u043e\u0434 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u043c \u201c\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u201d, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e IoC \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u0412 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 AsciiDrawer.<\/p>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442\u044b ASCII \u0440\u0438\u0441\u043e\u0432\u0430\u043b\u044c\u0449\u0438\u043a\u0430 \u043d\u0435 \u0445\u0440\u0430\u043d\u044f\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439, \u0435\u0449\u0435 \u043e\u043d\u0438 \u201c\u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u201d &#8212; \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u043d\u043e \u0431\u0435\u0437 \u043e\u043f\u0430\u0441\u0435\u043d\u0438\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u044b \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445. \u0412 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043d\u0430\u0448\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 IoC \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u043a\u0430\u043a SingleInstance.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0432 <a href=\"https:\/\/alexeyboiko.github.io\/AsciiDrawerSite\/\" rel=\"noopener noreferrer nofollow\"><u>Blazor WebAssembly \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438<\/u><\/a> \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0435 Run \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">var res = new StringBuilder();  AsciiDrw     .OnBlockDraw((blockStr, isEnd) =&gt; {         res.Append(blockStr);         if (isEnd)             \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 UI             Res = res.ToString();     })     .Draw(new FuncsDrawerContext {          \/\/ \u043f\u043e\u043b\u044f \u0444\u043e\u0440\u043c\u044b         Rounding = Rounding,         Scale = Scale,         XMin = Xmin,         XMax = Xmax,         YMin = Ymin,         YMax = Ymax,          \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f y \u043e\u0442 x         Functions = funcs     });<\/code><\/pre>\n<p>\u0412 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0431\u043b\u043e\u043a\u0438:<\/p>\n<pre><code class=\"cs\">new EndDrawer(), new EndLineDrawer(), new FuncsDrawer(), \/\/ \u0440\u0438\u0441\u0443\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 new XAxisDrawer(), \/\/ \u0440\u0438\u0441\u0443\u0435\u0442 \u043e\u0441\u044c X new YAxisDrawer(), \/\/ \u0440\u0438\u0441\u0443\u0435\u0442 \u043e\u0441\u044c Y new EmptyDrawer()<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u0435\u0449\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c:<\/p>\n<ul>\n<li>\n<p>\u0431\u043b\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043a\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u043f\u043b\u043e\u0449\u0430\u0434\u044c \u043f\u043e\u0434 \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u043c,<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0448\u043a\u0430\u043b\u0443 \u043d\u0430 \u043e\u0441\u044f\u0445,<\/p>\n<\/li>\n<li>\n<p>\u0431\u043b\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0442\u043e\u0447\u043a\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0434\u0430\u0436\u0435 \u0448\u043a\u043e\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0435\u0440\u044c\u0435\u0437\u043d\u043e \u0437\u0430\u043f\u0443\u0442\u0430\u0442\u044c &#8212; \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0437\u043d\u0430\u0442\u044c \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u044b \u0438 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/547614\/\"> https:\/\/habr.com\/ru\/post\/547614\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<p>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0430\u043c\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u043e\u0439. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0431\u0443\u0445\u0433\u0430\u043b\u0442\u0435\u0440\u0441\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0418 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u044b, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0442\u0440\u0443\u0434\u043d\u0438\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043f\u043e \u0433\u0440\u0430\u0444\u0438\u043a\u0443 \u201c2 \u0447\u0435\u0440\u0435\u0437 2\u201d \u0434\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u0437\u0430\u0440\u043f\u043b\u0430\u0442\u044b. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043e\u0442\u043f\u0443\u0441\u043a\u0430, \u0441\u043c\u0435\u043d\u044b \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b, \u0443\u0432\u043e\u043b\u044c\u043d\u0435\u043d\u0438\u044f\/\u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u043e\u0442\u0434\u0435\u043b\u044b \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043a\u0430\u0434\u0440\u043e\u0432\u044b\u0435 \u043c\u0435\u0440\u043e\u043f\u0440\u0438\u044f\u0442\u0438\u044f. \u042d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u043f\u0440\u0438\u043a\u0430\u0437\u043e\u0432, \u0443 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0435\u0441\u0442\u044c \u201c\u0414\u0430\u0442\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u201d \u0438 \u201c\u0414\u0430\u0442\u0430 \u043a\u043e\u043d\u0446\u0430\u201d, \u0442.\u0435. \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u044b \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430\u0439\u0442\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432:<\/p>\n<pre><code class=\"cs\">          2              5         7         9                   |--------------|         |---------|         0              3    4         6    7              10   |--------------|    |---------|    |--------------|         1              4    5              8                   |--------------|    |--------------|              Result           2    3                   7    8                        |----|                   |----|  \/\/ \u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0432\u043e\u0441\u043f\u0440\u0438\u044f\u0442\u0438\u044f \u0434\u0430\u0442\u044b \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u044b \u043d\u0430 \u0447\u0438\u0441\u043b\u0430<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447 \u0438 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0430\u043d\u043e\u043d\u0441\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u0435\u0440\u0438\u043e\u0434\u0430\u043c\u0438 \u0432 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (\u043d\u0430\u0431\u043e\u0440 \u0442\u0435\u0441\u0442\u043e\u0432 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c) \u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0443\u044e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e ASCII \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u0432\u044b\u0448\u0435.<\/p>\n<p>\u041e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 ASCII \u0433\u0435\u043d\u0435\u0440\u0438\u043b\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0435 \u0438 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 y=f(x).<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p><em>\u0420\u0438\u0441 1. \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 ASCII \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432 \u043d\u0430 Blazor WebAssembly. \u041c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 y \u043e\u0442 x.<\/em><\/p>\n<h2>\u0410\u043d\u043e\u043d\u0441 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430\u043c\u0438 IntervalUtility  <\/h2>\n<p><a href=\"https:\/\/github.com\/AlexeyBoiko\/IntervalUtility\" rel=\"noopener noreferrer nofollow\"><u>GitHub<\/u><\/a>, <a href=\"https:\/\/www.nuget.org\/packages\/IntervalUtility\/\" rel=\"noopener noreferrer nofollow\"><u>NuGet<\/u><\/a>, \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 <a href=\"https:\/\/alexeyboiko.github.io\/IntervalUtility\/\" rel=\"noopener noreferrer nofollow\"><u>demo<\/u><\/a> \u043d\u0430 Blazor WebAssembly.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0430\u0440\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u0443\u0442\u0438\u043b\u0438\u0442\u044b. \u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043d\u0430 <a href=\"https:\/\/github.com\/AlexeyBoiko\/IntervalUtility\" rel=\"noopener noreferrer nofollow\"><u>GitHub<\/u><\/a>.<\/p>\n<p><strong>\u041d\u0430\u0439\u0442\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432<\/strong><\/p>\n<pre><code class=\"cs\">var arrayOfArrays = new[] {     new[] { new Interval&lt;int&gt;(2,5), new Interval&lt;int&gt;(7, 9) },     new[] { new Interval&lt;int&gt;(0,3), new Interval&lt;int&gt;(4, 6),              new Interval&lt;int&gt;(7, 10) },     new[] { new Interval&lt;int&gt;(1,4), new Interval&lt;int&gt;(5, 8) }, };  var intervalUtil = new IntervalUtil(); var res = intervalUtil.Intersections(arrayOfArrays); \/\/ =&gt; [2,3], [7,8]             2              5         7         9                  |--------------|         |---------|        0              3    4         6    7              10  |--------------|    |---------|    |--------------|        1              4    5              8                  |--------------|    |--------------|             Result           2    3                   7    8                       |----|                   |----| <\/code><\/pre>\n<p><strong>\u0412\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u043e\u0432<\/strong><\/p>\n<pre><code class=\"cs\">var intervalsA = new[] { new Interval&lt;int&gt;(1, 5), new Interval&lt;int&gt;(7, 10) }; var intervalsB = new[] { new Interval&lt;int&gt;(0, 2), new Interval&lt;int&gt;(3, 5),                           new Interval&lt;int&gt;(8, 9) };  var intervalUtil = new IntervalUtil(); var res = intervalUtil.Exclude(intervalsA, intervalsB); \/\/ =&gt; [2,3], [7,8], [9,10]        1                   5         7              10      |-------------------|         |--------------| 0         2    3         5              8    9 |---------|    |---------|              |----| Result           2    3                   7    8    9    10           |----|                   |----|    |----|<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0414\u0430\u043b\u044c\u0448\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0431\u0435\u0441\u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 ASCII \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432.<\/p>\n<h2>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 ASCII \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432<\/h2>\n<p>\u0418\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 <a href=\"https:\/\/alexeyboiko.github.io\/AsciiDrawerSite\/\" rel=\"noopener noreferrer nofollow\"><u>demo<\/u><\/a> \u043d\u0430 Blazor WebAssembly.<\/p>\n<p>\u0412 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0435\u0441\u0442\u044c \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u201c<strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>\u201d. \u042d\u0442\u0438 \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043f\u0440\u0438\u0435\u043c\/\u043f\u0430\u0442\u0442\u0435\u0440\u043d. \u041f\u043e \u0437\u0430\u0434\u0443\u043c\u043a\u0435, \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u201c\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e\u201d, \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u201c\u0443\u043c\u043d\u044b\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0441\u043a\u0438\u0435\u201d \u0442\u0435\u0440\u043c\u0438\u043d\u044b &#8212; \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0440\u0430\u0442\u043a\u0438\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0438\u0434\u0435\u0439.<\/p>\n<h3>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f: \u201c\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c ASCII\u201d \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u043c\u0438<\/h3>\n<p>\u041d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (\u0438\u043b\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432). \u041f\u0443\u0441\u0442\u044c \u201c\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u201d \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u0434\u043b\u0438\u043d\u044b. \u0422\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u0435\u0435. \u041c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0431\u043b\u043e\u043a &#8212; \u043e\u0434\u0438\u043d \u043f\u0438\u043a\u0441\u0435\u043b\u044c. \u041f\u0438\u043a\u0441\u0435\u043b\u0438 \u0442\u043e\u0436\u0435 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430\u043c\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f. \u0412\u044b\u0441\u043e\u0442\u0430 \u0431\u043b\u043e\u043a\u0430 \u0442\u0430\u043a\u0436\u0435 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0430 &#8212; \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430.<\/p>\n<p>\u0422\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u0443 \u043f\u0438\u043a\u0441\u0435\u043b\u044f, \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0435\u0441\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>\u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438,<\/p>\n<\/li>\n<li>\n<p>\u043d\u043e\u043c\u0435\u0440 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0438\u043b\u0438, \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043d\u043e\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\/\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u043b\u043e\u043a\u0438, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u043d\u043e\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435.<\/p>\n<pre><code class=\"cs\">public class DrawerProcessor {     public void Draw(         \/\/ \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 \u0431\u043b\u043e\u043a \u043f\u043e \u043d\u043e\u043c\u0435\u0440\u0443 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u043d\u043e\u043c\u0435\u0440\u0443 \u0431\u043b\u043e\u043a\u0430 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435         Func&lt;int, int, DrawerBlock&gt; blockDraw,          \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u0433\u0434\u0430 \u0431\u043b\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c         Action&lt;string, bool&gt; onBlockDraw) {          int row = 0;         int blockIndex = 0;          var done = false;         while (!done) {             var block = blockDraw(row, blockIndex);              switch (block.Command) {                 case DrawerCommand.Continue:                     blockIndex = blockIndex + block.Displacement;                     break;                 case DrawerCommand.NewLine:                     row = row + 1;                     blockIndex = 0;                     break;                 case DrawerCommand.End:                     done = true;                     break;             }              onBlockDraw(block.Value, done);         }     } }  public class DrawerBlock {     public string Value { get; set; }     public DrawerCommand Command { get; set; }      \/\/ \u0421\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0431\u043b\u043e\u043a\u0430,     \/\/ Value \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u043b\u043e\u043a\u043e\u0432     \/\/ \u0415\u0441\u043b\u0438 \u0432 Value \u0434\u0432\u0430 \u0431\u043b\u043e\u043a\u0430 \u0438\u043d\u0434\u0435\u043a\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u043d\u0430\u0434\u043e \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043d\u0430 2     public int Displacement { get; set; } = 1; }<\/code><\/pre>\n<p>DrawerProcessor \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439 \u0431\u043b\u043e\u043a\u0430. DrawerProcessor \u043d\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439:<\/p>\n<ul>\n<li>\n<p>\u043e\u043d \u043d\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0431\u043b\u043e\u043a\u043e\u0432,<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u0440\u0435\u0448\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u043b\u0438 \u043d\u0435\u0442,<\/p>\n<\/li>\n<li>\n<p>\u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u0438\u043b\u0438 \u043f\u0440\u0435\u0440\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 DrawerProcessor:<\/p>\n<pre><code class=\"cs\">var drawer = new DrawerProcessor(); drawer.Draw(     (row, blockIndex) =&gt; {         \/\/ \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0443\u0441\u043a\u0435 \u043a\u043e\u0434\u0430          if (row == 3)             return new DrawerBlock {                  Command = DrawerCommand.End              };          if(blockIndex == 3)             return new DrawerBlock {                 Value = Environment.NewLine,                 Command = DrawerCommand.NewLine             };          return new DrawerBlock {             Value = $\"[{row},{blockIndex}]\",             Command = DrawerCommand.Continue         };     },     (blockStr, isEnd) =&gt; Console.Write(blockStr) );  \u0412\u044b\u0432\u043e\u0434 [0,0][0,1][0,2] [1,0][1,1][1,2] [2,0][2,1][2,2]  \/\/ \u041b\u0438\u0441\u0442\u0438\u043d\u0433 1. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 DrawerProcessor. \/\/ \u041d\u0435 \u043b\u0443\u0447\u0448\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f - \u0432\u0441\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0430 \/\/ \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0443\u0441\u043a\u0435 \u043a\u043e\u0434\u0430 (\u0432 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0435  (row, blockIndex) =&gt; { .. }), \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0441\u0442\u0430\u0442\u044c\u0441\u044f.<\/code><\/pre>\n<p>\u0417\u0430\u0447\u0435\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u0434\u0432\u043e\u0439\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438, \u0438 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0437\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e DrawerBlock.Displacement? \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c &#8212; \u0434\u043b\u0438\u043d\u0430 \u0431\u043b\u043e\u043a\u0430 1 \u0441\u0438\u043c\u0432\u043e\u043b, \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b \u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u0438 \u043a \u043a\u043e\u043d\u0446\u0430\u043c:<\/p>\n<pre><code class=\"cs\">8         11 |---------|<\/code><\/pre>\n<p>\u201c11\u201d &#8212; \u044d\u0442\u043e \u0434\u0432\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u0430. \u041e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u201c11\u201d \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 \u0441\u043b\u043e\u0436\u043d\u043e &#8212; \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u201c\u043f\u0438\u0448\u0435\u043c \u201c11\u201d, \u201c1\u201d \u0443\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 &#8212; \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0435\u0449\u0435 \u201c1\u201d \u201d. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0440\u0435\u0445\u0437\u043d\u0430\u0447\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e? \u041f\u0440\u043e\u0449\u0435 \u0441\u0440\u0430\u0437\u0443 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u201c11\u201d \u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430: \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c DrawerBlock.Displacement = 2.<\/p>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>: \u0435\u0441\u043b\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u201c11\u201d \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0431\u043b\u043e\u043a\u0430\u043c\u0438, \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u0440\u0438\u0441\u043e\u0432\u0430\u043b \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0431\u043b\u043e\u043a \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434-\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439). \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0431\u043b\u043e\u043a\u0430\u043c\u0438 (\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0431\u043b\u043e\u043a \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043b \u201c1\u201d &#8212; \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0434\u043e \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0435 \u201c1\u201d), \u0442.\u0435. \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f &#171;\u0441\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430&#187;. \u0421\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044e.<\/p>\n<\/blockquote>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430:<\/p>\n<pre><code class=\"cs\">static class Block {     public static DrawerBlock Continue(string val, int displacement = 1)                  =&gt; new() {             Command = DrawerCommand.Continue,             Value = val,             Displacement = displacement         };      public static DrawerBlock End() =&gt;         new() { Command = DrawerCommand.End };      public static DrawerBlock NewLine() =&gt;         new() {              Command = DrawerCommand.NewLine,              Value = Environment.NewLine          }; }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">return new DrawerBlock {     Value = Environment.NewLine,     Command = DrawerCommand.NewLine };<\/code><\/pre>\n<p>\u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0440\u043e\u0447\u0435:<\/p>\n<pre><code class=\"cs\">return Block.NewLine();<\/code><\/pre>\n<h3>\u0420\u0438\u0441\u0443\u0435\u043c \u043d\u0435\u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0431\u043b\u043e\u043a\u0430\u043c\u0438<\/h3>\n<p>\u0412 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 1 \u0432\u0441\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u0443\u0441\u043a\u0435 \u043a\u043e\u0434\u0430 (\u0432 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0435 (row, blockIndex) =&gt; { .. }). \u041f\u043e\u043a\u0430 \u044d\u0442\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u043d\u0435 \u043c\u043d\u043e\u0433\u043e, \u044d\u0442\u043e \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e. \u041d\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0441\u0442\u0430\u043d\u0438\u0438, \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u044b\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439\/\u0443\u0441\u043b\u043e\u0432\u0438\u0439 &#8212;&nbsp; \u043a\u043e\u0434 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430 (row, blockIndex) =&gt; { .. } \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0442\u0438 \u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440: \u0432 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435 1 \u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0438 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0438 \u0441 \u0446\u0438\u0444\u0440\u0430\u043c\u0438:<\/p>\n<pre><code class=\"cs\">[0,0][0,1][0,2] [1,0][1,1][1,2] [2,0][2,1][2,2]<\/code><\/pre>\n<p>\u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u0446\u0438\u0444\u0440\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a\u0430\u0445 \u0432 \u0448\u0430\u0445\u043c\u0430\u0442\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435:<\/p>\n<pre><code class=\"cs\">[   ][0,1][   ] [1,0][   ][1,2] [   ][2,1][   ]<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0438 \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u0442\u044c \u043a\u043e\u0434 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u0430 (row, blockIndex) =&gt; { .. }.<\/p>\n<blockquote>\n<p><strong>\u0412\u044b\u0440\u0430\u0436\u0430\u044f\u0441\u044c \u043d\u0430\u0443\u043a\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e<\/strong>: \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u201c\u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438\/\u0437\u0430\u043a\u0440\u044b\u0442\u043e\u0441\u0442\u0438\u201d &#8212; \u043a\u0430\u0436\u0434\u043e\u0435 \u043d\u043e\u0432\u043e\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u043b\u0435\u0447\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u043d\u0435\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430, \u0442.\u0435. \u043a\u043e\u0434 \u201c\u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u0442 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f\u201d &#8212; \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u0418 \u043a\u043e\u0434 \u201c\u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0442 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439\u201d &#8212; \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0443\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<p>\u0422.\u0435. \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434, \u043a\u0430\u043a \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 (\u0441\u043c. \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0440\u0430\u0437\u0434\u0435\u043b), \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430. \u0421\u0432\u044f\u0437\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u0443\u0441\u043b\u043e\u0436\u043d\u0435\u043d\u0438\u044e.<\/p>\n<\/blockquote>\n<p>\u041f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041f\u0443\u0441\u0442\u044c \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430 (\u201c\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a \u0441 \u0446\u0438\u0444\u0440\u0430\u043c\u0438\u201d, \u201c\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a \u0431\u0435\u0437 \u0446\u0438\u0444\u0440\u201d, \u201c\u0431\u043b\u043e\u043a \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438\u201d, \u201c\u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0438\u0439 \u0431\u043b\u043e\u043a\u201d) \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f (\u0434\u0435\u043b\u0435\u0433\u0430\u0442).<\/p>\n<pre><code class=\"cs\">\/\/ \u0431\u043b\u043e\u043a \"\u043a\u043e\u043d\u0435\u0446\" DrawerBlock end(int row, int blockIndex) =&gt;     row == 3 ? Block.End() : null;  \/\/ \u0431\u043b\u043e\u043a \"\u043d\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430\" DrawerBlock newLine(int row, int blockIndex) =&gt;     blockIndex == 3 ? Block.NewLine() : null;  \/\/ \u0431\u043b\u043e\u043a \"\u043a\u0438\u0440\u043f\u0438\u0447\u0438\u043a \u0441 \u0446\u0438\u0444\u0440\u0430\u043c\u0438\" DrawerBlock brick(int row, int blockIndex) =&gt;      Block.Continue($\"[{row},{blockIndex}]\");<\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u043b\u043e\u043a\u043e\u0432:<\/p>\n<pre><code class=\"cs\">public class BlockDrawer {     readonly DrawerProcessor _DrawerProcessor;     public BlockDrawer(DrawerProcessor drawerProcessor) {         _DrawerProcessor = drawerProcessor              ?? throw new ArgumentNullException(nameof(drawerProcessor));     }<\/code><\/pre>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-319776","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319776","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=319776"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/319776\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=319776"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=319776"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=319776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}