Storniertes Datum legalisieren

18

Eingang:

Ein Date (enthält dd, MMund yyyy). Ein Datumsobjekt oder drei separate Ganzzahlen sind ebenfalls als Eingabe gültig.

Ausgabe:

Jedes Teil ( dd, MMund yyyy) wird einzeln zurückgesetzt und auf das nächste gültige Datum gerundet.

Zum Beispiel (im Format dd-MM-yyyy):
21-10-2016wird12-01-6102

Herausforderungsregeln:

  • Nur dd, MM, yyyygültig ist , aber die Reihenfolge und die getrennten-Symbole , die Sie verwenden , ist Ihre eigene Wahl.
    Das sind also einige gültige Format Beispiele: dd-MM-yyyy; MM/dd/yyyy; yyyy MM dd; ddMMyyyyEtc.
    Und das sind einige ungültige Format Beispiele: dd MMM yyyy; dd-MM-'yy; etc.
  • Sie können auch nur ein Datumsobjekt eingeben, wenn Ihre Sprache dies unterstützt, oder drei separate Ganzzahlparameter anstelle der Zeichenfolge, die ein Datum darstellt.
  • Bitte geben Sie an, welches Datumsformat Sie verwendet haben! (Und die Eingabe und Ausgabe müssen im selben Format sein.) Es ist auch erlaubt, ein Date-Objekt auszugeben, solange es alle Testfälle und die unten stehende Herausforderungsregel verarbeiten kann.
  • Der Übergang vom Julianischen zum Gregorianischen Kalender wird für diese Herausforderung ignoriert. Ist 1582also nur ein gültiges umgekehrtes Jahr für 2851.
    Siehe Challenge-Info / Tipps für alle gültigen Jahre, Monate und Tage.
  • Da der Februar von keinem anderen Monat umgekehrt werden kann, müssen Sie sich keine Gedanken über Schaltjahre machen.

Alle umgekehrten Jahre, Monate und Tage:

  • Das Jahr kann jederzeit problemlos umgekehrt werden und reicht von 0001 (umgekehrt von 1000) bis 9999 (verbleibend 9999). (Also 0000keine gültige Eingabe, und es gibt auch keine Testfälle dafür.)
  • Die einzigen Monate, die Sie umgekehrt haben, sind: Januar (umgekehrt von Oktober / 10); Oktober (umgekehrt ab Januar / 01); November (bleibt November / 11); und Dezember (umgekehrt zu jedem zweiten Monat / 02- 09, 12).
  • Die einzigen Tage, die Sie rückgängig gemacht haben, sind: 01 (rückgängig gemacht von 10), 02 (rückgängig gemacht von 20), 03 (rückgängig gemacht von 30), 10 (rückgängig gemacht von 01), 11 (übrig geblieben 11), 12 (rückgängig gemacht von 21), 13 (rückgängig gemacht von 31) , 20 (rückgängig gemacht von 02), 21 (rückgängig gemacht von 12), 22 (übrig geblieben 22), 30 (rückgängig gemacht von 03oder dasselbe wie 31 für November!), 31 (rückgängig gemacht von 04- 09/ 13-19/ 23- 29).

Allgemeine Regeln:

  • Das ist , also gewinnt die kürzeste Antwort in Bytes.
    Lassen Sie sich von Code-Golf-Sprachen nicht davon abhalten, Antworten mit Nicht-Codegolf-Sprachen zu veröffentlichen. Versuchen Sie, für jede Programmiersprache eine möglichst kurze Antwort zu finden.
  • Standardregeln gelten für Ihre Antwort, daher dürfen Sie STDIN / STDOUT, Funktionen / Methode mit den richtigen Parametern und Rückgabeanweisungen / Ausgabe, vollständige Programme verwenden. Ihr Anruf.
  • Standardlücken sind verboten.
  • Fügen Sie nach Möglichkeit einen Link mit einem Test für Ihren Code hinzu.
  • Fügen Sie ggf. auch eine Erklärung hinzu.

Testfälle ( dd-MM-yyyyals Format):

21-07-2016   ->   12-12-6102
12-11-1991   ->   21-11-1991
01-01-2000   ->   10-10-0002
27-08-1875   ->   31-12-5781
18-12-2010   ->   31-12-0102
13-01-1981   ->   31-10-1891
04-11-1671   ->   30-11-1761  // Semi-tricky case, since November has 30 days
28-11-2036   ->   30-11-6302  // Semi-tricky case, since November has 30 days
14-06-1855   ->   31-12-5581
30-10-9999   ->   03-01-9999
01-01-2851   ->   10-10-1582
Kevin Cruijssen
quelle
@ LegionMammal978 Nein, es 21-07-2016wird zurückgesetzt, 12-70-6102was auf gerundet ist 12-12-6102. Nicht sicher, wie Sie das Ergebnis erhalten ##-10-6107..
Kevin Cruijssen
@ KevinCruijssen Okay, ich dachte, es wäre der Monat 70, in dem das Jahr zunimmt.
LegionMammal978
Ist 10-10-2im dritten Fall eine gültige Ausgabe?
Luis Mendo
@ LuisMendo Ja sicher. Ich habe auch andere Leute gesehen, die das gemacht haben. Die Herausforderung besteht mehr darin, die Daten korrekt umzukehren und zu runden als das Eingabe- oder Ausgabeformat.
Kevin Cruijssen
Wäre es akzeptabel, drei Zeichenfolgen zu verwenden und führende Nullen zu erwarten?
JustinM

Antworten:

3

Konvex , 23 Bytes

Die Byteanzahl setzt die CP-1252-Codierung voraus.

qS/Wf%_1=:=31^sCs¶.e<S*

E / A-Format ist dd mm yyyy.

Probieren Sie es online!

Dies ist ein direkter Port meiner CJam-Antwort . Convex basiert stark auf CJam. Der einzige Unterschied besteht in der Verwendung des Convex- Operators, der die beiden obersten Stapelelemente in eine Liste einschließt und so ein Byte überschreibt [...].

Martin Ender
quelle
8

CJam, 24 Bytes

qS/Wf%[_1=:=31^sCs].e<S*

E / A-Format ist dd mm yyyy.

Probieren Sie es online!

Gleiche Byteanzahl, E / A-Format mm dd yyyy:

qS/Wf%_0=:=1231^s2/.e<S*

Probieren Sie es online!

Erläuterung

qS/     e# Read input, split around spaces.
Wf%     e# Reverse each component.
[       e# Set marker for new list.
  _1=   e#   Duplicate reversed strings, extract reversed month.
  :=    e#   Check for equality of the characters. This gives 1 for
        e#   November (11) and 0 for everything else.
  31^   e#   XOR the result with 31, giving 30 for November and 31
        e#   for everything else.
  s     e#   Convert the result to a string, "30"/"31".
  Cs    e#   Push 12, convert to string, "12".
]       e# Wrap "30"/"31" and "12" in a list.
.e<     e# Element-wise minimum. This clamps the day and month to their
        e# respective maxima.
S*      e# Join the result with spaces.

Die andere Version funktioniert ähnlich, mit der Ausnahme, dass wir von der Ganzzahl 1230oder 1231vor der Konvertierung in ["12" "30"] oder beginnen ["12" "31"].

Martin Ender
quelle
2
Sprachen mit Datum eingebaut ...
Undichte Nonne
1
@LeakyNun Dies verwendet kein eingebautes Datum und ich verstehe nicht, wie es helfen würde.
Martin Ender
Woher wissen Sie dann, dass es im November 30 Tage gibt?
Undichte Nonne
2
@LeakyNun Ich werde später eine Erklärung hinzufügen, aber 1=den umgekehrten Monat abrufen , :=prüfen , ob die Ziffern gleich sind, und ^das Ergebnis in 31 zerlegen, wobei 30 für Monat 11und 31 für alles andere angegeben werden.
Martin Ender
Oh, ich habe die Spezifikationen nicht gelesen ...
Undichte Nonne
5

Pyth, 55 53 46 43 41 Bytes

APJ_Mczd = HhS, 12sH = GhS, sGC @. "❤❤ó» î "H%"% 02d% 02d% s "[GHeJ 
APJ_Mczd = hS, 12sH = hS, sGC @." ❤❤ó »î" H% "% 02d% 02d% s" [GHeJ 
APJ_Mcz \ -% "% 02d% 02d% s" [hS, sGx31q11sHhS, 12sHeJ 
APJ_Mczdjd [> 2+ \ 0hS, sGx31q11sH> 2+ \ 0hS, 12sHeJ
APJ_Mczdjd. [L \ 02 [`hS, sGx31q11sH`hS, 12sHeJ

wo ❤❤waren zwei unprintables, jeweils U + 001C und U + 001F.

Testsuite.

Undichte Nonne
quelle
3

Python 3, 82 Bytes

lambda x:[min(x[0][::-1],['31','30'][x[1]=='11']),min(x[1][::-1],'12'),x[2][::-1]]

Eine anonyme Funktion, die das Datum über ein Argument als Liste von Zeichenfolgen des Formulars ['dd', 'mm', 'yyyy']eingibt und das validierte umgekehrte Datum im gleichen Format zurückgibt.

Wie es funktioniert

Python vergleicht Zeichen und Zeichenketten anhand ihrer Unicode-Codepunkte. Dies bedeutet, dass jeder Vergleich mit zwei oder mehr Ganzzahlen den gleichen Wert wie der Vergleich mit diesen Ganzzahlen als Zeichenfolgen zurückgibt. Wenn Sie also minzwei Ganzzahlen als Zeichenfolgen aufrufen, wird die kleinste Ganzzahl als Zeichenfolge zurückgegeben. Indem der umgekehrte Datumsteil als ein Argument und der Maximalwert als ein anderer verwendet werden, werden Tag und Monat auf den gewünschten Bereich begrenzt. Die Datumsteile werden durch Indizieren mit den Schritten von -1( [::-1]) umgekehrt , und der Maximalwert für den Monat wird durch Indizieren in eine Liste mit dem Booleschen Ergebnis einer Bedingung von in geändert '31', '30'wenn der Monat November ist.

Probieren Sie es auf Ideone

TheBikingViking
quelle
2

Dyalog APL , 32 33 Bytes

⍕¨{⍵-3↑31 11≡2↑⍵}31 12 1E4⌊⍎∊⍕⌽¨⎕

I / O ist eine Liste mit drei Zeichenfolgen ( 'dd' 'mm' 'yyyy').

TryAPL , aber beachten Sie, dass (Eingabeaufforderung) durch ersetzt wurde und die gesamte in {... eingeschlossene Zeile }, um Online-Tests zu ermöglichen, und (Ausdruck ausführen) durch 2⊃⎕VFI(Eingabe überprüfen und korrigieren) ersetzt wurde, da die Ausführung von beliebigem Code blockiert ist .

Adam
quelle
2

C # 314 305 299 249 232 223 Bytes

using System.Linq;string f(int d,int m,int y){Func<int,string>r=i=>string.Concat((""+i).PadLeft(2,'0').Reverse());Func<string,int,string>x=(j,k)=>int.Parse(j)>k?""+k:j;return x(r(d),m==11?30:31)+"-"+x(r(m),12)+"-"+r(y);}

Vielen Dank an @KevinCruijssen für den Hinweis, dass ich meine Variablendeklaration verkürzen konnte, wodurch auch Aliasing-Strings einige Bytes einsparen konnten.

Es wurden 50 Byte für die Speicherung der Umkehrfunktion zur Wiederverwendung und weitere 13 Byte für das Runden und Entfernen der Variablendeklarationen eingespart.

Beim letzten Update wird die Aliasing-Zeichenfolge nicht länger als Byte-Speicher verwendet.

Ungolfed Version:

using System.Linq;
    string dateReverse(int day, int month, int year)
{
    //setup a resuable function to reverse
    Func<int, string> reverse = intToReverse => string.Concat((""+intToReverse).PadLeft(2, '0').Reverse());

    //another function for rounding
    Func<string, int, string> round = (strToRound, maxVal) => int.Parse(strToRound) > maxVal ? "" + maxVal : strToRound;

    //Join the strings into the "dd-mm-yyyy" date format
    return 
        //Round down the day value, if november cap to 30 otherwise cap to 31
        round(reverse(day), month == 11 ? 30 : 31) + "-" +

        //Round the month down
        round(reverse(month), 12) + "-" +

        //we can use the reverse function here too and pad left just won't do anything
        reverse(year);
}

Teste es hier

JustinM - Setzen Sie Monica wieder ein
quelle
Sie können das Leerzeichen zwischen using System.Linq;und der Funktion ignorieren, das ist also -1 Byte. Außerdem var n=...;var e=...;kann stattdessen mit diesem Befehl 1 Byte Golf gespielt werden: string n=...,e=...;Es ist nicht viel, aber immer noch -2 Byte. ;)
Kevin Cruijssen
Guter Fang in diesem Bereich, obwohl es so aussieht, als ob meine Byteanzahl es tatsächlich nicht gezählt hätte. Ich denke auch, dass ich mit diesem Variablendeklarationsstil ein paar weitere Bytes durch Aliasing gewinnen kann.
JustinM
2

Javascript, 106 105 94 Bytes

d=>d.split`,`.map((a,b,r)=>(e=[...a].reverse().join``,f=!b?r[1]==11^31:b<2&&12,f&&f<e?f:e))+''

Testsuite (Rev. 3)


Erläuterung

d=>d.split`,`                 // split into sections by `,`

.map((a,b,r)=>(               // map each section

e=[...a].reverse().join``,    // spread a date section into array and reverse and 
                              // join with `` to get string result

f=!b?r[1]==11^31              // if section being mapped is day (section 0), 
                              // then max (f) is 30 for November(month 11) or else 31

:b<2&&12,                     // if part being mapped is month (section 1), then max (f) is 12

f&&f<e?f:e))                  // if there is a max (f)
                              // and the max (f) is less than the reversed string (e),
                              // then return the max (f), 
                              // else return the reversed string (e)

+''                           // join all the sections back together with `,` 
                              // (concatenating [] with a string will do this)

Vielen Dank an @KevinCruijssen für das Speichern von 1 Byte für b==1to b<2. Vielen Dank an @Neil, dass Sie 11 Bytes gespart haben, indem Sie ein ES6-Vorlagenliteral und ein ,Trennzeichen vorgeschlagen haben.

CShark
quelle
Ich bin ziemlich schlecht in JS. Korrigieren Sie mich, wenn ich etwas Falsches sage, aber nicht zum Speichern eines Bytes b==1herabgolfen werden kann b<2. Es kann nicht mehr 0 sein, da Sie dies bereits !b?im Code überprüft haben . Es scheint in Ihrer Testsuite zu funktionieren, wenn ich es ändere.
Kevin Cruijssen
@ KevinCruijssen yep, du hast recht, danke! Ich habe es einfach übersehen. Ich habe nicht in Javascript für sehr aussehen Golf gemacht, so dass ich
solche
* Ich meinte "für sehr lange", nicht "für sehr aussehen"
CShark
2
Wenn Sie auf ES6 abzielen, können Sie Vorlagenzeichenfolgen verwenden, um den Code zu verkürzen - join``anstatt join('')beispielsweise -, aber Sie können etwas mehr sparen, indem Sie ,als Trennzeichen verwenden, mit dem Sie +''die drei Werte miteinander verbinden können.
Neil
@Neil meinst du ,als Trennzeichen in der Eingabe?
CShark
1

Ruby, 92 84 + 1 ( -pFlag) = 93 85 Bytes

Verwendet -als Trennzeichen.

d,m,y=chomp.split(?-).map &:reverse
$_=[[d,m=="11"?"30":"31"].min,[m,"12"].min,y]*?-
Wert Tinte
quelle
0

Python 2, 154 Bytes

z=input().split("-");r=[x[::-1]for x in z];z[1]=r[1]if r[1]<'12'else '12';z[0]=r[0]if r[0]<'31'else '30'if z[1]=='11'else '31';z[2]=r[2];print "-".join(z)

Übernimmt die Eingabe als Zeichenfolge, daher müssen Anführungszeichen in der Eingabe angegeben werden, z. B. "11-04-2016".

Jeremy
quelle
Nur eine grundlegende Verbesserung , da ich kein Python Golfer bin: z=[x[::-1]for x in z];z[1]=min(z[1],'12');z[0]=min(z[0],['31','30'][z[1]=='11']);print"-".join(z). Grundsätzlich müssen Sie überhaupt nicht verwenden rund minerledigen eine Menge der Dinge, die Sie tun möchten.
Value Ink
0

05AB1E , 24 Byte

#íÐÅsË31^12‚øεßт+¦}sθªðý

Port von @MartinEnders CJam-Antwort , also auch Ein- und Ausgaben als String im Format dd MM yyyy.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

#                         # Split the (implicit) input by spaces
                          #  i.e. "04 11 1671" → ["04","11","1671"]
                          #  i.e. "20 01 2000" → ["20","01","2000"]
 í                        # Reverse each string
                          #  i.e. ["04","11","1671"] → ["40","11","1761"]
                          #  i.e. ["20","01","2000"] → ["02","10","0002"]
  Ð                       # Triplicate this list
   Ås                     # Pop one of them, and push it's middle element (the months)
                          #  i.e. ["40","11","1761"] → "11"
                          #  i.e. ["02","10","0002"] → "10"
     Ë                    # Check if the digits are the same (1 for 11; 0 otherwise)
                          #  i.e. "11" → 1 (truthy)
                          #  i.e. "10" → 0 (falsey)
      31^                 # Bitwise-XOR with 31 (30 for November, 31 for other months)
                          #  i.e. 1 → 30
                          #  i.e. 0 → 31
         12              # Pair it with 12
                          #  i.e. 30 → [30,12]
                          #  i.e. 31 → [31,12]
            ø             # Zip/transpose; swapping rows and columns
                          # (implicitly removes year)
                          #  i.e. ["40","11","1761"] and [30,12] → [["40",30],["11",12]]
                          #  i.e. ["02","10","0002"] and [31,12] → [["02",31],["10",12]]
             ε    }       # Map each pair to:
              ß           # Get the minimum (implicitly converts to integer unfortunately)
                          #  i.e. [["40",30],["11",12]] → [30,11]
                          #  i.e. [["02",31],["10",12]] → [2,10]
               т+         # Add 100
                          #  i.e. [30,11] → [130,111]
                          #  i.e. [2,10] → [102,110]
                 ¦        # Remove the first character
                          #  i.e. [130,111] → ["30","11"]
                          #  i.e. [102,110] → ["02","10"]
                   s      # Swap so the triplicated list is at the top of the stack again
                    θ     # Pop and only leave it's last element (the year)
                          #  i.e. ["40","11","1761"] → "1761"
                          #  i.e. ["02","10","0002"] → "0002"
                     ª    # Append it to the list
                          #  i.e. ["30","11"] and "1761" → ["30","11","1761"]
                          #  i.e. ["02","10"] and "0002" → ["02","10","0002"]
                      ðý  # Join the list by spaces (and output implicitly)
                          #  i.e. ["30","11","1761"] → "30 11 1761"
                          #  i.e. ["02","10","0002"] → "02 10 0002"
Kevin Cruijssen
quelle