Ne le dites à personne, mais j'ai piqué la machine à voyager dans le temps de mon oncle! Mon oncle est obsédé par les nombres premiers, cependant, et cela se voit dans la machine - il l'a programmé de sorte qu'il ne puisse aller qu'aux dates qui se résument à un nombre premier.
Donc ça ne peut pas aller 1947-08-15
parce que 1947 + 8 + 15 = 1970, ce qui n'est pas un nombre premier. Il peut aller à 1947-07-25
, car 1947 + 7 + 25 = 1979, ce qui est premier. Donc, si je veux revenir pour regarder les célébrations de l'indépendance de l'Inde, il semble que je devrai y aller quelques semaines plus tôt et attendre ces 20 jours.
J'ai d'autres dates auxquelles je veux aller, et je devrai également aller à une date antérieure (ou si j'ai de la chance, égale) à ma date cible, qui se résume à un nombre premier. Je suis impatient, cependant, et je ne veux pas trop attendre - je veux donc trouver la date que je peux utiliser la plus proche de ma date cible.
Pouvez-vous m'écrire un programme qui prend ma date cible et me donne la date que je devrais entrer dans la machine à remonter le temps - la date la plus proche avant ou égale à la date donnée dont les parties totalisent un nombre premier?
(Pour ce défi, nous utilisons le calendrier grégorien proleptique - ce qui signifie simplement que nous utilisons le calendrier grégorien actuel même pour les périodes où les gens utilisaient alors l'ancien calendrier julien.)
Contribution
- Un rendez-vous
- idéalement, n'importe quelle date de l'ère actuelle (AD); pratiquement, quel que soit le sous-ensemble de ce que votre langue peut naturellement gérer
- dans n'importe quel format lisible par l'homme - vous aimez
Sortie
- La date la plus proche de la date d'entrée, qui est inférieure ou égale à l'entrée et dont la date + mois + année se résume à un nombre premier.
- dans n'importe quel format lisible par l'homme - vous aimez
⁺: "lisible par l'homme" comme le jour, le mois et l'année, tous énoncés séparément, dans n'importe quel ordre
Cas de test
1947-08-15
=> 1947-07-25
1957-10-04
=> 1957-09-27
1776-07-04
=> 1776-07-04
999-12-12
=> 0999-12-10
2018-06-20
=> 2018-06-15
1999-01-02
=> 1998-12-29
1319-12-29
=> 1319-07-01
(Merci à @Shaggy, @PeterTaylor et @Arnauld pour leur aide avec la question.)
Fri Jul 25 02:46:39 CEST 1947
)Réponses:
Rouge , 87 octets
Essayez-le en ligne!
Plus lisible:
la source
JavaScript (Node.js) , 94 octets
Prend l'entrée comme 3 entiers dans la syntaxe de curry
(year)(month)(day)
. Renvoie une chaîne séparée par des tirets avec un trait d'union.Essayez-le en ligne!
Comment?
Nous convertissons d'abord la date au format JSON
yyyy-mm-ddT00:00:00.000Z
( ISO 8601 ), la divisons sur le'T'
, ne gardons que la partie gauche et ajoutons un trait d'union, ce qui donne-yyyy-mm-dd
.Cette expression s peut maintenant être
eval()
calculée pour obtenir l'opposé n de la somme de l' année + mois + jour .Nous utilisons la fonction d'assistance P () pour tester si -n est premier (auquel cas il renvoie 0 ). Si tel est le cas, nous renvoyons l' art . Sinon, nous réessayons avec la veille.
la source
Python 2 ,
130127 octetsL'entrée est
year, month, day
.-3 octets grâce à Kevin Cruijssen .
Essayez-le en ligne!
la source
Java 8,
144128 octetsEssayez-le en ligne.
java.time.LocalDate
la classe a été une amélioration par rapport à l'anciennejava.util.Date
, mais pourquoi ont-ils dû allonger ces noms (getMonthValue
etgetDayOfMonth
au lieu degetMonth
etgetDay
) ..>.>Explication:
la source
Rubis , 94 octets
Essayez-le en ligne!
Prend une seule entrée Date et renvoie une chaîne au format ISO 8601 (
YYYY-MM-DD
).Il utilise le module principal de Ruby. Si cela n'est pas autorisé ou désapprouvé, alors pour deux octets de plus, je présente cette abomination:
Rubis , 97 octets
Essayez-le en ligne!
Il utilise une vérification pour un nombre premier de cette réponse stackoverflow . Je n'ai aucune idée de comment ça marche, ça ressemble un peu à de la sorcellerie. Même entrée que ci-dessus et même sortie.
la source
d
et de l'espace aprèsif
, cependant, vous pouvez donc raser 3 octets de votre première réponse en les supprimant. Lien TIO?x*n !~ /^x?$|^(xx+?)\1+$/
= pour vérifier si n est premier, faites une chaîne de n 'x, vérifiez que ce n'est pas 0 ou 1 x (qui ne sont pas premiers), et qu'il ne correspond à aucun 2 x ou plus se répétant (l'appariement^(xxxxx)\1+$
signifierait que n est divisible par 5). Il abuse du retour en arrière du moteur regex pour faire notre boucle pour nous - c'est génial, c'est monstrueux, et le sacrifice animal a probablement été impliqué dans sa découverte.Rubis ,
5753 octetsEssayez-le en ligne!
Pas mon idée - volé de "l'abomination" par IMP1
Idée originale:
Rubis , 59 octets
Essayez-le en ligne!
la source
8e4
place fonctionnerait?R , 117 octets
Essayez-le en ligne!
la source
F #,
134133 octets-1 octet grâce à de Sundar .
Essayez-le en ligne!
Additionnez le jour, le mois et l'année et voyez si c'est premier. Si c'est le cas, retournez cette date. Sinon, décrémentez la date d'un jour et réessayez.
la source
-1.0
as-1.
, dans l'appel AddDays.PowerShell ,
10590 octetsEssayez-le en ligne!
Merci à Sundar pour -13 octets.
Prend l'entrée comme un
DateTime
2018-06-20
et l'enregistre$a
. Ensuite, nous sommes dans unefor
boucle. À chaque itération, nous prenons ou$a
-f
mattons commeyyyy+MM+dd
(c.-à-d. La date actuelle à laquelle nous sommes séparés par des+
signes) ajoutés avec|iex
(similaire àeval
), en multipliant les chaînes avec1
s pour former un nombre unaire et en utilisant une expression rationnelle de vérification principale pour déterminer si la date actuelle est prime ou non. S'il n'est pas premier, il.AddDays(-1)
faut reculer d'un jour et continuer la boucle. S'il est premier, nous sortons de la boucle et le plaçons$a
sur le pipeline avec une sortie implicite.La sortie résultante dépend de la culture. Sur TIO, qui utilise
en-us
, la sortie est au format longue date, qui ressemble àSaturday, July 1, 1319 12:00:00 AM
.la source
0001-01-01
dont la somme est 3). J'ai pris une fissure à ces changements ici .Bash ,
114108 octetsEssayez-le en ligne!
Mon tout premier golf bash. Honnêtement, mon premier vrai programme bash jamais ... test de primalité pris d' ici .
Cela peut parfois échouer en cas de changement de fuseau horaire, mais TIO utilise UTC, donc cela devrait fonctionner.
la source
@$
, donne un code de travail à 110 octets .C (gcc) , 167 octets
Essayez-le en ligne!
Fatigué
La fonction anti-prime-vérification. Étant donné que la première année valide à traiter est 0001-01-01, le nombre le plus bas dont nous devons nous préoccuper est 3, de sorte que les vérifications de cas spécial pour n == 2 ou n <2 sont supprimées. r est réglé sur une valeur vraie si n n'est pas un nombre premier. r est maintenu global, car sans avoir à le retourner, il économise deux octets (
i=n;
pour retourner vs,r
pour vérifier le global). i est mis à 1 par l'appelant de la fonction, pour enregistrer encore 2 octets.Nous prenons la date comme trois entiers séparés et commençons la boucle principale, qui continue jusqu'à ce que y + m + d soit premier. Ensuite, nous arrivons à la viande de la fonction:
Il peut sembler difficile d'utiliser m et y à la fois dans la vérification de l'année bissextile et comme index de la chaîne, lorsque l'ordre d'évaluation n'est pas spécifié. Heureusement, nous ne vérifions l'année bissextile que si m == 2, ce qui ne peut pas se produire en même temps que nous changeons m et y, car cela ne se produit que de janvier à décembre, de sorte que la vérification de l'année bissextile n'est jamais gênée par le ordre d'évaluation.
Enfin, le résultat est imprimé sur STDOUT:
la source
C # -
281239232 Charnon golfé:
Rendu le code moins efficace mais plus petit. La boucle principale montera maintenant à l'entier plutôt qu'à la racine carrée. Il traitera également tous les nombres pairs.
la source
public
. De plus, comme il ne semble pas interdit d'obtenir l'entrée de la date en tant que paramètre d'appel, vous pourriez avoirMain(string[]a)
et ensuiteDateTime.Parse(a[0])
MATL , 14 octets
Essayez-le en ligne!
Alternativement:
15 octets
Essayez-le en ligne!
la source