Votre défi est d'écrire un programme qui, compte tenu d'une année, affiche le nombre de "vendredi 13".
Règles et détails:
- Vous pouvez saisir des informations via
STDIN
ou comme argument transmis à votre programme. - Vous devez afficher le résultat dans
STDOUT
. - Vous pouvez supposer que la saisie sera une année valide et ne date pas d'avant le calendrier grégorien (un comportement indéfini est autorisé dans ces cas).
- Les bibliothèques de calendrier / date sont autorisées.
Il s'agit d'un code-golf , donc le code le plus court (en octets) l'emporte.
Réponses:
APL (Dyalog APL) avec cal des dfns , 29 octets
Essayez-le en ligne!
⍳ 12
les entiers un à douze⎕ ,¨
prendre une entrée numérique et ajouter à chacun des douze nombres{
…}¨
Sur chacune des paires, appliquez la fonction…cal⍵
obtenir un calendrier pour cette année-mois2 ↓
déposer deux lignes (légende et jours)⍉
transposer (afin que nous puissions adresser des colonnes au lieu de lignes)¯5 ↑
prendre les cinq derniers (deux chiffres pour chacun des vendredis et samedis plus un espace)3 ↑
prendre les deux premiers (deux chiffres pour vendredi plus un espace)⍉
transposer (donc on obtient l'ordre de lecture),
effilochage⍎
exécuter comme expression APL (donne la liste des dates du vendredi)13 ∊
treize est-il membre de cette liste?+/
additionner les 12 booléensEn utilisant l'algorithme de @ Wrzlprmft , nous pouvons le faire sans bibliothèques pour 53 octets:
-∘0 1
soustraire zéro et un400 100 4 ∘.|
tableau des divisions restantes pour les deux années (dans l'ensemble) divisé par ces chiffres (vers le bas)0 ≠.=
"produit" intérieur avec 0, mais en utilisant ≠ et = au lieu de +. ×⊢ ,
ajouter l'année de l'argument non modifié2 3 ¯1 +.×
produit intérieur avec ces chiffres14 |
reste de division divisé par quatorze'21232211321211' ⌷⍨
indexer dans cette chaînela source
Mathematica
49 46 45 4442En tant que fonction pure : 42 caractères
Exemple
En tant que fonction nommée : 44 caractères
Exemples
la source
f=DayName@{#,m,6}~Table~{m,12}~Count~Friday&
Rubis,
49 48 4746Edit: Rasé un personnage en remontant une semaine, grâce à Jan, et un autre en passant de Time.new à Time.gm
Edit: Au détriment de l'obscurcir un peu plus, je peux arriver à 46 avec
la source
Time.gm(m,i).wday<1
. De plus, je ne sais pas pourquoi vous nommez la fonction.Powershell,
6863585250Merci Iszi pour l'astuce.
En utilisant le fait que si le 1er jour du mois est dimanche, le 13 sera vendredi.
J'ai aussi essayé:
mais ce n'est pas la même chose
$args
à l'intérieur du bloc de script.la source
$n
par$args
dans la boucle, et vous pouvez vous en passer$n=read-host;
complètement. Enregistre 8. Supprimez @, comme mentionné ci-dessus, et vous êtes à 54.$args
pour$input
, alimentant ainsi l'année depuis le pipeline, et le script s'exécutera mais il sort toujours 3.R
767257la source
"%a %d")=="Fri 13"
par"%w%d)=="513")
en utilisant dow comme nombre et en supprimant les espaces.seq
seul du mois soit en fait plus court ici!sum(format(as.Date(paste(scan(),1:12,13,sep="-")),"%w%d")=="513")
c'est seulement 65 caractères!<
cela contraindrait un caractère à un entier. Joli tour!Python2.7
9086Lundi 9 mai ne pas avoir la même sonnerie, mais fonctionne aussi bien.
Edit: Un an et demi pour remarquer que
date
c'est plus court quedatetime
:)la source
from datetime import*
f=lambda y:sum([date(y,m,13).weekday()==4 for m in range(1,13)])
.... Solution de même taille avec l'importation (86 octets), cependant.Ne pas utiliser de bibliothèques ou de fonctions de date intégrées:
Golfscript - 51
Python -
8279Essentiellement le même algorithme.
En utilisant cette astuce , cela peut être approfondi pour:
la source
C
301+287Pas la réponse la plus courte, mais n'utilise aucune bibliothèque.
la source
static char GetNumberOfFriday13s(int year) { const string perpetualCalendar = "1221212213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213112213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122213113213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122213122221122131122121221311321312222112213112212122131132131222211221311221212213113213122221122131"; return perpetualCalendar[year % 400];
. Ne fonctionnera pas pendant des années négatives.v[0]
devrait l'êtrev[1]
. Vous pouvez également jouer au golf un peu; envisagez d'utiliserstrcat
, de stocker des caractères pour imprimer directementa[]
et de soustraire des constantes numériques au lieu de constantes de caractères. :)main(int x,char**v){char p[400],*a[]={"1221212213113213","2131222","21122131","1222","112213113","122223113","122221122"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";*p=0;for(;*b;b++)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);}
(215 caractères)C (
151145137131 131130 car.)Je suis surpris de voir qu'il n'y a qu'une seule autre solution qui n'utilise pas d'outils de calendrier intégrés. Voici une approche mathématique (très obscure), également en C:
(Ce qui précède se compile dans GCC sans erreur)
Solution alternative: C (287-> 215 caractères)
J'ai plutôt apprécié la solution de Williham Totland et son utilisation de la compression. J'ai corrigé deux petits bugs et ajusté le code pour raccourcir sa longueur:
la source
PHP, 82
<?for($i=1,$c=0;$i<13;$i++)$c+=(date("N",mktime(0,0,0,$i,1,$argv[1]))==7);echo $c;
Basé sur
"Tout mois qui commence un dimanche contient un vendredi 13 et il y a au moins un vendredi 13 dans chaque année civile."
Depuis http://en.wikipedia.org/wiki/Friday_the_13th
la source
bash
4736Merci à @DigitalTrauma d'avoir enregistré 10 caractères en utilisant
seq
le démarrage par défaut de1
.(La version précédente utilisant
echo
présentait un bogue à cause de la ligne vide quand<(echo $1-{1..12}-6$'\n')
. Donc, cette fonction a bien fonctionné jusqu'à aujourd'hui est un vendredi.Voyons voir:
Est dépend des paramètres régionaux , si cela ne fonctionne pas, vous devrez peut-être
ou
Dans une fonction; +7 -> 43
Bonus: +78 -> 121
De là, si ma fonction devient:
ou
la source
C
. Mais il y a un bug ...%s\\n
seq
pour supprimer 8 caractères:date -f<(seq -f$1-%g-6 1 12)|grep -c ^F
seq -f$1-%g-6 12|date -f-|grep -c ^F
JavaScript, 70
la source
,b,c
de la déclaration de fonction (! Il est correct de fuite vars pour le golf), aussib
est jeté commeNumber
vous pouvez+=
le résultat du test au lieu de&&b++
:b+=/^F/.test(new Date(a,c,6))
. Cependant, vous pouvez enregistrer un autre octet en utilisant!new Date(a,c,1).getDay()
(cela fonctionne cargetDay
retourne 0 pour dimanche et si le 13 est un vendredi, le 1er sera un dimanche) au lieu de cetest
qui devrait vous faire économiser 7 octets!k
64 caractères
Lit à partir de stdin
la source
Lisp commun (CLISP), 149
la source
C #
1101019392C # Linq 88
Merci à Jeppe Stig Nielsen pour linq et suggestion de vérifier dimanche le 8.
Merci à Danko Durbić d'avoir suggéré à la
>
place de==
.la source
c+=(int)new DateTime(y,i,13).DayOfWeek==5?1:0;
, utilisez l'équivalentc+=new DateTime(y,i,8).DayOfWeek==0?1:0;
. L'astuce consiste à soustraire5
, car alors vous pouvez vous débarrasser de la distributionint
, et le nombre8
a également un chiffre de moins que le nombre13
. Dimanche huitième!int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}
. Bien sûr, en tant que lambda, c'esty=>Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0)
..DayOfWeek<1
.c#
réponse mais vous ne savez pas comment l'appliquerlinq
.DayOfWeek
avec un autre entier que0
-error CS0019: Operator '<' cannot be applied to operands of type 'System.DayOfWeek' and 'int'
.PHP, 55 octets
Courez avec
echo <year> | php -nR '<code>'
.Fondamentalement, la même chose qu'Oleg a essayé et Damir Kasipovic a fait, juste avec un meilleur golf:
chaque mois qui commence par un dimanche, a un vendredi 13.
Je passe donc en revue les mois et compte les premiers jours qui sont des dimanches.
panne
la source
K, 42
.
la source
Bash (
5247 caractères)la source
Rebol, 63
Exemple d'utilisation dans la console Rebol:
Une solution alternative qui recueille tous les vendredis 13 dans une année donnée est:
la source
Bash et Sed, 39 ans
ncal
imprime un calendrier pour l'année donnée avec les jours de la semaine en bas à gauche.sed
avec un/g
drapeau sous-marin tous les 13 avec des nouvelles lignesgrep -c
compte les lignes commençant par "2" (20 suit toujours 13)Merci à @DigitalTrauma d'avoir trouvé un bug dans mon ancienne version et d'avoir proposé une solution!
la source
ncal $1|sed /F/s/13/\\n/g|grep -c ^\ 2
Scala,
7668 caractèresEn 78 caractères:
def f(y:Int)=0 to 11 count(new java.util.GregorianCalendar(y,_,6).get(7)==6)
Rien d'extraordinaire, sauf pour utiliser des nombres magiques pour
DAY_OF_WEEK = 7
etFRIDAY = 6
.Version 68 caractères:
def f(y:Int)=0 to 11 count(new java.util.Date(y-1900,_,6).getDay==5)
Oui, Java a changé les valeurs des constantes du jour de la semaine entre les API.
la source
new java.util.GregorianCalendar
ça doit être si long :(Python 195/204
Fonctionne uniquement pour les années précédentes, car
monthdatescalendar
renvoie un calendrier pour l'année donnée jusqu'à présent . Je pense qu'il reste encore beaucoup de potentiel d'optimisation :).Une autre solution, fonctionne pour chaque date mais elle n'est pas plus petite:
la source
Perl 6,
5553Ancienne réponse:
la source
Python (v2) 120
la source
Perl + lib POSIX 55
Avec l'idée de ne pas chercher
13th
mais d'abord, et commesunday
c'est le cas,0
économisons 3 caractères! Merci @ Iszi et Danko Durbić!Pourrait calculer 2010 à 2017 (pour exemple) de cette façon:
(Ok, il n'y a pas de nouvelle ligne , mais cela n'a pas été demandé;)
Ancien poste: 63
En action:
la source
Dans Smalltalk (saveur Squeak / Pharo), implémentez cette méthode dans Integer ( 86 caractères)
Puis l' utiliser comme ceci:
2014countFriday13
.Bien sûr, nous pourrions utiliser un nom plus court, mais ce ne serait pas Smalltalk
la source
C ++ - Trop d'octets :(
J'ai essayé une solution qui n'utilise aucune bibliothèque de dates.
J'ai trouvé une solution plutôt sympa (si je puis dire moi-même). Malheureusement, je ne peux pas le raccourcir, ce qui me dérange vraiment car il me semble qu'il devrait y avoir une meilleure solution.
La solution repose sur cet algorithme qui ne fait que 44 octets en soi. Malheureusement, j'ai besoin de 100 autres octets pour bien envelopper ...
Sortie via le code retour (en C ++, utiliser
cout
ouprintf
ou quelque chose comme ça en nécessite un autre#include
, ce qui ferait exploser encore plus la solution).Pilote / programme de test:
Sortie du programme pilote:
la source
($m<3?$y--:$y-2)+3
au lieu ded=13,
,d+=m<3?y--:y-2,
etd+4
devrait fonctionner aussi bien et économise beaucoup.+5
au lieu de+3
et-5
devrait fonctionner aussi et économise 2 octets.for(m=0;++m<13;)
enregistre un octet. Passerm=0
à la tête de fonction enregistre un autre octet; et passer()%7||++f
à la tête de boucle en enregistre une autre. De 149 à 136 octets.Clojure,
207187 octets-20 octets en se débarrassant de la
import
, et des espaces blancs que j'ai manqués.À partir du 1er janvier de l'année donnée, il se boucle chaque jour. Si le jour est le vendredi 13, il incrémente le décompte. Il continue de boucler jusqu'à ce qu'il atteigne l'année prochaine.
la source
PHP, pas de code intégré, 81 octets
Courez avec
echo <year> | php -nR '<code>'
.panne
Les jours de la semaine se répètent tous les 400 ans.
Dans les résultats de 1600 à 1999 (par exemple), il y a une période de 28 longueurs avec seulement trois lacunes:
Après avoir ajusté l'année pour ces écarts, nous pouvons obtenir le résultat avec un hachage simple:
Pas court (95 octets) mais joli. Et nous pouvons jouer au golf
la source
for(;++$m<13;23*$m/9+($m<3?$y--:$y-2)+5+$y/4-$y/100+$y/400)%7?:$f++)$y=$argn;echo$f;
Japt
-x
, 10 octetsEssayez-le
la source