bastien.monsarrat пре 6 година
родитељ
комит
9782ccb9af

+ 8 - 2
Adv2018.sln

@@ -75,9 +75,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D17.1and2", "D17.1\D17.1and
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D18.1", "D18.1\D18.1.csproj", "{92B12539-90F5-4B96-B9BD-C8BC25A961B9}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D18.2", "D18.2\D18.2.csproj", "{8197F29E-B659-487A-B91B-DE58E19A4365}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D18.2", "D18.2\D18.2.csproj", "{8197F29E-B659-487A-B91B-DE58E19A4365}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D19.1", "D19.1\D19.1.csproj", "{C144EBD4-9A70-4272-A006-A1E8F207315A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D19.1", "D19.1\D19.1.csproj", "{C144EBD4-9A70-4272-A006-A1E8F207315A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D17.Bonus", "D17.Bonus\D17.Bonus.csproj", "{B2F8CC8B-1A12-4778-BE51-14B32EBB2B89}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -237,6 +239,10 @@ Global
 		{C144EBD4-9A70-4272-A006-A1E8F207315A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C144EBD4-9A70-4272-A006-A1E8F207315A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C144EBD4-9A70-4272-A006-A1E8F207315A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B2F8CC8B-1A12-4778-BE51-14B32EBB2B89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B2F8CC8B-1A12-4778-BE51-14B32EBB2B89}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B2F8CC8B-1A12-4778-BE51-14B32EBB2B89}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B2F8CC8B-1A12-4778-BE51-14B32EBB2B89}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 6 - 0
D17.Bonus/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
+    </startup>
+</configuration>

+ 81 - 0
D17.Bonus/D17.Bonus.csproj

@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{B2F8CC8B-1A12-4778-BE51-14B32EBB2B89}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>D17.Bonus</RootNamespace>
+    <AssemblyName>D17.Bonus</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Accord, Version=3.8.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=MSIL">
+      <HintPath>..\packages\Accord.3.8.0\lib\net462\Accord.dll</HintPath>
+    </Reference>
+    <Reference Include="Accord.Video, Version=3.8.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=MSIL">
+      <HintPath>..\packages\Accord.Video.3.8.0\lib\net462\Accord.Video.dll</HintPath>
+    </Reference>
+    <Reference Include="Accord.Video.FFMPEG, Version=3.8.0.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7, processorArchitecture=x86">
+      <HintPath>..\packages\Accord.Video.FFMPEG.3.8.0\lib\net462\Accord.Video.FFMPEG.dll</HintPath>
+    </Reference>
+    <Reference Include="AForge, Version=2.2.5.0, Culture=neutral, PublicKeyToken=c1db6ff4eaa06aeb, processorArchitecture=MSIL">
+      <HintPath>..\packages\AForge.2.2.5\lib\AForge.dll</HintPath>
+    </Reference>
+    <Reference Include="AForge.Video, Version=2.2.5.0, Culture=neutral, PublicKeyToken=cbfb6e07d173c401, processorArchitecture=MSIL">
+      <HintPath>..\packages\AForge.Video.2.2.5\lib\AForge.Video.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="..\packages\Accord.3.8.0\build\Accord.targets" Condition="Exists('..\packages\Accord.3.8.0\build\Accord.targets')" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\Accord.3.8.0\build\Accord.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Accord.3.8.0\build\Accord.targets'))" />
+    <Error Condition="!Exists('..\packages\Accord.Video.FFMPEG.3.8.0\build\Accord.Video.FFMPEG.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Accord.Video.FFMPEG.3.8.0\build\Accord.Video.FFMPEG.targets'))" />
+  </Target>
+  <Import Project="..\packages\Accord.Video.FFMPEG.3.8.0\build\Accord.Video.FFMPEG.targets" Condition="Exists('..\packages\Accord.Video.FFMPEG.3.8.0\build\Accord.Video.FFMPEG.targets')" />
+</Project>

+ 251 - 0
D17.Bonus/Program.cs

@@ -0,0 +1,251 @@
+using Accord.Video.FFMPEG;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace D17.Bonus
+{
+    class Program
+    {
+        enum EnumType
+        {
+            Clay, StillWater, RunningWater
+        }
+
+        static int panY = 0;
+
+        static void Main(string[] args)
+        {
+            if (args.Length < 1) return;
+            if (File.Exists(args[0]) == false) return;
+            var file = File.OpenText(args[0]);
+
+            var reg = new Regex(@"[xy]=(\d+), [xy]=(\d+)[.][.](\d+)");
+
+            var map = new Dictionary<(int x, int y), EnumType>();
+            var rwater = new Dictionary<(int x, int y), (int x, int y)>();
+
+            int MAXY = 0;
+            int MINX = int.MaxValue;
+            int MINY = int.MaxValue;
+            int MAXX = 0;
+
+            do
+            {
+                var line = file.ReadLine();
+                if (line == null) break;
+
+                var result = reg.Match(line);
+
+                CreateMap(map, ref MAXY, ref MINX, ref MINY, ref MAXX, line, result);
+
+            } while (true);
+
+            // Start with river
+            rwater.Add((500, 0), (500, 0));
+            map.Add((500, 0), EnumType.RunningWater);
+
+            VideoFileWriter writer = new VideoFileWriter();
+
+            var width = MAXX - MINX + 2;
+            if (width % 2 == 1) width++;
+            var height = (width * 3) / 4;
+            if (height % 2 == 1) height++;
+            int tpy = (height * 2) / 3;
+
+            writer.Open("out.avi", width, height);
+
+            while (rwater.Count > 0)
+            {
+                if (rwater.Any(r => r.Key.y > panY + tpy)) panY++;
+                PrintMap(map, writer, MINX, MAXX, MAXY, width, height);
+
+                var enumer = rwater.FirstOrDefault();
+                var water = enumer.Key;
+                var source = enumer.Value;
+
+                if (map.ContainsKey((water.x, water.y + 1)) == false && water.y > MAXY)
+                {
+                    rwater.Remove(water);
+                    continue;
+                }
+
+                if (map.ContainsKey((water.x, water.y + 1)) == false || map[(water.x, water.y + 1)] == EnumType.RunningWater)
+                {
+                    RaindropsOnRoses(map, rwater, water);
+                }
+
+                else
+                {
+                    ExpandToBothSides(map, rwater, water, source);
+
+                    int maxX, minX;
+                    bool canConvert = CanConvertToStillWater(map, rwater, water, source, out maxX, out minX);
+
+                    if (canConvert)
+                        ConvertToStillWater(map, rwater, water, source, maxX, minX);
+                    else
+                        rwater.Remove(water);
+                }
+            }
+
+            PrintMap(map, writer, MINX, MAXX, MAXY, width, height);
+        }
+
+        private static void RaindropsOnRoses(Dictionary<(int x, int y), EnumType> map, Dictionary<(int x, int y), (int x, int y)> rwater, (int x, int y) water)
+        {
+            rwater.Remove(water);
+
+            var drop = (water.x, water.y + 1);
+            if (!rwater.ContainsKey(drop)) rwater.Add(drop, water);
+            map[drop] = EnumType.RunningWater;
+        }
+
+        private static void ConvertToStillWater(Dictionary<(int x, int y), EnumType> map, Dictionary<(int x, int y), (int x, int y)> rwater, (int x, int y) water, (int x, int y) source, int maxX, int minX)
+        {
+            for (var x = minX; x <= maxX; ++x)
+            {
+                var res = map.TryGetValue((x, water.y), out var type);
+                if (type == EnumType.RunningWater)
+                {
+                    map[(x, water.y)] = EnumType.StillWater;
+                    rwater.Remove((x, water.y));
+                }
+            }
+
+            rwater.Remove(water);
+            if (!rwater.ContainsKey(source)) rwater.Add(source, (source.x, source.y - 1));
+        }
+
+        private static bool CanConvertToStillWater(Dictionary<(int x, int y), EnumType> map, Dictionary<(int x, int y), (int x, int y)> rwater, (int x, int y) water, (int x, int y) source, out int maxX, out int minX)
+        {
+            bool canConvert = true;
+            maxX = 0;
+            minX = 0;
+            for (int x = water.x; canConvert; ++x) // left to right
+            {
+                maxX = x;
+                var res = map.TryGetValue((x, water.y), out var type);
+                if (res == false)
+                {
+                    canConvert = false;
+                    //rwater.TryAdd((x - 1, water.y), source);
+                }
+                else if (type == EnumType.Clay) break;
+            }
+            for (int x = water.x; canConvert; --x) // right to left
+            {
+                minX = x;
+                var res = map.TryGetValue((x, water.y), out var type);
+                if (res == false)
+                {
+                    canConvert = false;
+                    //rwater.TryAdd((x + 1, water.y), source);
+                }
+                else if (type == EnumType.Clay) break;
+            }
+
+            return canConvert;
+        }
+
+        private static void ExpandToBothSides(Dictionary<(int x, int y), EnumType> map, Dictionary<(int x, int y), (int x, int y)> rwater, (int x, int y) water, (int x, int y) source)
+        {
+            var next = water;
+
+            while (true)
+            {
+                var last = next;
+                next = (last.x - 1, water.y);
+
+                var res = map.TryGetValue((next.x, water.y), out var value);
+                if (res && value == EnumType.Clay) break;
+
+                rwater.Remove(last);
+                if (!rwater.ContainsKey(next)) rwater.Add(next, source);
+                map[next] = EnumType.RunningWater;
+
+                var hasBottom = map.TryGetValue((next.x, next.y + 1), out var bottom);
+                if (hasBottom == false || bottom == EnumType.RunningWater)
+                    break;
+            }
+
+            next = water;
+
+            while (true)
+            {
+                var last = next;
+                next = (last.x + 1, water.y);
+
+                var res = map.TryGetValue((next.x, water.y), out var value);
+                if (res && value == EnumType.Clay) break;
+
+                rwater.Remove(last);
+                if (!rwater.ContainsKey(next)) rwater.Add(next, source);
+                map[next] = EnumType.RunningWater;
+
+                var hasBottom = map.TryGetValue((next.x, next.y + 1), out var bottom);
+                if (hasBottom == false || bottom == EnumType.RunningWater)
+                    break;
+            }
+        }
+
+        private static void CreateMap(Dictionary<(int x, int y), EnumType> map, ref int MAXY, ref int MINX, ref int MINY, ref int MAXX, string line, Match result)
+        {
+            var c1 = int.Parse(result.Groups[1].Value);
+            var rmin = int.Parse(result.Groups[2].Value);
+            var rmax = int.Parse(result.Groups[3].Value);
+
+            if (line.StartsWith("x"))
+            {
+                if (c1 > MAXX) MAXX = c1;
+                if (c1 < MINX) MINX = c1;
+            }
+            else
+            {
+                if (c1 > MAXY) MAXY = c1;
+                if (c1 < MINY) MINY = c1;
+            }
+
+            for (int i = rmin; i <= rmax; ++i)
+            {
+                if (line.StartsWith("x"))
+                {
+                    if (i > MAXY) MAXY = i;
+                    if (i < MINY) MINY = i;
+
+                    map[(c1, i)] = EnumType.Clay;
+                }
+                else
+                {
+                    if (i > MAXX) MAXX = i;
+                    if (i < MINX) MINX = i;
+                    map[(i, c1)] = EnumType.Clay;
+                }
+            }
+        }
+
+        private static void PrintMap(Dictionary<(int x, int y), EnumType> map, VideoFileWriter writer, int MINX, int MAXX, int MAXY, int width, int height)
+        {
+            var bmp = new Bitmap(width, height);
+
+            for (int y = panY; y < height + panY; ++y)
+            {
+                int px = 0;
+                int py = y - panY;
+                for (int x = MINX - 1; x < MAXX + 1; ++x)
+                {
+                    var res = map.TryGetValue((x, y), out var type);
+                    if (res == false) bmp.SetPixel(px, py, Color.White);
+                    else if (type == EnumType.Clay) bmp.SetPixel(px, py, Color.Maroon);
+                    else if (type == EnumType.RunningWater) bmp.SetPixel(px, py, Color.Aqua);
+                    else if (type == EnumType.StillWater) bmp.SetPixel(px, py, Color.Aquamarine);
+                    px++;
+                }
+            }
+            writer.WriteVideoFrame(bmp);
+        }
+    }
+}

+ 36 - 0
D17.Bonus/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("D17.Bonus")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("D17.Bonus")]
+[assembly: AssemblyCopyright("Copyright ©  2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("b2f8cc8b-1a12-4778-be51-14b32ebb2b89")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 8 - 0
D17.Bonus/packages.config

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Accord" version="3.8.0" targetFramework="net472" />
+  <package id="Accord.Video" version="3.8.0" targetFramework="net472" />
+  <package id="Accord.Video.FFMPEG" version="3.8.0" targetFramework="net472" />
+  <package id="AForge" version="2.2.5" targetFramework="net472" />
+  <package id="AForge.Video" version="2.2.5" targetFramework="net472" />
+</packages>