Какой Ваш знак Зодиака?


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

правила

  • Знак, элемент и качество будут рассчитываться по дате ввода точно в соответствии с таблицей википедии.
  • Я даю некоторую свободу над входным форматом даты (см. Раздел « Ввод » ниже). Вы должны четко указать в своем ответе, какой формат вы используете.
  • Если указана недопустимая дата (непарсируемая дата или месяц или день месяца вне диапазона), программа завершит работу с сообщением Invalid date.
  • Программа должна правильно обрабатывать високосные годы. то есть, если 29-е февраля является входом, то выход должен быть правильно Pisces, Water, Mutable.
  • Библиотеки / API-интерфейсы Date вашего языка разрешены, но любые API-интерфейсы, которые специально рассчитывают знаки зодиака, запрещены.
  • Стандартные «лазейки», которые больше не смешны
  • Это , поэтому выигрывает самый короткий ответ в байтах.

вход

  • Программа может считывать введенную дату из STDIN, командной строки, переменных среды или любого другого метода, удобного для вашего языка.
  • Это в первую очередь не упражнение при разборе даты-строки, поэтому входная строка может быть предоставлена ​​в любом формате, который вы выберете, при условии, что она состоит только из компонентов месяца и дня месяца, а не других значений (таких как год или время) , Например, Jul 24или, 24th of Julyили, 7/24или 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 valid input => valid output; неверный ввод => сообщение об ошибке; "неопределенное поведение" не допускается для любого заданного ввода.
Цифровая травма

разрешена полная дата? дни, месяцы и годы?
Теун Пронк

@TeunPronk Нет, только месяц и день месяца. Я уточнил правило ввода.
Цифровая травма

Является ли день года (например Jan 21 -> 21, Feb 5 -> 36) допустимым форматом ввода?
Мего

Ответы:


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

групповое назначение - 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

3

С 353 352

Редактировать Исправлена ​​ошибка и опечатка, 1 символ больше

Прежде чем спросить: да, даже без #include действует и работающий стандарт Си.
Формат ввода: два числа, первый месяц, затем день.

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;-)
Digital Trauma

@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, 447 387 символов

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"на 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');

Hexdump файла 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 за это.
Цифровая травма

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 дает заказ

  • or Eэто дешевый способ создания исключения ( NameError)

  • Есть ли более дешевый способ объединения строк? +и литералы оказались меньше чем join.

  • Нет никаких веских причин для того, чтобы поиск в одном байте начинался с 1, а с другого - с 0, я просто забыл 29-дневный февраль и изменил 0-> 1 вместо того, чтобы повторить все это.


0

PHP 548 524 502 419 (без тегов php)

Требуется PHP> = 5.4.0

Ввод: Day Month(числовое значение, начинающееся с 1), например, 2 3для 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]}";

EDIT: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

Хорошо, я фиктивная пустышка. Как вы управляете этим? Я пытался 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. Я использую php 5.5.9 на Ubuntu 14.04
Digital Trauma

Код исправлен. Смотрите редактировать.
Ноахну
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.