C# Coding Test Course, Dividing Line Segments into Groups

Algorithm problems are becoming increasingly important in coding tests, and many companies place great emphasis on the ability to solve these problems. In this course, we will address the issue of dividing given line segments into groups. This problem can be solved through efficient classification and sorting, as well as grouping logic.

Problem Description

When given line segments are represented as points on a map, write a program to divide these segments into overlapping segment groups. A segment has a starting point and an endpoint, and is provided in the following input format:

Input Example:
5
1 3
2 5
6 8
7 9
10 12

The first line of the above input indicates the number of segments, and the following lines represent the starting and ending points of each segment. Overlapping segments must be grouped together. For example, the input segments can be divided as follows:

Output Example:
Group 1: (1, 5)
Group 2: (6, 9)
Group 3: (10, 12)

Approach to Solve the Problem

To solve this problem, the following approach can be used:

  1. Store the line segments provided in the input in a list.
  2. Sort the list based on the starting points.
  3. Traverse the sorted list to group the overlapping segments.
  4. Finally, output the range of continuous segments for each group.

Step 1: Input Processing

First, we will define a structure to receive the segments input by the user and process the input. This structure will hold the starting point and endpoint of the segments, managing them in list form.

using System;
using System.Collections.Generic;

public class Segment{
    public int Start { get; set; }
    public int End { get; set; }
    
    public Segment(int start, int end){
        Start = start;
        End = end;
    }
}

Step 2: Sorting

This is the code to sort the segment list based on starting points. This will bring similar segments closer together, preparing us to group them.

public List<Segment> SortSegments(List<Segment> segments){
    segments.Sort((a, b) => a.Start.CompareTo(b.Start));
    return segments;
}

Step 3: Grouping Logic

The grouping logic determines whether each segment can be added to the current group while traversing. If the starting point of the current segment is less than or equal to the endpoint of the last segment, it is included in the same group. Otherwise, a new group is started.

public List<List<Segment>> GroupSegments(List<Segment> segments){
    List<List<Segment>> groups = new List<List<Segment>>();
    groups.Add(new List<Segment>());
    
    foreach(var segment in segments){
        var lastSegment = groups[groups.Count - 1];
        if(lastSegment.Count == 0 || segment.Start > lastSegment[lastSegment.Count - 1].End){
            groups.Add(new List<Segment>());
        }
        groups[groups.Count - 1].Add(segment);
    }

    return groups;
}

Step 4: Final Output

Finally, we output the grouped results. The results are displayed in a simple text format based on the starting and ending points of each group.

public void PrintGroups(List<List<Segment>> groups){
    for(int i = 0; i < groups.Count; i++){
        var group = groups[i];
        if(group.Count > 0){
            Console.WriteLine($"Group {i + 1}: ({group[0].Start}, {group[group.Count - 1].End})");
        }
    }
}

Complete Code

Now let’s write the final code by combining all the steps:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    public class Segment
    {
        public int Start { get; set; }
        public int End { get; set; }

        public Segment(int start, int end)
        {
            Start = start;
            End = end;
        }
    }

    public static void Main(string[] args)
    {
        int n = int.Parse(Console.ReadLine());
        List<Segment> segments = new List<Segment>();

        for (int i = 0; i < n; i++)
        {
            var input = Console.ReadLine().Split(' ');
            int start = int.Parse(input[0]);
            int end = int.Parse(input[1]);
            segments.Add(new Segment(start, end));
        }

        segments = SortSegments(segments);
        var groups = GroupSegments(segments);
        PrintGroups(groups);
    }

    public static List<Segment> SortSegments(List<Segment> segments)
    {
        segments.Sort((a, b) => a.Start.CompareTo(b.Start));
        return segments;
    }

    public static List<List<Segment>> GroupSegments(List<Segment> segments)
    {
        List<List<Segment>> groups = new List<List<Segment>>();
        groups.Add(new List<Segment>());

        foreach (var segment in segments)
        {
            var lastSegment = groups[groups.Count - 1];
            if (lastSegment.Count == 0 || segment.Start > lastSegment[lastSegment.Count - 1].End)
            {
                groups.Add(new List<Segment>());
            }
            groups[groups.Count - 1].Add(segment);
        }

        return groups;
    }

    public static void PrintGroups(List<List<Segment>> groups)
    {
        for (int i = 0; i < groups.Count; i++)
        {
            var group = groups[i];
            if (group.Count > 0)
            {
                Console.WriteLine($"Group {i + 1}: ({group[0].Start}, {group[group.Count - 1].End})");
            }
        }
    }
}

Conclusion

Through this course, we explored how to solve the segment grouping problem and how to write code using C#. In coding tests, it is important to develop algorithmic thinking through a variety of problems. Practice different types of problems through repetitive exercises!

Additional Learning Resources

Here are some useful resources introduced during the process of solving this problem:

  • Programmers: A platform providing various algorithm problems.
  • LeetCode: A site providing domestic and international problems for algorithm practice.
  • Baekjoon Online Judge: A site where you can solve algorithm problems of various difficulties.

I hope this article helps in your coding test preparation. If you have any questions or additional inquiries, please leave a comment. Thank you!