¿Cual es tu signo del zodiaco?

14

Escriba un programa que tome una fecha de nacimiento (mes y día del mes) como entrada y haga salir el signo, elemento y calidad correspondientes del zodiaco occidental . Para los propósitos de este desafío, estos se definen exactamente como en la tabla en la página de Wikipedia vinculada:

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

Reglas

  • El signo, el elemento y la calidad se calcularán a partir de la fecha de entrada exactamente de acuerdo con la tabla de wikipedia.
  • Estoy dando algo de libertad sobre el formato de fecha de entrada (ver la sección de Entrada a continuación). Debe indicar claramente en su respuesta qué formato está utilizando.
  • Si se proporciona una fecha no válida (fecha no analizable, o mes o día del mes fuera de rango), el programa se cerrará con el mensaje Invalid date.
  • El programa debe manejar correctamente los años bisiestos. es decir, si el 29 de febrero es la entrada, la salida debe ser correctamente Pisces, Water, Mutable.
  • Las bibliotecas de fechas / API de su idioma están permitidas, pero cualquier API que calcule específicamente los signos del zodiaco está prohibida.
  • "Lagunas" estándar que ya no son divertidas
  • Este es el , por lo que gana la respuesta más corta en bytes.

Entrada

  • El programa puede leer la fecha de entrada de STDIN, línea de comandos, variables de entorno o cualquier método que sea conveniente para el idioma que elija.
  • Este no es principalmente un ejercicio de análisis de fechas, por lo que la cadena de entrada puede proporcionarse en el formato que elija, siempre que consista solo en componentes de mes y día del mes y no en otros valores (como año u hora) . Por ejemplo, Jul 24o 24th of Julyo 7/24o 24/07o cualquier formato que sea conveniente. Si se ingresa una entrada que no coincide con su elección de formato de entrada, se Invalid datedebe arrojar el error.

Salida

  • El programa saldrá a STDOUT, cuadro de diálogo o cualquier método de visualización que sea conveniente para el idioma que elija.
  • El formato de salida será el signo, el elemento y la calidad separados por una coma y un espacio: Sign, Element, Quality

Ejemplos

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
Trauma digital
fuente
¿Se requiere la detección / advertencia de una fecha no válida? Si es así, ¿podemos suponer que los números no válidos ingresados ​​por el usuario serán mayores que cero? (Supongo que la mayoría de la gente usará un formato de fecha numérico.)
Level River St
1
@steveverrill Creo que lo dejé claro en el tercer elemento de las reglas, pero he editado la sección Entrada para aclarar. TLDR entrada válida => salida válida; entrada inválida => mensaje de error; no se permite "comportamiento indefinido" para ninguna entrada dada.
Trauma digital
¿Se permite una fecha completa? días, meses y años?
Teun Pronk
@TeunPronk No, solo mes y día del mes. He aclarado la regla de entrada.
Trauma digital
¿Es el día del año (p Jan 21 -> 21. Ej . Feb 5 -> 36) Un formato de entrada válido?
Mego

Respuestas:

8

JavaScript, 285 bytes

(Mi primera respuesta aquí después de estar al acecho aquí por un tiempo)

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')

El primero prompt()es el mes en forma numérica y el segundo prompt()es el día del mes (ignore el texto de la solicitud). Los ceros iniciales son opcionales para ambos. La salida se muestra con alert(). (Gracias a bitpwner, Snack, edc65 y core1024 por ayudar a acortar el código).

Pruébelo más arriba usando fragmentos de pila o en http://jsfiddle.net/8vq89/5/ .

Código con espacios en blanco y comentarios para explicar las partes confusas agregadas:

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')
NinjaOsoMono
fuente
1
Para 'Cardinal0Fixed0Mutable'.split(0)y 'Earth0Air0Water0Fire'.split(0), ['Cardinal','Fixed','Mutable']y ['Earth','Air','Water','Fire']es un poco más corto.
Merienda
Tenía una solución, pero demasiado similar: 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']). Eche un vistazo a la división individual
edc65
@ edc65 Me sale un Invalid left-hand side in assignmenterror cuando intento ejecutar eso, probablemente tenga que ver con el aviso
NinjaBearMonkey
la asignación de grupo es Ecmascript 6, solo funciona en firefox. p=prompt().split(/\D/),m=p[0],d=p[1]debería funcionar (pero mucho más)
edc65
3
Puede hacerlo aún más corto si lo usa en '...ScorpioSagittarius'.match(/[A-Z][a-z]+/g)lugar de'...Scorpio0Sagittarius'.split(0)
core1024
3

C 353 352

Editar error y error tipográfico, 1 char más

Antes de preguntar: sí, incluso sin #include es válido y funciona el estándar C.
Formato de entrada: dos números, primer mes, luego día.

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");
}

Prueba

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
fuente
Bien, excepto por el error tipográfico de Ivalid;-)
Digital Trauma
@DigitalTrauma No tan bueno, tal vez tiene un error al discriminar el inicio de señal (21,20,24, etc.). Lo estoy revisando justo ahora.
Estén
2

Perl 287 (286 + 1 para la -pbandera)

/\//;$_=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

La entrada es de STDIN y la salida va a STDOUT. Aquí están las pruebas de 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
fuente
1

Python, 447 387 caracteres

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]]

Toma la entrada como MM / DD, siempre debe tener dos dígitos.

$ 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
fuente
1
Puede probar estos: [20,21,20,19,20,21,22,22,22,23,20,22][a%12]-> 19+int('121012333413'[a%12]) y [32,30,32,31,32,31,32,32,31,32,31,32][a]->30+int('202121221212'[a])
Vectorizado
1

Javascript, 403 396 bytes

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}

Otro enfoque. Creo que puedo jugar más al golf, pero más tarde.

Ingrese el mes en el primer aviso, la fecha en el segundo aviso.

Bocadillo
fuente
1

PHP - 294 bytes (sin etiquetas php *)

* Como lo hizo la otra entrada de php

Entrada: Month Daycomo enteros, no se requiere cero inicial.

Ej: php starsign.php <<< "2 29"para el 29 de febrero.

Golfizado (no copie esto directamente, ver más abajo):

<?@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 del archivo 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

Para generar el archivo golfed, ejecute el siguiente script php (genera a 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);

Versión completamente sin golf:

<?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
fuente
Finalmente descubrí que necesito editar /etc/php5/cli/php.ini y configurarlo short_open_tag = Onpara que funcione. Funciona para esta respuesta, pero la otra respuesta de PHP todavía tiene errores. +1 para este.
Trauma digital
1

Python 3 - 332 bytes

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)
  • Toma datos como argumentos separados (es decir 1 1)

  • Una división para todas las cuerdas

  • La indexación de bytes en py3 da el ord

  • or Ees una forma barata de generar una excepción ( NameError)

  • ¿Hay alguna forma más barata de concatenar las cadenas? +y los literales resultaron ser más pequeños que join.

  • No hay una buena razón para que una búsqueda de bytes comience con 1 y la otra con 0, simplemente olvidé el 29 de febrero y cambié 0-> 1 en lugar de rehacer todo.

Jason S
fuente
0

PHP 548 524 502 419 (sin etiquetas php)

Requiere PHP> = 5.4.0

Entrada: Day Month(valor numérico a partir de 1), por ejemplo, 2 3para el 2 de marzo.

<?
$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]}";

EDITAR: El A non well formed numeric valueaviso se produce al realizar un incremento previo en la cadena $m. Independientemente de la notificación, la siguiente salida aún debería ser correcta. Este aviso varía según la versión de PHP. Para solucionar esto, se debe colocar una conversión simple de cadena a entero antes de la segunda última línea. He actualizado el código con las conversiones.

Entrada / salida de muestra (en 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
fuente
OK, soy un tonto de php. ¿Cómo ejecutas esto? Lo intenté echo 2 3 | php -f zod.php, pero solo hace eco del guión en STDOUT
Digital Trauma
1
@ DigitalTrauma Creo que necesita habilitar las etiquetas cortas en su intérprete, de lo contrario, use en <?phplugar de <?.
core1024
Lo intenté, pero ahora lo entiendo PHP Notice: A non well formed numeric value encountered in /home/ubuntu/zod.php on line 6. Estoy ejecutando php 5.5.9 en Ubuntu 14.04
Digital Trauma
Código fijo Ver editar.
noahnu