Hackerboard Wiki HaboBlog
Hackerboard bei Facebook Hackerboard bei Google+ Hackerboard bei Twitter

[HaBo]

 
Programmieraufgaben Hier wird regelmäßig eine neue Programmieraufgabe gestellt, die dann gelöst werden soll und in Zusammenarbeit mit den Moderatoren auch besprochen werden kann.

Tage berechnen

Diskussion: Tage berechnen im Forum Programmieraufgaben, in der Kategorie Code Kitchen; Anzeige Hallo zusammen Meine Ruby Lösung darf natürlich nicht fehlen; jetzt, wo ich die halbe Nacht daran gearbeitet habe. (Ist ...

Antwort
Alt 17.02.11, 01:28   #31 (permalink)
phi
 
Registriert seit: 15.02.11
phi Leistung: Facit NTK
Likes: 0
Standard Ruby

Anzeige

Hallo zusammen

Meine Ruby Lösung darf natürlich nicht fehlen; jetzt, wo ich die halbe Nacht daran gearbeitet habe. (Ist mein erstes etwas größeres Ruby Programm.)

PS. Ich habe mir weder die Mühe gemacht, den Code möglichst kurz zu halten, noch habe ich die Eingabe auf Korrektheit geprüft.
Aber der Übergang vom Julianischen zum Gregorianischen Kalender funktioniert.

Ruby   

#!/usr/bin/ruby
# -*- coding: utf-8 -*-

# @autor Philipp Gressly Freimann
# 17. Feb. 2011 (Corinas Geburtstag)
#
# Aufgabe hackerboard.de + programmieraufgaben.ch
# Gegeben dd.mm.yyyy (ein Datum). Berechne die Position im Jahr:
# 1. Jan. = 1
# 31. Dez. = 365 (mit Ausnahmen)
#
# Es wird keine Prüfung gemacht, ob das Datum existiert!

# Hilfsfunktionen:

def nach15OktImJahr1582(d, m, y)
puts "greg #{d}. #{m}. #{y}"
if( 1582 != y) then return false end
if( 10 < m) then return true end
if( 10 > m) then return false end
return 15 <= d
end

def schaltJahr(y)
# julianisch:
if(y < 1582) then return 0 == y % 4 end
# gregorianisch:
return 0 == y % 400 ? true : (0 == y % 100 ? false : (0 == y % 4))
end

# Julianische Korrektur:
# Je Differenzen zum standard ägyptischen bürgerlichen
# Verwaltungsmonat mit je 30 Tagen:
# MONAT0, Jan, Feb, März, ..., Nov (Dez. unnötig)
diff30 = [-30,1,-2,1,0,1,0,1,1,0,1,0]

# Einlesen
print "DD.MM.YYYY eingeben: "
dd,mm,yy = STDIN.gets.scan(/(\d{2})\.(\d{2})\.(\d{4})/).flatten
dd = dd.to_i; mm = mm.to_i; yy = yy.to_i

if(schaltJahr(yy))
diff30[2] += 1 #Im Februar einen Tag dazuzählen
end

res = dd
# Rechne alle Monate mit 30 Tagen (+/- Korrektur) zum Datum dazu.
diff30[0..(mm.to_i-1)].each {|d| res += d + 30}

# 1582 Korrektur:
if(nach15OktImJahr1582(dd, mm, yy))
res = res - 10
end

#Ausgabe
puts "Der #{dd}. #{mm}. #{yy} ist der #{res}. Tag im Jahr."
phi ist offline   Mit Zitat antworten
Alt 18.02.11, 18:40   #32 (permalink)
 
Registriert seit: 12.01.09
lone.wolf Leistung: Z3
lone.wolf eine Nachricht über AIM schicken
Likes: 1
Standard

Code:
[delphi]
program Project2;

{$APPTYPE CONSOLE}

var
  d, m: Byte;
  y, e: Word;
  w: Char;


const
  DayOfWeekStr: Array[0..6] of String = (
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday',
    'Sunday'
  );

function IsLeapYear(const Year: Word): Boolean;
begin
  Result := ( Year mod 4 ) = 0;
end;

function ElapsedDaysWithinAYear(const D, M: Byte; const Y: Word): Word;
var
  i: Integer;
  LeapYear: Boolean;
begin
  Result := 0;
  if not( D in [1..31] ) or not( M in [1..12] ) then
    Exit;
  LeapYear := IsLeapYear( Y );
  for i := 1 to M - 1 do
    if i mod 2 = 1 then
    begin
      if i < 8 then
        inc( Result, 31 )
      else
        inc( Result, 30 );
    end else
    if ( i = 2 ) then
    begin
      if LeapYear then
        inc( Result, 29 )
      else
        inc( Result, 28 );
    end else
      if i < 8 then
        inc( Result, 30 )
      else
        inc( Result, 31 );
  inc( Result, D );
end;

function ElapsedDays(const fromDay, fromMonth: Byte; const fromYear: Word;
  const toDay, toMonth: Byte; const toYear: Word): DWord;
var
  i: Integer;
begin
  Result := 0;
  if fromYear = toYear then
    Result := ElapsedDaysWithinAYear( toDay, toMonth, toYear ) -
      ElapsedDaysWithinAYear( fromDay, fromMonth, toYear )
  else
  begin
    for i := fromYear+1 to toYear-1 do
      inc( Result, ElapsedDaysWithinAYear( 31, 12, i ) );
    inc( Result, ElapsedDaysWithinAYear( 31, 12, fromYear ) -
      ElapsedDaysWithinAYear( fromDay, fromMonth, fromYear ) );
    inc( Result, ElapsedDaysWithinAYear( toDay, toMonth, toYear ) );
  end;
end;

function WeekCount(const Days: Word): Byte;
begin
  Result := Days div 7;
end;

function DayOfWeek(const D, M: Byte; const Y: Word): String;
var
  DaysPassedBySince1Jan1900: DWord;
begin
//  1 Jan 1900 was a Monday.
  DaysPassedBySince1Jan1900 := ElapsedDays( 1, 1, 1900, D, M, Y );
  Result := DayofWeekStr[(DaysPassedBySince1Jan1900-1) mod 7];
end;

begin
  repeat
    Writeln( 'Input: Day Month Year' );
    Readln( d, m, y );
    e := ElapsedDaysWithinAYear( d, m, y );
    if e <> 0 then
      Writeln( 'Elapsed days: ', e, ' (as weeks: ', DaysAsWeeks( e ), ')' )
    else
      Writeln( 'Error!' );
    Write( 'Again? [j/n] ' );
    Read( w );
    Writeln;
  until w <> 'j';
  readln;
end.
[/delphi]
Auszug:
Code:
Input: Day Month Year
18 02 2011
Elapsed days: 49 (as weeks: 7)
Again? [j/n]

Geändert von lone.wolf (24.02.11 um 22:37 Uhr)
lone.wolf ist offline   Mit Zitat antworten
Alt 22.02.11, 14:32   #33 (permalink)
 
Registriert seit: 22.02.11
slowfly Leistung: Facit NTK
Likes: 0
Standard Mein Versuch

Hier noch mein Versuch. Was ich prinzipiell anders gemacht habe, ist, dass die Methode zur Berechnung nichts mit Strings macht, also die Splittung erfolgt vorher (01.02.2000 -> []{1,2,2000}.
Die Validierung ob der Übergabeparameter korrekt ist mache ich mit nem mehr oder weniger simplen Regex. Man hätte noch weiter gehen können und überprüfen, ob das Datum als solches überhaupt existiert (wie z.B. 31.11, 29.02.2001, etc).
Die Anzahl Tage pro Monat sind in einem int-array gespeichert.


Code:
package ch.slowy.days;

public class CalculateDays {
    private static int[] amountOfDaysPerMonth;

    static {
        // I am Lazy... declare in static block
        amountOfDaysPerMonth = new int[12];
        amountOfDaysPerMonth[0] = 31;
        amountOfDaysPerMonth[1] = 28;
        amountOfDaysPerMonth[2] = 31;
        amountOfDaysPerMonth[3] = 30;
        amountOfDaysPerMonth[4] = 31;
        amountOfDaysPerMonth[5] = 30;
        amountOfDaysPerMonth[6] = 31;
        amountOfDaysPerMonth[7] = 31;
        amountOfDaysPerMonth[8] = 30;
        amountOfDaysPerMonth[9] = 31;
        amountOfDaysPerMonth[10] = 30;
        amountOfDaysPerMonth[11] = 31;
    }

    public static int calculateDays(int[] splittedDate) {
        int amountOfDays = 0;
        for (int i = 0; i < splittedDate[1] - 1; i++) {
            amountOfDays += amountOfDaysPerMonth[i];
        }
        amountOfDays += splittedDate[0];
        if (isLeapYear(splittedDate[2])) {
            amountOfDays++;
        }
        return amountOfDays;
    }

    public static boolean isValidDate(String inDate) {
        return inDate
                .matches("(0[1-9]|1[0-9]|2[0-9]|3[01])\\.(0[0-9]|1[012])\\.\\d+");
    }

    public static int[] splitDate(String arg) {
        int[] returnValue = new int[3];

        boolean errorOccured = false;

        String[] splitted = arg.split("\\.");

        // the defined date pattern has three values
        if (splitted.length != 3) {
            errorOccured = true;
        } else {
            try {
                for (int i = 0; i < returnValue.length; i++) {
                    returnValue[i] = Integer.valueOf(splitted[i]);
                }
            } catch (NumberFormatException e) {
                errorOccured = true;
            }
        }

        if (errorOccured) {
            System.out.println("Unable to split argument " + arg);
            System.exit(1);
        }

        return returnValue;

    }

    public static boolean isLeapYear(int year) {
        return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }
}
TestCase dazu
Code:
 package ch.slowy.days;

import junit.framework.TestCase;

public class TestCalculateDays extends TestCase {
    public void testIsLeapYear() {
        assertTrue(CalculateDays.isLeapYear(2000));
        assertFalse(CalculateDays.isLeapYear(2001));
        assertFalse(CalculateDays.isLeapYear(2002));
        assertFalse(CalculateDays.isLeapYear(2003));
        assertTrue(CalculateDays.isLeapYear(2004));
        assertFalse(CalculateDays.isLeapYear(2005));
        assertFalse(CalculateDays.isLeapYear(2006));

        assertTrue(CalculateDays.isLeapYear(2400));
        assertTrue(CalculateDays.isLeapYear(2800));
    }

    public void testIsValidDate() {
        assertTrue(CalculateDays.isValidDate("01.01.2010"));
        assertTrue(CalculateDays.isValidDate("02.01.2011"));
        assertTrue(CalculateDays.isValidDate("03.01.2012"));
        assertTrue(CalculateDays.isValidDate("04.01.1999"));
        assertTrue(CalculateDays.isValidDate("05.01.1322"));
        assertTrue(CalculateDays.isValidDate("06.01.1764"));
        assertTrue(CalculateDays.isValidDate("07.02.1955"));
        assertFalse(CalculateDays.isValidDate("32.01.1900"));
        assertFalse(CalculateDays.isValidDate("00.01.0199"));
    }
    
    public void testCalculateDays(){
        assertEquals(224, CalculateDays.calculateDays(CalculateDays.splitDate("12.08.2005")));
    }
}
slowfly ist offline   Mit Zitat antworten
Alt 09.06.11, 09:29   #34 (permalink)
 
Registriert seit: 07.06.11
NattleBet Leistung: Facit NTK
Likes: 0
Standard

Hier meine Variante
JAVA   
public class Datumsrechner {
class Date {
int day, month, year;
Date(String date) {
String[] split = date.split("\\.");
day = Integer.parseInt(split[0]);
month = Integer.parseInt(split[1]);
year = Integer.parseInt(split[2]);
}
}

private boolean getLeapYear(int year) {
if (year % 400 == 0) return true;
else if (year % 100 == 0) return false;
else if (year % 4 == 0) return true;
return false;
}

private int[] getDaysInYear(int year) {
return new int[] { 31, getLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
}

public boolean valid(String date) {
Date d = new Date(date);
if ((d.month >= 1 && d.month <= 12) && (d.day >= 1 && d.day <= getDaysInYear(d.year)[d.month - 1]))
return true;
return false;
}

public int countDays(String startDate, String endDate) {
if (!valid(startDate) || !valid(endDate)) return -1;
Date start = new Date(startDate);
Date end = new Date(endDate);
int sumDays = 0, year = start.year, month = start.month, day = start.day;
for (; year <= end.year; year++) {
for (; month <= 12; month++) {
for (; day <= getDaysInYear(year)[month - 1]; day++) {
sumDays++;
if (day == end.day && month == end.month && year == end.year)
return sumDays;
}
day = 1;
}
month = 1;
}
return -1;
}

public static void main(String[] args) {
Datumsrechner datum = new Datumsrechner();
String start = "01.01.2005";
String end = "12.08.2005";
System.out.println("Startdatum: " + start + " -> " + datum.valid(start));
System.out.println("Enddatum: " + end + " -> " + datum.valid(end));
System.out.println("Tage: " + datum.countDays(start, end));
}
}

Geändert von NattleBet (09.06.11 um 09:31 Uhr)
NattleBet ist offline   Mit Zitat antworten
Alt 05.08.11, 09:56   #35 (permalink)
 
Registriert seit: 13.07.11
2Fake Leistung: Facit NTK
Likes: 0
Standard

Zitat:
Zitat von benwilliam Beitrag anzeigen
weiß eigentlich einer von euch warum der Juli und der August beide 31 Tage haben?? *g*

Hilfestellung
Juli => Julius Cäser
August => Augustus

die Geschichten der beiden überschneiden sich. Und die überschneidung liefert die Lösung *g*

(falls der Post euch so dämlich erscheint einfach löschen!!)
Weil der der nach dem anderen kam (weiß grad nicht, wer es war und bin zu faul nachzugucken), es nicht einsah, dass der andere eine Monat nach seinem Namen hat, der mehr Tage besaß, als der Monat des anderen. Darum haben beide 31 Tage.

Hoffe, dass ich das verständlich beschrieben habe :-)
2Fake ist offline   Mit Zitat antworten
Alt 17.08.11, 17:35   #36 (permalink)
 
Registriert seit: 17.08.11
77fill Leistung: Facit NTK
Likes: 0
Standard

Hallo,
wollte mal meine lösung in assembler reinstellen (bin noch anfänger)
dieser code ist aber nicht grad "optimal" ^^
das heißt er funktioniert aber man kann ihn sicher noch verbessern ...
und er überprüft noch nicht ob man jetzt die tage also 30 oder 31 richtig
hatt ...
aber hier der code : (ist für nasm. assemblieren mit
nasm blabla.asm -fbin -o blabla.com)

code   
org 100h
;; Procedur zum lesen von TT.MM.YYYY (nasm)
%macro Lesen 0
push bp
mov bp,sp
sub sp,28h
cmp byte [80h],11 ; 80h = wie viel eingegeben ? TT.MM.YYYY + Leerzeichen = 11
je %%genug
%%fehler:
FEHLER ; prozedur FEHLER
%%genug:
mov si,82h ; 82h = beginn von den commandozeilen argumenten (81h=Leerzeichen)
xor bx,bx
inc bx
xor al,al
%%load:
lodsb ; al =zeichenladen
cmp bx,3
jb %%kleiner3
cmp bx,3
je %%punkt1
cmp bx,6
jb %%kleiner6
cmp bx,6
je %%punkt2
cmp bx,0Bh
je %%ente
mov di,bx ; bx ist ja der conter aber bp+bx ist falsch dafür bp+di ist richtig und ....
neg di ; man braucht bp-di
mov [bp+di],al
inc bx ; counter eins erhöhen ..
jmp %%load
%%kleiner3:
mov di,bx
neg di
mov [bp+di],al
inc bx
jmp %%load
%%punkt1:
%%punkt2:
cmp al,'.'
jne %%fehler
inc bx
jmp %%load
%%kleiner6:
mov di,bx
neg di
mov [bp+di],al
inc bx
jmp %%load
%%ente: ; ende ...
;; in BCD gepackt umwandeln
;; TT
xor ax,ax
mov al,byte [bp-1] ; al=erste Ziffer
cmp al,30h ;überprüfung ob es überhaupt eine ziffer ist
jb %%fehler
cmp al,39h
ja %%fehler
and al,0fh ; die ziffer ist im ascii format : ich wandele es in normale zahl um
shl al,4 ; die erste zahl ist ja die zehnerstelle also ....

mov ah,byte [bp-2] ; ist das gleiche bloß für die einerstelle
cmp ah,30h
jb %%fehler
cmp ah,39h
ja %%fehler
and ah,0fh
or al,ah ; al=Gepackte BCD Zahl zehner und einerstelle
;; MM ; hier passiert dass gleiche nur für Monat
xor bx,bx
mov bl,byte [bp-4]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-5]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov ah,bl ; ah=Gepackte BCD Zahl zehner und einerstelle von monat
;; JJJJ ; das gleiche für das Jahr

xor bx,bx
mov bl,byte [bp-7]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-8]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov dh,bl


xor bx,bx
mov bl,byte [bp-9]
cmp bl,30h
jb %%fehler
cmp bl,39h
ja %%fehler
and bl,0fh
shl bl,4
mov bh,byte [bp-10]
cmp bh,30h
jb %%fehler
cmp bh,39h
ja %%fehler
and bh,0fh
or bl,bh
mov dl,bl ; hier ist das für das Jahr zuende und dann steht in dh GBCD huderter und in dl GBCD einer/zehner
mov sp,bp
pop bp
%endmacro

;; ENDE der Procedur

;; Procedur zum überprüfen ob TT<=31 und MM<=12 (Jahr ist sowiso richtig ...)
%macro Uberprufen 0 ; ich denker die prozedur ist selbsterklärend ....
push bp
mov bp,sp
sub sp,28h

cmp al,00110001b ; 31
ja %%fehler
cmp ah,00010010b ; 12
ja %%fehler

jmp %%nee
%%fehler:
FEHLER
%%nee:
mov sp,bp
pop bp
%endmacro
;; ENDE der Procedur

;; Procedur zum ausrechnen des Unterschiedes
%macro Rechnen 0
mov cl,dl ; dl (zehner einer des Jahres) nach cl
teilbar ; überprüft ob durch 4 teilbar und setet carry wenn ja und ansonsten clear carry
jc %%nuller ; wenn durch 4 teilbar
%%normal:
xor bx,bx ; da wird ergebnis gespeichert
%%schalti:
dec al ; tag um eins verkürzen (der unterschied ist ja zwischen TT und 01 und nicht 00)
mov cl,al ; al ist eine gepackte bcd zahl ...
and al,0F0h ; in al steht jetzt die zehner ..
shr al,4 ;werden zu einern gemacht also als beispiel : wird 50 zu 5 ; da ich es nach binär umwandeln muss
mov ch,al ; zehner nach ch absichern
add al,al ; al*10 ...
add al,al
add al,al
add ch,ch
add al,ch ; ...
add bl,al ; in bl steht ja dann das ergebniss drin
and cl,0Fh ; in cl jetzt einer
add bl,cl ; ...
mov ch,ah ; Monat ... gebackte BCD ...
and ah,0Fh
and ch,0F0h
shr ch,4
mov cl,ch ; ch*10 ...
add ch,ch
add ch,ch
add ch,ch
add cl,cl
add ch,cl ; ...
add ah,ch
movsx di,ah
add di,di
add bx,word [TABELLE+di] ; ... monat ...
jmp %%ente
%%nuller:
test dl,dl ;durch huntert teilbar ?
je %%hundert
cmp ah,3 ; wenn der monat kleiner ist als 3 dann ist es egal ob schaltjahr oder nicht
jb %%nee1
xor bx,bx ; wenn schaltjahr dann bx auf 1 setzten = wenn schaltjahr um eins erhöhen
inc bx
jmp %%schalti
%%nee1:
jmp %%normal
%%hundert: ; wenn durch hundert teilbar muss überprüft werden ob durch 400 teilbar wenn ja = SChaltjahr wenn nein = kein schaltjahr
mov cl,dh ; dh nach cl (dh = GBCD Hunderter da ich nur überprüfen brauche ob die hunderter durch 4 teilbar sind)
teilbar ; ...
jnc %%nichtschalt
cmp ah,3
jb %%nee1
xor bx,bx
inc bx
jmp %%schalti
%%nichtschalt:
jmp %%normal
%%ente:
%endmacro
;; ENDE der Procedur

;; Prozedur zum Ausgeben des Ergebnisses
%macro Ausgeben 0

mov ax,bx ; in ax jetzt dass ergebniss
mov cx,000ah ; mann muss immer wieder durch 10 (=0ah) teilen
xor bx,bx
xor dx,dx ; ohne gibts probleme ...
%%weita:
div cx ; in ax steht jetzt dass ergebniss und in dx der rest also beispiel: 35/10 = ax=3 dx=5
push dx ; wird alles hochgepusht dann wieder runter gepopt und später ausgegeben
xor dx,dx ; ..
inc bl ; zähler...
test ax,ax ; ergebnis 0 ?
je %%fertig ; dann aufhöhren
jmp %%weita ; ansonsten weitermachen
%%fertig:
mov dx,unterschied ; ...
mov ah,09
int 21h ; ausgeben
mov ah,02 ; um ascii zeichen in dx auszugeben
%%inter:
pop dx ; hohle letzte berechnete ziffer ...
add dx,30h ; um in ascii umzuwandeln
int 21h ; ausgeben
dec bl ; zähler eins weniger
test bl,bl
je %%jea ; wenn zähler 0 dann fertig
jmp %%inter ; ansonsten weiter
%%jea:
%endmacro
;; ENDE der Prozedur

;; Prozedur für Fehler :)
%macro FEHLER 0 ; wenn ein fehler passiert .......
mov dx,fehl
mov ah,09
int 21h
mov ax,4c00h
int 21h
%endmacro
;; ENDE der Prozedur

;; Prozedur um festzustellen ob eine BCD Zahl durch 4 teilbar ist mit cl = gepackte BCD zahl ch wird für temporäre zwecke benutzt
%macro teilbar 0
mov ch,cl
and cl,0Fh
and ch,0F0h
shr ch,4
add ch,ch
add cl,ch
add ch,ch
add ch,ch
add cl,ch
shl cl,6
test cl,cl
je %%ja
clc
jmp %%ne
%%ja:
stc
%%ne:
%endmacro
;; ENDE der Prozedur


;; Programm zum berechnen von TT.MM.YYYY undzwar der unterschied zwischen 01.01.YYYY und TT.MM.YYYY
Lesen ; lesen von TT.MM.YYYY
Uberprufen ; stimmt die eingabe ?
Rechnen ; rechne unterschied aus
Ausgeben ; gib das ergebniss aus
mov ax,4c00h ; Ende
int 21h

fehl db 0dh,0ah,"Hilfe:",0dh,0ah,"Geben sie den namen dieses Programms gefolgt von ",0dh,0ah
db "einem LEERZEICHEN UND eines Datums z.B. :",0dh,0ah
db "unter.com 25.11.1922",0dh,0ah
db "die Syntax ist dabei immer TT.MM.JJJJ",0dh,0ah
db "TT= Tag z.B. 05 MM= Monat z.B. 08 JJJJ= Jahr z.B. 1520",0dh,0ah,'$'
unterschied db "Der Unterschied in Tagen, zum 01.01 der Jahres, ist ",'$'
TABELLE: ; tabelle für monate ...
dw 0
dw 0
dw 31
dw 59
dw 90
dw 120
dw 151
dw 181
dw 212
dw 243
dw 273
dw 304
dw 334
77fill ist offline   Mit Zitat antworten
Alt 17.08.11, 23:58   #37 (permalink)
 
Registriert seit: 13.08.07
thodt Leistung: Z3
Likes: 2
Standard

In Ruby mit Validierung des Datums:

Code:
#!/usr/bin/env ruby

day, month, year = ARGV[0].split(/\./)
day = day.to_i; month = month.to_i; year = year.to_i

(year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ? is_leap_year = true : is_leap_year = false
months = [31,28,31,30,31,30,31,31,30,31,30,31]

begin
  raise if (day > months[month-1] && !(is_leap_year == true && month == 2 && day == months[month-1] + 1))
  raise if (day <= 0 || month > 12 || month <= 0 || year < 0) 
rescue
  puts "Kein korrektes Datum"
  exit
end

days = 0
(month-1).times { |i| days += months[i] }
days += day

days += 1 if is_leap_year == true && month > 2

puts "Anzahl Tage: #{days}"

Geändert von thodt (18.08.11 um 14:01 Uhr)
thodt ist offline   Mit Zitat antworten
Alt 10.10.11, 16:11   #38 (permalink)
 
Benutzerbild von Sleepprogger
 
Registriert seit: 17.10.09
Sleepprogger Leistung: Facit NTK
Likes: 10
Thumbs up

Einige sehr schöne Lösungen hier.
Ich habe mich auch einmal dran gesetzt und das ganze in Java und in möglichst kurz gebastelt.
Ich glaube nach der perl und ruby variante habe ich damit den dritt kürzesten
Vlt. folgt noch eine Version in C

ohne validierung   
Code:
public class DaysSince {
    public static void main(String[] args) {
        if(args.length < 1){System.out.println("Usage: DD.MM.YYYY"); return;}
        int daysToMonth[] = new int[]{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};    // days to i. month
        String[] in = args[0].split("\\.");
        int date[] = new int[3];
        for (int i = 0; i < date.length; i++) date[i] = Integer.parseInt(in[i]);
        if((date[2]%4 == 0 && date[2]%100 != 0) || date[2]%400   == 0) for (int i = 2; i < date[1]; i++) daysToMonth[i]++;    //   handle leap year
        System.out.println((date[0]-1 + daysToMonth[date[1]-1]) + " days   from " + 1+"."+1+"."+date[2] + " to " +   date[0]+"."+date[1]+"."+date[2]);
    }
}


mit validierung   
Code:
public class DaysSinceV2 {
    public static void main(String[] args) {
        int daysToMonth[] = new int[]{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};    // days to [i]. month
        int daysPerMonth[] = new int[]{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if(args.length < 1){System.out.println("Usage: DD.MM.YYYY"); return;}                    // parameter check
        if(!args[0].matches("[0-9]{1,2}\\.[0-9]{1,2}\\.[0-9]{4}")){System.out.println("Invalid date."); return;}
        String[] in = args[0].split("\\.");
        int date[] = new int[3];
        for (int i = 0; i < date.length; i++) date[i] = Integer.parseInt(in[i]);                // This should never produce a NFE !?
        if(date[1] > 12){System.out.println("Invalid date."); return;}                            // check month
        if((date[2]%4 == 0 && date[2]%100 != 0) || date[2]%400 == 0){for (int i = 2; i < date[1]; i++)daysToMonth[i]++; daysPerMonth[1]++;}    // handle leap year
        if(date[0] > daysPerMonth[date[1]-1]){System.out.println("Invalid date."); return;}        // check days
        System.out.println((date[0]-1 + daysToMonth[date[1]-1]) + " days from " + 1+"."+1+"."+date[2] + " to " + date[0]+"."+date[1]+"."+date[2]);
    }
}


edit: Die Kommentare sind Englisch, die Eingabe des Datums allerdings in deutscher Schreibweise. Vlt. wird das noch geändert. ^^

Geändert von Sleepprogger (10.10.11 um 16:18 Uhr)
Sleepprogger ist offline   Mit Zitat antworten
Antwort
   
- Anzeige -

Werbung ist gerade online    

[HaBo] » Software Home » Code Kitchen » Programmieraufgaben » Tage berechnen
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
43 Tage Easyrider Off topic-Zone 2 01.11.09 19:28
Stream Last berechnen Easyrider Network · LAN, WAN, Firewalls 1 27.03.09 15:21
a^-1 modulo m Wie berechnen? elite-noob Science & Fiction 3 04.02.09 17:23
a^-1 modulo m Wie berechnen? elite-noob Off topic-Zone 3 04.02.09 17:23
Festplattenkapazität berechnen BlackMarvel Off topic-Zone 4 16.07.06 23:02


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61