Datum multiplizieren Challenge

19

(Inspiriert von Riddler von letzter Woche auf FiveThirtyEight.com. Sandbox-Post .)

Berechnen Sie bei einem Jahr zwischen 2001 und 2099 die Anzahl der Tage in diesem Kalenderjahr und geben Sie sie zurück mm * dd = yy(wobei yydas zweistellige Jahr ist).

2018 hat zum Beispiel 5:

  • 18. Januar (1 * 18 = 18)
  • 9. Februar (2 * 9 = 18)
  • 6. März (3 * 6 = 18)
  • 3. Juni (6 * 3 = 18)
  • 2. September (9 * 2 = 18)

Die Eingabe kann eine 2- oder 4-stellige numerische Jahreszahl sein.

Die Ausgabe sollte eine Ganzzahl sein. Optionales Leerzeichen oder Return ist in Ordnung.

Komplette Ein- / Ausgabeliste:

Input = Output
 2001 = 1     2021 = 3     2041 = 0     2061 = 0     2081 = 2
 2002 = 2     2022 = 3     2042 = 4     2062 = 0     2082 = 0
 2003 = 2     2023 = 1     2043 = 0     2063 = 3     2083 = 0
 2004 = 3     2024 = 7     2044 = 3     2064 = 2     2084 = 5
 2005 = 2     2025 = 2     2045 = 3     2065 = 1     2085 = 1
 2006 = 4     2026 = 2     2046 = 1     2066 = 3     2086 = 0
 2007 = 2     2027 = 3     2047 = 0     2067 = 0     2087 = 1
 2008 = 4     2028 = 4     2048 = 6     2068 = 1     2088 = 3
 2009 = 3     2029 = 1     2049 = 1     2069 = 1     2089 = 0
 2010 = 4     2030 = 6     2050 = 3     2070 = 3     2090 = 5
 2011 = 2     2031 = 1     2051 = 1     2071 = 0     2091 = 1
 2012 = 6     2032 = 3     2052 = 2     2072 = 6     2092 = 1
 2013 = 1     2033 = 2     2053 = 0     2073 = 0     2093 = 1
 2014 = 3     2034 = 1     2054 = 4     2074 = 0     2094 = 0
 2015 = 3     2035 = 2     2055 = 2     2075 = 2     2095 = 1
 2016 = 4     2036 = 6     2056 = 4     2076 = 1     2096 = 4
 2017 = 1     2037 = 0     2057 = 1     2077 = 2     2097 = 0
 2018 = 5     2038 = 1     2058 = 0     2078 = 2     2098 = 1
 2019 = 1     2039 = 1     2059 = 0     2079 = 0     2099 = 2
 2020 = 5     2040 = 5     2060 = 6     2080 = 4

Dies ist eine Herausforderung, die niedrigste Byte-Anzahl in jeder Sprache gewinnt.

Vorausberechnung und einfaches Nachschlagen der Antworten sind normalerweise gemäß unseren Regelungslücken ausgeschlossen , aber ich erlaube dies ausdrücklich für diese Herausforderung. Es erlaubt einige interessante alternative Strategien, obwohl es unwahrscheinlich ist, dass eine Nachschlageliste mit 98 bis 99 Einträgen am kürzesten sein wird.

BradC
quelle
Wenn es in Ihrer Sprache einfacher ist, ist die Antwort unabhängig vom Jahrhundert dieselbe. 1924 und 2124 haben die gleiche Anzahl von Tagen wie 2024.
BradC
Wenn das Ergebnis von mm * dd größer als 100 ist, wird es automatisch gefiltert.
DanielIndie
@DanielIndie Richtig, es sollten keine "Wraparound" -Daten gezählt werden. Mit anderen Worten, der 12. Dezember 2044 zählt nicht, obwohl 12 * 12 = 144.
BradC
Da wir nur eine begrenzte Anzahl von Eingaben verarbeiten müssen, habe ich sie alle in bearbeitet. Sie können jederzeit ein Rollback oder eine Neuformatierung durchführen.
Shaggy
1
@gwaugh Nur damit Sie entscheiden können, welche Eingabe als gültige Eingabe akzeptiert werden soll (damit Sie keine zusätzlichen Zeichen für die Konvertierung zwischen den beiden Zeichen aufwenden müssen).
BradC

Antworten:

14

Excel, 48 Bytes

Hurra! Schließlich ist etwas Excel eigentlich gut.

=COUNT(VALUE(ROW(1:12)&"/"&A1/ROW(1:12)&"/"&A1))

Übernimmt die Eingabe von A1 in Form einer Ganzzahl von 1 bis 99, die das Jahr darstellt, und gibt sie an die Stelle aus, an der Sie diese Formel eingeben. Es handelt sich um eine Array-Formel. Verwenden Sie daher Strg-Umschalt-Eingabe anstelle der Eingabetaste, um sie einzugeben.

Dies macht sich die Tatsache zunutze, dass COUNTFehler ignoriert werden, sodass alle Fehler, die entweder durch den Monat verursacht werden, der das Jahr nicht teilt (was Excel dazu veranlasst, so etwas zu analysieren, 2/12.5/25oder durch das Datum, das nicht gültig ist, so 2/29/58, werden einfach unbemerkt ignoriert.

Sophia Lechner
quelle
1
Sehr schön. Wahrscheinlich erwähnenswert, erfordert es eine zweistellige Jahreszahl A1. Die Eingabe einer vierstelligen Jahreszahl kehrt einfach zurück 0.
BradC
Wahr! Ich werde das in der Beschreibung bearbeiten.
Sophia Lechner
Auch sollte ich erwähnen, dass es länderspezifisch ist; Dies hängt von einem Gebietsschema ab, das die Reihenfolge MM / TT / JJ verwendet. In einem Gebietsschema mit der Reihenfolge TT / MM / JJ wäre die Antwort natürlich die gleiche Anzahl von Bytes.
Sophia Lechner
1
Super schlau; Mir gefällt, dass Sie nur zwölf Kandidaten testen (einen pro Monat), anstatt jeden Tag im Jahr durchzugehen.
BradC
Fixieren Sie das Jahr auf ein nicht sprunghaftes Speicherbyte?
14.
6

Python 2 , 44 Bytes

[k/32%13*(k%32)for k in range(96,509)].count

Probieren Sie es online!

Eine anonyme Funktion, die als Methodenobjekt angegeben wird. Produziert alle Produkte von (month, day)Paaren (m, d)so codiert durch k=32*m+dmit 0≤m≤12, 0≤d≤31, Umwickeln. Eliminiert den 29. bis 31. Februar, indem sie aus dem Bereich ausgeschlossen werden.

xnor
quelle
5

Java (JDK 10) , 65 Byte

y->{int m=13,c=0;for(;m-->1;)if(y%m<1&y/m<29+m%2*3)c++;return c;}

Probieren Sie es online!

Credits

Olivier Grégoire
quelle
Es passt kein Schaltjahr 29*n, also brauchen Sie den Scheck nicht
l4m2
Danke für deinen Beitrag. Ich konnte insgesamt 27 Bytes mit ein paar anderen Änderungen entfernen.
Olivier Grégoire
1
Der Wechsel (m==2?29:32)zu 29+m%2*3scheint immer noch alle OKErgebnisse zu liefern . Dank an die Ruby-Antwort von @AsoneTuhid .
Kevin Cruijssen
4

PowerShell , 94 Byte

param($a)for($x=Date 1/1/$a;$x-le(Date 12/9/$a);$x=$x.AddDays(1)){$z+=$x.Month*$x.Day-eq$a};$z

Probieren Sie es online!

Nimmt die Eingabe als zweistelliges Jahr und erstellt dann eine forSchleife von 1/1/yearbis 12/9/year(da 12/10 und höher niemals zählen und dies ein Byte spart). Bei jeder Iteration $zerhöhen wir, wenn die .MonthZeiten .Daygleich unserem Eingabejahr sind. Wird außerhalb der Schleife $zin der Pipeline belassen und die Ausgabe erfolgt implizit.

Bearbeiten - das ist kulturabhängig. Der obige Code funktioniert für en-us. Das Datumsformat muss möglicherweise für andere Kulturen geändert werden.

AdmBorkBork
quelle
2
"Kultur"? Meinten Sie "locale"? ...
user202729
1
@ user202729 Umgangssprachlich ja, aber in der PowerShell-Dokumentation wird dies als "Kultur" bezeichnet.
AdmBorkBork
"Kultur" ist das Wort, das MS im Allgemeinen verwendet, um über das Gebietsschema zu sprechen, z. System.Globalization.CultureInfo in .NET.
Sundar - Reinstate Monica
3

JavaScript (ES6), 91 Byte

Ich war gespannt, wie sich Hardcoding mit einer iterativen Berechnung vergleichen lässt. Es ist definitiv länger (siehe @ Shaggys Antwort ), aber nicht furchtbar länger.

Edit : Es ist jedoch viel länger als eine direktere Formel (siehe @ l4m2 Antwort ).

Übernimmt die Eingabe als Ganzzahl in [1..99] .

n=>(k=parseInt('8ijkskercdtbnqcejh6954r1eb2kc06oa3936gh2k0d83d984h'[n>>1],36),n&1?k>>3:k&7)

Probieren Sie es online!

Wie?

In ungeraden Jahren ist die Wahrscheinlichkeit, dass MM * TT = JJ ist, signifikant geringer als in geraden Jahren. Genauer gesagt haben ungerade Jahre 0 bis 3 Übereinstimmungen, während gerade Jahre 0 bis 7 Übereinstimmungen haben. Dies ermöglicht es uns, jedes Paar von Jahren mit nur 5 Bits zu codieren, die in Basis 36 bequem als ein einzelnes Zeichen dargestellt werden können.

Arnauld
quelle
3

Bash + GNU-Dienstprogramme , 57

  • Dank @SophiaLechner 1 Byte gespart
seq -f1/1/$1+%gday 0 365|date -f- +%m*%d-%y|bc|grep -c ^0

Beachten Sie, dass der seqBefehl immer eine Liste mit 366 Daten erstellt - für Nicht-Schaltjahre wird der 1. Januar des nächsten Jahres einbezogen. Im Datumsbereich 2001..2099 ist MM * DD für keines dieser Jahre der 1. Januar des nächsten Jahres, sodass dieser zusätzliche Tag das Ergebnis nicht beeinflusst.

Probieren Sie es online!

Digitales Trauma
quelle
Sehr schön - ich hatte nicht einmal gewusst, datedass ich beim Parsen so ein Datum berechnen werde. seqbenötigt nach dem kein Leerzeichen -f, so dass Sie dort ein Byte speichern können.
Sophia Lechner
3

T-SQL, 123 121 Bytes

Gemäß unseren E / A-Regeln erfolgt die Eingabe über die bereits vorhandene Tabelle t mit einem ganzzahligen Feld y , das eine zweistellige Jahreszahl enthält.

WITH c AS(SELECT 1m UNION ALL SELECT m+1FROM c WHERE m<12)
SELECT SUM(ISDATE(CONCAT(m,'/',y/m,'/',y)))FROM c,t WHERE y%m=0

Zeilenumbruch dient nur der Lesbarkeit. Vor allem von der Excel-Lösung von Sophia inspiriert .

  • Die oberste Zeile erzeugt eine 12-Posten-Nummern-Tabelle c, die mit der Eingabetabelle t verknüpft ist .
  • Wenn das passiert habe ich einen Datumskandidaten mit zerdrückt CONCAT(), der implizite varcharDatentypkonvertierungen vornimmt. Sonst würde ich habe eine Reihe von tun CASToder CONVERTAussagen.
  • Es wurde die perfekte Bewertungsfunktion gefunden ISDATE(), die 1 für gültige Daten und 0 für ungültige Daten zurückgibt.
  • Wickeln Sie es in eine SUMME und ich bin fertig.
  • BEARBEITEN : Verschob die Ganzzahl-Division check ( y%m=0) in die WHEREKlausel, um 2 Bytes zu sparen, danke @RazvanSocol.

Leider ist es nicht viel kürzer als die Lookup-Table-Version (unter Verwendung des Strings aus der osdavison-Version ):

T-SQL-Suche, 129 Byte

SELECT SUBSTRING('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)FROM t

BEARBEITEN : Ich lasse mein Original oben, aber wir können ein paar Bytes sparen, indem wir einige neue Funktionen verwenden:

  • STRING_SPLIT ist in MS SQL 2016 und höher verfügbar.
  • CONCAT_WS ist in MS SQL 2017 und höher verfügbar.
  • Wie oben, ersetzt IIFdurchWHERE

MS-SQL 2017, 121 118 Byte

SELECT SUM(ISDATE(CONCAT_WS('/',value,y/value,y)))
FROM t,STRING_SPLIT('1-2-3-4-5-6-7-8-9-10-11-12','-')
WHERE y%value=0

MS-SQL 2017, zusätzliche betrügerische Ausgabe: 109 Bytes

SELECT SUM(ISDATE(CONCAT_WS('/',number,y/number,y)))
FROM t,spt_values WHERE number>0AND y%number=0AND'P'=TYPE

Erfordert, dass Sie sich in der masterDatenbank befinden, die eine Systemtabelle enthält , mit der Sie spt_values(bei Filterung nach TYPE='P') Zahlen von 0 bis 2048 zählen können.

BradC
quelle
Ähnlich wie bei anderen Antworten m/d/yhängt die Reihenfolge, in der ich das Datum ( ) zusammenstelle, von den Lokalitätseinstellungen der SQL-Instanz ab. Andere Lokalitäten erfordern möglicherweise eine andere Reihenfolge oder ein anderes Trennzeichen, aber ich glaube nicht, dass sich dies auf die Codelänge auswirkt.
BradC
Ich vermute, Sie haben festgestellt, dass die Konvertierung von '2/29/64' in ein Datum den 29.02.1964 ergibt (nicht den 29.02.2964). Angesichts der Tatsache, dass die Jahre 2000 und 2100 ausgeschlossen sind, ist dies eine gute Möglichkeit, eine kürzere zu erhalten Code.
Razvan Socol
Durch die Verwendung SPLIT_STRINGeines CTE anstelle eines CTE werden 120 Byte erreicht. Wenn Sie CONCAT_WSanstelle von verwenden, wird ein CONCATanderes Zeichen gespeichert und auf 119 Byte gebracht.
Razvan Socol
@RazvanSocol Ja, ich bin mir nicht sicher, wo die Pause zwischen zweistelligen Daten liegt, die 19xx vs 20xx entsprechen, aber beide geben die gleiche Antwort. Ich werde die anderen beiden Vorschläge ausprobieren, danke!
BradC
1
Ersetzen IIFdurch WHERE.
Razvan Socol
3

Julia 0,6 , 49 44 42 Bytes

y->sum(y/i1:28+3(i%2i÷8)for i=1:12)

Probieren Sie es online!

-5 Bytes, inspiriert von Asone Tuhids Ruby-Antwort.
-2 Bytes, die count durch sum ersetzen

Erläuterung:

Für jeden Monat iBerechnen Sie von 1 bis 12 y/iund prüfen Sie, ob es sich um einen Tag dieses Monats handelt. Monate mit 31 Tagen sind 1, 3, 5, 7, 8, 10, 12 - also ungerade unter 8 und gerade bei und über 8. Also entweder i%2oder i÷8(das ist 0 für i <8 und 1 für i> = 8 hier) sollte 1 sein, aber nicht beide - also XOREN wir sie. Wenn das xor-Ergebnis wahr ist, überprüfen wir Datumsangaben, 1:28+3dh 1:31, ansonsten überprüfen wir nur Datumsangaben 1:28.

1:28ist für den Rest der Monate ausreichend (diese Verbesserung ist von Asone Tuhids Ruby-Antwort inspiriert ), weil:

  • Für Februar wäre die einzige Möglichkeit gewesen 2*29 = 58, aber es 2058ist kein Schaltjahr, also können wir davon ausgehen, dass der Februar immer 28 Tage hat.

  • Die anderen Monate mit 30 Tagen sind Monat 4 und höher - für die i*29(und i*30) über 100 liegen, was ignoriert werden kann.

Schließlich zählen wir die Anzahl der y/iin diese Liste der Tage gehörenden Tage (indem wir hier den Booleschen Wert verwenden sum) und geben diesen zurück.

Sundar - Setzen Sie Monica wieder ein
quelle
3

JavaScript, 91 85 82 81 77 Bytes

Übernimmt die Eingabe als zweistellige Zeichenfolge (oder als 1- oder 2-stellige Ganzzahl).

Nutzt die Tatsache, dass new Dateein Rollover auf den nächsten Monat ausgeführt wird, und setzt dies fort, wenn Sie einen Tageswert übergeben, der die Anzahl der Tage in dem Monat überschreitet, in dem Sie ihn übergeben, sodass bei der ersten Iteration versucht wird, den zu erstellen Datum, yyyy-01-345das wird yyyy-12-11, oder yyyy-12-10Schaltjahre. Danach brauchen wir keine Daten mehr zu überprüfen, da 12*11+sich eine dreistellige Zahl ergibt.

y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)

3 Bytes gespart dank Arnauld .


Probier es aus

f=
y=>(g=d=>d&&([,M,D]=new Date(y,0,d).toJSON().split(/\D/),D*M==y)+g(--d))(345)
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>

Zottelig
quelle
2

Excel, 83 Bytes

{=SUM(IF(MONTH(DATE(A1,1,0)+ROW(1:366))*DAY(DATE(A1,1,0)+ROW(1:366))=A1-2000,1,0))}

Die Eingabe erfolgt in der Zelle A1im Format yyyy. Dies ist eine Matrixformel und wird mit Ctrl+ Shift+ eingegeben Enter, um die geschweiften Klammern zu erhalten {}. Es ist ziemlich einfach und ohne Schlauheit.

Gibt in einer Array-Formel DATE(A1,1,0)+ROW(1:366)ein Array mit 366 Datumswerten an. Auf Nicht-Schaltjahren wird dies den 1. Januar des nächsten Jahres einschließen, aber das ist kein Problem, da 1*1=1und würde nur als falsch positiv gelten, wenn das nächste Jahr 2001aber ist, da der erforderliche Jahresbereich ist2001 - 2099 , wird es nie als eine entstehen Problem.

Wenn Sie diesen Teil einfach kurzgeschlossen haben, ~ist die Formel viel einfacher zu befolgen:

{=SUM(IF(MONTH(~)*DAY(~)=A1-2000,1,0))}

Ich habe versucht, COUNTIF()anstelle von zu verwenden, SUM(IF())aber Excel ließ mich nicht einmal als Matrixformel eingeben, geschweige denn, ich erhielt ein Ergebnis. Ich habe eine Google Sheets- Lösung gefunden CountIf(), die dieselbe Methode verwendet, ansonsten waren es 91 Byte, hauptsächlich, weil sie verwendet wird, ArrayFormula()anstatt einfach { }.

=CountIf(ArrayFormula(Month(Date(A1,1,0)+Row(1:366))*Day(Date(A1,1,0)+Row(1:366))),A1-2000)
Ingenieur Toast
quelle
Ich habe keinen Konsens gesehen, aber im Allgemeinen habe ich die äußeren geschweiften Klammern nicht in meine Byteanzahl für Excel aufgenommen. Sie fühlen sich eher wie eine Art und Weise, wie Excel seine Anzeige formatiert, als wie ein Teil der Formel. Meinungen?
Sophia Lechner
@SophiaLechner Ich habe sie eingefügt, anstatt zu entscheiden, wie die zusätzlichen Tastenanschläge eingefügt werden sollen, die für die Eingabe als Matrixformel erforderlich sind. Es gibt eine Meta - Frage über das und die einzige Antwort , sagt , dass die STRG + ALT + ENTER - Befehl als 1 Tastendruck zählen würde. Wenn Sie dasselbe wie vim ( per Meta ) verwenden, wird dieser Tastenanschlag als 1 Byte gezählt. Normalerweise zähle ich die EINGABETASTE am Ende der Eingabe einer Formel in anderen Antworten nicht als 1 Byte.
Ingenieur Toast
2

Retina 0,8,2 , 55 Bytes

..
$*
(?<=^(1{1,12}))(?=(?(?<=^11$)\1{0,27}|\1{0,30})$)

Probieren Sie es online! Nimmt ein zweistelliges Jahr an; Fügen Sie 1 Byte hinzu, um 4-stellige Jahre zu unterstützen. Erläuterung: Die erste Stufe wird einfach zu Unary konvertiert. Die zweite Phase beginnt damit, dass 1 bis 12 Zeichen vor der Übereinstimmungsposition abgeglichen werden, die den Monat darstellen. Anschließend wird versucht, nach einer ganzen Anzahl von Wiederholungen dieses Monats zu suchen. Der Lookahead enthält jedoch eine Bedingung, die je nach Monat zwischen 27 oder 30 weiteren Wiederholungen auswählt. Die Anzahl der Match-Positionen ist dann das gewünschte Ergebnis.

Neil
quelle
2

R , 22 122 Bytes

x=scan();substr("122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012",x,x)

Probieren Sie es online!

Beschlossen, mit einer Nachschlagetabelle Ansatz zu gehen. Das Eingabejahr muss zweistellig sein.

Robert S.
quelle
1
Bei TIO können Sie auch auf die Schaltfläche "Link" klicken, um die Antwort automatisch für Sie zu formatieren. Vielen Dank an Dennis für die Einrichtung!
Giuseppe
Sie können die Initiale entfernen if, da die Eingabe wahlweise zweistellig oder vierstellig sein kann (Sie können also nur zweistellige Eingaben akzeptieren). . Aber es sieht aus wie der Code jeden Monat hält 31 Tage enthalten, so zum Beispiel 62 (für 2062) gibt 1 zurück , wo es 0 zurückgeben sollte
sundar - wieder einzusetzen Monica
2
Ich habe es falsch verstanden. Abgesehen davon bin ich mir ziemlich sicher, dass die Nachschlagetabelle in die Byteanzahl einbezogen werden muss.
ngm
@ngm Ich war mir auch nicht sicher, ob die Nachschlagetabelle aufgenommen werden musste, aber ich werde sie zur Sicherheit zur Byteanzahl hinzufügen.
Robert S.
Ich bin mir immer noch nicht sicher, welche Regeln es gibt!
ngm
2

C (gcc) 65 60 59 Bytes

d(a,t,e){for(t=0,e=13;e-->1;)t+=a%e<1&a/e<(e-2?32:29);a=t;}

Port der Java- Antwort von user202729 . Probieren Sie es hier online aus . Vielen Dank an Jonathan Frech für das Golfen mit 1 Byte.

OOBalance
quelle
a=0,m=13;for(;~> for(a=0,m=13;.
Jonathan Frech
@JonathanFrech Danke für den Hinweis, den ich bearbeitet habe.
OOBalance
2

J , 29 Bytes

1#.(,x*i."+29+3*2~:x=.i.13)=]

Probieren Sie es online!

Wie es funktioniert

1#.(,x*i."+29+3*2~:x=.i.13)=]    Input: year (2-digit, 1..99)
                   x=.i.13       array of 0..12; assign to x
                2~:              1 1 0 1 .. 1
              3*                 3 3 0 3 .. 3
           29+                   32 32 29 32 .. 32
       i."+                      for each item of above, generate a row 0 .. n
    ,x*                          each row times 0 .. 12 and flatten
                           =]    1 for each item == input, 0 otherwise
1#.                              sum

Versucht, unter 2 Mal Jelly Lösung zu bekommen :)

Randnotiz

Wenn jemand die 99-stelligen Daten wirklich fest codieren möchte, finden Sie hier einige Informationen:

Teilen Sie die 99-stellige Zahl in zweistellige Teile. Dann ist die erste Ziffer <4und die zweite <8, was bedeutet, dass fünf Bits zwei Zahlen codieren können. Dann können die gesamten Daten in 250 Bits oder 32 Bytes codiert werden.

Bubbler
quelle
2

Python 3 , 158 162 215 241 Bytes

Entfernt 4 Danke an Stephen für das Golfen der Bedingungen.

53 Danke Stephen für den Hinweis auf den Leerraum entfernt

26 dank des Links von caird entfernt

Ich bin ziemlich neu darin. Ich könnte mir nicht vorstellen, wie ich das machen könnte, ohne die Tage in einem Monat zu beschreiben.

r=range
def n(Y):
 a,b,c=31,30,0
 for x in r(12):
  for y in r([a,(28if Y%4else 29),a,b,a,b,a,a,b,a,b,a][x]):
   if(x+1)*(y+1)==int(str(Y)[2:]):c+=1
 return c

Probieren Sie es online!

akozi
quelle
5
Willkommen auf der Seite und schönen ersten Beitrag! Es gibt ein paar Möglichkeiten, wie Sie Golf spielen können, z. B. das Entfernen von Leerzeichen.
Lesen Sie die folgenden
@cairdcoinheringaahing Danke für den Rat, der Link war sehr nützlich!
Akozi
1
158 Bytes - einige davon entfernt, aber meistens hatten Sie eine große lange Reihe von Leerzeichen in Ihrer dritten Zeile, keine Ahnung, wie diese dahin gekommen sind
Stephen
@Stephen Danke :) Ich habe deine als zwei Änderungen hinzugefügt. Eine für den weißen Raum und die andere für das Golfen.
Akozi
(28if Y%4else 29)kann auf gekürzt werden [29,28][Y%4>0]. Auch die lange Liste kann auf gekürzt werden [a,...]+2*[a,b,a,b,a]. a,b,ckann zur Parameterliste hinzugefügt werden, um eine Zeile zu speichern. int(str(Y)[2:])kann auf gekürzt werden Y%100. Schließlich können Zählervariablen meistens auf lens Listenverständnis abgekürzt werden, wodurch nauch ein gemacht werden kann lambda. Das ergibt 118 .
Black Owl Kai
2

Forth (gforth) , 60 59 Bytes

: f 0 13 1 do over i /mod swap 32 i 2 = 3 * + 0 d< - loop ;

Probieren Sie es online!

Diese Version nutzt die Tatsache, dass es nicht mehr als einen passenden Tag pro Monat geben kann und dass das Jahr durch den Monat teilbar sein muss, damit es passt.

Erläuterung

Durchläuft die Monate, prüft, ob das Jahr durch den Monat teilbar ist und ob der Quotient <31 (28 für Februar) ist. Monate nach März können nicht mit Tagen größer als 25 übereinstimmen, daher können wir nur alle Monate (außer Februar) annehmen. haben 31 Tage für den Zweck des Puzzles.

Code-Erklärung

: f                   \ start new word definition
  0                   \ set up counter
  13 1 do             \ start a counted loop from 1 to 12
    over i /mod       \ get the quotient and remainder of dividing year by month
    swap              \ default order is remainder-quotient, but we want to swap them
    32 i 2= 3 * +     \ we want to compare to 32 days unless month is Feb
    0 d<=             \ treat the 4 numbers on the stack as 2 double-length numbers
                      \ and compare [1]
    -                 \ subtract result from counter (-1 is true in Forth)
  loop                \ end loop
;                     \ end word definition    

[1] - Forth hat das Konzept der doppelten Länge von Zahlen, die auf dem Stapel als zwei Zahlen einfacher Länge gespeichert werden (in der Form xy, wobei der Wert von double = y * 2^(l) + xwobei l die Größe in Bits eines einzelnen in der ist vierte Implementierung, mit der Sie arbeiten).

In diesem Fall habe ich Quotient und Rest mit 32 (oder 29) 0 verglichen. Wenn der Rest größer als 0 wäre (Jahr nicht teilbar durch Monat), wäre das erste Double automatisch größer als 32 (oder 29) 0 und das Ergebnis wäre falsch. Wenn der Rest 0 ist, wird eine regelmäßige Überprüfung des Quotienten <= 32 (oder 29) durchgeführt.

Viertens (gviertens) , 61 Bytes

: f 0 13 1 do i 2 = 3 * 32 + 1 do over i j * = - loop loop ; 

Probieren Sie es online!

Einige Bytes gespart, indem erkannt wurde, dass nur der Februar für die korrekte Anzahl von Tagen im Monat von Bedeutung ist

Erläuterung

Vier (mindestens vier) Vergleiche geben -1 für wahr und 0 für falsch zurück

0                     \ place 0 on top of the stack to use as a counter
13 1 do               \ begin the outer loop from 1 to 12
  i 2 = 3 *           \ if i is 2 place -3 on top of the stack, otherwise 0
  32 + 1 do           \ begin the inner loop from 1 to 31 (or 28)
    over              \ copy the year from stack position 2 and place it on top of the stack
    i j * = -         \ multiply month and day compare to year, subtract result from counter 
  loop                \ end the inner loop
loop                  \ end the outer loop
reffu
quelle
1

Java (JDK 10) , 79 72 70 Bytes

y->{int a=0,m=13;for(;m-->1;)a+=y%m<1&&y/m<(m==2?29:32)?1:0;return a;}

Probieren Sie es online!

user202729
quelle
@ Shaggy Danke! (Überbleibsel aus der vorherigen Version, in der ich alle dAys durchschleife)
user202729
Wenn Sie zu ändern &&, ist &es die gleiche Antwort wie die Java-Antwort von OlivierGrégoire, obwohl er 19 Minuten zuvor geantwortet hat.
Kevin Cruijssen
@ KevinCruijssen Zufälliger Zufall. Obwohl meine Version etwas schlechter ist (unnötige Verwendung von ternary).
user202729
1

JavaScript (Node.js) , 108 Byte

a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]

f=a=>'0122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012'[a]
o.innerText=[...Array(99)].map((_,x)=>(2001+x++)+` = `+f(x)).join`\n`
pre{column-count:5;width:480px;}
<pre id=o></pre>


quelle
Brute-Force-Lookup, schön!
BradC
Willkommen bei PPCG!
Shaggy
1

Python 3, 132 Bytes

Das ist wirklich ein ziemlich langes Programm, aber ich dachte, es könnte von Interesse sein.

Alle Werte liegen zwischen 0 und 7, also codiere ich jede Zahl mit 3 Bits in einer langen Binärzeichenfolge. Ich habe versucht, eine rohe Binärzeichenfolge in mein Python-Programm einzufügen, aber ich konnte sie nicht zum Laufen bringen, also habe ich mich für base64 in der Datei entschieden.

Ich habe die folgende Zeichenfolge als Nachschlagetabelle verwendet (Ende 7 wird zum Auffüllen verwendet): 01223242434261334151533172234161321260115040331061312042410060032130113060021220420051013051110140127

Das Programm nimmt diese Zeichenfolge und decodiert sie als Zahl. Anschließend extrahiert es das Ergebnis mithilfe der Bitverschiebung.

import base64
lambda n:int.from_bytes(base64.b64decode(b'pNRRxYtw01s9Jw4tFYE0QNkYsoRQgYBosEsYBFIRAUgsUkgwFQM='),'big')>>(6306-3*n)&7

66 Bytes + 37 Bytes Datei = 103 Bytes

Dies liest eine aufgerufene Binärdatei eund vermeidet die Verwendung von base64.

lambda n:int.from_bytes(open('e','rb').read(),'big')>>(6306-3*n)&7

Hier ist ein Hexdump der gelesenen Datei (ohne Auffüllung):

00000000  a4 d4 51 c5 8b 70 d3 5b  3d 27 0e 2d 15 81 34 40  |..Q..p.[='.-..4@|
00000010  d9 18 b2 84 50 81 80 68  b0 4b 18 04 52 11 01 48  |....P..h.K..R..H|
00000020  2c 52 48 30 0a                                    |,RH0.|
qwr
quelle
1

Oracle SQL, 115 Byte

select count(decode(sign(decode(l,2,29,32)-y/l),1,1))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

Wir können bemerken, dass es nicht wirklich wichtig ist, wie viele Tage im April (und in späteren Monaten), da 100/4 <28. Es ist auch nicht notwendig zu überprüfen, ob das Jahr ein Sprung ist oder nicht. Wir müssen nur spezifizieren, dass es im Februar 28 Tage gibt (nicht 29, da diese Validierung nur für 2058 ausgeführt wird, was kein Sprung ist), andernfalls kann es für jeden Monat nur 31 sein.

Andere Ansätze

Oracle SQL (12c Release 2 und höher), 151 Byte

select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

Oracle SQL (12c Release 2 und höher), 137 Byte

select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
(select level l from dual connect by level<=12)where mod(y,l)=0

Beide Lösung könnte 8 Byte kürzer gewesen , wenn wir ersetzen (select level l from dual connect by level<=12)mit xmltable('1to 12'columns l int path'.')aber Oracle wirft eine Ausnahme , weil der Bug (getestet auf Versionen 12.2.0.1.0, 18.3.0.0.0).

SQL> select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select count(to_date(y/l||'-'||l||'-1' default '' on conversion error,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected DATE got DATE


SQL> select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
  2  xmltable('1to 12'columns l int path'.')where mod(y,l)=0
  3  /
select sum(validate_conversion(y/l||'-'||l||'-1'as date,'dd-mm-y'))from t,
*
ERROR at line 1:
ORA-43909: invalid input data type

Der einzige Fall in beiden Lösungen, in dem das Jahr eine Rolle spielt, ist 2058. Dies ist kein Schaltjahr. Daher wurde zur Angabe des Schaltjahres das Literal '-1' verwendet.

Oracle SQL, 128 Byte

select count(d)from t,(select date'1-1-1'+level-1 d from dual connect by level<365)
where to_char(d(+),'mm')*to_char(d(+),'dd')=y

Oracle SQL, 126 Byte

select substr('122324243426133415153317223416132126011504033106131204241006003213011306002122042005101305111014012',y,1)from t

Aktualisieren

Oracle SQL, 110 Byte

select-sum(least(sign(y/l-decode(l,2,29,32)),0))from t,
xmltable('1to 12'columns l int path'.')where mod(y,l)=0

Oracle SQL, 108 Byte

select sum(decode(sign(decode(l,2,29,32)-y/l)*mod(y+1,l),1,1))from t,
xmltable('1to 12'columns l int path'.')

Spark SQL, 137 Byte

select count(cast(regexp_replace(concat_ws('-','2001',l,y/l),'.0$','')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t

Spark 2.3+ SQL, 126 Bytes

( replaceFunktion wird verfügbar)

select count(cast(replace(concat_ws('-','2001',l,y/l),'.0')as date))
from(select explode(array(1,2,3,4,5,6,7,8,9,10,11,12))l),t
Trockener Humor
quelle
1

PHP , 73 Bytes

Verwenden der Pipe-Eingabe und php -nR:

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argn==$m*$d++;echo$c;

Probieren Sie es online!

PHP , 76 Bytes

Verwenden der Befehlszeilen-Arg-Eingabe php dm.php 18:

for(;++$m<13;$d=1)while($d<25+($m-2?$m>4?:7:4))$c+=$argv[1]==$m*$d++;echo$c;

Probieren Sie es online!

Iterativer Ansatz. Da das einzige zu betrachtende Schaltjahr 2 * 29 = 58 ist und 2058 kein Schaltjahr ist, muss das Schaltjahr in den Feb-Tagen nicht berücksichtigt werden. Und da Wraparound kein Problem darstellt, wird ab April jeder Tag, der größer als 25 ist, 100 überschreiten. In den restlichen Monaten sind es nur noch 25 Tage.

Die Eingabe erfolgt zweistellig über die Kommandozeile (-10 Byte als Programm, danke an @Titus).

ODER:

PHP , 101 Bytes

$y=$argv[1];for($d=strtotime("$y-1");date(Y,$d)==$y;$d+=86400)eval(date("$\x+=j*n=='y';",$d));echo$x;

Probieren Sie es online!

Immer noch iterativ, aber mit den Zeitstempelfunktionen von PHP. Akzeptiert das Jahr als vierstellige Zahl. Vielen Dank an @Titus für den Vorschlag, strtotime()anstelle von mktime().

640 KB
quelle
Die erste Version schlägt für vierstellige Jahre fehl, die zweite für zweistellige. Aber nett zu denken. Versuchen Sie es $m<5?$m-2?31:28:25zum ersten und $d=strtotime("$y-1")zum zweiten
Titus
Ähm ... Warum hast du ydas in Anführungszeichen gesetzt?
Titus
@Titus, weil PHP7 jetzt Ziffern mit vorangegangener 0 als Oktal behandelt, sodass 08 und 09 eigentlich nicht gültig sind. Mit der Funktion date () können Sie nur ein zweistelliges, mit Nullen aufgefülltes Jahr erhalten.
4.
Schade! Na sicher.
Titus
1
@Titus, aktualisierte zweite Version unter Verwendung strtotime()von mktime()-7 Bytes anstelle von und erneut als Programm implementiert. Außerdem habe ich mir die Mehrheit der Einreichungen angesehen, einschließlich der Einreichungen mit den meisten Stimmen, die nur ein Jahr mit zwei oder vier Ziffern akzeptieren. Danke nochmal für die Vorschläge!
4.
0

PHP, 74-70 Bytes

while(++$m<13)for($d=$m<5?$m-2?31:28:25;$d;)$n+=$d--*$m==$argn;echo$n;

akzeptiert nur zweistellige Jahreszahlen.

Ich übernahm Gwaughs Überlegungen und spielte sie aus. Meine erste Annäherung war länger als seine (92 Bytes):

for($y=$argn%100;++$m<13;)for($d=$m-2?30+($m+$m/8)%2:29-($y%4>0);$d;)$n+=$d--*$m==$y;echo$n;

%100 Ermöglicht die Verwendung von 4-stelligen Jahreszahlen.


Laufen Sie als Pipe mit -nRoder probieren Sie sie online aus .

Titus
quelle
Sie können 4 Bytes sparen, indem Sie% 100 entfernen und nur zweistellige Eingaben vornehmen
640KB