3
\$\begingroup\$

Loop through a given array 7 times and print the following output:

int[] arr = { 9, 2, 7, 4, 6, 1, 3 };
92746
13927
46139
27461
39274
61392
74613 

And this is my code so far:

static void Main(string[] args)
{
    int[] arr = { 9, 2, 7, 4, 6, 1, 3 };
    int rotate = 7;
    int printsize = 5;
    int addsize = 0;
    int startsize = 0;
    for (int i = 0; i < rotate; i++)
    {
        Print(arr, printsize, ref addsize, ref startsize);
    }
}

static void Print(int[] arr, int printsize,ref int addsize, ref int startsize)
{
    int n = (arr.Length - 1);
    int loop = 0;
    for (int j = startsize; j <= (printsize + addsize); j++)
    {
        Console.Write(arr[j]);
        if (loop == 4)
        {
            startsize = j + 1;
            addsize = (n) - j;
            break;
        }
        if (j == n)
        {
            addsize = 0;
            j = -1;
            printsize = printsize - (loop + 1);
        }
        loop = loop + 1;
    }
    Console.WriteLine();
}
\$\endgroup\$
0

3 Answers 3

8
\$\begingroup\$

Looks simple. Try some math with remainder.

  • When making a method, let it do the whole job. Don't return control variable by ref. If you are sure that the method is consistent, prefer return values, using tuple to group the multiple returning values. Modifying caller's variables isn't a good thing to do. I suggest the method that does the whole job.

  • The problem can be solved using modulo, %. It allows you to iterate linearly whilst staying in the array range by 'wrapping' from the end to the beginning.

  • One loop might be faster than two or more, but I didn't test the performance. At least it might be faster because of less condition checks.

  • It's better to use pascalCase for local variable names instead of lowercasednamesthatwhouldbediffuculttoread.

static void Main()
{
    int[] arr = { 9, 2, 7, 4, 6, 1, 3 };
    int rotate = 7;
    int printSize = 5;
    Print(arr, rotate, printSize);
}

static void Print(int[] arr, int rotate, int printSize)
{
    for (int i = 0; i < rotate * printSize; i++)
    {
        Console.Write(arr[i % arr.Length]);
        if ((i + 1) % printSize == 0)
            Console.WriteLine();
    }
}

Further improvement can affect the large array handling: using StringBuilder to create the output, the print it with a single Console.WriteLine.

The output:

92746
13927
46139
27461
39274
61392
74613
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Hi aepot. Thank you for taking the time to edit your answer to be inline with the site's rules. I have cleaned up the post as your answer is safely within the site's rules. (removing comments and banner) I have attempted to make your answer a little easier to read, but please check I have not misrepresented you or your ideas. Thank you. \$\endgroup\$
    – Peilonrayz
    Commented Jul 6, 2021 at 19:04
  • \$\begingroup\$ @Peilonrayz thank you very much! \$\endgroup\$
    – aepot
    Commented Jul 6, 2021 at 19:10
5
\$\begingroup\$

You're using conditionals and nested loops when you should need neither. In Python this is as easy as

arr = '9274613'
start = 0
for _ in arr:
    print((arr[start:] + arr[:start])[:5])
    start = (start + 5) % len(arr)

C# can do similar.

  • Format your array to a string
  • Loop as many times as there are characters in the string
  • Split the string at the current start index to the end
  • Print the second half followed by the first half; then finally
  • Add 5 to the starting index and modulate by the array length.

Courtesy @aepot, this could look like

static void Main()
{
    int[] arr = { 9, 2, 7, 4, 6, 1, 3 };
    int rotate = 7;
    int printsize = 5;
    Print(arr, rotate, printsize);
}
 
static void Print(int[] arr, int rotate, int printSize)
{
    string text = string.Concat(arr); // "9274613"
    int start = 0;
    for (int i = 0; i < rotate; i++)
    {
        Console.WriteLine((text[start..] + text[..start])[..printSize]);
        start = (start + printSize) % text.Length;
    }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ @aepot That's very kind; thank you! \$\endgroup\$
    – Reinderien
    Commented Jul 5, 2021 at 17:01
  • 2
    \$\begingroup\$ Or even make a string with a 2nd copy of the array, like "92746139274613" (actually stopping short based on the line length). Then you can take sliding windows into that without any string-concat work, just a fixed-size window into that string. In C, it could be repeated fwrite calls, or printf("%7s\n", p++); either of which are just contiguous copies of data already laid out in memory, something a good memcpy can do really fast. \$\endgroup\$ Commented Jul 6, 2021 at 7:43
3
\$\begingroup\$

probably would be best to keep things together and let the method return the results instead.

public static IEnumerable<int> GetPrintResult(int[] array , int size, int rotate)
{
    var count = size * rotate;
    
    var base10 = (int) Math.Pow(10, size - 1);
    
    var result = 0;

    var multiplier = base10;

    for(int x = 0; x < count; x++)
    {
        result += array[x % array.Length] * multiplier;

        multiplier /= 10;

        if(( x + 1 ) % size == 0)
        {
            yield return result;
            multiplier = base10;
            result = 0;
        }
    }
}

then you can retrieve the results as an IEnumerable<int> which would be more flexible to work with.

For instance, if you want to print the results to the Console

var results =  GetPrintResult(arr, 5, 7);
var resultsStr = string.Join(Environment.NewLine, results);
Console.WriteLine(resultsStr);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.