Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions DKey.Algorithms.Tests/Graph/DFSTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ public void Iterative_GivenGraph_ReturnsExpectedTraversal()

Assert.That(traversal, Is.EqualTo(new[] { 0, 1, 3, 4, 2 }));
}

[Test]
public void IterativeWithExitExtiOn_GivenGraph_ReturnsExpectedTraversal()
{
var graph = new[]
{
new List<int> { 1, 2 },
new List<int> { 3, 4 },
new List<int>(),
new List<int>(),
new List<int>(),
};
var context = new DFSContext(graph, 0);
var traversal = new List<int>();

DFS.IterativeWithExitAction(context, null, c => traversal.Add(c.CurrentVertex));

Assert.That(traversal, Is.EqualTo(new[] { 3, 4, 1, 2, 0 }));
}

[Test]
public void Recursive_GivenGraph_ReturnsExpectedTraversal()
Expand Down
13 changes: 3 additions & 10 deletions DKey.Algorithms.sln.DotSettings.user
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AClipboardService_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003FDmitry_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fc2f443684b8f6ce4be697c58d76497aee602b98fa51102318ed43ac1c30bbd1_003FClipboardService_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIComparer_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003FDmitry_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fae7b821dd3ae45b4a8027ef197e5363fb1e910_003Fce_003F53b98a92_003FIComparer_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003FDmitry_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F6879c9ed20391a5ccfea363be5964fbcfe4f1dfde9558aa84b36df6b6ec92c6_003FList_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003FDmitry_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003F6879c9ed20391a5ccfea363be5964fbcfe4f1dfde9558aa84b36df6b6ec92c6_003FList_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANumber_002EParsing_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003FDmitry_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fa83431c785a617acf31cd8bcdbb745e3b182479dc3be62330cb2a70994df844_003FNumber_002EParsing_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANumber_002EParsing_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003FDmitry_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FSourcesCache_003Fb42dbe862dd51fb5e77e5fe0ab92bfe2f4e9d579a34b2110f5a774eaaf7ec_003FNumber_002EParsing_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003FDmitry_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F36e740b59df23626d207e72ea77e34298e53dd99db463eee529f8c416b5664_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

Expand All @@ -11,16 +13,7 @@



<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=da0784d7_002Dba34_002D413e_002D82f5_002Da990c8d84b73/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="Tests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;&#xD;
&lt;Not&gt;&#xD;
&lt;And&gt;&#xD;
&lt;Project Location="C:\Repos\github\DKey.Algorithms\Dkey.Algorithms.Tests" Presentation="&amp;lt;DKey.Algorithms.Tests&amp;gt;" /&gt;&#xD;
&lt;TestAncestor&gt;&#xD;
&lt;TestId&gt;NUnit3x::705969DA-A152-47DC-9BB6-D5060B8D81F0::net7.0::DKey.Algorithms.Tests.Search.GoldenSectionSearchTests.Test_InvalidRange&lt;/TestId&gt;&#xD;
&lt;/TestAncestor&gt;&#xD;
&lt;/And&gt;&#xD;
&lt;/Not&gt;&#xD;
&lt;/SessionState&gt;</s:String>




Expand Down
55 changes: 55 additions & 0 deletions DKey.Algorithms/DataStructures/Graph/DepthFirstSearch/DFS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,61 @@ public static void Iterative<TContext>(TContext context, Action<TContext>? actio
}
}
}

/// <summary>
/// Iterative depth-first search with some action on the current context.
/// Use this for big graphs to avoid stack overflow.
/// Can be more memory efficient if you push vertices 1 by 1 tracking how many children ha been pushed, but this is easier to understand.
/// </summary>
public static void IterativeWithExitAction<TContext>(TContext context, Action<TContext>? enterAction = default, Action<TContext>? exitAction = default, bool preallocate = false) where TContext : DFSContext
{
if(context.stopFlag)
return;
var stack = new Stack<int>(preallocate ? context.Graph.Length : 0);
stack.Push(context.CurrentVertex);
context.VertexInfo[context.CurrentVertex] = (-1, 0);

while (stack.Count > 0)
{
var currentVertex = stack.Peek();
context.CurrentVertex = currentVertex;

if (!context.Used.Contains(currentVertex))
{
//On entering the vertex.
enterAction?.Invoke(context);
context.Used.Add(currentVertex);
context.Parents.Push(currentVertex);

var wasPushed = false;
//Pushing children to the stack of vertices to visit.
for (int i = context.Graph[currentVertex].Count - 1; i >=0 ; i--)
{
var nextAdjacent = context.Graph[currentVertex][i];
if (!context.Used.Contains(nextAdjacent))
{
wasPushed = true;
stack.Push(nextAdjacent);
context.VertexInfo[nextAdjacent] = (currentVertex, context.TraverseDepth);
}

}
if (wasPushed)
{
continue;
}
}

//On exiting the vertex. If graph is not tree, we need to check current parent, to avoid removing vertex if it already was removed, but got visited through another branch.
if (context.Parents.Peek() == currentVertex)
{
context.Parents.Pop();
exitAction?.Invoke(context);
}
stack.Pop();
}
}


/// <summary>
/// Depth-first search with some action on current context
Expand Down
18 changes: 18 additions & 0 deletions DKey.Algorithms/DataStructures/Graph/DepthFirstSearch/DFSTools.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace DKey.Algorithms.DataStructures.Graph.DepthFirstSearch;

public class DFSTools
{
public List<int> Traverse(DFSContext context, bool reverse = false)
{
var result = new List<int>();
DFS.Iterative(context, x =>
{
result.Add(x.CurrentVertex);
});
if (reverse)
{
result.Reverse();
}
return result;
}
}
5 changes: 3 additions & 2 deletions DKey.CodeForces/Program.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using DKey.Algorithms;
using DKey.CodeForces.Contest2103;
using DKey.CodeForces.Contest2117;
using DKey.CodeForces.Sandbox;

namespace DKey.CodeForces;

public static class Program
{
private static Solver _solver = new Solver2103D();
private static Solver _solver = new SandboxSolver();
public static void Main()
{
_solver.Run();
Expand Down
43 changes: 43 additions & 0 deletions DKey.CodeForces/Sandbox/SandboxSolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using DKey.Algorithms;
using DKey.Algorithms.DataStructures.Graph;
using DKey.Algorithms.DataStructures.Graph.DepthFirstSearch;

namespace DKey.CodeForces.Sandbox;

public class SandboxSolver : Solver
{
public SandboxSolver() : base( new []{typeof(int)})
{
}

public override void Solve(object[] objects)
{
var roots = new HashSet<int>();
var n = (int) objects[0];
var edges = new List<(int, int)>();
for (var i = 0; i < n; i++)
{
var parent = IOHelper.ReadInt();
if (parent == -1)
{
roots.Add(i);
continue;
}

edges.Add((parent - 1, i));
}

var graph = GraphBuilder.Directed(edges, n);

var maxTraverseDepth = 0;
foreach (var root in roots)
{
var context = new DFSContext(graph.G, root);
DFS.IterativeWithExitAction(context, null, c =>
{
maxTraverseDepth = Math.Max(maxTraverseDepth, c.TraverseDepth);
});
}
output.AddLine(maxTraverseDepth + 1);
}
}
2 changes: 1 addition & 1 deletion DKey.ContestTemplateBuilder/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
public class Config
{
public static string repoPath = @"C:\Repos\GitHub\DKey.Algorithms\DKey.CodeForces";
public static string contestID = "2103";
public static string contestID = "2117";
public static int problemCount = 8;
}
Loading