// August Druzgal
// 9/16/2023
// Code for CIS 3362 Fall 23 Homework 2B Question 3

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;

class Hmk2B3
{
    public static void main(String[] args) 
    {
        String cyphertext;
        
        try
        {
            File input = new File("input2B3.txt");
            BufferedReader reader = new BufferedReader(new FileReader(input));

            cyphertext = reader.readLine();

            reader.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return;
        }

        // Calculate the index of coincidence of the cyphertext
        System.out.println(10 + " - " + indexOfCoincidence(cyphertext, 10));
        frequency(cyphertext, 10);
        System.out.println(decrypt(cyphertext, "sabbatical"));
    }

    // Calculates the average index of coincidence of the letter groups in the cyphertext
    //  for the specified key length
    private static float indexOfCoincidence(String cyphertext, int len)
    {
        int[][] counts = new int[len][26];
        float[] outputs = new float[len];

        for (int i = 0; i < cyphertext.length(); i++)
            counts[i%len][cyphertext.charAt(i) - (int)'a']++;

        float total;
        float sum;

        for (int i = 0; i < len; i++)
        {
            total = 0;
            sum = 0;

            for (int value:counts[i])
            {
                sum += value * (value - 1);
                total += value;
            }

            outputs[i] = sum / (total * (total - 1));
        }

        sum = 0;

        for (float val:outputs)
            sum += val;

        return sum / len;
    }

    // Counts the frequency of letters in the input cyphertext, and outputs them as 
    // letter group graphs for a key of the specified length
    private static void frequency(String cyphertext, int len)
    {
        int[][] counts = new int[len][26];
        
        for (int i = 0; i < cyphertext.length(); i++)
            counts[i%len][cyphertext.charAt(i) - (int)'a']++;

        for (int i = 0; i < len; i++)
        {
            System.out.println("\nGroup " + i + ":");
            for (int j = 0; j < 26; j++)
            {
                System.out.print((char)((int)'a' + j) + " - ");
                for (int k = 0; k < counts[i][j]; k++)
                    System.out.print('o');
                System.out.println("");
            }
        }
    }

    // Decrypts Vigenere-encrypted input cyphertext using the input key
    private static String decrypt(String cyphertext, String key)
    {
        char[] output = new char[cyphertext.length()];
        int temp;
        for (int i = 0; i < cyphertext.length(); i++)
        {
            temp = cyphertext.charAt(i) - (int)'a';
            temp += 26 - (key.charAt(i%key.length()) - 'a');
            temp %= 26;
            output[i] = (char) ((int)'a' + temp);
        }
        return String.valueOf(output);
    }
}
