/* KöMaL 2016. March - exercise i397
* Nagy Ábel Mihály 11th grade
* Budapesti Fazekas Mihály Gimnázium
* E-mail: nagyabelmihaly@gmail.com
* Can be compiled by Microsoft Visual Studio 2013
*/
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
namespace i397
{
///
/// This class provides useful methods.
///
public static class Utilities
{
///
/// The two character letters.
///
private static string[] twoCharacterLetters = new string[] { "cs", "dz", "gy", "ly", "ny", "sz", "ty", "zs" };
///
/// The three character letters.
///
private static string[] threeCharacterLetters = new string[] { "dzs" };
///
/// Shortens the specified name by taking only the first letters of the words, and putting a point after each letter.
///
/// The name to shorten.
public static string Shorten(string name)
{
IEnumerable parts = name.Split(' ').Select(part => string.Format("{0}.", FirstLetter(part)));
return string.Join(" ", parts);
}
///
/// Gets the first letter of the specified word.
///
/// The first letter of the specified word.
/// The word.
private static string FirstLetter(string word)
{
if (word.Length >= 2)
{
string startingTwoCharacters = word[0].ToString() + word[1];
if (word.Length >= 3)
{
string startingThreeCharacters = startingTwoCharacters + word[2];
if (threeCharacterLetters.Contains(startingThreeCharacters.ToLower()))
{
return startingThreeCharacters;
}
}
if (twoCharacterLetters.Contains(startingTwoCharacters.ToLower()))
{
return startingTwoCharacters;
}
}
return word[0].ToString();
}
}
///
/// Represents a chess player.
///
public class Competitor
{
///
/// The points of the competitor.
///
private int points;
///
/// Gets the first name of the competitor.
///
/// The first name.
public string FirstName { get; private set; }
///
/// Gets the last name of the competitor.
///
/// The last name.
public string LastName { get; private set; }
///
/// Gets the full name of the competitor.
///
/// The full name.
public string FullName
{
get
{
return string.Format("{0} {1}", this.LastName, this.FirstName);
}
}
///
/// Gets or sets the points of the competitor.
///
/// The points.
public int Points
{
get
{
return this.points;
}
set
{
this.PointsChange += value - this.points;
this.points = value;
}
}
///
/// Gets the change of the points of the competitor relative to his starting points.
///
/// The points change.
public int PointsChange { get; private set; }
///
/// Gets or sets a value indicating whether this is still in game.
///
/// true if the competitor is in game; otherwise, false.
public bool InGame { get; set; }
///
/// Initializes a new instance of the class.
///
/// The first name.
/// The last name.
/// The points.
public Competitor(string firstName, string lastName, int points)
{
this.FirstName = firstName;
this.LastName = lastName;
this.points = points;
this.InGame = true;
}
///
/// Parses the competitor represented by the specified string,
///
/// The string which contains the data of the competitor in the following format: "[points] [last name] [first name(s)]".
public static Competitor Parse(string s)
{
string[] words = s.Split(' ');
int points = int.Parse(words[0]);
string lastName = words[1];
string firstName = string.Join(" ", words.Skip(2));
return new Competitor(firstName, lastName, points);
}
///
/// Returns a that represents the current .
///
/// A that represents the current .
public override string ToString()
{
return string.Format("{0} {1} ({2})", this.LastName, Utilities.Shorten(this.FirstName), this.Points);
}
}
class MainClass
{
///
/// The path of the file which contains the data of the competitors.
///
const string INPUT_FILE_NAME = "sakk.txt";
///
/// The path of the output file.
///
const string SECOND_ROUND_FILE_NAME = "kor2.txt";
///
/// The chess competitors participating in the championship.
///
static List competitors;
///
/// The random instance which will be used to simulate the rounds.
///
static Random random = new Random();
public static void Main(string[] args)
{
// Array of the subtasks
Action[] exercises = new Action[] { Exercise1, Exercise2, Exercise3, Exercise4, Exercise5, Exercise6, Exercise7, Exercise8 };
// Execute all exercises
for (int i = 0; i < exercises.Length; i++)
{
Console.WriteLine("{0}. feladat:", i + 1);
exercises[i]();
Console.WriteLine();
}
}
///
/// Simulates a chess game where each competitor has a chance to win proportional to his points.
///
/// true, if first competitor won, false otherwise.
/// The points of the first competitor.
/// The points of the second competitor.
static bool ElsoNyer(int a, int b)
{
return (random.Next(a + b) < a);
}
///
/// Sorts the competitors based on their points descending, and then on their names ascending.
///
static void SortCompetitors()
{
competitors.Sort((c1, c2) =>
{
if (c1.Points == c2.Points)
{
return c1.FullName.CompareTo(c2.FullName);
}
return c2.Points.CompareTo(c1.Points);
});
}
///
/// Plays a round in the championship.
///
static void PlayRound()
{
for (int i = 0; i < competitors.Count / 2; i++)
{
Competitor competitor1 = competitors[i];
Competitor competitor2 = competitors[competitors.Count - 1 - i];
if (ElsoNyer(competitor1.Points, competitor2.Points))
{
SaveGameResults(ref competitor1, ref competitor2);
}
else
{
SaveGameResults(ref competitor2, ref competitor1);
}
}
}
///
/// Saves the game results.
///
/// The winner competitor.
/// The looser competitor.
static void SaveGameResults(ref Competitor winner, ref Competitor looser)
{
winner.Points += (int)Math.Ceiling(looser.Points / 20f);
looser.InGame = false;
}
///
/// Prints the competitor pairs of the actual round to the specified output stream.
///
/// The output.
static void PrintRound(TextWriter output)
{
for (int i = 0; i < competitors.Count / 2; i++)
{
output.WriteLine("{0}---{1}", competitors[i], competitors[competitors.Count - 1 - i]);
}
}
///
/// Eliminates the competitors not in game.
///
static void EliminateCompetitors()
{
competitors.RemoveAll(competitor => !competitor.InGame);
}
static void Exercise1()
{
using (StreamReader reader = new StreamReader(INPUT_FILE_NAME))
{
competitors = new List();
while (true)
{
string line = reader.ReadLine();
if (string.IsNullOrEmpty(line))
{
break;
}
competitors.Add(Competitor.Parse(line));
}
}
}
static void Exercise2()
{
foreach (Competitor competitor in competitors)
{
Console.WriteLine(competitor);
}
}
static void Exercise3()
{
}
static void Exercise4()
{
SortCompetitors();
PlayRound();
PrintRound(Console.Out);
}
static void Exercise5()
{
int maximumPointsChange = competitors.Select(competitor => competitor.PointsChange).Max();
int maximumPointsChangeCompetitorIndex = competitors.FindIndex(competitor => competitor.PointsChange == maximumPointsChange);
int opponentIndex = competitors.Count - 1 - maximumPointsChangeCompetitorIndex;
Console.WriteLine("{0} szerezte a legtöbb pontot ({1}) {2} ellen.",
competitors[maximumPointsChangeCompetitorIndex], maximumPointsChange, competitors[opponentIndex]);
}
static void Exercise6()
{
EliminateCompetitors();
SortCompetitors();
PlayRound();
using (StreamWriter writer = new StreamWriter(SECOND_ROUND_FILE_NAME))
{
PrintRound(writer);
}
}
static void Exercise7()
{
int minimumInGamePointsChange = competitors.Where(competitor => competitor.InGame).Select(competitor => competitor.PointsChange).Min();
IEnumerable competitorsToPrint = competitors.Where(competitor => !competitor.InGame && competitor.PointsChange > minimumInGamePointsChange);
Console.WriteLine(string.Join(", ", competitorsToPrint));
}
static void Exercise8()
{
for (int i = 0; i < 3; i++)
{
EliminateCompetitors();
SortCompetitors();
if (i == 2)
{
PrintRound(Console.Out);
}
PlayRound();
}
PrintRound(Console.Out);
}
}
}