Les premiers mercredis


22

Les premiers mercredis

Votre tâche consiste à compter le nombre de mercredis qui tombent un premier jour du mois dans une année particulière. Par exemple, 7-13-16c'est un premier mercredi. Par souci de cohérence, utilisez le calendrier grégorien pour toutes les dates.

Contribution

L'entrée dans votre programme / fonction sera d'un an (par exemple 2016) et est flexible. L'année sera un nombre entier compris entre 1912 et 2233 inclus.

Sortie

La sortie est également flexible et devrait être le nombre de mercredis principaux (par exemple 18).

Notation

C'est le donc le code le plus court en octets gagne!

Cas de test

entrée -> sortie
--------------------
1912 -> 19
1914 -> 16
1984 -> 17
1996 -> 19
2063 -> 19
2150 -> 16
2199 - > 18
2233 -> 18

Réponses:


7

MATL , 38 36 34 octets

FT+"@llI$YO]q&:t8XO!s9\~)9#1$ZOZps

Essayez-le en ligne! Ou vérifiez tous les cas de test (prend quelques secondes).

Explication

FT+     % Input year implicitly. Add [0 1] element-wise. Gives array with input year
        % and next year
"       % For each of those two years
  @     %   Push year
  ll    %   Push 1 twice. This indicates January 1.
  I$YO  %   Convert year, month, day to serial date number
]       % End for each. We now have the serial date number for January 1 of the input
        % year and that of the following year
q       % Subtract 1 to the latter, to yield December 31 of the input year
&:      % Inclusive range between those two numbers. This gives an array of serial date
        % numbers for the whole input year
t       % Push another copy of that array
8XO     % Convert to date string with format 8. This gives weekday as "Mon", "Tue" etc.
        % The result is a 3-column 2D char array, where each row is a day
!s      % Transpose, sum of each column. 'Wed' gives 288 (sum of ASCII codes)
9\~     % 288 gives 0 modulo 9, and is the only weekday to do so. So we compute modulo 9
        % and negate. This gives true for Wednesdays, false for the rest
)       % Apply as logical index into the array of serial date numbers
9#1$ZO  % Array of month numbers corresponding to those serial date numbers
Zp      % Array that contains true for prime numbers, false for the rest
s       % Sum of array. Display implicitly

Je suis convaincu que MATL ne peut pas être battu sur des défis basés sur des dates. Nous devons créer DATL qui est encore optimisé pour gérer les défis basés sur la date.
Suever

@Suever Haha, joli nom
Luis Mendo

20

Python 2, 95 93 68 67 octets

lambda y:0x10ea2c8dbb06c5619/5**((y+((y-22)/99-y/2002)*16)%28)%5+16

Merci à @Josay d'avoir joué au golf sur 1 octet!

Testez-le sur Ideone .


3
Vous pouvez enregistrer 1 caractère avec 0x10ea2c8dbb06c5619au lieu de 19501370182350951961.
SylvainD

Je comprends l'idée de big_constant//5**long_expressionmais comment diable êtes-vous venu avec cette constante et cette expression? C'est fou: D
Sherlock9

2
La constante est une simple table de consultation utilisant des chiffres de base 5, mais convertie en base 10, de sorte que les chiffres sont extraits numériquement plutôt qu'en utilisant un index de chaîne. L'expression ressemble à un calendrier perpétuel pour moi. (Le problème serait trop facile s'il était limité aux années de 1901 à 2099, car les réponses se répètent tous les 28 ans dans cet intervalle, il s'agirait donc simplement de prendre l'année mod 28 et de la rechercher dans le tableau. )
Neil

13

Brain-Flak , 6588 , 2310 , 2308 , 2290 octets

Tout d'abord, je n'ai pas écrit près de 100% de ce programme, ce qui est probablement mis en évidence par l'énorme taille du programme. La plupart de ce code a été écrit par mon propre algorithme de golf Brain-Flak . Avec un script python supplémentaire, j'ai écrit pour l'inviter dans la bonne direction.

Essayez-le en ligne!

({}<(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()()())){}{}){})[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])()())[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])())()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())>[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}]){({}[()]<{}>)}{}({}<{{}}>)

Bien que ce programme soit assez long pour le golf de code, il est vraiment assez court pour Brain-Flak. Actuellement, le record du monde pour la division entière est supérieur à 1000 octets.

Explication

L'algorithme est assez simple. Parce qu'il y a un nombre limité d'années disponibles (321), il pousse simplement les réponses dans l'ordre inverse sous l'entrée et utilise un algorithme de recherche pour trouver la bonne réponse. Bien que le codage en dur de toutes les 321 possibilités puisse sembler plutôt inefficace avec une tâche aussi complexe que celle-ci et un langage aussi ésotérique que le brain-flak, cela pourrait très bien être la meilleure solution. (Je prévois de le découvrir dans la semaine à venir).

Étant donné que la plupart des 321 nombres ont environ 18 en moyenne et qu'ils diffèrent très peu d'une année à l'autre au lieu de pousser tous les nombres individuellement, je pousse la première année (2233) normalement, puis je double et modifie un peu la valeur pour chaque année après. De cette façon, au lieu de payer pour pousser ~ 18 pour les 321 années, je ne paie que pour pousser ~ 2 pour chaque année.

Une fois que toutes les réponses ont été poussées, il soustrait 1912 de l'entrée ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}])(cela peut être sous-optimal, j'ai réécrit l'optimiseur pour ignorer certaines valeurs que je pensais ne pas être optimales car les numéros de codage en dur sont un processus super-exponentiel et l'exécuter jusqu'à la fin peut avoir quelques jours).

Il soustrait ensuite un du premier élément et fait apparaître le deuxième élément jusqu'à ce que le résultat atteigne zéro, {({}[()]<{}>)} .

Il fait apparaître le zéro {}et tous les éléments sous l'élément supérieur ({}<{{}}>).


Quelle est l'approche générale des numéros de golf?
Neil

L'idée simple est que si vous avez un nombre avec des facteurs n et m, vous appuyez sur n m-1 fois, puis pop m-1 fois. La poussée initiale est évaluée comme n et chaque pop est évaluée comme un n supplémentaire, ce qui donne (1 + m-1) (n) qui est identique à mn. Cela se fait récursivement car pour pousser n, nous devons aussi jouer au golf n. Comme cette méthode ne fonctionne pas bien pour certains nombres, en particulier les nombres premiers, nous regardons également autour de nous pour voir s'il y a un nombre plus efficace à proximité et si c'est le cas, nous l'exprimons comme la somme de ce nombre et la différence.
Wheat Wizard

Je vois ... donc étant donné deux nombres net mqui ont des longueurs ket l, je suppose, n+mauraient une longueur k+l? Et alors n*m?
Neil

n*mserait k+4m-4ou l+4n-4. En effet, la multiplication est codée en dur. Nous poussons d'abord les n m-1temps. Pour ce faire, nous avons besoin de ksymboles pour exprimer net de 2m-2symboles pour exprimer les poussées (chaque poussée est composée de 2 symboles). Ensuite, nous passons des m-1heures, ce qui nous coûte un supplément 2m-2(les pop coûtent également 2 symboles). Cela totalise à k+4m-4. on peut aussi multiplier m*n(propriété commutative) pour obtenir l+4n-4. Le résultat sera le plus court des deux.
Wheat Wizard

1
Eh bien, si c'est vrai, alors +1coûte 2, *2coûte 4, *3coûte 8, *4coûte 12, ce qui est plus cher que *2*2, donc cela ne vaut pas la peine (sur les nombres inférieurs à 1000, je n'en ai trouvé que 10 qui n'ont pas utilisé *2: 1, 2, 3 , 4, 5, 9, 15, 27, 45, 135). Pour 1912, le mieux que j'ai pu faire était ((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2avec une longueur de 52.
Neil

7

Bash + utilitaires communs, 39

ncal $1|grep W|factor|egrep -c ': \S+$'

Prend l'année en entrée comme paramètre de ligne de commande. Produit généralement des messages comme celui-ci à STDERR - Je pense que c'est légal selon cette méta-réponse :

factor: We is not a valid positive integer

Si vous souhaitez supprimer explicitement la sortie STDERR, vous pouvez le faire à la place pour un score de 43 :

ncal $1|grep W|factor 2>-|egrep -c ': \S+$'

Notez que cela suppose un environnement local anglais ou C / POSIX. Cela ne fonctionne pas si bien en gd_GB.utf8, où tous les noms de jours sont abrégés Di.
Toby Speight

6

Octave, 86 octets

Ce n'est pas rapide, d'aucune façon. Mais ce n'est pas vraiment le but d'un golf de code, n'est-ce pas?

function r=p(y)r=0;for(i=698346:7:815953)d=datevec(i);r+=d(1)==y*isprime(d(3));end;end

Octave peut suivre les dates par "numéro de date" - nombre de jours écoulés où le 1er janvier 0 est le jour 1. Selon cette mesure, le 3 janvier 1912 (le premier mercredi de notre série) est le jour 698 346. Commencez par là, et parcourez tous les 7 jours (tous les mercredis) jusqu'à la fin de 2233, et ajoutez 1 si l'année est l'année cible ET le mois-jour est premier.


5

Python 2.7, 166 , 165 , 150 octets

from datetime import*
y=input()
d,c=date(y,1,1),0
while d.year==y:n=d.day;c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n));d+=timedelta(1)
print c

Il y a certainement place à amélioration ici. Je suis plutôt novice dans le golf en python. Cela utilise ledatetime module. Il parcourt tous les jours de l'année en ajoutant un à un accumulateur s'il correspond au critère. Il imprime ensuite le résultat. La plupart des tâches lourdes sont dans le module, le code peut donc être assez mince.

Un octet enregistré grâce à Morgan Thrapp et 15 octets enregistrés par Pietu1998 .


1
Vous pouvez enregistrer un octet en basculant n%x==0sur n%x<1.
Morgan Thrapp

2
Le -1n'est pas nécessaire car l range'index de fin est exclusif. De plus, vous pouvez convertir le filteren un générateur. [0for x in range(2,n)if n%x<1]
PurkkaKoodari

Vous pouvez utiliser any(...)ou all(...)au lieu de not filter(...).
kennytm

1
En combinant des comparaisons chaînées et allvous pouvez enregistrer tout un tas. c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
PurkkaKoodari

3

J, 44 octets

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)

Je viens de découvrir que J a intégré des manipulations de date.

Usage

Des commandes supplémentaires sont utilisées pour formater plusieurs entrées / sorties.

   f =: +/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)
   (,.f"0) 1912 1914 1984 1996 2063 2150 2199 2233
1912 19
1914 16
1984 17
1996 19
2063 19
2150 16
2199 18
2233 18

Explication

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)  Input: year
                                       i.12   The range [0, ..., 11]
                              >:              Increment each to get the months [1, ..., 12]
                                    p:        Get the first 12 primes [2, ..., 37]
                                ,"0/          Make a table between each month and prime
                           ,/                 Join the rows
                       ,.&                    Prepend the year to each
                                              The date format is YYYY MM DD
            3=weekday                         Check if each date occurs on Wednesday
    valdate*                                  and is a valid date
+/@                                           Count the number of true values and return

1

PowerShell v3 +, 99 95 octets

Approche par force brute -

param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count

Prend l'entrée $y, boucle de 1à 12, stocke temporairement le mois dans $m, puis boucle sur chaque prime de 2à 31. Pour chacun d'eux, nous construisons un Get-Datede ce jour particulier, puis sélectionnons uniquement ceux avec DayOfWeek -equal à 3(c.-à-d., Mercredi). Encapsule tout cela dans une parenthèse pour formuler un tableau, et prend .Countcelui - ci.


Alternativement, approche mathématique -

PowerShell v3 +, 105 octets

param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)

En fin de compte, c'est juste un cheveu plus long que l'approche par force brute, mais je l'inclus ici car cela peut être bénéfique pour les autres.

Prend à nouveau l'entrée $ycomme l'année. Cette fois, nous effectuons des opérations strictement mathématiques basées sur le premier jour de l'année. Nous calculons d'abord le jour de la semaine et le stockons $apour une utilisation ultérieure. Cela indexe dans le premier tableau, ce qui nous donne le nombre qui est généralement correct. Nous devons ajouter à cela un deuxième indice selon qu'il s'agit d'une année bissextile potentielle, qu'il s'agisse d'un dimanche, d'un mardi, d'un mercredi ou d'un jeudi et en fonction de l'année.

Ceci est basé sur l'observation suivante. La première colonne est le jour de la semaine du 1er janvier, la seconde est la sortie habituelle. À moins que l'année ne soit l'un des nombres intermédiaires, c'est plutôt le nombre en parens. La dernière colonne décrit le fonctionnement de l'indexation% 5.

Jan-1 -> #  ... Except if $y=       (then it's this number) | $y % 5 =
Sun   -> 16 ... 1928 1956 1984 etc. (17)                    |    3
Mon   -> 19
Tue   -> 18 ... 1924 1952 1980 etc. (20)                    |    4
Wed   -> 20 ... 1936 1964 1992 etc. (17)                    |    1
Thur  -> 16 ... 1920 1948 1976 etc. (17)                    |    0
Fri   -> 18
Sat   -> 19

Remarque: les deux supposent qu'il en-uss'agit du paramètre PowerShell actuel pour les informations de culture / date. Le formatage de la date et le DayOfWeeknombre peuvent devoir être ajustés en conséquence pour d'autres variantes de culture.


1

Ruby, 83 + 15 ( -rdate -rprimedrapeaux) = 98 octets

Essayez-le en ligne! (Les modules importés sont en ligne car idk si je peux utiliser des drapeaux dans repl.it)

->y{k=0;Prime.each(31){|d|k+=(1..12).count{|m|Date.new(y,m,d).wday==3 rescue p}};k}

1

JavaScript ES6, 187 182 181 179 octets

179 Échangé dans une boucle for pour la boucle while

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);for(;a()<=y;c())N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

181 Compacté le ternaire

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());c()}return N}

182 Combiné les deux boucles

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=a()==y?-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b()):0;c()}return N}

187

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<y)c();for(;a()==y;c())N+=-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

Je ne pense pas que cela compte car vous avez donné le premier mercredi initial pour l'année spécifique, dans cet exemple. Le défi du PO indique qu'il a besoin de l'année comme seul paramètre ... Un
gros

"L'entrée dans votre programme / fonction sera d'un an" - mais ce que vous signalez n'est pas cela. J'utilise le premier mercredi de 1912 comme graine parce que c'est ou est avant tous les deux mercredis dans la période donnée par l'OP, mais je pourrais tout aussi facilement utiliser n'importe quel mercredi arbitraire de 1911 ou avant pour le semer aussi. L'entrée dans ma fonction est toujours d'un an, et la fonction calcule toujours le nombre de mercredis principaux dans une année donnée dans le délai suggéré par l'OP, donc je ne sais pas comment cela ne correspond pas au défi.
Pandacoder

Ah, excuses ... Je ne savais pas au début que vous utilisiez ça comme composant d'amorçage ... Excellente idée ... Surtout si l'on considère que votre solution dépasse la mienne d'environ 30 ..;)
WallyWest

1
Merci. Je me suis inspiré de la mise en œuvre de Brain-Flak d'Eamon Olive, qui a en fait toutes les réponses pré-programmées, selon son explication.
Pandacoder

1

Lot, 248 octets

@set/ad=0,l=1,n=20
@for /l %%i in (1913,1,%1)do @set/ad=(d+l+1)%%7,l=!(%%i%%4)-!(%%i%%100)+!(%%i%%400)
@goto %l%%d%
:03
:06
@set/an-=1
:12
:13
:16
@set/an-=1
:01
:04
:14
@set/an-=1
:00
:05
:10
:15
@set/an-=1
:02
:11
@echo %n%

Explication: dest le jour de la semaine, avec 0pour lundi, qui est commodément le 1er janvier 1912. lest un indicateur indiquant si l'année est une année bissextile, 1pour 1912. Nous passons ensuite de 1913 à l'année d'entrée, en mettant à jour le jour de semaine et recalculer le drapeau de l'année bissextile au fur et à mesure. Enfin, nous utilisons le drapeau de l'année bissextile et le jour de la semaine pour indexer ce qui est en fait une déclaration de gros commutateur pour déterminer nle nombre de mercredis principaux. Mettre nà 20 et la décrémenter avec l'automne est cependant moins cher que d'utiliser la logique de contrôle de flux, mais le résultat est que si le 1er janvier d'une année non bissextile est jeudi ou dimanche, il y a 16 mercredis principaux et ainsi de suite pour les autres cas .


1

JavaScript ES6 206 203 199 197 197 195 183 182 179

Pas le plus court, mais le mieux que je puisse faire pour l'instant ... Suggestions de golf bienvenues ...

p=n=>--d-1?n%d&&p(n):1;v=Date;D=(x,y)=>new v(x.setDate(x.getDate()-y));W=a=>eval('for(Z=0,z=D(w=new v(a,11,31),(w.getDay()+4)%7);z>new v(a,0,1);)Z+=~~p(d=z.getDate()),z=D(z,7);Z')

Changements:

  1. modification du composant ternaire de: 3>=x?3-x:10-xà 6-(x+10)%7, enregistrement: 3 Modifications des emplacements de déclaration;
  2. fusionné x=w.getDay();z=D(w,6-(x+10)%7)avec z=D(w,6-(w.getDay()+10)%7), enregistrement: 4
  3. déplacé Z=0de la forboucle à la déclaration Date et poussé z=D(w,6-(x+10)%7)dans la forboucle pour ranger, sauvegarde: 2
  4. w=new Date(a,Z=0,1)déclaration décalée en forboucle, fusion avec la wdéclaration existante , sauvegarde: 2
  5. réécriture de la fonction de recherche principale en une fonction de test principale, économisant: 12
  6. changer +!!pour ~~réduire et toujours convertir p(d=1)de NaNà 0, permettant à la fonction Prime Test de continuer à fonctionner, économisant: 1
  7. Déplacement de toutes les fonctions supplémentaires de la fonction d'appel principale W, forboucle redéfinie - en sens inverse à partir du 31 décembre, écriture de l' Dateobjet en tant que variable distincte, puis réécriture de la forboucle dans l' evalappel; enregistrement 3.

@PandaCoder, je vous rattrape, mec!


1

R, 149 147 octets

y=function(x){s=strftime;b=ISOdate
a=seq(b(x,1,1),t=b(x,12,31),b='d')
length(a[s(a,'%u')==3&trimws(s(a,'%e'))%in%c(2,3,5,7,11,13,17,19,23,29,31)])}

Testez-le sur Ideone .


0

Groovy, 126

Groovy n'a pas de validation de nombre premier, a dû le construire aussi.

{n->p={x->x<3||(2..Math.sqrt(x)).every{x%it}};(new Date("1/1/$n")..new Date("12/31/$n")).collect{it[7]==4&&p(it[5])?it:0}-[0]}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.