Forum: PC-Programmierung 22.02.2022 Symmetrie


von Nano (Gast)


Lesenswert?

Dieses Datum haben wir bald.
Daraus kann man ein schönes Zahlenspiel machen.

Aufgabe:

Finde einen Algorithmus, der alle symmetrischen Datumsangaben vom Jahr 
1000 bis 9999 bestehend aus Tag und Monat, sowie Jahr findet und 
berechnet.

Weitere zu erfüllende Bedingungen:
1. Die Zahlen im voll angegeben Datum der Form DD.MM.JJJJ muss sich 
spiegeln. Der Punkt zwischen Monat und Tag wird zwar ausgegeben, aber 
hierbei ignoriert. Die Spiegelachse liegt somit auf dem zweiten Punkt, 
also zwischen Monat und Jahr.
2. Einstellige Tag und Monatsangaben haben eine führende 0.
3. Im Datum dürfen nur **maximal zwei unterschiedliche Ziffern** 
vorkommen.
4. Der Algorithmus muss eine Berechnung sein und darf nicht nur aus 
einer Ausgabe der unten angegebenen und gegebenenfalls manuell 
vervollständigten Tabelle bestehen.
5. Die Ausgabe muss steigend erfolgen, das älteste Jahr zuerst, das 
letzte zukünftige  zuletzt.
6. Das Datum muss es geben. Ungültige Datumsangaben zählen nicht.

Beispiel (keine Gewähr auf Vollständigkeit):
1
10.01.1001
2
01.01.1010
3
11.01.1011 **
4
10.11.1101
5
11.11.1111 **, ***
6
21.11.1112
7
12.11.1121
8
22.11.1122 **
9
13.11.1131
10
14.11.1141
11
15.11.1151
12
16.11.1161
13
17.11.1171
14
18.11.1181
15
19.11.1191
16
20.02.2002
17
02.02.2020
18
22.02.2022 ** (Baldiges Datum, dann 89 Jahre auf das nächste warten)
19
11.12.2111 **
20
12.12.2121
21
21.12.2112
22
22.12.2122 ** 
23
30.03.3003
24
03.03.3030
25
04.04.4040
26
05.05.5050
27
06.06.6060
28
07.07.7070
29
08.08.8080
30
09.09.9090

Optional:
Die mit ** gekennzeichneten Datumsangaben sind eine Besonderheit,
da die Ziffern des Tages und die letzten zwei Ziffern der Jahreszahl 
identisch sind.
Wer möchte, der kann das in der Programmausgabe gesondert kennzeichnen.

Die mit *** gekennzeichnete Datumsangabe ist einzigartig. Denn sie 
besteht nur aus einer Ziffer und mit Symmetrie kommt sie nicht mehr 
wieder.

Ebenso kann man noch neben jedem Datum ausgeben, wie viele Jahre es bis 
zum
Datum mit der nächsten Symmetrie dauert.


Prinzipiell könnte man daraus einen Wettbewerb machen und
als Siegesbedingungen festlegen, dass derjenige gewinnt, der den 
schnellsten Algorithmus hat und alle Bedingungen von 1 bis 6 erfüllt.

Allerdings weiß ich noch nicht, wie man das dann am besten auswertet?
Wenn man alle Sprachen zulässt, dann wird das extrem viel Aufwand.
Insofern müsste man das vielleicht auf 1 bis 2 Sprachen begrenzen.
Ich dachte an C und C++.
Der Sprachumfang sollte dann aber auch auf eine bestimmte 
Compilerversion begrenzt sein, die dieser unterstützt, z.B. den GCC 
Version <= 10.2.1.
Und obige Aufgabe dürfte auf einem modernen Rechner extrem schnell 
berechnet sein, da braucht man also auch noch eine Lösung. Vielleicht 
mehrere n-Millionen Durchläufe?
Und dann ist da noch die Frage, wie der Code ausgetauscht wird. Eine 
E-Mail werde ich nicht angeben und wenn man das einfach ins Forum 
postet, sieht ja gleich jeder den Code der anderen und könnte seinen 
optimieren, da habe ich also auch noch keine Lösung für.
Wer Vorschläge hat und ob man so etwas überhaupt machen soll und wie man 
das umsetzen könnte, kann das gerne posten. Vielleicht besteht auch gar 
kein Interesse.
Als Abgabedatum könnte man den 22.02.2022 nehmen, das wäre in ca. 3 
Wochen.

Damit diejenigen, die die Optionalen Sachen auch noch erfüllen wollen 
nicht benachteiligt werden, dürften sie natürlich die Optionalen Sachen 
bei dem Speedtest ausklammern. Das könnte man bspw. per 
Präprozessordirektive machen.

von Peter D. (peda)


Lesenswert?

Nano schrieb:
> Vielleicht besteht auch gar
> kein Interesse.

Stimmt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Nicht auf Geschwindigkeit optimiert (Laufzeit: 4,4 s), dafür leicht auf
Korrektheit prüfbar:
1
import Data.List
2
import Data.Time.Calendar
3
import Data.Time.Format
4
import Control.Monad
5
6
-- Konvertierungsfunktionen
7
mjd = ((toModifiedJulianDay .) .) . fromGregorian
8
fmt = (. ModifiedJulianDay) . formatTime defaultTimeLocale
9
10
main = mapM_ putStrLn $ do
11
  d <- [
12
         mjd 0000 01 01                    -- 01.01.0000
13
         ..                                -- bis
14
         mjd 9999 12 31                    -- 31.12.9999
15
       ]
16
17
  let s  = fmt "%d%m%0Y" d                 -- Konvertierung in TTMMJJJJ
18
  guard  $ s == reverse s                  -- Symmetrie
19
  guard  $ (length $ group $ sort s) <= 2  -- maximal 2 verschiedene Ziffern
20
  return $ fmt "%d.%m.%0Y" d               -- Konvertierung in TT.MM.JJJJ

Ausgabe:
1
10.10.0101
2
01.10.0110
3
11.10.0111
4
10.01.1001
5
01.01.1010
6
11.01.1011
7
10.11.1101
8
01.11.1110
9
11.11.1111
10
21.11.1112
11
12.11.1121
12
22.11.1122
13
13.11.1131
14
14.11.1141
15
15.11.1151
16
16.11.1161
17
17.11.1171
18
18.11.1181
19
19.11.1191
20
20.02.2002
21
02.02.2020
22
22.02.2022
23
11.12.2111
24
21.12.2112
25
12.12.2121
26
22.12.2122
27
30.03.3003
28
03.03.3030
29
04.04.4040
30
05.05.5050
31
06.06.6060
32
07.07.7070
33
08.08.8080
34
09.09.9090

Ich habe noch die Jahreszahlen <1000 mit hinzu genommen. Man kann sie
aber auch weglassen, in dem man in Zeile 12 das Startdatum ändert.

In deiner Liste fehlt übrigens der 01.11.1110, und Bedingung (5) ist
nicht erfüllt.

von Rolf M. (rmagnus)


Lesenswert?

Nano schrieb:
> 6. Das Datum muss es geben. Ungültige Datumsangaben zählen nicht.

Woher weiß ich denn, ob in z.B. 5000 Jahren unsere jetzige Zeitrechnung 
überhaupt noch so existiert? Aus Star Trek wissen wir ja, dass 
irgendwann auf Sternzeit umgestellt wird.

von Le X. (lex_91)


Lesenswert?

Rolf M. schrieb:
> Woher weiß ich denn, ob in z.B. 5000 Jahren unsere jetzige Zeitrechnung
> überhaupt noch so existiert? Aus Star Trek wissen wir ja, dass
> irgendwann auf Sternzeit umgestellt wird.

Das dürfte keine Rolle spielen. Ich würde einfach die aktuellen Regeln 
heranziehen. Das sollte für die Aufgabenstellung reichen.
Außer ich wäre Querulant und müsste dringend jemanden Kontra geben 
damits mir gut geht, dann würde ich hier irgendwas von Star Trek faseln.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Dazu der passende Song
https://de.wikipedia.org/wiki/In_the_Year_2525
(if man is still alive)

von 50c (Gast)


Lesenswert?

Yalu X. schrieb:
> Nicht auf Geschwindigkeit optimiert (Laufzeit: 4,4 s), dafür leicht auf
> Korrektheit prüfbar:

...jetzt wäre, um die Spielerei auf die "Spitze" zu trieben, interessant 
die Zeitabstände zwischen den magischen Tagen in einem Diagramm 
abzubilden. Vielleicht erkennt man etwas systematisches... ;-)

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

F. Merz hat mal erwähnt, dass er am 11.11.55 geboren sei, auf die Frage 
wie er zu Karneval steht.

Zum Year 2525 gibt es einige Videoclips
https://www.youtube.com/results?search_query=in+the+year+2525
aus welchem Film stammt die Blondine mit Dinosauriern?
https://www.youtube.com/watch?v=JNbUUSuiEho

von Noch ein Kommentar (Gast)


Lesenswert?

> dafür leicht auf Korrektheit prüfbar:

Zumindest hat Haskell kein npm. Da kann man zumindest mal davon 
ausgehen, die importierten Module machen auch Morgen noch das selbe wie 
Heute.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Aus dem Rückenmark:
1
#include <stdio.h>
2
3
int ist_max2digits(char a, char b, char c, char d) {
4
5
    if ( a == b ) {
6
        if ( a == c ) return 1;
7
        if ( a == d ) return 1;
8
        if ( c == d ) return 1;
9
    }
10
    else if ( a == c ) {
11
        if ( a == d ) return 1;
12
        if ( b == d ) return 1;
13
    }
14
    else if ( b == c ) {
15
        if ( a == d ) return 1;
16
        if ( b == d ) return 1;
17
    }
18
19
    return 0;
20
}
21
22
int ist_datum(char a, char b, char c, char d) {
23
24
    int tag = 10 * (a - '0') + (b - '0');
25
    int monat = 10 * (c - '0') + (d - '0');
26
27
    if ( tag == 0 ) return 0;
28
29
    switch ( monat ) {
30
        case 2  : if ( tag > 27 ) return 0; break; // Hinreichend da der 28.02. immer gegen die 2 unterschiedliche Ziffern-Regel verstößt.
31
        case 1  :
32
        case 3  :
33
        case 5  :
34
        case 7  :
35
        case 8  :
36
        case 10 :
37
        case 12 : if ( tag > 31 ) return 0; break;
38
        case 4  :
39
        case 6  :
40
        case 9  :
41
        case 11 : if ( tag > 30 ) return 0; break;
42
        default : return 0;
43
    }
44
45
    return 1;
46
}
47
48
int ist_symdatum(char a, char b, char c, char d) {
49
50
    if ( ist_max2digits(a, b, c, d) == 0 ) return 0;
51
    if ( ist_datum(a, b, c, d) == 0 ) return 0;
52
53
    return 1;
54
}
55
56
int main(void) {
57
58
    for (char d = '0'; d <= '9'; d++)
59
        for (char c = '0'; c <= '1'; c++)
60
            for (char b = '0'; b <= '9'; b++)
61
                for (char a = '0'; a <= '3'; a++)
62
                    if ( ist_symdatum(a, b, c, d) )
63
                        printf("%c%c.%c%c.%c%c%c%c\n", a, b , c, d, d, c, b, a);
64
65
    return 0;
66
}

: Bearbeitet durch User
von Gästle (Gast)


Lesenswert?

Yalu X. schrieb:
> Nicht auf Geschwindigkeit optimiert (Laufzeit: 4,4 s), dafür
> leicht auf
> Korrektheit prüfbar:

> 10.10.0101
> ...
> 09.09.9090

Und trotzdem fehlt das letzte Datum in der Liste, welches wenn ich mich 
nicht irre der 29.09.9092 wäre.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Gästle schrieb:
> Yalu X. schrieb:
>> Nicht auf Geschwindigkeit optimiert (Laufzeit: 4,4 s), dafür
>> leicht auf
>> Korrektheit prüfbar:
>
>> 10.10.0101
>> ...
>> 09.09.9090
>
> Und trotzdem fehlt das letzte Datum in der Liste, welches wenn ich mich
> nicht irre der 29.09.9092 wäre.

Die Ziffern 2, 9, 0 sind schon 3 Ziffern...

von Andreas M. (andreas_m62)


Lesenswert?

Rolf M. schrieb:
> Aus Star Trek wissen wir ja, dass
> irgendwann auf Sternzeit umgestellt wird.

Mir "reicht" es schon, wenn jedes Jahr auf Sommerzeit umgestellt wird.

von Gästle (Gast)


Lesenswert?

Tim T. schrieb:
> Die Ziffern 2, 9, 0 sind schon 3 Ziffern...

Nano schrieb:
> 3. Im Datum dürfen nur **maximal zwei unterschiedliche Ziffern**
> vorkommen.

Stimmt, da hab ich doch tatsächlich Bedingung 3 überlesen. Asche auf 
mein Haupt.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Nochmal mit etwas mehr Überlegung:
1
#include <stdio.h>
2
3
int ist_symdatum(char a, char b, char c, char d) {
4
5
    int tag = 10 * (a - '0') + (b - '0');
6
    int monat = 10 * (c - '0') + (d - '0');
7
8
    switch ( monat ) {
9
        case 11 : if ( ( a == '1' ) || ( tag == 01 ) || ( tag == 21 ) || ( tag == 22 ) ) return 1; break;
10
        case 12 : if ( ( tag == monat ) || ( tag == 11 ) || ( tag == 21 ) || ( tag == 22 ) ) return 1; break;
11
        case 10 : if ( ( tag == monat ) || ( tag == 01 ) || ( tag == 11 ) ) return 1; break;
12
        case 1  : if ( ( tag == monat ) || ( tag == 10 ) || ( tag == 11 ) ) return 1; break;
13
        case 2  : if ( ( tag == monat ) || ( tag == 20 ) || ( tag == 22 ) ) return 1; break;
14
        case 3  : if ( ( tag == monat ) || ( tag == 30 ) ) return 1; break;
15
        case 4  :
16
        case 5  :
17
        case 6  :
18
        case 7  :
19
        case 8  :
20
        case 9  : if ( tag == monat ) return 1; break;
21
        default : break;
22
    }
23
24
    return 0;
25
}
26
27
int main(void) {
28
29
    for (char d = '0'; d <= '9'; d++)
30
        for (char c = '0'; c <= '1'; c++)
31
            for (char b = '0'; b <= '9'; b++)
32
                for (char a = '0'; a <= '3'; a++)
33
                    if ( ist_symdatum(a, b, c, d) )
34
                        printf("%c%c.%c%c.%c%c%c%c\n", a, b , c, d, d, c, b, a);
35
36
    return 0;
37
}

von 50c (Gast)


Angehängte Dateien:

Lesenswert?

50c schrieb:
> ...jetzt wäre, um die Spielerei auf die "Spitze" zu trieben, interessant
> die Zeitabstände zwischen den magischen Tagen in einem Diagramm
> abzubilden. Vielleicht erkennt man etwas systematisches... ;-)

...schade, nichts spannendes...

von Nano (Gast)


Lesenswert?

Yalu X. schrieb:
> Ich habe noch die Jahreszahlen <1000 mit hinzu genommen. Man kann sie
> aber auch weglassen, in dem man in Zeile 12 das Startdatum ändert.
>
> In deiner Liste fehlt übrigens der 01.11.1110, und Bedingung (5) ist
> nicht erfüllt.

Oh ja, stimmt. Mein Fehler. Die Liste ist manuell erstellt.

von Noch ein Kommentar (Gast)


Lesenswert?

> Vielleicht erkennt man etwas systematisches...
> ...schade, nichts spannendes...

Dann müssen wir die Abstände hartnäckiger untersuchen. Newcomb und 
Benford haben das nach ihnen benannte Gesetz auch nicht nach 5 Minuten 
gesehen.

von DanVet (Gast)


Lesenswert?

Christoph db1uq K. schrieb:
> aus welchem Film stammt die Blondine mit Dinosauriern?
> https://www.youtube.com/watch?v=JNbUUSuiEho

Das ist Scarlett Johansson, könnte "Lucy" sein.

von Christoph db1uq K. (christoph_kessler)


Lesenswert?

Danke. Andere Filmausschnitte stammen aus Fritz Langs "Metropolis", Wie 
auch im Videoclip zu "Radio Gaga".

Die Bundeswehr wurde am 5.5.55 beschlossen.

von Anita H. (anita1995)


Lesenswert?

Am 11.11.1111 hatten wir demnach Supersymmetrie...

von Mombert H. (mh_mh)


Lesenswert?

Rolf M. schrieb:
> Nano schrieb:
>> 6. Das Datum muss es geben. Ungültige Datumsangaben zählen nicht.
>
> Woher weiß ich denn, ob in z.B. 5000 Jahren unsere jetzige Zeitrechnung
> überhaupt noch so existiert? Aus Star Trek wissen wir ja, dass
> irgendwann auf Sternzeit umgestellt wird.

Ich hoffe, dass es deutlich weniger als 5000 Jahre dauert, bis wir auf 
eine sinnvolle "Zeitrechnung" wechseln. Ein einfacher Start wäre eine 
sinnvolle internationale Schreibweise (YYYY-MM-DD) ...

: Bearbeitet durch User
von Für jedes Problem der richtige Hammer (Gast)


Lesenswert?

Verdammt! Jetzt wollte ich über Leute Lästern, die umständliche, 
langatmige Sprachen benutzen und bekomme eine Fehlermeldung: "the 
datetime strftime() methods require year >= 1900"

Na ja - findet jemand einen besseren Weg für die Date Formatierung in 
Python?
1
from datetime import date, timedelta
2
3
print [datestr for datestr in [str(d.day).zfill(2)+"."+str(d.month).zfill(2)+"."+str(d.year).zfill(4) for d in [(date(1000, 1, 1) + n*timedelta(days=1)) for n in range((date(9999, 12, 31) - date(1000, 1, 1)).days)]]
4
       if len(set(datestr)) == 3
5
       and datestr[4]+datestr[3]+datestr[1]+datestr[0] == datestr[6:]]

von Yalu X. (yalu) (Moderator)


Lesenswert?

Für jedes Problem der richtige Hammer schrieb:
> if len(set(datestr)) == 3

Da sollte <= 3 stehen, damit auch der 11.11.1111 berücksichtigt wird.

von 50c (Gast)


Lesenswert?

Für jedes Problem der richtige Hammer schrieb:
> bekomme eine Fehlermeldung: "the
> datetime strftime() methods require year >= 1900"

Python 3.8.10 (default, Nov 26 2021, 20:14:08)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> print(datetime.strptime('10-01-0101', "%d-%m-%Y"))
0101-01-10 00:00:00
>>>
>>> from datetime import date
>>> print(datetime.date(101, 1, 10))
0101-01-10

von Christoph db1uq K. (christoph_kessler)


Angehängte Dateien:

Lesenswert?

Pollin feiert "Happy Twosday"
recht haben sie, der 22.2.22 war auch noch ein Tuesday.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.