你是什​​么星座?


14

写一个程序,它出生日期(月和月某一天的)作为输入,并输出相应的符号,元件和质量西黄道。出于此挑战的目的,它们的定义与链接的维基百科页面中的表完全相同:

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

规则

  • 符号,元素和质量将根据Wikipedia表从输入日期中准确计算得出。
  • 我可以自由选择输入日期格式(请参见下面的“ 输入”部分)。您必须在答案中明确说明您使用的格式。
  • 如果提供了无效的日期(不可解释的日期,或超出日期范围的月份或月份),程序将退出并显示消息Invalid date
  • 该程序必须正确处理leap年。即,如果输入2月29日,则输出必须正确为Pisces, Water, Mutable
  • 允许使用您的语言的日期库/ API,但禁止任何专门计算十二生肖的API。
  • 标准的“漏洞”不再有趣
  • 这是,因此最短的答案以字节为单位。

输入值

  • 该程序可以从STDIN,命令行,环境变量或任何适合您选择的语言的方法中读取输入日期。
  • 这主要不是日期字符串解析的练习,因此输入字符串可以以您选择的任何格式提供,只要它仅包含月和月中的日期部分,而不包含其他值(例如年或时间)即可。 。例如Jul 24or 24th of July7/24or 24/07或任何方便的格式。如果输入的输入与您选择的输入格式不匹配,则Invalid date必须引发错误。

输出量

  • 程序将输出到STDOUT,对话框或任何适合您选择语言的显示方法。
  • 输出格式将是符号,元素和质量,以逗号和空格分隔: Sign, Element, Quality

例子

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

是否需要检测/警告无效日期?如果是这样,我们是否可以假设用户输入的无效数字将大于零?(我猜大多数人会使用数字日期格式。)
Level River St

1
@steveverrill我我已经在规则的第三项中阐明了这一点,但是我已经编辑了Input部分以明确说明。TLDR有效输入=>有效输出;输入无效=>错误消息;任何给定的输入都不允许“未定义的行为”。
Digital Trauma

允许全日制吗?天,月和年?
Teun Pronk

@TeunPronk不,仅一个月和一个月中的某一天。我已经澄清了输入规则。
Digital Trauma

是年(如当天Jan 21 -> 21Feb 5 -> 36)一个有效的输入格式?
Mego

Answers:


8

JavaScript,285字节

(潜伏在这里一段时间后,我的第一个答案)

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

第一个prompt()是数字形式的月份,第二个prompt()是该月的一天(忽略提示文本)。两者的前导零都是可选的。输出显示为alert()。(感谢bitpwner,Snack,edc65和core1024有助于缩短代码。)

在上面使用堆栈片段或在http://jsfiddle.net/8vq89/5/上尝试一下。

带有空格和注释的代码来解释添加的令人困惑的部分:

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

1
对于'Cardinal0Fixed0Mutable'.split(0)'Earth0Air0Water0Fire'.split(0)['Cardinal','Fixed','Mutable']并且['Earth','Air','Water','Fire']要短一些。
零食

我有一个解决方案,但太相似了: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'])。看看单分裂
edc65

@ edc65我Invalid left-hand side in assignment尝试运行该错误时出现错误,可能与提示有关
NinjaBearMonkey 2014年

小组分配是Ecmascript 6,仅适用于Firefox。p=prompt().split(/\D/),m=p[0],d=p[1]应该工作(但时间更长)
edc65

3
如果使用'...ScorpioSagittarius'.match(/[A-Z][a-z]+/g)代替,您可以使其更短'...Scorpio0Sagittarius'.split(0)
core1024 2014年

3

Ç353 352

编辑固定的错误和错字,还有1个字符

在您询问之前:是的,即使没有#include也是有效且有效的C标准。
输入格式:两个数字,第一个月,第二天。

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

测试

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

很好,除了错别字Ivalid;-)
数字创伤

@DigitalTrauma不太好,也许它在辨别符号开始时有错误(21、20、24等)。我正在修改它。敬请期待
edc65

2

Perl 287(286 + 1 -p

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

输入来自STDIN,输出进入STDOUT。这是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

1

Python,447387个字符

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

输入为MM / DD,必须始终为两位数。

$ 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

1
您可以尝试以下方法:[20,21,20,19,20,21,22,22,22,23,20,22][a%12]-> 19+int('121012333413'[a%12])[32,30,32,31,32,31,32,32,31,32,31,32][a]->30+int('202121221212'[a])
矢量化

1

Javascript 403 396字节

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}

另一种方法。我想我可以打更多的球,但是以后。

在第一个提示上输入月份,在第二个提示上输入日期。


1

PHP-294字节(不带php标签*)

*与其他php条目一样

输入:Month Day整数,不需要前导零。

例如:php starsign.php <<< "2 29"2月29日。

打高尔夫球(请勿直接复制,请参见下文):

<?@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');

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

要生成高尔夫球文件,请运行以下php脚本(生成为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);

完全取消发布版本:

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

最终弄清楚,我需要编辑/etc/php5/cli/php.ini并进行设置short_open_tag = On以使其正常工作。适用于此答案,但其他PHP答案仍会出错。+1。
Digital Trauma 2014年

1

Python 3-332字节

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)
  • 将输入作为单独的参数(即1 1

  • 一键拆分所有字符串

  • py3中的索引字节给出了ord

  • or E是生成异常的廉价方法(NameError

  • 有没有一种便宜的方法来连接字符串?+结果文字比小于join

  • 没有充分的理由让一个字节的查找以1开头,而另一个以0开头,我只是忘记了2月29日,而是更改了0-> 1而不是重做整个事情。


0

的PHP 548 524 502 419(不含php标签)

需要PHP> = 5.4.0

输入:(Day Month数值从1开始)例如2 33月2日。

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

编辑:A non well formed numeric value通知是由对字符串执行预递增引起的$m。不管发出什么通知,以下输出仍然正确。此通知因版本而异PHP。要解决此问题,应在最后第二行之前放置一个简单的字符串到整数的转换。我已经使用转换更新了代码。

示例输入/输出(在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

好的,我是php虚拟对象。你如何运行这个?我尝试过echo 2 3 | php -f zod.php,但是它只是将脚本本身呼应到STDOUT
Digital Trauma

1
@DigitalTrauma我认为您需要在解释器中启用短标签,否则请使用<?php代替<?
core1024

我尝试过,但是现在我得到了PHP Notice: A non well formed numeric value encountered in /home/ubuntu/zod.php on line 6。我在Ubuntu 14.04上运行php 5.5.9
Digital Trauma

代码固定。参见编辑。
noahnu 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.