Friday, April 19, 2013

How to Solve Mayan Long Count Problem

Problem Description:
The Mayan Long Count calendar is a counting of days with these units: "* The Maya name for a day was k'in. Twenty of these k'ins are known as a winal or uinal. Eighteen winals make one tun. Twenty tuns are known as a k'atun. Twenty k'atuns make a b'ak'tun.*". Essentially, we have this pattern:
  • 1 kin = 1 day
  • 1 uinal = 20 kin
  • 1 tun = 18 uinal
  • 1 katun = 20 tun
  • 1 baktun = 20 katun
  • The long count date format follows the number of each type, from longest-to-shortest time measurement, separated by dots. As an example, '12.17.16.7.5' means 12 baktun, 17 katun, 16 tun, 7 uinal, and 5 kin. This is also the date that corresponds to January 1st, 1970. Another example would be December 21st, 2012: '13.0.0.0.0'. This date is completely valid, though shown here as an example of a "roll-over" date.

    Write a function that accepts a year, month, and day and returns the Mayan Long Count corresponding to that date. You must remember to take into account leap-year logic, but only have to convert dates after the 1st of January, 1970.

    Input Description:
    Through standard console, expect an integer N, then a new-line, followed by N lines which have three integers each: a day, month, and year. These integers are guaranteed to be valid days and either on or after the 1st of Jan. 1970.

    Output Description:
    For each given line, output a new line in the long-form Mayan calendar format: <Baktun>.<Katun>.<Tun>.<Uinal>.<Kin>.

    Sample Input:

    3
    1 1 1970
    20 7 1988
    12 12 2012
    
    Sample Output:
    12.17.16.7.5
    12.18.15.4.0
    12.19.19.17.11
    
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.Scanner;
    
    public class MayanLongCount {
        private static class MayanCalendar {
            private final int kin;
            private final int uinal;
            private final int tun;
            private final int katun;
            private final int baktun;
            
            public MayanCalendar(int baktun, int katun, int tun, int uinal, int kin) {
                this.baktun = baktun;
                this.katun = katun;
                this.tun = tun;
                this.uinal = uinal;
                this.kin = kin;
            }
            
            @Override
            public String toString() {
                return baktun + "." + katun + "." + tun + "." + uinal + "." + kin;
            }
        }
        
        private static Date epochTime() {
            Calendar cal = Calendar.getInstance();
            cal.setTime(new Date(0));
            return cal.getTime();
        }
        
        private static long getNumberOfDays(Date date1, Date date2) {
            return ((date2.getTime() - date1.getTime()) / (1000 * 60 * 60 * 24));
        }
        
        private static MayanCalendar toMayanCalendar(long numberOfDays) {
            long numOfMayanDaysBeforeEpoch = 0;
            int[] mayanEpoch = new int[]{12, 17, 16, 7, 5};
            int[] mayan = new int[]{20*20*18*20, 20*18*20, 18*20, 20, 1};
            for (int i = 0; i < mayan.length; i++) {
                numOfMayanDaysBeforeEpoch += mayan[i] * mayanEpoch[i];
            }
            int[] result = new int[mayan.length];
            long remainder = numberOfDays + numOfMayanDaysBeforeEpoch;
            for (int i = 0; i < mayan.length; i++) {
                int value = (int) (remainder / mayan[i]);
                if (value > 0) {
                    remainder = remainder % mayan[i];
                }
                result[i] = value;
            }
            return new MayanCalendar(
                result[0], result[1], result[2], result[3], result[4]);
        }
        
        public static void main(String[] args) throws Exception {
            Scanner scanner = null;
            try {
                scanner = new Scanner(System.in);
                int n = Integer.parseInt(scanner.nextLine());
                for (int i = 0; i < n; i++) {
                    Date epoch = epochTime();
                    Date input = new SimpleDateFormat("dd MM yyyy")
                        .parse(scanner.nextLine());
                    long numberOfDays = getNumberOfDays(epoch, input);
                    MayanCalendar mc = toMayanCalendar(numberOfDays);
                    System.out.println(mc);
                }
            } finally {
                scanner.close();
            }
        }
    }
    

    No comments:

    Post a Comment