Обчисліть китайський знак зодіаку


10

Враховуючи, що Китайський Новий рік наближається, тут є завдання для розрахунку китайського Зодіаку, стихії та Тайджіту на дану дату.

Введіть дату:

1/31/2014

Дату, яку тут використовують, є американський стиль mm/dd/yyyy, але альтернативно може бути стиль ISO-8601: yyyy-mm-ddтому стиль введення дати не є суворим.

Вихід повинен бути знаком тварини в Китайському Зодіаку, включаючи елемент, що відповідає даті, та його аналог Тайджіту :

Horse - Wood - Yang

Таблиця із зодіаком - елемент - Тайджіту можна побачити тут: Китайський Зодіак - Роки

Формат виводу не є суворим, але повинен містити тварини, елементи та компоненти Тайджіту, і його слід певним чином розмежувати.

Приклади дійсних результатів для вищевказаної дати можуть включати:

(horse, wood, yang)
["Horse", "Wood", "Yang"]

Ваша програма повинна повернути дійсний результат протягом принаймні 100 років, включаючи сьогоднішню дату. Це означає, що йому потрібно буде враховувати щонайменше два 60-річні ( статеві роки ) цикли.


3
Чи є у вас зручне посилання, як розрахувати початок року зодіаку?
Hand-E-Food

3
Ви не маєте ідеї, як обчислити зодаїчний рік, але це "здається досить простим". Можливо, ми повинні зараз закрити це питання і знову відкрити його, коли ви загладили ці дрібниці?

1
Ще одна річ, яку слід зазначити, це завжди між 21 січня та 21 лютого включно.
Джастін

3
Таблиця, до якої ви посилаєтеся, не приносить користі, якщо ви не додасте обмеження, що не потрібно давати правильний вихід для дат, що не входять до цього діапазону.
Пітер Тейлор

2
Едуард Флорінеску, два питання, які ви повинні уточнити у питанні: 1) діапазон дат введення, як вказує @PeterTaylor, і 2) чи має формат виводу точно такий, як ви вказали у своєму прикладі? Кожен персонаж рахується, тому будь ласка, поставте цю мету. Дякую.
Даррен Стоун

Відповіді:


4

Mathematica 63

Гаразд, це може старіти, але воно працює (введення дат у багатьох випадках неоднозначне):

z=WolframAlpha[#<>" Chinese zodiac",{{"Result",1},"Plaintext"}] &

Приклад:

z@"1/31/2014"

"Кінь (Ян Вуд)"


Широта математики мене вражає. Ваш вихідний формат невірний, але я впевнений, що це легко виправити.
Даррен Стоун

1
@DarrenStone це дещо безславно, оскільки Mathematica просто називає W | A. Як ви думаєте, висновок повинен точно відповідати формату ОП?
Ів Клетт

Схоже, інші відповіді форматуються точно так само, як і приклад запиту, і для цього, безумовно, потрібен додатковий код для будь-якої мови. Але це справді питання до @EduardFlorinescu
Даррен Стоун,

@DarrenStone правда. Це, безумовно, додасть зовсім небагато накладних витрат. W&C ...
Ів Клетт

4

C # - 357 337 339 байт

string Z(System.DateTime d){var c=new System.Globalization.ChineseLunisolarCalendar();var y=c.GetSexagenaryYear(d);var s=c.GetCelestialStem(y)-1;return",Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Monkey,Rooster,Dog,Pig".Split(',')[c.GetTerrestrialBranch(y)]+" - "+"Wood,Fire,Earth,Metal,Water".Split(',')[s/2]+" - Y"+(s%2>0?"in":"ang");}

Відформатовано:

string Z(System.DateTime d)
{
  var c = new System.Globalization.ChineseLunisolarCalendar();
  var y = c.GetSexagenaryYear(d);
  var s = c.GetCelestialStem(y) - 1;
  return
    ",Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Monkey,Rooster,Dog,Pig".Split(',')[c.GetTerrestrialBranch(y)]
    + " - "
    + "Wood,Fire,Earth,Metal,Water".Split(',')[s / 2]
    + " - Y" + (s % 2 > 0 ? "in" : "ang");
}

+1 Також ви можете зберегти понад 20 символів, уникаючи string.Format.
Hand-E-Food

Так, дякую, я спробував пограти в гольф різних s% 2 == 0 і т.д., і забув великий. :-) І, власне, це було рівно 20 символів, IIANM.
Мормегіл

4

Пітон 2: 360 * 387 586 594 - Персонажі

Зменшується далі

m,n,p=map(int,raw_input().split("/"));p-=1924;d=int("5od2nauh6qe4obvj8rf5pd2math6re3ocvi8sf5pd2l9uh6rf3nbvi7sg5pd2k9th6rf4navj7sg5oc1m9ti7qe3navj8sg5pc1math6qd3nbvj8sf4oc1ma"[p],36);p-=31*m-31+n<(d<21)*31+d;print"Rat Ox Tiger Rabbit Dragon Snake Horse Goat Monkey Rooster Dog Pig".split()[p%12],"Wood Fire Earth Metal Water".split()[p%10/2],["Yang","Yin"][p%2]

Наведений вище код працює в наступний інтервал: 5 лютого 1924 - 31 грудня 2043

Приклад: після вставки вищевказаного коду в курсор інтерпретатора пітона

>>> m,n,p=map(int,raw_input().split("/"));p-=1924;d=int("5od2nauh6qe4obvj8rf5pd2math6re3ocvi8sf5pd2l9uh6rf3nbvi7sg5pd2k9th6rf4navj7sg5oc1m9ti7qe3navj8sg5pc1math6qd3nbvj8sf4oc1ma"[p],36);p-=31*m-31+n<(d<21)*31+d;print"Rat Ox Tiger Rabbit Dragon Snake Horse Goat Monkey Rooster Dog Pig".split()[p%12],"Wood Fire Earth Metal Water".split()[p%10/2],["Yang","Yin"][p%2]

а потім натисніть Enter, введіть таку дату

6/13/2018

а потім натисніть Enterще раз, вихід буде

Dog Earth Yang


* скорочено ще на 27 байт за допомогою Брайана, дивіться коментарі.


2
Ви помітили, що ваш номер-36 містить "математику" двічі? :)
Тімві

1
@Timwi: D Ні, я цього не зробив, і це приємно і моторошно!
Едуард Флорінеску

Едуарде, ти можеш пояснити частину d = int (базовий 36 номер)? Я натрапив на вашу відповідь, роблячи дослідження в stackoverflow для подібної проблеми. Мені потрібно розширити обчислення року до діапазону 1500 - 2043 років. Заздалегідь дякую за будь-яку допомогу.
Луїс Мігель

1
Ви можете зберегти ще 23 символи за допомогою деяких мікрооптимізацій. Дивіться reddit.com/r/Python/comments/2oqobw/…
Брайан

1
@Timwi 1math6і 2math6. Навіть попередні 5 та наступні 3 відображені між собою різними ознаками. Це 3spooky5me.
Чарівний восьминіг Урна

3

Рубі, 340

m,d,y=gets.split(?/).map(&:to_i);y+=1if 31*m+d-51>"d88jac8mlbuppp21ygmkjsnfsd4n3xsrhha4abnq9zgo6g2jupc39zav84434f75op4ftfhdcsa3xhc8nsw1ssw8p9qns1tf14mncy8j18msr9rsb7j7".to_i(36)>>5*y-9625&31
$><<[%w(Goat Monkey Rooster Dog Pig Rat Ox Tiger Rabbit Dragon Snake Horse)[y%12],%w(Metal Water Wood Fire Earth)[(y-1)/2%5],%w(Yin Yang)[y%2]]*' - '

Це працюватиме на дати між 5 лютого 1924 року та 29 січня 2044 року.


Що за чорт це "чарівне" число?
tomsmeding

1
@tomsmeding, це 600-бітове ціле число, закодоване в Базі 36 для компактності. Розбита на бітфілди, це таблиця першого дня місячного календаря на кожен рік між 1924 та 1944 роками.
Даррен Стоун,

3

GolfScript (212 символів)

При цьому використовуються символи, що не друкуються, ось ось вихід з xxd:

0000000: 272d 272f 6e2a 7e5c 2833 312a 2b5c 3a5e  '-'/n*~\(31*+\:^
0000010: 3139 2a22 d4e3 275a 747f 878c 70cb 996d  19*"..'Zt...p..m
0000020: a4f9 19e9 699e d818 bb61 c4e3 2232 3536  ....i....a.."256
0000030: 6261 7365 2033 6261 7365 5e31 3932 322d  base 3base^1922-
0000040: 3c7b 282d 7d2f 3330 2532 312b 3e5e 352d  <{(-}/30%21+>^5-
0000050: 2b3a 5e31 3225 2752 6174 0a4f 780a 5469  +:^12%'Rat.Ox.Ti
0000060: 6765 720a 5261 6262 6974 0a44 7261 676f  ger.Rabbit.Drago
0000070: 6e0a 536e 616b 650a 486f 7273 650a 476f  n.Snake.Horse.Go
0000080: 6174 0a4d 6f6e 6b65 790a 526f 6f73 7465  at.Monkey.Rooste
0000090: 720a 446f 670a 5069 6727 6e2f 3d6e 5e32  r.Dog.Pig'n/=n^2
00000a0: 2f35 2527 576f 6f64 0a46 6972 650a 4561  /5%'Wood.Fire.Ea
00000b0: 7274 680a 4d65 7461 6c0a 5761 7465 7227  rth.Metal.Water'
00000c0: 6e2f 3d6e 5e31 2627 5961 6e67 0a59 696e  n/=n^1&'Yang.Yin
00000d0: 276e 2f3d                                'n/=

Еквівалентна програма, яка використовує рядкові стрибки і, отже, трохи довша:

'-'/n*~\(31*+\:^19*"\xD4\xE3'Zt\x87\x8Cp\xCB\x99m\xA4\xF9\x19\xE9i\x9E\xD8\x18\xBBa\xC4\xE3"256base 3base^1922-<{(-}/30%21+>^5-+:^12%'Rat
Ox
Tiger
Rabbit
Dragon
Snake
Horse
Goat
Monkey
Rooster
Dog
Pig'n/=n^2/5%'Wood
Fire
Earth
Metal
Water'n/=n^1&'Yang
Yin'n/=

Цікавою частиною є обчислення, враховуючи дату, перед чи після китайського Нового року, який припадає на той григоріанський рік. Отримавши натхнення з алгоритму розрахунку Великодня, який я використав у попередньому запитанні, я шукав досить простий підрахунок новорічної дати. Врешті-решт я пішов з простою формулою, яка переносить мене більшу частину шляху, плюс таблицю пошуку терміна помилки.

Простий розрахунок є day_of_year = 21 + (19 * year % 30). Термін помилки в діапазоні від 0до 8більш цікавить діапазону (1924 до 2044), і ніколи не змінюється з року в рік більш ніж на один, так що таблиця перекодування кодуються в збалансованому потрійному і обчислюється помилка шляхом підсумовування умови похибки префікс таблиці.


Хороший, найкоротший поки що, за винятком того, що для Mathematica використовується зовнішній ресурс. +1
Едуард Флорінеску

2

C #, 630 611 604 572 570 байт, 120 років

(додайте ~ 2⅔ байтів за додатковий рік, якщо знаєте компенсацію)

Це добре для людей, народжених 31 січня-1900 р. По 24 січня-2020 р. І, швидше за все, впаде за межі цього діапазону. Чи існують бонусні бали за кількість охоплених років?

string Z(DateTime date)
{
    int[] days = new int[] {  3, 22, 11,  1, 19,  7, -3, 16,  5, -6, 13,  2,
                             21,  9, -2, 17,  6, -5, 14,  4, 23, 11,  0, 19,
                              8, -3, 16,  5, -5, 13,  2, 20,  9, -2, 17,  7,
                             -4, 14,  3, 22, 11, -1, 18,  8, -3, 16,  5, -6,
                             13,  1, 20,  9, -1, 17,  6, -4, 15,  3, 21, 11,
                              0, 18,  8, -3, 16,  5, -7, 12,  2, 20,  9, -1,
                             18,  6, -5, 14,  3, 21, 10,  0, 19,  8, -3, 16,
                              5, 23, 12,  1, 20,  9, -1, 18,  7, -5, 13,  3,
                             22, 10,  0, 19,  8, -4, 15,  4, -6, 12,  1, 21,
                             10, -2, 17,  6, -5, 13,  3, 22, 11,  0, 19,  8 };
    string[] signs = "Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Monkey,Rooster,Dog,Pig".Split(',');
    string[] elements = "Metal,Water,Wood,Fire,Earth".Split(',');
    string[] polarities = new string[] { "Yang", "Yin" };
    int year = date.Year - 1900;
    int x = year - (date.DayOfYear < days[year] + 28 ? 1 : 0);
    return signs[x % 12] + " - " + elements[x / 2 % 5] + " - " + polarities[x % 2];
}

Або конденсований (із доданими розривами рядків):

string Z(DateTime d){
int y=d.Year-1900,
x=y-(d.DayOfYear<new[]{3,22,11,1,19,7,-3,16,5,-6,13,2,21,9,-2,17,6,-5,14,4,23,11,0,19,8,-3,16,5,-5,13,2,20,9,-2,17,7,-4,14,3,22,11,-1,18,8,-3,16,5,-6,13,1,20,9,-1,17,6,-4,15,3,21,11,0,18,8,-3,16,5,-7,12,2,20,9,-1,18,6,-5,14,3,21,10,0,19,8,-3,16,5,23,12,1,20,9,-1,18,7,-5,13,3,22,10,0,19,8,-4,15,4,-6,12,1,21,10,-2,17,6,-5,13,3,22,11,0,19,8}[y]+28?1:0);
return "Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Monkey,Rooster,Dog,Pig".Split(',')[x%12]+" - "+"Metal,Water,Wood,Fire,Earth".Split(',')[x/2%5]+" - "+new[]{"Yang","Yin"}[x%2];
}

Один із прийомів полягав у тому, щоб мати початок офсетної таблиці на 28 січня. Це виявилося найменшим числом персонажів.

Якщо випадково наполягають, що введення є рядком, додайте 22 символи, щоб змінити підпис методу на:

string Z(string i){

і додайте рядок:

var d=DateTime.Parse(i);

ЗМІНИ:

  • Покладіть всі рядки в один масив і додайте зміщення до селекторів виводу.
  • Змінено зміщення дня на 28 січня.
  • string.Split()Натхнення взяте з відповіді Едуарда Флоринеску .
  • Накреслені всі масиви. Це врятувало мене лише 2 символи. : - /

Збережіть 5 символів, змінивши " - "+new[]{"Yang","Yin"}[x%2]на " - Y"+(x%2<1?"ang":"in"):)
Timwi

-1

Досить прямо вперед з PHP за допомогою оператора Switch .

  • Розрахунок, наскільки ви хочете ...

    <?php
    
    // input the year
    $Y = 2020;
    
    // calculate the Z sign
    switch (($Y - 4) % 12) {
      case  0: $z = 'Rat';break;
      case  1: $z = 'Ox';break;
      case  2: $z = 'Tiger';break;
      case  3: $z = 'Rabbit';break;
      case  4: $z = 'Dragon';break;
      case  5: $z = 'Snake';break;
      case  6: $z = 'Horse';break;
      case  7: $z = 'Goat';break;
      case  8: $z = 'Monkey';break;
      case  9: $z = 'Rooster'; break;
      case 10: $z = 'Dog';break;
      case 11: $z = 'Pig';break;
    }
    
    // calculate the e
    switch (($Y / 2) % 5) {
      case  0: $e = 'Metal';break;
      case  1: $e = 'Water';break;
      case  2: $e = 'Wood'; break;
      case  3: $e = 'Fire'; break;
      case  4: $e = 'Earth'; break;
    }
    
    // calculate the polarity
     switch ($Y % 2) {
        case  0: $p = 'Yang';break;
        case  1: $p = 'Yin';break;
    
    }
    
     echo '$Y is $z - $e - $p.';
    

1
Ласкаво просимо до PPCG! Ми вимагаємо, щоб усі відповіді були серйозними конкурентами , тому у випадку з кодом-гольф ми вимагаємо відповіді, щоб докласти зусиль щодо скорочення коду. Наприклад, назви змінних з однієї літери, видалення зайвих пробілів тощо
Втілення

1
Ласкаво просимо до PPCG, ваш код працює лише роками не завершені дати
Едуард Флоринеску

це правда. Це важче, ніж я думаю…
MACboyet

вилучили пробіли і скоротили вже вар. дякую за інформацію
MACboyet
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.