Tuesday, November 5, 2019

UVa 110 - Meta-Loopless Sorts

// UVa 110 - Meta-Loopless Sorts

import java.util.*;

public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        for (int numberOfTestCases = scanner.nextInt(); numberOfTestCases > 0; numberOfTestCases--) {
            int n = scanner.nextInt();

            new PascalProgramPrinter(n).print();

            if (numberOfTestCases > 1)
                System.out.println();
        }

    }

    private static class PascalProgramPrinter {

        private static char[] VAR_IDS = new char[]{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};

        private final int n; // e.g. 3
        private final String vars; // e.g. "a,b,c"

        private char[] relativeOrdering;

        PascalProgramPrinter(int n) {
            this.n = n;
            this.vars = commaSeparated(VAR_IDS);
            this.relativeOrdering = new char[n + 1];
        }

        private String commaSeparated(char[] charArray) {
            StringBuilder sb = new StringBuilder();
            sb.append(charArray[0]);
            for (int i = 1; i < n; i++) {
                sb.append(',');
                sb.append(charArray[i]);
            }
            return sb.toString();
        }

        void print() {
            printHeader();
            printIfs();
            printFooter();
        }

        private void printHeader() {
            System.out.println("program sort(input,output);");
            System.out.println("var");
            System.out.println(vars + " : integer;");
            System.out.println("begin");
            System.out.println("  readln(" + vars + ");");
        }

        private void printIfs() {
            relativeOrdering[0] = 'a';
            printIfs('b', 1);
        }

        private void printIfs(char varToOrder, int level) {
            if (varToOrder >= 'a' + this.n) {
                printIdent(level);
                System.out.println("writeln(" + commaSeparated(relativeOrdering) + ")");
                return;
            }

            for (int pos = level; pos >= 0; pos--) {
                printIdent(level);
                if (pos < level)
                    System.out.print("else ");
                relativeOrdering[pos + 1] = relativeOrdering[pos];
                relativeOrdering[pos] = varToOrder;
                if (pos > 0)
                    printOneIf(relativeOrdering[pos - 1], relativeOrdering[pos]);
                else
                    System.out.println();
                printIfs((char) (varToOrder + 1), level + 1);
            }
            for (int pos = 0; pos < level; pos++)
                relativeOrdering[pos] = relativeOrdering[pos + 1];
        }

        private static void printIdent(int identLevel) {
            for (int i = 0; i < identLevel; i++)
                System.out.print("  ");
        }

        private static void printOneIf(char v1, char v2) {
            System.out.println(String.format("if %c < %c then", v1, v2));
        }

        private void printFooter() {
            System.out.println("end.");
        }
    }
}

No comments:

Post a Comment