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
2 changes: 1 addition & 1 deletion exercises/practice/tree-building/.meta/Example.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private static void ValidateRecord(TreeBuildingRecord record, int previousRecord
throw new ArgumentException();
else if (!record.IsRoot && record.ParentId >= record.RecordId)
throw new ArgumentException();
else if (!record.IsRoot && record.RecordId != previousRecordId + 1)
else if (record.RecordId != previousRecordId + 1)
throw new ArgumentException();
}

Expand Down
53 changes: 53 additions & 0 deletions exercises/practice/tree-building/.meta/Generator.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{{ func assertions(node, path)
id = node.id ?? node.recordId
children = node.children ?? []

assertion = children.empty? ? $"AssertTreeIsLeaf({path}, id: {id});" : $"AssertTreeIsBranch({path}, id: {id}, childCount: {children | array.size});"
checks = [assertion]

for child in children
checks = array.add_range checks (assertions child $"{path}.Children[{for.index}]")
end

ret checks
end }}

public class {{ testClass }}
{
{{- for test in tests }}
[Fact{{ if !for.first }}(Skip = "Remove this Skip property to run this test"){{ end }}]
public void {{ test.testMethod }}()
{
{{- if test.input.records.empty? }}
var records = Array.Empty<TreeBuildingRecord>();
{{- else }}
var records = new[]
{
{{- for record in test.input.records }}
new TreeBuildingRecord { RecordId = {{ record.recordId }}, ParentId = {{ record.parentId }} }{{ if !for.last }},{{ end }}
{{- end }}
};
{{- end }}

{{- if test.expected.error || test.expected.empty? }}
Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
{{- else }}
var tree = TreeBuilder.BuildTree(records);

{{ test.expected.node | assertions "tree" | array.join "\n" }}
{{- end }}
}
{{ end }}
private static void AssertTreeIsBranch(Tree tree, int id, int childCount)
{
Assert.Equal(id, tree.Id);
Assert.False(tree.IsLeaf);
Assert.Equal(childCount, tree.Children.Count);
}

private static void AssertTreeIsLeaf(Tree tree, int id)
{
Assert.Equal(id, tree.Id);
Assert.True(tree.IsLeaf);
}
}
58 changes: 58 additions & 0 deletions exercises/practice/tree-building/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[761790a3-4c27-461a-b4e9-8bce8ccee5a1]
description = "empty list"

[dcc89dc3-eb39-4f26-a3cd-964e607c95ff]
description = "single record"

[dcdb80f0-e5da-43e1-8b8d-6f307be89c0e]
description = "three records in order"

[2ff5b8f8-d95e-401e-9359-233919488d22]
description = "three records in reverse order"

[de798d3b-8905-4446-a114-a0dd2476d945]
description = "more than two children"

[13dd9b3c-6137-415f-b6fe-5044c1dfbc50]
description = "binary tree"

[5cfd29dc-166b-47da-84ca-1c60b5ae5941]
description = "unbalanced tree"

[a05ddb5d-2d11-4948-88d3-b5f18a44ddce]
description = "one root node and has parent"

[9ed09df2-8fd6-4e37-aa37-e7753c057a1a]
description = "root node has parent"

[8755a2c4-2c6b-4396-b155-b5bf4b6bc280]
description = "no root node"

[c6ef8f9a-4045-4949-a1e1-e0ae804e4af4]
description = "duplicate node"

[7a7b77a6-3447-4905-b79c-d22bfe43f408]
description = "duplicate root"

[c6f51bd7-3608-4390-b446-dfd1bcbf3ddc]
description = "non-continuous"

[1f3d1b50-4494-4b22-b88a-68f32f7d321d]
description = "cycle directly"

[ac568b50-3f9b-4cb4-b602-e0eb13de4269]
description = "cycle indirectly"

[cf954b21-3cef-420c-8e72-d19547505e1f]
description = "higher id parent of lower id"
70 changes: 44 additions & 26 deletions exercises/practice/tree-building/TreeBuildingTests.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,33 @@
public class TreeBuildingTests
{
[Fact]
public void One_node()
public void Empty_list()
{
var records = Array.Empty<TreeBuildingRecord>();
Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

[Fact(Skip = "Remove this Skip property to run this test")]
public void Single_record()
{
var records = new[]
{
new TreeBuildingRecord { RecordId = 0, ParentId = 0 }
};

var tree = TreeBuilder.BuildTree(records);

AssertTreeIsLeaf(tree, id: 0);
}

[Fact(Skip = "Remove this Skip property to run this test")]
public void Three_nodes_in_order()
public void Three_records_in_order()
{
var records = new[]
{
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 1, ParentId = 0 },
new TreeBuildingRecord { RecordId = 2, ParentId = 0 }
};

var tree = TreeBuilder.BuildTree(records);

AssertTreeIsBranch(tree, id: 0, childCount: 2);
Expand All @@ -31,15 +36,14 @@ public void Three_nodes_in_order()
}

[Fact(Skip = "Remove this Skip property to run this test")]
public void Three_nodes_in_reverse_order()
public void Three_records_in_reverse_order()
{
var records = new[]
{
new TreeBuildingRecord { RecordId = 2, ParentId = 0 },
new TreeBuildingRecord { RecordId = 1, ParentId = 0 },
new TreeBuildingRecord { RecordId = 0, ParentId = 0 }
};

var tree = TreeBuilder.BuildTree(records);

AssertTreeIsBranch(tree, id: 0, childCount: 2);
Expand All @@ -52,12 +56,11 @@ public void More_than_two_children()
{
var records = new[]
{
new TreeBuildingRecord { RecordId = 3, ParentId = 0 },
new TreeBuildingRecord { RecordId = 2, ParentId = 0 },
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 1, ParentId = 0 },
new TreeBuildingRecord { RecordId = 0, ParentId = 0 }
new TreeBuildingRecord { RecordId = 2, ParentId = 0 },
new TreeBuildingRecord { RecordId = 3, ParentId = 0 }
};

var tree = TreeBuilder.BuildTree(records);

AssertTreeIsBranch(tree, id: 0, childCount: 3);
Expand All @@ -79,15 +82,13 @@ public void Binary_tree()
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 6, ParentId = 2 }
};

var tree = TreeBuilder.BuildTree(records);

AssertTreeIsBranch(tree, id: 0, childCount: 2);
AssertTreeIsBranch(tree.Children[0], id: 1, childCount: 2);
AssertTreeIsBranch(tree.Children[1], id: 2, childCount: 2);

AssertTreeIsLeaf(tree.Children[0].Children[0], id: 4);
AssertTreeIsLeaf(tree.Children[0].Children[1], id: 5);
AssertTreeIsBranch(tree.Children[1], id: 2, childCount: 2);
AssertTreeIsLeaf(tree.Children[1].Children[0], id: 3);
AssertTreeIsLeaf(tree.Children[1].Children[1], id: 6);
}
Expand All @@ -105,24 +106,24 @@ public void Unbalanced_tree()
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 6, ParentId = 2 }
};

var tree = TreeBuilder.BuildTree(records);

AssertTreeIsBranch(tree, id: 0, childCount: 2);
AssertTreeIsBranch(tree.Children[0], id: 1, childCount: 1);
AssertTreeIsBranch(tree.Children[1], id: 2, childCount: 3);

AssertTreeIsLeaf(tree.Children[0].Children[0], id: 4);
AssertTreeIsBranch(tree.Children[1], id: 2, childCount: 3);
AssertTreeIsLeaf(tree.Children[1].Children[0], id: 3);
AssertTreeIsLeaf(tree.Children[1].Children[1], id: 5);
AssertTreeIsLeaf(tree.Children[1].Children[2], id: 6);
}

[Fact(Skip = "Remove this Skip property to run this test")]
public void Empty_input()
public void One_root_node_and_has_parent()
{
var records = new TreeBuildingRecord[0];

var records = new[]
{
new TreeBuildingRecord { RecordId = 0, ParentId = 1 }
};
Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

Expand All @@ -134,7 +135,6 @@ public void Root_node_has_parent()
new TreeBuildingRecord { RecordId = 0, ParentId = 1 },
new TreeBuildingRecord { RecordId = 1, ParentId = 0 }
};

Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

Expand All @@ -143,12 +143,34 @@ public void No_root_node()
{
var records = new[]
{
new TreeBuildingRecord { RecordId = 1, ParentId = 0 }
new TreeBuildingRecord { RecordId = 1, ParentId = 0 },
new TreeBuildingRecord { RecordId = 2, ParentId = 0 }
};
Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

[Fact(Skip = "Remove this Skip property to run this test")]
public void Duplicate_node()
{
var records = new[]
{
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 1, ParentId = 0 },
new TreeBuildingRecord { RecordId = 1, ParentId = 0 }
};
Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

[Fact(Skip = "Remove this Skip property to run this test")]
public void Duplicate_root()
{
var records = new[]
{
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 0, ParentId = 0 }
};
Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

[Fact(Skip = "Remove this Skip property to run this test")]
public void Non_continuous()
Expand All @@ -160,7 +182,6 @@ public void Non_continuous()
new TreeBuildingRecord { RecordId = 1, ParentId = 0 },
new TreeBuildingRecord { RecordId = 0, ParentId = 0 }
};

Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

Expand All @@ -177,7 +198,6 @@ public void Cycle_directly()
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 6, ParentId = 3 }
};

Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

Expand All @@ -194,7 +214,6 @@ public void Cycle_indirectly()
new TreeBuildingRecord { RecordId = 0, ParentId = 0 },
new TreeBuildingRecord { RecordId = 6, ParentId = 3 }
};

Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

Expand All @@ -207,7 +226,6 @@ public void Higher_id_parent_of_lower_id()
new TreeBuildingRecord { RecordId = 2, ParentId = 0 },
new TreeBuildingRecord { RecordId = 1, ParentId = 2 }
};

Assert.Throws<ArgumentException>(() => TreeBuilder.BuildTree(records));
}

Expand All @@ -223,4 +241,4 @@ private static void AssertTreeIsLeaf(Tree tree, int id)
Assert.Equal(id, tree.Id);
Assert.True(tree.IsLeaf);
}
}
}
Loading