Wann war das Datum das letzte Mal durch n teilbar?

24

Ein Datum kann durch eine ganze Zahl ohne Vorzeichen dargestellt werden: JJJJMMTT. Was Sie tun müssen, ist, das kürzeste Programm oder die kürzeste Funktion zu schreiben, die das letzte Datum ermittelt, dessen Nummer durch eine bestimmte Zahl teilbar war n(einschließlich des heutigen Datums), und dieses Datum dann in dem oben gezeigten Format zurückzugeben. Wenn es noch nie ein Datum (zwischen 00000101 und einschließlich heute) gab, das durch die angegebene Ganzzahl teilbar ist, sollten Sie -1 zurückgeben.

Beispiele

Current Date     Input     Output

30 July, 2014      4       20140728
30 July, 2014      7       20140729
28 July, 2014      4       20140728
28 July, 2014      7       20140722
28 July,    5    90000     -1

Eingang

Sie können aus STDIN lesen, ein Funktionsargument verwenden oder sogar erwarten, dass die Eingabe in einer Variablen gespeichert wird. Die Eingabe ist eine vorzeichenlose Ganzzahl.

Ausgabe

Schreiben Sie in STDOUT oder geben Sie die Ganzzahl für das Datum im Format JJJJMMTT zurück (oder speichern Sie sie in einer Variablen).

Beschränkungen

Sie können jede Standardbibliothek verwenden, die Ihre Sprache anbietet. Es gelten Standardlücken .

Gewinnbedingungen

Dies ist ein , also gewinnt das kleinste Programm (in Bytes). Bei Stimmengleichheit gewinnt die Antwort mit den meisten Stimmen.

Überakteur
quelle
4
Datum 00000101 existiert nicht. Die Anzahl der Jahre beginnt am 1. en.wikipedia.org/wiki/0_%28year%29
edc65
1
@ edc65 können wir so tun, als ob es existiert?
Overactor
3
Was ist mit dem 29. Februar? Müssen wir die Regeln für Schaltjahre anwenden, um nach gültigen Daten zu suchen? en.wikipedia.org/wiki/Leap_year
Digitales Trauma
6
Was ist mit den Tagen, die durch den Wechsel des julianisch-gregorianischen Kalenders verloren gegangen sind? Oder gehen wir den ganzen Weg gregorianisch? en.wikipedia.org/wiki/Gregorian_calendar
Digitales Trauma
1
Ihre Eingabe- / Ausgabespezifikationen sind ziemlich locker. Soll beispielsweise die Variable "Erwarten, dass die Eingabe in einer Variablen gespeichert wird" die Variablendeklaration in einer Sprache wie C zählen? Sie sagen "Schreiben Sie ein Programm", aber Sie sagen "Nehmen Sie ein Funktionsargument" - bedeutet das, dass wir nur eine Funktion schreiben können und nicht ein vollständiges Programm?
Bob

Antworten:

16

Mathematica, 93 60 Bytes

For[i=0,(r=DatePlus@i--~FromDigits~100)>0&&!n∣r,];r~Max~-1

Erwartet, dass die Eingabe in gespeichert wird n.

Beachten Sie, dass die vertikale Linie das Unicode-Zeichen für "Teilungen" ist, die ich als 3 Bytes (UTF-8) gezählt habe.

Bearbeiten: Fand einen ordentlichen Trick, um die aufgeblähte DateStringund Formatangabe zu vermeiden :).

Bearbeiten: Total vergessen über die -1Anforderung. Jetzt behoben.

Hier ist eine Erklärung

For[i=0,            i--                        ,];         (* i is the number of days AFTER
                                                              today. Hence, we decrement 
                                                              it. *)
For[i=0,   DatePlus@i--                        ,];         (* If no reference date is
                                                              provided, DatePlus will add
                                                              the given number of days to
                                                              today's date. The result is a 
                                                              list of 3 integers, luckily 
                                                              in order {year,month,day} *)
For[i=0,   DatePlus@i--~FromDigits~100         ,];         (* Interpret these as the digits
                                                              of a base 100 number. The 
                                                              beauty is that FromDigits
                                                              doesn't care about digits 
                                                              greater than the base and 
                                                              just carries them over. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)        ,];         (* Store the number in r. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)>0      ,];         (* Make sure it's positive. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)>0&&!n|r,];         (* And keep going while n does 
                                                              not divide r. *)
For[i=0,(r=DatePlus@i--~FromDigits~100)>0&&!n|r,];r~Max~-1 (* Clamp result to -1. *)

Beachten Sie, dass ich |stattdessen in der Erklärung verwendet habe, weil der Unicode mit Monospacing herumspielt.

Martin Ender
quelle
+ 1.Haben Sie einen Link, der darauf hinweist, dass Sie Unicode-Zeichen als 3 Byte zählen sollten?
Dr. Belisarius
2
@belisarius Das OP gab an, dass dieser Code Golf durch Bytes und nicht durch Zeichen gezählt wird (dies ist auch die Standardeinstellung, wie im Tag-Wiki angegeben).
Martin Ender
Ich habe nie bis zum Ende des Wikis gelesen :) Danke!
Dr. Belisarius
6

Python 2 - 150

import datetime as d,re
def f(n):
 t=d.date.today()
 while t:
    c=int(re.sub("-","",str(t)))
    if c%n<1:return c
    try:t-=d.timedelta(1)
    except:return-1

Vielen Dank an @ chill0r für den Vorschlag, days = zu entfernen, und an Jason S für den Hinweis, dass der try-Block auf eine Zeile reduziert werden kann.

Vektorisiert
quelle
Ja. Das ist eine Standardarbeitsanweisung;). Die Tabs werden nach dem Einfügen in Leerzeichen umgewandelt.
Vectorized
Sie können die entfernen days=in t-=d.timedelta(days=1). Dies funktioniert auch gut (zumindest in Python3)
chill0r
@bitpwner ah ich verstehe, egal dann.
Martin Ender
1
Sie können mehr sparen: (1) Verwenden int(t.strftime("%Y%m%d"))und Löschen re, (2) Verwenden einer einzeiligen Zeile, tryda diese nur enthalten sein t-=d.timedelta(1)muss.
Jason S
1
@bitpwner strftimeauf älteren Daten funktioniert in Python3, überprüft und ich bekomme einen Fehler in Python2
Jason S
5

C # 136

Mit den überarbeiteten Spezifikationen eine Funktion, die ein vorzeichenloses int annimmt und ein int zurückgibt.

int F(uint n){var d=System.DateTime.Now;int i;try{while((i=int.Parse(d.ToString("yyyMMdd")))%n>0)d=d.AddDays(-1);}catch{i=-1;}return i;}

152 Zeichen mit variabler Ein- / Ausgabe

Unter Ausnutzung der losen Eingabe- / Ausgabeanforderungen muss die Eingabe in der Variablen gespeichert werden n(derzeit werden alle Zeichen außer dem Ganzzahlliteral gezählt), und die Ausgabe wird mit der Variablen bereitgestellt s.

class P{static void Main(){var n=4;var d=System.DateTime.Now;string s;try{while(int.Parse(s=d.ToString("yyyMMdd"))%n>0)d=d.AddDays(-1);}catch{s="-1";}}}

204 Zeichen mit STDIN / STDOUT:

using System;class P{static void Main(){int n=int.Parse(Console.ReadLine());var d=DateTime.Now;string s;try{while(int.Parse(s=d.ToString("yyyMMdd"))%n>0)d=d.AddDays(-1);}catch{s="-1";}Console.Write(s);}}
Bob
quelle
1
Wirklich eine Ablehnung? Löst dies das Problem nicht richtig? Bitte erkläre. Wenn jemand denkt, dass ich die andere C # -Antwort dupliziert habe, habe ich dies ungefähr eine Stunde vor der anderen geschrieben und sogar versucht , C # 6.0 für die Deklarationsausdrücke zu verwenden. Etwas abgelenkt, was dazu führte, dass die Antwort zu spät kam. Selbst dann ist das ein ziemlich schwacher Grund für eine Ablehnung.
Bob
4

T-SQL (2012) - 148

Angenommen, es gibt eine freie Variable @n mit dem Wert n.

declare @ date=getdate()while convert(char,@,112)%@n>0 and'00010101'<@ set @=dateadd(d,-1,@)print iif(convert(char,@,112)%@n=0,convert(char,@),'-1')
Michael B
quelle
4

Golflua 90 86

n=I.r()d="%Y%m%d"i=O.d(d)+0j=0@i>0?i%n==0w(i)O.q()$j=j+1i=O.d(d,O.t()-j*86400)+0$w(-1)

Eine ungolfed Lua Version wäre,

n = io.read()
d = "%Y%m%d"
i = os.date(d)+0   -- implicitly casts os.date(d) to int
j = 0
while i>0 do
   if i % n == 0 then
      print(i)
      os.exit()
   end
   j = j+1
   i = os.date(d,os.time()-j*86400)+0
end
print(-1)
Kyle Kanos
quelle
2
Getestet hier n = 20140699 Ausgänge 20140699
William Barbosa
@ WilliamBarbosa: Behoben; 20140699 gibt -1 zurück.
Kyle Kanos
4

MATLAB: 61

-1,s=str2num(datestr(1:now,'YYYYmmDD')),d=s(~mod(s,n)),d(end)

Angenommen, der Divisor ist in gespeichert n. Das Ergebnis wird in einer Variablen namens gespeichert ans.


Kommentierte Version:

-1                                     % Store -1 in ans in case we don't find anything
s=str2num(datestr(1:now,'YYYYmmDD'))   % Make a list of date numbers
d=s(~mod(s,n)),                        % Select only those who are dividable and prepend -1
d(end)                                 % Store last found value in ans, if anything is found

Erzeugt einen Fehler, wenn kein Ergebnis gefunden wird, die Antwort aber trotzdem in der Variablen verfügbar ist.


Fehler könnten auf Kosten von 2 zusätzlichen Zeichen vermieden werden:

s=str2num(datestr(1:now,'YYYYmmDD')),d=[-1;s(~mod(s,n))],d(end)
Dennis Jaheruddin
quelle
@ MartinBüttner Hmm, habe dieses Problem gelöst, aber jetzt ist die Lösung nur für minimale Zeichen gebunden. Kannst du irgendwelche Verbesserungen sehen?
Dennis Jaheruddin
1
Nein, nicht von oben. Aber meine Motivation, Ihnen zu helfen, mich zu schlagen, ist etwas begrenzt. ;)
Martin Ender
4

PHP (92 = 85 + 7)

Erwartet, dass die Eingabe in gespeichert wird $n.

for($d=date("Ymd");!($d%$n==0&checkdate($d/100%100,$d%100,substr($d,0,4))|$d<0);$d--);echo$d

Mir ist gerade eingefallen, warum ich PHP nicht mehr mag =)

EDIT: Jetzt ist auch die -1 der Spezifikation implementiert.

Fehler
quelle
Nein, nur geprüft, $ d ist beim Echo zu niedrig. Was meinst du mit "Du hast geschmiedet"? (Sorry, kein englischer Muttersprachler =)
Fehler
Oh, ich habe diese Spezifikation nicht gesehen, das muss natürlich hinzugefügt werden, danke!
Fehler
3

JavaScript (ES6) 115

Erwartet Zahl in Variable n, Ergebnis in Variable r gespeichert. Jeder Tag wird überprüft, beginnend mit dem aktuellen Datum und absteigend - es muss einen besseren Weg geben.
Bei Verwendung der Standard-Javascript-Datumsfunktionen sind alle Datumsangaben bis zum Jahr 1 gregorianisch (wobei Schaltjahre vor der gregorianischen Reform dementsprechend falsch sind).

for(z=new Date,t=n+1;t>n&&t%n;)
  d=z.getDate(),
  t=z.getFullYear()*1e4+(z.getMonth()+1)*100+d,
  z.setDate(d-1);
r=t>n?t:-1
edc65
quelle
3

C # - 144 (oder 124 in LINQPad) + 1 für jede Ziffer in n

Dies erwartet, dass sich die Eingabe in der Variablen befindet n. Am Ende der Ausführung befindet sich der gewünschte Wert in der Variablen r. Dies gilt jedoch 00010101als erstes Datum, da das Datum 00000101nicht vorhanden ist. Verbesserungsvorschläge sind immer willkommen.

class P{static void Main(){int n=7,r;var d=System.DateTime.Now;try{for(;(r=int.Parse(d.ToString("yyyMMdd")))%n>0;d=d.AddDays(-1));}catch{r=-1;}}}

LINQPad-Version:

int n=7,r;var d=System.DateTime.Now;try{for(;(r=int.Parse(d.ToString("yyyMMdd")))%n>0;d=d.AddDays(-1));}catch{r=-1;}r.Dump();
William Barbosa
quelle
3

Groovy - 301 300 Zeichen

Sehr einfach (und langsam), ohne Tricks, um die Tatsache zu verbergen, dass es Joda Time verwendet.

Golf gespielt:

@Grab(group='joda-time', module='joda-time', version='2.3')
import org.joda.time.*
import org.joda.time.format.*
f={DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(it)) as int}
n=args[0] as int;b=0;x=-1;c=0
while(!b){if(f(c++)%n==0){x=f(--c);b=1};if(f(0)-c<=101){b=1}}
println x

Beispiellauf (am 30.07.2014):

$ groovy D.groovy  7
20140729
$ groovy D.groovy  16
20140720
$ groovy D.groovy  90000
-1

Ungolfed:

@Grab(group='joda-time', module='joda-time', version='2.3')

import org.joda.time.*
import org.joda.time.format.*

f = { DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(it)) as int }

n = args[0] as int
b = 0 
x = -1
c = 0

while (!b) {
    if(f(c++)%n==0) { x=f(--c); b=1}
    if(f(0)-c<=101){b=1}
}

println x
Michael Easter
quelle
3

R 146, 139

D=function(n){
z=as.double(gsub("-","",y<-Sys.Date()))
d=F
while(z>100&!d){
y=y-1 
z=as.double(gsub("-","",y))
d=!z%%n}
ifelse(z>100,z,-1)}

Viel Glück bei einem Date, das nicht funktioniert. microbenchmarkBerichten zufolge dauert es ungefähr eine halbe Sekunde, um 15 Tage zurückzugehen. Ab dem 31. Juli 2014 dauert das Ausspucken etwa 20 Millionen Sekunden (~ 23 Tage) -1, zumindest entsprechend der Rückseite des Umschlags.

Bearbeiten : Einige Verknüpfungen in den Kommentaren

Shadowtalker
quelle
!dist kürzer als d==Fund !z%%nals z%%n==0. Das Verwandeln as.numeric(gsub("-","",...)in eine Funktion sollte auch die Anzahl der Zeichen verringern. Trotzdem gute Arbeit!
Plannapus
Oh und as.realist oft eine gute, kürzere Alternative zu as.numeric.
Plannapus
Ist leider nicht mehr as.realaktuell ab R 3.0.0. Aber wir haben immer noch as.doubleein Zeichen kürzer.
Shadowtalker
Oh, das wusste ich nicht, da ich immer noch R 2.14
plannapus
1
Ich arbeite nicht an einem Computer, auf dem ich Administratorrechte habe, daher liegt es nicht wirklich an mir. Aber das habe paste0ich .Rprofilenatürlich schon in meinem :)
31.07.14
3

Matlab 104

function d=f(v);for d=fix(now):-1:1 d=str2num(datestr(d,'YYYYmmDD'));if~mod(d,v)return;end;end;d=-1;end

Ungolfed:

function d = f(v)
   for d=fix(now):-1:1
       d = str2num(datestr(d,'YYYYmmDD'));
       if ~mod(d,v)
          return; 
       end
   end
   d = -1;
end

EDIT: Ich schaffte es ein wenig zu optimieren, aber @DennisJaheruddin hat die wirkliche Lösung hier

Scott
quelle
Hier kann noch einiges golfen werden, ich werde es updaten.
Dennis Jaheruddin
@DennisJaheruddin Ich habe Ihre Bearbeitung aufgrund dieses Metapost abgelehnt . Bitte schlagen Sie Ihre Verbesserungen in einem Kommentar vor, damit das OP sie überprüfen kann, bevor Sie seine Antwort ändern.
Martin Ender
Beachten Sie, dass Sie Zeichen auf verschiedene Arten speichern können: Verwenden Sie ein Skript anstelle einer Funktion, lassen Sie die Dinge ans zuweisen, führen Sie die Schleife von niedrig nach hoch aus und lassen Sie jedes Ergebnis die vorherige überschreiben, damit Sie die Schleife nicht unterbrechen müssen . - Natürlich kann auch eine Vektorisierung helfen, siehe meine Antwort .
Dennis Jaheruddin
Hier ist eine kürzere, auf einer Schleife basierende Version von 67 Zeichen:-1,for s=str2num(datestr(1:now,'YYYYmmDD'))',if~mod(s,n),+s,end,end
Dennis Jaheruddin
@ MartinBüttner Danke für den Kommentar. Wie Sie sagten, ist ein Fehler aufgetreten. Jetzt sollte es okay sein.
Scott
3

Python 3 - 151 148 Bytes, Generatoren

from datetime import*
t=date.today()
f=lambda n:next((y for y in(int((t-timedelta(o)).strftime("%Y%m%d"))for o in range(t.toordinal()))if y%n<1),-1)

Danke @ nyuszika7h für den import*Vorschlag

Jason S
quelle
2

Rubin 103

require'date'
f=->{d=Date.today 
(s=d.strftime('%Y%m%d').to_i
return s if s%n<1
d-=1)while d.year>0
-1}

Eingang

Erwartet, dass der Divisorwert in Variable vorhanden ist n.

Ausgabe

Der Rückgabewert der fFunktion

Online-Beispiel: http://ideone.com/LoYxG4

Cristian Lupascu
quelle
2

Java: 373 Zeichen

Dies ist ein Port der Groovy-Antwort und verwendet Joda Time.

Golf gespielt:

import org.joda.time.*;
import org.joda.time.format.*;
public class D {
static int f(int i){return Integer.parseInt(DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(i)));}
public static void main(String[] args){
int n=Integer.parseInt(args[0]);int b=0,c=0,x=-1;
while(b!=1){if(f(c++)%n==0){x=f(--c);b=1;};if(f(0)-c<=101){b=1;}}
System.out.println(x);}}

Beispielläufe (mit joda-time-2.4.jar auf classpath:

$ java D 7
20140729
$ java D 4
20140728
$ java D 16
20140720
$ java D 90000
-1

Ungolfed:

import org.joda.time.*;
import org.joda.time.format.*;

public class D {
    static int f(int i) {
        return Integer.parseInt(DateTimeFormat.forPattern("yyyyMMdd").print(new LocalDate().minusDays(i)));
    }

    public static void main(String[] args) {
        int n = Integer.parseInt(args[0]);
        int b = 0,c = 0,x = -1;

        while(b!=1) {
            if(f(c++)%n==0) { x=f(--c);b=1; }
            if(f(0)-c<=101) { b=1; }
        }

        System.out.println(x);
    }
}
Michael Easter
quelle
3
Es gibt auch java.time.*in der neuesten Version von Java.
ntoskrnl
2

Bash + Coreutils (8,21), 67 Bytes

seq -f-%gday $[9**9]|date -f- +[pq]sp[_1pq]sq%Y%m%ddA1=qd$1%%0=p|dc
  • seqgeneriert ganze Zahlen von 1 bis 9 9 , eine pro Zeile, und formatiert sie als-<x>day
  • Leiten Sie dies weiter, date -fum jede Zeile zu interpretieren und das Datum als dcAusdruck auszugeben , z. B. [pq] sp [_1pq] sq 20140728 d A1 =q d 7% 0=p(Leerzeichen zur besseren Lesbarkeit hinzugefügt).
    • [pq] Definieren Sie ein Makro, um den oberen Bereich des Stapels zu drucken, und beenden Sie es dann
    • sp Makro in Register p speichern
    • [pq] Definieren Sie ein Makro, um -1 zu drücken, den oberen Bereich des Stapels zu drucken und dann zu beenden
    • sq Makro in Register q speichern
    • 20140728 eingebettete Datums-Ganzzahl
    • d Doppelte Oberseite des Stapels
    • A1 Drücken Sie 101 (00000101).
    • =qPop-Top-2-Stack-Werte: Vergleiche Datum und 101 und rufe das Makro auf, qwenn es gleich ist
    • 7 Teiler drücken
    • % Pop-Teiler und Dividee, das Teilen und den Rest schieben
    • 0 0 drücken
    • =pPop-Top-2-Stack-Werte: Vergleiche Rest und 0 und rufe das Makro auf, pwenn es gleich ist
    • d Doppelte Oberseite des Stapels
    • Makro pheißt: gibt Datumszahl aus und wird dcvollständig beendet
  • dcAusdrücke werden dczur Auswertung weitergeleitet. Sobald dcder richtige Wert gedruckt und beendet wurde, wird der Rest der Pipeline abgerissen

Ausgabe:

$ ./lastdivdate.sh 4
20140728
$ ./lastdivdate.sh 7
20140729
$ ./lastdivdate.sh 123456
17901120
$ ./lastdivdate.sh 77777
19910912
$ ./lastdivdate.sh 7777777
-1
$ 

Da dieses Programm Ganzzahlen von 1 bis 9 9 generiert , wird es in etwas mehr als 1 Million Jahren in der Zukunft gültig sein. Ich hoffe diese Einschränkung ist akzeptabel ;-)


Vielen Dank an @ WumpusQ.Wumbley für die Verkürzung der Rückgabe von -1.

Digitales Trauma
quelle
@ MartinBüttner Flüche! Jetzt mit einer 19-Byte-Strafe :)
Digital Trauma
Kürzere Möglichkeiten, leere Ausgaben in -1 umzuwandeln: Fügen Sie |grep .||echo -1sie am Ende der Pipeline hinzu oder verwenden Sie zsh, wo Sie Erweiterungen wie echo ${$(cmd):-1}diese verschachteln können (dies kostet Sie einen Backslash an anderer Stelle ...)
@ WumpusQ.Wumbley Warum habe ich nicht daran gedacht? Vielen Dank!
Digital Trauma
1
Übrigens scheint dies empfindlich auf die Coreutils-Version zu reagieren. Mine (8.15) weigert sich, vor 1901 mit der Spezifikation "vor Tagen" zurückzugehen.
1
Eigentlich scheint es ein sizeof time_tProblem zu sein, da die Grenze, an der es bricht, 2 ** 31 Sekunden vor dem 1.1.1970 ist. Meine ältere Installation ist auch pathetisch 32-Bit
2

PYTHON: 134 Bytes

Ich werde nicht in der Lage sein, den aktuellen Anführer zu schlagen, und es ist nicht viel besser als die beste Python-Antwort, aber ich habe mich entschieden, meine beste Python-Lösung zu veröffentlichen.

from datetime import*
def y(a,n):
 s=a.strftime("%Y%m%d")
 if int(s)%n==0:yield s
 try:x=y(a-timedelta(1),n)
 except:yield -1
 yield x

Ungolfed:

from datetime import *
def y(a, n):
    s=int(a.strftime("%Y%m%d"))
    if s%n==0:
        yield s
    try:
        x=y(a-timedelta(1), n)
    except:
        yield -1
    yield x
RageCage
quelle
Es sind tatsächlich 138 Bytes. Sie können 4 Bytes sparen, indem Sie from datetime import*anstelle von import datetime as d, timedelta(1)anstelle von d.timedelta(1)und yieldanstelle von verwenden return.
Nyuszika7h
Ich verwende einen zufälligen Online-Bytezähler. Gibt es eine bessere Option?
RageCage
Was unterscheidet das von diesem? bytecount.bluebus112.com
RageCage
Dieser zählt keine Zeilenumbrüche und auch keine Zeichen und keine Bytes. Für ASCII-Text sind die beiden identisch, sodass letzterer hier keinen Unterschied macht. Beim Code-Golf zählen Sie normalerweise Zeichen, sofern das OP nichts anderes angibt. (Auch die, die ich verlinkt habe, war das erste Ergebnis in Google für "
Byteanzahl
2

JavaScript (ES5) - 94

Es erwartet die Eingabe in Variable xund platziert die Ausgabe in o.

for(i=Date.now();i>-7e13&&(o=(new Date(i)).toISOString().replace(/-|T.*/g,''))%x;i-=864e5)o=-1
Ben
quelle
2

k4 (84) (73)

f:{f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;.z.D];x]}

Dies ist nur ein erster Schnitt mit dem ersten Algorithmus, der mir in den Sinn kam; Ich bin mir sicher, dass sowohl in der Leistung als auch in der Länge etwas Besseres möglich ist.

Diese Version kodiert den "Heute" -Teil fest (das ist der .z.D); Ändern Sie es in ein Datumsliteral ( yyyy.mm.dd) oder eine Ganzzahl im q-Datumssystem (Tage seit dem 1. Januar 2000), um die Testfälle auszuführen. (q parst Datumsliterale nicht vor dem frühen 18. Jahrhundert. Daher müssen Sie für Datumsangaben davor den Wert ermitteln und die entsprechende Ganzzahl direkt verwenden. 1. Januar: "AD 0" aus der Spezifikation wird gedreht out to be -730457, das im Funktionscode verwendet wird. 28. Juli, AD 5, aus dem letzten Testfall, stellt sich als -728450.)

Die gegebenen Testfälle:

  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.30];x]}4
20140728
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.30];x]}7
20140729
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.28];x]}4
20140728
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;2014.07.28];x]}7
20140722
  "d"$-728450
0005.07.28
  {f d@*|&~.q.mod[(f:{$[^x;-1;.($x)@&~"."=$x]})'d:{"d"$x+!1+"i"$y-x}[-730457;-728450];x]}90000
-1

bearbeiten:

g:.,/$`\:`$$:;f:{$[Z=r:{(z>x)&.q.mod[g z]y}[Z:-730458;y]{x-1}/x;-1;g"d"$r]}

Dies ist ein anderer Ansatz, bei dem einer der Konvergenzoperatoren das Datum dekrementiert, bis entweder eine teilbare Zahl gefunden wird oder die Grenze von 1/1/0000 überschritten wird. Die Konvertierung von Datum zu Ganzzahl erfolgt ebenfalls geringfügig anders.

Die Testfälle, diesmal auf einmal:

  g:.,/$`\:`$$:;{$[Z=r:{(z>x)&.q.mod[g z]y}[Z:-730458;y]{x-1}/x;-1;g"d"$r]}'[2014.07.30 2014.07.30 2014.07.28 2014.07.28,"d"$-728450;4 7 4 7 90000]
20140728 20140729 20140728 20140722 -1
Aaron Davies
quelle
1

VBA 343 Bytes (Modul)

Sub divD(i As Long)
a = Now()
b = Format(a, "yyyymmdd")
    Do While b / i <> Int(b / i)
    a = DateAdd("d", -1, a)
    b = Format(a, "yyyymmdd")
        If b = "01000101" Then
            MsgBox -1
            Exit Sub
        End If
    Loop
MsgBox b
End Sub
Alex
quelle
Dies kann Sub d(i):a=Now:b=a:Do Until b/i=Int(b/i):a=DateAdd("d",-1,a):b=Format(a,"yyyymmdd"):If b="01000101"Then:b=-1:Exit Sub:Loop:Debug.?b:End Subfür 139 Bytes stark komprimiert werden
Taylor Scott
1

PowerShell - 76

Dies hängt von der in der Variablen gespeicherten Nummer ab $n.

try{@(0..$n|%{'{0:yyyyMMdd}'-f(date).AddDays(-$_)}|?{!($_%$n)})[0]}catch{-1}
Rynant
quelle