Spoj.com Dos Date

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@nomnom: Ich habe 84 Bytes eingereicht und einen Score von 0 bekommen. :-)

Edit: Und eine Java-Lösung für die es sicher keine gute Punktzahl geben wird. :-D
Month.java:

Code: Alles auswählen

package de.python_forum.blackjack.dosdate;

public enum Month {
    JANUARY("January"), FEBRUARY("February"), MARCH("March"), APRIL("April"),
    MAY("May"), JUNE("June"), JULY("July"), AUGUST("August"),
    SEPTEMBER("September"), OCTOBER("October"), NOVEMBER("November"),
    DECEMBER("December");

    private final String name;

    private Month(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}
DosDate.java:

Code: Alles auswählen

package de.python_forum.blackjack.dosdate;

public class DosDate {
    private static final Month[] MONTHS = Month.values();
    private final int day;
    private final int month;
    private final int year;

    private DosDate(int day, int month, int year) {
        if (day < 1 || day > 31
                || month < 1 || month > 12
                || year < 1 || year > 0x3fff)
        {
            throw new IllegalArgumentException("not a valid dos date");
        }
        this.day = day;
        this.month = month;
        this.year = year;
    }

    public static DosDate fromEncoded(int encoded) {
        if (encoded < 0 || encoded > 0x7fffff) {
            throw new IllegalArgumentException("encoded value out of range");
        }
        return new DosDate(encoded & 0x1f, encoded >> 5 & 0xf, encoded >> 9);
    }

    @Override
    public String toString() {
        return "" + day + " " + MONTHS[month - 1] + " " + year;
    }
}
Main.java:

Code: Alles auswählen

package de.python_forum.blackjack.dosdate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    private static final BufferedReader reader =
            new BufferedReader(new InputStreamReader(System.in));

    private static int readInt() throws IOException {
        return Integer.parseInt(reader.readLine());
    }

    public static void main(String args[]) throws IOException {
        int n = readInt();
        for (int i = 0; i < n; i++) {
            System.out.println(DosDate.fromEncoded(readInt()));
        }
    }
}
nooby
User
Beiträge: 91
Registriert: Montag 12. März 2012, 20:39
Wohnort: 127.0.0.1

Kann mir jemand bitte noch ein Beispiel geben, damit ich mein Code testen kann? :?:
Habe es so umprogrammiert, dass es bei allen gegebenen und dem von BlackJack funktioniert. Kriege jedoch immer noch ein "Wrong Answer".
Hier mein Code:

Code: Alles auswählen

date = []
month_name = {1:"January", 2:"February", 3:"March", 4:"April", 5:"May", 6:"June", 7:"July", 8:"August", 9:"September", 10:"Oktober", 11:"November", 12:"December"}
anzahl = int(input())
for i in range(1, anzahl+1):
    number = int(input())
    number = bin(number)
    number = str(number)
    number = number.split("0b")[1]
    number = number[::-1]
    year = str(number[9:])
    year = year[::-1]
    year = "0b" + year
    year = int(year, 2)
    month = str(number[5:9])
    month = month[::-1]
    month = "0b" + month
    month = int(month, 2)
    day = str(number[:5])
    day = day[::-1]
    day = "0b" + day
    day = int(day, 2)
    date.append([day, month_name[month], year])
    #print(number)
for i in date:
    print i[0], i[1], i[2]
Ich weiss, ich sollte das mit Bitoperatoren machen, aber ich möchte zuerst dieser Programm zum Laufen bringen. :oops:

Danke für eure Hilfe!
nomnom
User
Beiträge: 487
Registriert: Mittwoch 19. Mai 2010, 16:25

Du hast „Oktober“ statt „October“ dastehen.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich habe es jetzt auch mal in Java probiert (ohne auf die Codegröße zu achten), bekomme aber "Wrong Answer" von SPOJ. Sieht jemand den Fehler?

Code: Alles auswählen

import java.io.*;
import java.text.*;
import java.util.*;

class DosDate {
    private static final DateFormat formatter = 
       new SimpleDateFormat("d MMMM y");

    private static final Calendar cal = Calendar.getInstance();

    public static String decode(int dosDate) {
        int day = dosDate & 31;
        int month = dosDate >> 5 & 15;
        int year = dosDate >> 9;
        cal.set(year, month - 1, day);
        return formatter.format(cal.getTime());
    }

    public static void main(String[] args) throws IOException {
        BufferedReader reader = 
          new BufferedReader(new InputStreamReader(System.in));
        int numLines = Integer.parseInt(reader.readLine());
        for (int i = 0; i < numLines; i++) {
            int dosDate = Integer.parseInt(reader.readLine());
            System.out.println(decode(dosDate));
        }
    }
}
Das `public` für die Klassendefinition habe ich weggelassen, da es ansonsten nicht von SPOJ kompiliert wird.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

bei mir gibt Java die Monate in Deutsch und die Jahreszahl grundsätzlich mit 2 Ziffern aus.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Sirius3 hat geschrieben:bei mir gibt Java die Monate in Deutsch und die Jahreszahl grundsätzlich mit 2 Ziffern aus.
Das mit den 2 Ziffern kann ich bei mir nicht bestätigen. Bei der Ausgabe des Monatsnamen gehe ich mal davon aus, dass das Standard-Locale auf SPOJ für eine englischsprachige Ausgabe eingestellt ist. Aber selbst wenn ich `SimpleDateFormat("d MMMM y", Locale.ENGLISH)` definiere, bleibt es bei der falschen Antwort. Wobei meine Tests eigentlich nur (meiner Meinung nach) richtige Antworten ausspucken.
BlackJack

@snafu: Bei mir werden auch nur zwei Stellen beim Jahr bei Deinem Quelltext ausgegeben. Und zwar auf einem Rechner der auf Englisch eingestellt ist.

Edit: Und nachdem ich jetzt in die Java-Dokumentation geschaut habe, ist das eigentlich auch zu erwarten. Bin verwundert, dass die Ausgabe bei Dir vier Stellen ist. Würde ich für einen Bug in Deinem Java halten.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

BlackJack hat geschrieben:@snafu: Bei mir werden auch nur zwei Stellen beim Jahr bei Deinem Quelltext ausgegeben. Und zwar auf einem Rechner der auf Englisch eingestellt ist.

Edit: Und nachdem ich jetzt in die Java-Dokumentation geschaut habe, ist das eigentlich auch zu erwarten. Bin verwundert, dass die Ausgabe bei Dir vier Stellen ist. Würde ich für einen Bug in Deinem Java halten.
Die Ausgabe ist bei mir nicht immer vier Stellen, sondern sie enspricht der Originalangabe. Das Jahr 1 wird nur als 1 angezeigt, das Jahr 12 als 12, usw. Ist ja sehr merkwürdig.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ist bei euch denn auch standardmäßig der `GregorianCalendar` gesetzt? Kriegt man mittels `System.out.println(formatter.getCalendar())` raus.
BlackJack

@snafu: Ja. `java.util.GregorianCalendar` laut Ausgabe. Was anderes würde auch nicht so viel Sinn machen, oder? Und wie gesagt: die abgekürzte Jahreszahl sollte man laut Dokumentation bei der verwendeten Formatierungsangabe auch erwarten.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@BlackJack: Wenn ich allerdings "yyyy" angebe, dann macht er mir aus dem Jahr 1 z.B. ein 0001. Das ist ja dann auch nicht im Sinne des Erfinders. Ist ja echt "klasse", wie toll und konsistent das mit dem Datumsformatieren klappt.
BlackJack

@snafu: Dann benutze es doch einfach nur zum Formatieren des Monatsnamens. Und nur zur Vorsicht die Englische Locale mitgeben, damit der bei SPOJ auf dem Server dann nicht am Ende noch polnische Monatsnamen ausspuckt. :-)
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich geb's jetzt auf in Java. Egal wie klein ich den Puffer für den `BufferedReader` setze, ich bekomme bei der Ausführung auf SPOJ jedes Mal ein überschrittenes Zeitlimit als Antwort und atemberaubenden "Memory Usage". Meine Lösung für `.decode()` war jedenfalls:

Code: Alles auswählen

public static String decode(int dosDate) {
    int day = dosDate & 31;
    int month = dosDate >> 5 & 15;
    int year = dosDate >> 9;
    cal.set(Calendar.MONTH, month - 1);
    return String.format("%d %tB %d", day, cal, year);
}
Und ich denke, das ist auch korrekt.

EDIT: Und das man die verschiedenen "Formatierungswelten" hier so schön mischen kann, finde ich sogar ganz cool. :)
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

103 Zeichen in Ruby:

Code: Alles auswählen

ARGF.lines.next
ARGF.map{|l|d=l.to_i;printf"%d %s %d\n",d&31,Time.new(1,d>>5&15,1).strftime("%B"),d>>9}
EDIT: 99 Zeichen:

Code: Alles auswählen

ARGF.lines.next
ARGF.map{|s|d=s.to_i;puts"#{d&31} #{Time.new(1,d>>5&15,1).strftime("%B")} #{d>>9}"}
91 Zeichen:

Code: Alles auswählen

ARGF.drop(1).map{|s|d=s.to_i;puts"#{d&31} #{Time.new(1,d>>5&15,1).strftime("%B")} #{d>>9}"}
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@snafu: Wenn deine Lösungen noch kürzer werden, wäre es nett, wenn du die Quelltexte nicht mehr posten würdest ... :)
Antworten