0

I need a little help sorting a split array into highest to lowest while keeping the names next to the scores. Im a little unsure how to do so because the array is split.

This is the code I have so far.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace proj09LEA
{
    class Program
    {
        static void Main(string[] args)
        {
            // declare and array of integers          
            string[] name = new string[5];
            int[] score = new int[5];

            Console.WriteLine("\nSaturday Coder's Bowling Team");
            Console.WriteLine("Enter in a name and score for each person on the team.");
            Console.WriteLine("For example, Mary 143. Just hit Enter when you are done.\n");

            // fill an array with user input
            for (int i = 0; i < score.Length; i++)
            {
                Console.WriteLine("Enter in a name and score: ");
                string line = Console.ReadLine();

                name[i] = line.Substring(0, line.IndexOf(' '));
                score[i] = int.Parse(line.Substring(line.IndexOf(' ') + 1));
            }

            Console.WriteLine("------------ Input Complete ------------\n");
            Console.WriteLine("Here are the scores for this game, from highest to lowest:\n");

            for (int i = 0; i < score.Length; i++)
            {
                if (score[i] >= 300)
                {
                    Console.WriteLine("{0}'s score was {1}*.", name[i], score[i]);
                }
                else
                {
                    Console.WriteLine("{0}'s score was {1}.", name[i], score[i]);
                }
            }

            dynamic swap;
            for (int i = 0; i < score.Length - 1; i++)
            {
                for (int j = i + 1; j < score.Length; j++)
                {
                    swap = score[i];
                    score[i] = score[j];
                    score[j] = swap;

                    swap = name[i];
                    name[i] = name[j];
                    name[j] = swap;
                }
            }

            AverageScore(score);

            Console.WriteLine("Press Enter to continue. . .");
            Console.ReadLine();
        }

        static void AverageScore(int[] score)
        {
            int sum = score.Sum();
            int average = sum / score.Length;
            Console.WriteLine("The average score for this game was {0:d}.\n", average);
        }
    }
}
1
  • 9
    I would strongly recommend using a single collection of both scores and names combined into a Player class or something similar. See codeblog.jonskeet.uk/2014/06/03/… Commented Dec 7, 2014 at 22:17

3 Answers 3

2

Personally, I would use a class to represent the players, so that you can keep the names and scores together. Something like:

public class Player
{
    public string Name { get; set; }
    public int Score { get; set; }
}

Then, you can get the high, low and average like this:

private static void Main(string[] args)
{
    // Of course this list could be generated from user input, and the scores
    // would start at 0, incrementing as play progressed. This is just for example.
    var players = new List<Player>
    {
        new Player {Name = "Abe", Score = 140},
        new Player {Name = "Bert", Score = 200},
        new Player {Name = "Charlie", Score = 150},
        new Player {Name = "Donald", Score = 300},
        new Player {Name = "Ernie", Score = 120},
    };

    var maxScore = players.Max(p => p.Score);
    var minScore = players.Min(p => p.Score);

    foreach (var player in players.Where(p => p.Score == maxScore))
    {
        // Note the inline check for a perfect score, which adds a '*' after it
        Console.WriteLine("Congratulations {0}, your score of {1}{2} was the highest.",
            player.Name, player.Score, maxScore == 300 ? "*" : "");
    }

    foreach (var player in players.Where(p => p.Score == minScore))
    {
        Console.WriteLine("{0}, your score of {1} was the lowest. " + 
            "Better get some practice.", player.Name, player.Score);
    }

    Console.WriteLine("The average score for this game was {0}.", 
        players.Average(p => p.Score));
}

And if you want to sort the list of players by score, you can do something like this:

// This will sort the list by the score, with the highest score first
// Just for fun, it then sorts any ties by the player name
players = players.OrderByDescending(p => p.Score).ThenBy(p => p.Name).ToList();

Console.WriteLine("Here are all the players and their scores:");
players.ForEach(p => Console.WriteLine(" - {0}: {1}", p.Name, p.Score));
Sign up to request clarification or add additional context in comments.

Comments

0

try this to sort the array

dynamic swap;
for (int i = 0; i < score.length - 1; i++)
    for(int j = i + 1; j < score.length; j++)
    {
        if (score[i] < score[j]) 
        {
             swap = score[i];
             score[i] = score[j];
             score[j] = swap;

             swap = name[i];
             name[i] = name[j];
             name[j] = swap;
        }
    }

and use this for the perfect score

for (int i = 0; i < score.Length; i++)
{
    if (score[i] >= 300) 
    {
        Console.WriteLine("{0}'s score was {1}*.", name[i], score[i]);
    }
    else
    {
        Console.WriteLine("{0}'s score was {1}.", name[i], score[i]);
    }
}

2 Comments

You can't be serious to suggest that O(n*n) algorithm for sorting which also doesn't answer anything.
Well since he is not using classes this should work perfectly
0

My answer is a little different. Unless this is a school problem and your teacher wants you to write your own sort I would write a Class that stores all the Score data and Implements IComparable and use the List.Sort method to do the sort. I then override the Class's ToString method to display the score the way you want to.

Class to store your Data:

public class BowlingScore : IComparable<BowlingScore>
{
    private int _score = 0;

    public string Name { get; set; }

    public bool IsPerfectGame { get; protected set; }

    public int Score
    {
        get { return this._score; }

        set 
        { 
                this._score = value; 
                this.IsPerfectGame = value == 300; 
        }
    }

    public override string ToString()
    {
        if (this.IsPerfectGame)
        {
            return string.Format("{0}'s score was {1}*", this.Name, this.Score);
        }
        else
        {
            return string.Format("{0}'s score was {1}", this.Name, this.Score);

        }
    }

    public int CompareTo(BowlingScore other)
    {
        return this.Score.CompareTo(other.Score);
    }
}

Code to populate List of BowlingScore's and sort low to high and display high, low and average score. Note that you can have more then 1 high and low score.

        List<BowlingScore> scores = new List<BowlingScore>()
        {
            new BowlingScore() { Name = "Joe", Score = 278},
            new BowlingScore() { Name = "Pete", Score = 300},
            new BowlingScore() { Name = "Lisa", Score = 27},
            new BowlingScore() { Name = "Trevor", Score = 50},
            new BowlingScore() { Name = "Jim", Score = 78},
            new BowlingScore() { Name = "Bob", Score = 27},
            new BowlingScore() { Name = "Sally", Score = 50},
        };

        Console.WriteLine();
        Console.WriteLine("Here are the Scores:");

        scores.Sort();

        foreach (BowlingScore score in scores)
        {
            Console.WriteLine(score);
        }

        Console.WriteLine();
        HighScores(scores);

        Console.WriteLine();
        LowScores(scores);

        Console.WriteLine();
        Console.WriteLine(string.Format("Average score:{0}", scores.Average(f => f.Score)));

        Console.WriteLine();
        Console.WriteLine("Press any key...");
        Console.ReadKey();

    static void HighScores(List<BowlingScore> scores)
    {
        int highScore = scores.ElementAt(scores.Count - 1).Score;

        for(int index = scores.Count -1; index > 0; index--)
        {
            BowlingScore bowlingScore = scores.ElementAt(index);

            if (bowlingScore.Score == highScore)
            {
                Console.WriteLine(string.Format("High Score: {0} {1}", bowlingScore.Name, bowlingScore.Score));
            }
            else
            {
                break;
            }
        }
    }

    static void LowScores(List<BowlingScore> scores)
    {
        int lowScore = scores.ElementAt(0).Score;

        for (int index = 0; index < scores.Count; index++)
        {
            BowlingScore bowlingScore = scores.ElementAt(index);

            if (bowlingScore.Score == lowScore)
            {
                Console.WriteLine(string.Format("Low Score: {0} {1}", bowlingScore.Name, bowlingScore.Score));
            }
            else
            {
                break;
            }
        }
    }

6 Comments

OP uses high,low and average scores in questiion. Do you think it needs sorting ? A single loop ( an O(n) ) solution is enough.
a) Do you think your comment is readable b) What would scores.First() return If it is not sorted (Don't forget you don't need sorting) c), Do you think it is an efficient way to iterate on the list many times like *scores.First().Name* and *scores.First().Score*
You still don't need Sort to find min,max,average. A single loop is enough. No need for O(n*log(n)) algorithm.
Sure you don't need sort. But how does your single Loop handle multiple people having the same high and low scores. Seems like you have quite a bit more complexity in this single loop versus doing a single Sort that is slightly more expensive. I would rather have simpler code that is slightly slower then complicated code that isn't much faster.
It's pretty easy with a List of a simple class containing Name and Score to get all players with a high score. In fact, you can do it in one line: players.Where(p => p.Score == players.Max(p => p.Score)).ToList().ForEach(p => Console.WriteLine("{0} has a high score of: {1}!", p.Name, p.Score));
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.