Qual é o seu signo?

13

Escreva um programa que use uma data de nascimento (mês e dia do mês) como entrada e produz o sinal, elemento e qualidade correspondentes do zodíaco ocidental . Para os propósitos deste desafio, eles são definidos exatamente como na tabela na página da 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

Regras

  • O sinal, elemento e qualidade serão calculados a partir da data de entrada exatamente de acordo com a tabela da Wikipedia.
  • Estou dando liberdade ao formato da data de entrada (consulte a seção Entrada abaixo). Você deve indicar claramente em sua resposta qual formato está usando.
  • Se uma data inválida for fornecida (data não analisável ou mês ou dia do mês fora do intervalo), o programa sairá com a mensagem Invalid date.
  • O programa deve lidar corretamente com os anos bissextos. ou seja, se 29 de fevereiro é a entrada, a saída deve ser corretamente Pisces, Water, Mutable.
  • As bibliotecas / APIs de data do seu idioma são permitidas, mas qualquer API que calcule especificamente os signos do zodíaco é proibida.
  • “Brechas” padrão que não são mais engraçadas
  • Isso é , então a resposta mais curta em bytes vence.

Entrada

  • O programa pode ler a data de entrada no STDIN, na linha de comando, nas variáveis ​​de ambiente ou em qualquer método conveniente para o seu idioma de escolha.
  • Isso não é principalmente um exercício de análise de cadeia de dados; portanto, a sequência de entrada pode ser fornecida no formato que você escolher, desde que consista apenas em componentes de mês e dia do mês e não em outros valores (como ano ou hora) . Por exemplo, Jul 24ou 24th of Julyou 7/24ou 24/07ou qualquer formato que seja conveniente. Se a entrada que não corresponde à sua escolha de formato de entrada for inserida, o Invalid dateerro deverá ser gerado.

Resultado

  • O programa exibirá STDOUT, caixa de diálogo ou qualquer outro método de exibição conveniente para o seu idioma de escolha.
  • O formato de saída será o sinal, o elemento e a qualidade separados por vírgula e espaço: Sign, Element, Quality

Exemplos

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
fonte
É necessária a detecção / aviso de uma data inválida? Em caso afirmativo, podemos assumir que números inválidos inseridos pelo usuário serão maiores que zero? (Acho que a maioria das pessoas usará um formato de data numérico.) #
Level River St
1
@steveverrill Acho que deixei isso claro no terceiro item das regras, mas editei a seção Entrada para esclarecer. Entrada válida TLDR => saída válida; entrada inválida => mensagem de erro; nenhum "comportamento indefinido" permitido para qualquer entrada.
Digital Trauma
é permitida uma data completa? dias, meses e anos?
Teun Pronk
@TeunPronk Não, apenas mês e dia do mês. Esclareci a regra de entrada.
Digital Trauma
O dia do ano (por exemplo Jan 21 -> 21, Feb 5 -> 36) é um formato de entrada válido?
Mego

Respostas:

8

JavaScript, 285 bytes

(Minha primeira resposta aqui depois de espreitar aqui por um tempo)

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

O primeiro prompt()é o mês em formato numérico e o segundo prompt()é o dia do mês (ignore o texto do prompt). Os zeros à esquerda são opcionais para ambos. A saída é exibida com alert(). (Agradecemos a bitpwner, Snack, edc65 e core1024 por ajudar a diminuir o código.)

Experimente acima usando Snippets de pilha ou em http://jsfiddle.net/8vq89/5/ .

Código com espaço em branco e comentários para explicar as partes confusas adicionadas:

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
fonte
1
Para 'Cardinal0Fixed0Mutable'.split(0)e 'Earth0Air0Water0Fire'.split(0), ['Cardinal','Fixed','Mutable']e ['Earth','Air','Water','Fire']é um pouco mais curto.
Snack
Eu tinha uma solução, mas muito semelhantes: 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']). Dê uma olhada na divisão única
edc65
@ edc65 eu recebo um Invalid left-hand side in assignmenterro quando tento executar esse, provavelmente tem a ver com o prompt
NinjaBearMonkey
A tarefa do grupo é Ecmascript 6, funciona apenas no Firefox. p=prompt().split(/\D/),m=p[0],d=p[1]deve trabalhar (mas de modo mais)
edc65
3
Você pode torná-lo ainda mais curto se você usa '...ScorpioSagittarius'.match(/[A-Z][a-z]+/g)em vez de'...Scorpio0Sagittarius'.split(0)
core1024
3

C 353 352

Editar Corrigido bug e erro de digitação, mais 1 char

Antes de perguntar: sim, mesmo sem #include é válido e está funcionando como padrão C.
Formato de entrada: dois números, primeiro mês e depois dia.

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

Teste

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
fonte
Bom, exceto pelo erro de digitação de Ivalid;-) #
Digital Trauma
@DigitalTrauma Não é tão bom, talvez tenha um erro ao discriminar o início do sinal (21,20,24 etc.). Estou revisando agora. Fique atento
edc65
2

Perl 287 (286 + 1 para a -pbandeira)

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

A entrada é de STDIN e a saída vai para STDOUT. Aqui estão os testes do 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
fonte
1

Python, 447387 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]]

Aceita entrada como MM / DD, sempre deve ter dois 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
fonte
1
Você pode tentar estes: [20,21,20,19,20,21,22,22,22,23,20,22][a%12]-> 19+int('121012333413'[a%12]) e [32,30,32,31,32,31,32,32,31,32,31,32][a]->30+int('202121221212'[a])
vetorizado
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}

Outra abordagem. Acho que posso jogar mais, mas mais tarde.

Mês de entrada no primeiro prompt, data no segundo prompt.

Lanche
fonte
1

PHP - 294 bytes (sem tags php *)

* Como a outra entrada php fez

Entrada: Month Daycomo números inteiros, zero à esquerda não é necessário.

Ex: php starsign.php <<< "2 29"para 29 de fevereiro.

Golfed (não copie isso diretamente, veja abaixo):

<?@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 do arquivo 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 gerar arquivo golfed, execute o seguinte script php (gera para 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);

Versão completamente não destruída:

<?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
fonte
Finalmente descobri que preciso editar o /etc/php5/cli/php.ini e configurar short_open_tag = Onpara que isso funcione. Funciona para esta resposta, mas a outra resposta do PHP ainda gera erros. +1 para este.
Digital Trauma
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)
  • Recebe entrada como argumentos separados (ie 1 1)

  • Uma divisão para todas as strings

  • A indexação de bytes no py3 fornece a ordem

  • or Eé uma maneira barata de gerar uma exceção ( NameError)

  • Existe uma maneira mais barata de concatenar as strings? +e literais acabaram sendo menores que join.

  • Não há uma boa razão para que uma pesquisa de bytes comece com 1 e a outra com 0, eu esqueci o dia 29 de fevereiro e mudei 0-> 1 em vez de refazer tudo.

Jason S
fonte
0

PHP 548 524 502 419 (sem tags php)

Requer PHP> = 5.4.0

Entrada: Day Month(valor numérico começando em 1), por exemplo, 2 3para 2 de março.

<?
$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: O A non well formed numeric valueaviso é causado pela execução de um pré-incremento na string $m. Independentemente do aviso, a seguinte saída ainda deve estar correta. Este aviso varia de acordo com a versão do PHP. Para corrigir isso, uma string simples para conversão de número inteiro deve ser colocada antes da segunda última linha. Atualizei o código com as conversões.

Entrada / Saída de amostra (no 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
fonte
OK, eu sou um manequim de php. Como você executa isso? Eu tentei echo 2 3 | php -f zod.php, mas apenas ecoa o próprio script para STDOUT #
Digital Trauma
1
@DigitalTrauma Acho que você precisa habilitar as tags curtas no seu intérprete, caso contrário, use em <?phpvez de <?.
core1024
Eu tentei isso, mas agora entendo PHP Notice: A non well formed numeric value encountered in /home/ubuntu/zod.php on line 6. Estou executando o php 5.5.9 no Ubuntu 14.04
Digital Trauma
Código fixo. Veja editar.
noahnu