简化选择范围C#

时间:2018-02-28 07:24:34

标签: c# algorithm range solver puzzle

我一直致力于编码https://www.codingame.com/ide/puzzle/simplify-selection-ranges的简化选择范围拼图,我完全不知道如何完成它。编辑:我刚刚设法让它通过第一次测试,但其他所有测试都失败了,这里是测试4

  

发现: 10-12

     

预期: 1-4,10,12,17-20

任何帮助/解决方案将不胜感激 https://pastebin.com/JP81NLLe

/**
 * Auto-generated code below aims at helping you parse
 * the standard input according to the problem statement.
 **/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;


class Solution
{
    static void Main(string[] args)
    {
        string N = Console.ReadLine();
        // Write an action using Console.WriteLine()
        // To debug: Console.Error.WriteLine("Debug messages...");
        //Removing the brackets at the start and the end of the string
        N = N?.Remove(0, 1);
        N = N?.Remove(N.Length - 1, 1);
        List<int> ints = new List<int>(Array.ConvertAll(N?.Split(','), int.Parse));
        List<int> finalI = new List<int>();
        string finalRanges = "";
        ints.Sort();
        List<string> intsString = ints.ConvertAll(s => s.ToString());
        int tripleC = 0;
        for (int i = 0; i < ints.Count; i++)
        {
            if (i + 1 < ints.Count && ints[i] + 1 == ints[i + 1])
            {
                tripleC++;
                finalI.Add(ints[i]);
            }
            else
            {
                if (tripleC > 1)
                {
                    // Add the one after as the previous one will fail for the end of the range, example: range is 5-7,previously would print 5,6 instead of 5,6,7
                    finalI.Add(ints[i]);
                    finalRanges += finalI[0] + "-" + finalI[finalI.Count - 1];
                    // Removing the ranges from the ints string list to add in the finalranges
                    intsString.RemoveRange(intsString.IndexOf(finalI[0].ToString()), finalI.Count);
                }

                if (finalRanges != "" && finalRanges[finalRanges.Length - 1] != ',')
                    finalRanges += ",";
                tripleC = 0;
                finalI.Clear();
            }
        }

        ints = intsString.ConvertAll(int.Parse);


        string[] ranges = finalRanges.Split(',');
        foreach (var str in ints)
        {
            Console.Error.Write(str + ",");
        }
        Console.Error.WriteLine(" ");
        int[] rangeInts;
        for (int i = 0; i < ranges.Length - 1; i++)
        {
            int counter = 0;
            string s1 = ranges[i].Substring(0, ranges[i].IndexOf('-'));
            string s2 = ranges[i].Substring(ranges[i].IndexOf('-') + 1);
            Console.Error.WriteLine("s1 {0} s2 {1}", s1, s2);
            rangeInts = new[]
            {
                    // Finding the first and second number by substringing the start to before the hyphen, then after the hypen to the end to find the two numbers
                    int.Parse(s1),
                    int.Parse(s2),
                };
            for (int j = 0; j < ints.Count - 1; j++)
            {
                if (ints[j] < rangeInts[0] && ints[j + 1] > rangeInts[1])
                {
                    //insert the range in between the two values it's closest too, adding i as the intsString will be
                    // a different length to the ints so they will get put in a row without it
                    intsString.Insert(j + 1 + i, ranges[i]);
                    Console.Error.WriteLine(intsString[i]);
                    break;
                }
            }
        }

        for (int i = 0; i < intsString.Count; i++)
        {
            string s = intsString[i];
            if (i < intsString.Count - 1) s += ",";
            Console.Write(s);
        }
    }
}

谢谢!

2 个答案:

答案 0 :(得分:0)

我有一点时间,我已经尝试过,但你必须自己做,试图调试消息等等。快速实施,而不是最好的:

using System;
using System.Linq;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;

/**
 * Auto-generated code below aims at helping you parse
 * the standard input according to the problem statement.
 **/
class Solution
{
    static void Main(string[] args)
    {
        string N = Console.ReadLine();
        Console.Error.WriteLine(N);
        // Write an action using Console.WriteLine()
        // To debug: Console.Error.WriteLine("Debug messages...");
        int[] array = N.Replace("[", "").Replace("]", "").Split(',').Select(s => int.Parse(s.Trim())).OrderBy(n => n).ToArray();

        int lastNum = 0;
        int rangeLength = 0;
        string result = "";
        string bufferResult = "";
        int currentNum = 0;
        for (int i = 0; i <= array.Length; i++) {
            bool flush = false;
            if (i < array.Length) {
                currentNum = array[i];
                if (lastNum == 0) {
                    lastNum = currentNum;
                    rangeLength = 0;
                    bufferResult = "" + lastNum;
                }
                else if (lastNum + 1 == currentNum) {
                    lastNum = currentNum;
                    rangeLength++;
                    bufferResult += "," + lastNum;
                }
                else {
                    flush = true;
                }
            }
            else {
                flush = true;
            }
            if (flush) {
                // Flush
                if (result.Length > 0) {
                    result += ",";
                }
                if (rangeLength > 1) {
                    result += string.Format("{0}-{1}", (lastNum - rangeLength), lastNum);
                }
                else {
                    result += bufferResult;
                }
                lastNum = currentNum;
                bufferResult = "" + lastNum;
                rangeLength = 0;
            }
        }

        Console.WriteLine(result);
    }
}

答案 1 :(得分:0)

将问题分为两部分,这也使其变得更加简单。

我自己会创建一个代表结果范围的类。

public class Range
{
    public Range(int num)
    {
        Left = Right = num;
    }

    public int Left { get; set; }

    public int Right { get; set; }

    public bool IsAdjecentRight(int num)
    {
        return num == Right+1;
    }

    public bool TryAddRight(int num)
    {
        if (!IsAdjecentRight(num)) return false;
        Right = num;
        return true;
    }

    public override string ToString()
    {
        if (Left == Right) return $"{Left}";
        if (Left == Right - 1) return $"{Left},{Right}";
        return $"{Left}-{Right}";
    }
}

此解决方案的主要方法将变得更加简单:

class Solution
{
    static void Main(string[] args)
    {
        string N = Console.ReadLine();

        var nums = N.TrimStart('[').TrimEnd(']').Split(',').Select(x => byte.Parse(x)).OrderBy(x => x);

        List<Range> ranges = new List<Range>();
        Range r = null;
        foreach (var num in nums)
        {
            if (ranges.Count == 0)
            {
                r = new Range(num);
                ranges.Add(r);
                continue;
            }
            if (r.TryAddRight(num)) continue;

            r = new Range(num);
            ranges.Add(r);
        }

        Console.WriteLine(String.Join(",", ranges));
    }
}