Python, 221 217
def d(x):
q=x%10
if x%2==0:
p,r=q/2,"06-30"
else:
p,r=(q-1)/2,"12-31"
return"%d%d-%s 23:59:60"%(p+197,x/10,r)
for x in [20,21,31,41,51,61,71,81,91,12,22,32,52,73,93,5,24,34,44,55,74,85,57,87,28,58]:print(d(x))
Einige Einblicke
Grundsätzlich d(x)
dekomprimiert einen Vektor von ganzen Zahlen 3 von einer einzigen 2-stellige ganzen Zahl ist . d(x)
wird als die Umkehrfunktion (über die 26 Schaltsekunden-Datenzeiten) von konstruiert c(v)
, die wiederum eine Komprimierungsfunktion ist, die ein 3-uple wie (1998, 12, 31) in eine Zahl wie 85 umwandelt. Um die Liste abzuleiten [20 , 21 ... 28,58] Ich habe einen anderen Algorithmus entworfen, um zu überprüfen, ob die Komprimierungsfunktion über die Domäne bijektiv ist. Das heißt, ich habe sichergestellt, dass das folgende Programm keine Duplikate erzeugt, und ich habe seine Ausgabe als Liste des obigen Programms verwendet.
dates = [(1972,06,30),
(1972,12,31),
(1973,12,31),
(1974,12,31),
(1975,12,31),
(1976,12,31),
(1977,12,31),
(1978,12,31),
(1979,12,31),
(1981,06,30),
(1982,06,30),
(1983,06,30),
(1985,06,30),
(1987,12,31),
(1989,12,31),
(1990,12,31),
(1992,06,30),
(1993,06,30),
(1994,06,30),
(1995,12,31),
(1997,06,30),
(1998,12,31),
(2005,12,31),
(2008,12,31),
(2012,06,30),
(2015,06,30)]
def c(v):
x = (v[0] % 10) * 10
x += v[2] % 30
x += 2 * (int(v[0] / 10) - 197)
return x
for v in dates:
print(c(v))
Die Komprimierungsfunktion c(v)
wurde unter Verwendung eines sehr einfachen Schemas als bijektiv konzipiert. Nehmen wir als Beispiel (1998, 12, 31).
- Der Ausdruck (v [0]% 10) * 10 wählt die Einheiten des Jahres aus (z. B. 1 9 9 8 -> 8) und macht es zur zehnten Stelle der Ausgabe (jetzt x = 80).
- Es gibt nur eine Kombination von zwei Monaten und einem Tag, in der die Schaltsekunde auftritt. Daher habe ich beschlossen, die Tageskomponente zu verwenden, um zwischen dem Fall 06,30 und dem Fall 12,31 zu unterscheiden. Der Ausdruck v [2]% 30 ist 0, wenn der Tag 30 ist, und ist 1, wenn der Tag 31 ist. In unserem Beispiel addieren wir 1 zu x (daher ist jetzt x = 81).
- Schließlich stellte ich fest, dass dieses Rätsel nur fünf Jahrzehnte umfasst; Wenn ich also das erste Jahrzehnt (die siebziger Jahre) auf 0 und das letzte Jahrzehnt (die 2010er) auf 4 abbilde, kann ich coole Sachen machen. Genauer gesagt, wenn ich anstatt auf 0,1,2,3,4 I auf 0,2,4,6,8 abzubilden, kann ich diesen Wert zu den Einheiten von x addieren, die aufgrund der vorherigen Regel entweder 0 oder 0 sind 1. Am Ende haben wir also, dass auch dieser letzte Schritt nicht die Bijektion verdreht, und wir bekommen, dass die Einheiten eines 06,30-Falls eine von 0,2,4,6,8 sind und dass die Einheiten von a 12,31 Fall sind einer von 1,3,5,7,9. Daher ist die Bijektion offensichtlich. In unserem Beispiel liegt 1998 im dritten Jahrzehnt (70 -> 0, 80 -> 1, 90 -> 2), also addieren wir 2 * 2 = 4. Also bekommen wir x = 85.
Ich habe das Programm geschrieben, um zu überprüfen, ob dies wahr ist, und dann habe ich es d(x)
als das Gegenteil von definiert c(v)
. In unserem Beispiel wird c ((1998,12,31)) mit 85 und d (85) korrekt gedruckt 1998-12-31 23:59:60
.