<commit_before>package tournament

import (
	"fmt"
	"io"
	"strings"
)

type stat struct {
	MatchesPlayed int
	Wins          int
	Draws         int
	Loses         int
	Points        int
}

// Define a function Tally(io.Reader, io.Writer) error.
func Tally(r io.Reader, w io.Writer) error {
	lines, err := getLines(r)
	if err != nil {
		return err
	}
	teamsToScores := map[string]*stat{}
	for _, line := range lines {
		if isComment(line) {
			continue
		}
		// fmt.Printf("line: %s", line)
		parts := strings.Split(line, ";")
		if len(parts) < 3 {
			continue
		}
		fmt.Printf("parts: %s", parts)
		a := parts[0]
		b := parts[1]
		// _ := parts[2]

		if _, ok := teamsToScores[a]; !ok {
			teamsToScores[a] = &stat{}
		}
		if _, ok := teamsToScores[b]; !ok {
			teamsToScores[b] = &stat{}
		}

		teamsToScores[a].MatchesPlayed += 1
		teamsToScores[b].MatchesPlayed += 1
	}

	io.WriteString(w, getTable(teamsToScores))
	return nil
}

func isComment(line string) bool {
	return strings.HasPrefix(line, "#")
}

func getLines(r io.Reader) ([]string, error) {
	input, err := io.ReadAll(r)
	if err != nil {
		return []string{}, err
	}
	lines := strings.Split(string(input), "\n")
	return lines, nil
}

func getTable(teamsToScores map[string]*stat) (result string) {
	// const header = "Team                           | MP |  W |  D |  L |  P"
	var header = fmt.Sprintf("%-30s |%3s |%3s |%3s |%3s |%3s\n", "Team", "MP", "W", "D", "L", "P")
	result += header
	for team, stat := range teamsToScores {
		result += fmt.Sprintf("%-30s |%3d |%3d |%3d |%3d |%3d\n", team, stat.MatchesPlayed, stat.Wins, stat.Draws, stat.Loses, stat.Points)
	}
	return result
}<commit_msg>Sort teams by points then alphabetically<commit_after>package tournament

import (
	"fmt"
	"io"
	"sort"
	"strings"
)

type stat struct {
	Name          string
	MatchesPlayed int
	Wins          int
	Draws         int
	Loses         int
	Points        int
}

// Define a function Tally(io.Reader, io.Writer) error.
func Tally(r io.Reader, w io.Writer) error {
	lines, err := getLines(r)
	if err != nil {
		return err
	}
	teamsToScores := map[string]*stat{}
	for _, line := range lines {
		if isComment(line) {
			continue
		}
		// fmt.Printf("line: %s", line)
		parts := strings.Split(line, ";")
		if len(parts) < 3 {
			continue
		}
		// fmt.Printf("parts: %s", parts)
		a := parts[0]
		b := parts[1]
		outcome := parts[2]

		if _, ok := teamsToScores[a]; !ok {
			teamsToScores[a] = &stat{
				Name: a,
			}
		}
		if _, ok := teamsToScores[b]; !ok {
			teamsToScores[b] = &stat{
				Name: b,
			}
		}

		incrementMatchesPlayed(teamsToScores, a)
		incrementMatchesPlayed(teamsToScores, b)

		switch outcome {
		case "win":
			teamsToScores[a].Wins += 1
			teamsToScores[a].Points += 3
			teamsToScores[b].Loses += 1
		case "loss":
			teamsToScores[a].Loses += 1
			teamsToScores[b].Wins += 1
			teamsToScores[b].Points += 3
		case "draw":
			teamsToScores[a].Draws += 1
			teamsToScores[b].Draws += 1
			teamsToScores[a].Points += 1
			teamsToScores[b].Points += 1
		default:
			return fmt.Errorf("unexpected outcome %s", outcome)
		}
	}

	io.WriteString(w, getTable(teamsToScores))
	return nil
}

func getTable(teamsToScores map[string]*stat) (result string) {
	sorted := sortTeamsByPointsThenAlphabetically(teamsToScores)
	var header = fmt.Sprintf("%-30s |%3s |%3s |%3s |%3s |%3s\n", "Team", "MP", "W", "D", "L", "P")
	result += header
	for _, stat := range sorted {
		result += fmt.Sprintf("%-30s |%3d |%3d |%3d |%3d |%3d\n", stat.Name, stat.MatchesPlayed, stat.Wins, stat.Draws, stat.Loses, stat.Points)
	}
	return result
}

func sortTeamsByPointsThenAlphabetically(teamsToScores map[string]*stat) (result []*stat) {
	for _, stat := range teamsToScores {
		result = append(result, stat)
	}
	sort.SliceStable(result, func(i, j int) bool {
		if result[i].Points != result[j].Points {
			return result[i].Points > result[j].Points
		}
		return result[i].Name < result[j].Name
	})

	return result
}

func isComment(line string) bool {
	return strings.HasPrefix(line, "#")
}

func getLines(r io.Reader) ([]string, error) {
	input, err := io.ReadAll(r)
	if err != nil {
		return []string{}, err
	}
	lines := strings.Split(string(input), "\n")
	return lines, nil
}

func incrementMatchesPlayed(teamsToScores map[string]*stat, team string) {
	teamsToScores[team].MatchesPlayed += 1
}
{'fraction_non_alphanumeric': 0.16312874942316566, 'fraction_numerical': 0.011305952930318412, 'mean_word_length': 3.3611670020120723, 'pattern_counts': {'":': 3, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '745376', 'n_tokens_mistral': 1861, 'n_tokens_neox': 1704, 'n_words': 395}