Quel est ton signe astrologique?

14

Écrivez un programme qui prend une date de naissance (mois et jour du mois) comme entrée et produit le signe, l'élément et la qualité correspondants du zodiaque occidental . Aux fins de ce défi, ceux-ci sont définis exactement comme dans le tableau de la page wikipedia liée:

Sign           Date Range                    Element    Quality

Aries          March 21 to April 19          Fire       Cardinal
Taurus         April 20 to May 20            Earth      Fixed
Gemini         May 21 to June 21             Air        Mutable
Cancer         June 22 to July 22            Water      Cardinal
Leo            July 23 to August 22          Fire       Fixed
Virgo          August 23 to September 22     Earth      Mutable
Libra          September 23 to October 23    Air        Cardinal
Scorpio        October 24 to November 20     Water      Fixed
Sagittarius    November 21 to December 22    Fire       Mutable
Capricorn      December 23 to January 20     Earth      Cardinal
Aquarius       January 21 to February 21     Air        Fixed
Pisces         February 22 to March 20       Water      Mutable

Règles

  • Le signe, l'élément et la qualité seront calculés à partir de la date d'entrée exactement selon le tableau wikipedia.
  • Je donne une certaine liberté sur le format de date d'entrée (voir la section Entrée ci-dessous). Vous devez indiquer clairement dans votre réponse le format que vous utilisez.
  • Si une date non valide est fournie (date non comparable ou mois ou jour du mois hors limites), le programme se termine avec le message Invalid date.
  • Le programme doit gérer correctement les années bissextiles. c'est-à-dire si le 29 février est l'entrée, alors la sortie doit être correctementPisces, Water, Mutable .
  • Les bibliothèques de date / API de votre langue sont autorisées, mais toutes les API qui calculent spécifiquement les signes du zodiaque sont interdites.
  • Des «failles» standard qui ne sont plus drôles
  • Il s'agit de , donc la réponse la plus courte en octets l'emporte.

Contribution

  • Le programme peut lire la date d'entrée à partir de STDIN, de la ligne de commande, des variables d'environnement ou de la méthode qui convient à la langue de votre choix.
  • Ce n'est pas principalement un exercice d'analyse de chaîne de données, de sorte que la chaîne d'entrée peut être fournie dans le format que vous choisissez, tant qu'elle ne comprend que des composants de mois et de jour et pas d'autres valeurs (telles que l'année ou l'heure) . Par exemple, Jul 24ou 24th of Julyou 7/24ou 24/07ou n'importe quel format est pratique. Si une entrée ne correspondant pas à votre choix de format d'entrée est entrée, l' Invalid dateerreur doit être levée.

Production

  • Le programme sortira sur STDOUT, une boîte de dialogue ou toute autre méthode d'affichage convenant à la langue de votre choix.
  • Le format de sortie sera le signe, l'élément et la qualité séparés par une virgule et un espace: Sign, Element, Quality

Exemples

Input                 Output
1/1                   Capricorn, Earth, Cardinal
2/29                  Pisces, Water, Mutable
7/24                  Leo, Fire, Fixed
13/1                  Invalid date
2/31                  Invalid date
-1/-1                 Invalid date
1st of Golfember      Invalid date
Traumatisme numérique
la source
La détection / l'avertissement d'une date non valide est-il nécessaire? Dans l'affirmative, pouvons-nous supposer que les nombres non valides saisis par l'utilisateur seront supérieurs à zéro? (Je suppose que la plupart des gens utiliseront un format de date numérique.)
Level River St
1
@steveverrill Je pense que j'ai précisé cela dans le troisième élément des règles, mais j'ai édité la section Entrée pour clarifier. Entrée valide TLDR => sortie valide; entrée invalide => message d'erreur; aucun "comportement indéfini" n'est autorisé pour une entrée donnée.
Digital Trauma
une date complète est-elle autorisée? jours, mois et années?
Teun Pronk
@TeunPronk Non, juste le mois et le jour du mois. J'ai clarifié la règle d'entrée.
Digital Trauma
Est le jour de l'année (par exemple Jan 21 -> 21 . . Feb 5 -> 36) un format d'entrée valide?
Mego

Réponses:

8

JavaScript, 285 octets

(Ma première réponse ici après avoir rôdé ici pendant un certain temps)

d=prompt(m=prompt(e='MutableCardinalFixedAirWaterFireEarthCapricornAquariusPiscesAriesTaurusGeminiCancerLeoVirgoLibraScorpioSagittarius'.match(/[A-Z][a-z]+/g)));alert(m>0&m<13&d>0&d<29-~'202121221212'[--m]?e[n=7+m%12+(d>18-~'121012333413'[m])]+', '+e[n%4+3]+', '+e[n%3]:'Invalid date')

Le premier prompt()est le mois sous forme numérique et le second prompt()est le jour du mois (Ignorez le texte de l'invite). Les zéros non significatifs sont facultatifs pour les deux. La sortie est affichée avecalert() . (Merci à bitpwner, Snack, edc65 et core1024 pour avoir aidé à raccourcir le code.)

Essayez-le ci-dessus à l'aide d'extraits de pile ou à http://jsfiddle.net/8vq89/5/ .

Code avec espace et commentaires pour expliquer les parties déroutantes ajoutées:

var m = prompt(), d = prompt(),
e = 'MutableCardinalFixedAirWaterFireEarthCapricornAquariusPiscesAries\
TaurusGeminiCancerLeoVirgoLibraScorpioSagittarius'.match(/[A-Z][a-z]+/g);
alert(m > 0 && m < 13 && d > 0
      & d < 29 - ~'202121221212'[--m] /* ~ is bitwise NOT, which yields -(x + 1). It also
                                         converts a string to a number. Subtracting that
                                         number from 29 gives the number of days in the
                                         month given. */
      ? e[n = 7 + // 7 is added to skip over the 7 qualities and elements in array e.
      m % 12 // The modulus allows dates near the end of December to wrap around to January.
      + (d > 18 - ~'121012333413'[m])] + ', ' +
      e[n % 4 + 3] + /* Qualities and elements follow a pattern, so the modulus determines
                        which one it is. 3 is added to skip over the 3 qualities. */
      ', ' + e[n % 3] : 'Invalid date')
NinjaBearMonkey
la source
1
Pour 'Cardinal0Fixed0Mutable'.split(0)et 'Earth0Air0Water0Fire'.split(0), ['Cardinal','Fixed','Mutable']et ['Earth','Air','Water','Fire']est un peu plus court.
Snack
J'ai eu une solution, mais trop semblable: z='Air9Water9Fire9Earth9Fixed9Mutable9Cardinal9Aquarius9Pisces9Aries9Taurus9Gemini9Cancer9Leo9Virgo9Libra9Scorpio9Sagittarius9Capricorn'.split(9); [m,d]=prompt().split(/\D/); alert([m-->0&m<12&d>0&d<(32-'020101001010'[m])?z[(m+=(18-~'121012333413'[m]<d)+11)%12+7]+', '+z[m%4]+', '+z[m%3+4]:'Invalid date']). Jetez un œil au single split
edc65
@ edc65 J'obtiens une Invalid left-hand side in assignmenterreur lorsque j'essaye de l'exécuter, probablement à
cause de
l'affectation de groupe est Ecmascript 6, fonctionne uniquement dans Firefox. p=prompt().split(/\D/),m=p[0],d=p[1]devrait fonctionner (mais donc plus longtemps)
edc65
3
Vous pouvez le raccourcir encore plus si vous utilisez '...ScorpioSagittarius'.match(/[A-Z][a-z]+/g)au lieu de'...Scorpio0Sagittarius'.split(0)
core1024
3

C 353 352

Éditer bug et faute de frappe corrigés, 1 caractère de plus

Avant de demander: oui, même sans #include est valide et fonctionne standard C.
Format d'entrée: deux chiffres, le premier mois, puis le jour.

char*s[]={"Air","Water","Fire","Earth","Fixed","Mutable","Cardinal","Aquarius","Pisces","Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn"};
main(m,d){
  scanf("%d%d",&m,&d);
  m>0&m<13&d>0&d<(32-(4460832>>m>>m&3))
  ?m+=10+(" 121012333413"[m]-29<d),printf("%s, %s, %s\n",s[m%12+7],s[m%4],s[m%3+4])
  :puts("Invalid date");
}

Tester

char*s[]={"Air","Water","Fire","Earth","Fixed","Mutable","Cardinal","Aquarius","Pisces","Aries","Taurus","Gemini","Cancer","Leo","Virgo","Libra","Scorpio","Sagittarius","Capricorn"};
char *test(char *o, int m, int d)
{
  char *result=o;
  m>0&m<13&d>0&d<(32-(4460832>>m>>m&3))
  ?m+=10+(" 121012333413"[m]-29<d),sprintf(o, "%s, %s, %s\n",s[m%12+7],s[m%4],s[m%3+4])
  :(result = 0);
  return result;
}

int main()
{
  char buf[100];
  int m,d;
  for (m=0;m<14;m++)
    for(d=0;d<40;d++)
      if (test(buf, m,d)) printf("%d %d %s", m, d, buf);
  return 0;
}
edc65
la source
Bon, sauf pour la faute de frappe de Ivalid;-)
Digital Trauma
@DigitalTrauma Pas si bon, peut-être qu'il a un bug sur le début de signe discriminant (21,20,24 etc.) Je le révise tout à l'heure. Restez à l'écoute
edc65
2

Perl 287 (286 + 1 pour le -pdrapeau)

/\//;$_=32-(26830452>>$`*2&3)<$'|$'<1|$`<1|$`>12?'Invalid date
':qw(Aquarius01 Pisces23 Aries45 Taurus61 Gemini03 Cancer25 Leo41
Virgo63 Libra05 Scorpio21 Sagittarius43
Capricorn65)[$`-1-($'<20+(219503166088>>$`*3&7))].$/;s/\d/', '.qw(Air
Fixed Water Mutable Fire Cardinal Earth)[$&]/eg

L'entrée est de STDIN et la sortie va à STDOUT. Voici les tests d'OP:

1/1
Capricorn, Earth, Cardinal
2/29
Pisces, Water, Mutable
7/24
Leo, Fire, Fixed
13/1
Invalid date
2/31
Invalid date
-1/-1
Invalid date
1st of Golfember
Invalid date
core1024
la source
1

Python, 447 387 caractères

import sys
try:S=sys.argv[1];a,b=int(S[:2])-1,int(S[3:])
except:a=b=0
print['Invalid date',', '.join((s.split()*5)[a+(b>[20,21,20,19,20,21,22,22,22,23,20,22][a%12])]for s in"Capricorn Aquarius Pisces Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Capricorn|Earth Air Water Fire|Cardinal Fixed Mutable".split("|"))][-1<a<12and 0<b<[32,30,32,31,32,31,32,32,31,32,31,32][a]]

Prend l'entrée en MM / DD, doit toujours être à deux chiffres.

$ python zods.py 01/01
Capricorn, Earth, Cardinal
$ python zods.py 02/29
Pisces, Water, Mutable
$ python zods.py 07/24
Leo, Fire, Fixed
$ python zods.py 13/01
Invalid date
$ python zods.py 02/31
Invalid date
$ python zods.py -1/-1
Invalid date
$ python zods.py First of golfember
Invalid date
$ python zods.py
Invalid date
Claudiu
la source
1
Vous pouvez les essayer: [20,21,20,19,20,21,22,22,22,23,20,22][a%12]-> 19+int('121012333413'[a%12]) et [32,30,32,31,32,31,32,32,31,32,31,32][a]->30+int('202121221212'[a])
Vectorisé le
1

Javascript, 403 396 octets

M=prompt(),D=+prompt(),i=[52,85,117,147,180,213,246,278,310,343,372,406,415];if([0,0,-2,0,1,0,1,0,0,1,0,1,0][M]<D-31||M<1||D<1||M>12)alert("Invalid date");else for(x in i)if(M*32+D<=i[x]){alert("Capricorn0Aquarius0Pisces0Aries0Taurus0Gemini0Cancer0Leo0Virgo0Libra0Scorpio0Sagittarius0Capricorn".split(0)[x]+", "+["Earth","Air","Water","Fire"][x%4]+", "+["Cardinal","Fixed","Mutable"][x%3]);break}

Une autre approche. Je pense que je peux plus jouer au golf, mais plus tard.

Entrez le mois à la première invite, la date à la deuxième invite.

Casse-croûte
la source
1

PHP - 294 octets (sans balises php *)

* Comme l'a fait l'autre entrée php

Entrée: Month Daysous forme d'entiers, le zéro devant n'est pas requis.

Ex: php starsign.php <<< "2 29"pour le 29 février.

Golfé (ne copiez pas cela directement, voir ci-dessous):

<?@eval(gzinflate('=Œ1Â0…ÿŠC!Ë
¦q+JQ—
BEq¸¶¡Ô¤^ðç{¤"ï>/Ãò®`³GOBqú7v¥±MP#äpúµ;$:Å€Ý$“g¦Þ³ƒê‘).p¦¥·TL’Œ,ÝѾȑ¬]oëáJ<zh¨c„V3yhq¤VË_ü(²®TZË¥ØêܳÓF_'));die(fscanf(STDIN,'%u%u',$m,$d)/2&$m<13&&$m*$d&&$d<33-$b[$m]?$a[7+$m-=$d<20+$b[$m+9]].$a[$m%4].$a[$m%3+4]:'Invalid date');

Hexdump du fichier php:

3f3c 6540 6176 286c 7a67 6e69 6c66 7461
2865 3d27 318c c20b 1030 ff85 438a cb21
a60d 2b71 4a1d 9751 420a 0745 b871 a1b6
d41e 5ea4 f013 7be7 22a4 ef07 1e3e 2f8f
f2c3 60ae 47b3 4f0e 4205 7115 37fa 760c
03a5 4db1 2350 e40f fa70 1fb5 243b c53a
dd80 9324 671a dea6 83b3 1dea 2991 702e
a5a6 0bb7 4c54 1792 2c8c d1dd c8be ac91
6f5d 1a19 e1eb 3c4a 687a 63a8 5684 3304
6879 a471 5610 5fcb 28fc aeb2 5a54 9d1b
a5cb ead8 18dc d3b3 1546 275f 2929 643b
6569 6628 6373 6e61 2866 5453 4944 2c4e
2527 2575 2775 242c 2c6d 6424 2f29 2632
6d24 313c 2633 2426 2a6d 6424 2626 6424
333c 2d33 6224 245b 5d6d 243f 5b61 2b37
6d24 3d2d 6424 323c 2b30 6224 245b 2b6d
5d39 2e5d 6124 245b 256d 5d34 242e 5b61
6d24 3325 342b 3a5d 4927 766e 6c61 6469
6420 7461 2765 3b29

Pour générer un fichier golfé, exécutez le script php suivant (génère vers starsign.php):

<?php
$a=<<<'NOW'
$a=[', Earth',', Air',', Water',', Fire',', Cardinal',', Fixed',', Mutable',Capricorn,Aquarius,Pisces,Aries,Taurus,Gemini,Cancer,Leo,Virgo,Libra,Scorpio,Sagittarius,Capricorn];$b='1131212112121012333413';
NOW;
$p = '<?@eval(gzinflate(\'';
$s = <<<'NOW'
'));die(fscanf(STDIN,'%u%u',$m,$d)/2&$m<13&&$m*$d&&$d<33-$b[$m]?$a[7+$m-=$d<20+$b[$m+9]].$a[$m%4].$a[$m%3+4]:'Invalid date');
NOW;
file_put_contents('starsign.php',$p . gzdeflate($a) . $s);

Version complètement non golfée:

<?php
$a=[', Earth',', Air',', Water',', Fire',', Cardinal',', Fixed',', Mutable',Capricorn,Aquarius,Pisces,Aries,Taurus,Gemini,Cancer,Leo,Virgo,Libra,Scorpio,Sagittarius,Capricorn];$b='1131212112121012333413';
if(fscanf(STDIN, '%u%u', $m, $d) == 2
 and $m < 13
 and $m 
 and $d
 and $d < 33-$b[$m]){
    if($d < 20 + $b[$m+9])
        --$m;
    die($a[7+$m] . $a[$m%4] . $a[$m%3+4]);
}else die('Invalid date');
es1024
la source
Enfin compris que je dois modifier /etc/php5/cli/php.ini et régler short_open_tag = Onpour que cela fonctionne. Fonctionne pour cette réponse, mais l'autre réponse PHP contient toujours des erreurs. +1 pour celui-ci.
Digital Trauma
1

Python 3-332 octets

s="Capricorn Aquarius Pisces Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Earth Air Water Fire Cardinal Fixed Mutable".split()
import sys
try:m,d=map(int,sys.argv[1:]);13>m>0<d<b" 313232332323"[m]-19or E
except:x="Invalid date"
else:i=m-1+(d>b" 121012333413"[m]-29);x=s[i%12]+", "+s[-7+i%4]+", "+s[-3+i%3]
print(x)
  • Prend l'entrée comme arguments séparés (c.-à-d. 1 1)

  • Un split pour toutes les cordes

  • L'indexation des octets dans py3 donne l'ordre

  • or Eest un moyen peu coûteux de générer une exception ( NameError)

  • Existe-t-il un moyen moins coûteux de concaténer les chaînes? +et les littéraux se sont avérés être plus petits que join.

  • Il n'y a aucune bonne raison pour qu'une recherche d'octets commence par 1 et l'autre par 0, j'ai juste oublié le 29 février et j'ai changé 0-> 1 au lieu de refaire le tout.

Jason S
la source
0

PHP 548 524 502 419 (sans balises php)

Nécessite PHP> = 5.4.0

Entrée: Day Month(valeur numérique commençant à 1) par exemple 2 3pour le 2 mars.

<?
$x='Invalid date';
@list($d,$m)=split(' ',fgets(STDIN));
if(@$m<1||$m>12||@$d<1)die($x);
$z=['Aquarius','Pisces','Aries','Taurus','Gemini','Cancer','Leo','Virgo','Libra','Scorpio','Sagittarius','Capricorn','Air','Water','Fire','Earth','Fixed','Mutable','Cardinal','121012333413202121221212'];
$m=$m+0;$d<$z[19][--$m]+20&&$m--;$m<0&&$m=11;$d>$z[19][$m+12]+29&&die($x);
echo$z[$m+0],", {$z[$m%4+12]}, {$z[$m%3+16]}";

EDIT: l' A non well formed numeric valueavis est provoqué par l'exécution d'un pré-incrément sur la chaîne $m. Indépendamment de l'avis, la sortie suivante doit toujours être correcte. Cet avis varie selon la version de PHP. Pour résoudre ce problème, une simple chaîne de conversion en entier doit être placée avant l'avant-dernière ligne. J'ai mis à jour le code avec les conversions.

Exemple d'entrée / sortie (sous Windows):

// March 2nd
Input > echo 2 3 | php star.php
Output > Pisces, Water, Mutable

// Feb. 30th
Input > echo 30 2 | php star.php
Output > Invalid date

// June 30th
Input > echo 30 6 | php star.php
Output > Cancer, Water, Cardinal
noahnu
la source
OK, je suis un mannequin php. Comment gérez-vous cela? J'ai essayé echo 2 3 | php -f zod.php, mais cela fait juste écho au script lui-même sur STDOUT
Digital Trauma
1
@DigitalTrauma Je pense que vous devez activer les balises courtes dans votre interprète, sinon utilisez <?phpplutôt <?.
core1024
J'ai essayé ça, mais maintenant je comprends PHP Notice: A non well formed numeric value encountered in /home/ubuntu/zod.php on line 6. J'utilise php 5.5.9 sur Ubuntu 14.04
Digital Trauma
Code fixe. Voir modifier.
noahnu