중국 12 궁도 기호 계산


10

구정이 다가오는 것을 감안할 때, 주어진 날짜에 대한 중국 12 궁도, 요소 및 태극권을 계산하는 것은 어려운 일입니다.

입력은 날짜 여야합니다.

1/31/2014

여기에 사용 된 날짜는 US 스타일 mm/dd/yyyy이지만 ISO-8601 스타일 일 수도 있습니다. yyyy-mm-dd따라서 날짜 입력 스타일이 엄격하지 않습니다.

결과는 날짜에 해당하는 요소 및 Taijitu 대응 항목을 포함 하여 차이 니스 조디악 의 동물 표시 여야합니다 .

Horse - Wood - Yang

조디악-요소-Taijitu 관계를 보여주는 표는 여기에서 볼 수 있습니다. 중국어 조디악-년

출력 형식은 엄격하지 않지만 동물, 요소 및 Taijitu 구성 요소를 포함해야하며 어떤 방식 으로든 구분되어야합니다.

위 날짜에 유효한 출력의 예는 다음과 같습니다.

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

귀하의 프로그램은 오늘 날짜를 포함하여 100 년 이상의 유효 출력을 반환해야합니다. 즉, 최소 60 년 ( 성인 )주기를 고려해야 합니다.


3
조디악 년의 시작을 계산하는 방법에 대한 편리한 링크가 있습니까?
Hand-E-Food

3
당신은 조디악 년을 계산하는 방법을 모른다. 그러나 그것은 "꽤 간단 해 보인다". 아마도 우리는 지금이 질문을 닫고 작은 세부 사항을 다룰 때 다시 열어야합니까?

1
주목해야 할 또 다른 사항은 항상 1 월 21 일에서 2 월 21 일까지입니다.
Justin

3
해당 범위 밖의 날짜에 대해 올바른 출력을 제공 할 필요가 없다는 제한을 추가하지 않으면 연결 한 테이블은 사용되지 않습니다.
피터 테일러

2
Eduard Florinescu, 질문에서 분명히해야 할 두 가지 : 1) @PeterTaylor가 지적한 입력 날짜 범위 및 2) 출력 형식이 예제에서 지정한 것과 정확히 일치해야합니까? 모든 문자가 중요하므로이 목표를 설정하십시오. 감사.
Darren Stone

답변:


4

매스 매 티카 63

좋아, 이것은 오래되었을 지 모르지만 작동합니다 (많은 경우 날짜 입력이 모호합니다).

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

예:

z@"1/31/2014"

"말 (양 나무)"


Mathematica의 폭이 놀랍습니다. 출력 형식이 올바르지 않지만 쉽게 고쳐질 것입니다.
대런 스톤

1
@DarrenStone Mathematica는 단순히 W | A를 호출하기 때문에 다소 어색합니다. 출력이 OP의 형식과 정확히 일치해야한다고 생각하십니까?
Yves Klett

다른 답변은 질문의 예제 출력과 정확히 일치하는 것처럼 보이며 모든 언어에서 그렇게하려면 추가 코드가 필요합니다. 그러나 그것은 실제로 @EduardFlorinescu에 대한 질문입니다
Darren Stone

@DarrenStone true. 이것은 확실히 약간의 오버 헤드를 추가 할 것입니다. W & C ...
Yves Klett

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)였습니다.
Mormegil

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]

위의 코드는 다음 간격으로 작동합니다. 1924 년 2 월 5 일 – 2043 년 12 월 31 일

예 : 파이썬 인터프리터 커서에 위의 코드를 붙여 넣은 후

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


* Brian의 도움으로 주석을 추가하면 27 바이트 더 줄었습니다 .


2
당신의 base-36 숫자에“math”가 두 번 포함되어있는 것을 보셨습니까? :)
Timwi

1
@Timwi : D 아니, 나는하지 않았다 그리고 그것은 멋지고 짜증 난다!
Eduard Florinescu

에두아르, d = int (base 36 number) 부분을 설명해 주시겠습니까? 비슷한 문제에 대한 stackoverflow에서 연구를하고있는 귀하의 답변을 발견했습니다. 연도 계산을 1500-2043 년 범위로 확장해야합니다. 도움을 주셔서 감사합니다.
Luis Miguel

1
일부 미세 최적화를 통해 23 개의 문자를 더 저장할 수 있습니다. reddit.com/r/Python/comments/2oqobw/…
Brian

1
@Timwi 1math62math6. 선행 5와 다음 3도 서로 다른 문자로 미러링됩니다. 3spooky5me입니다.
Magic Octopus Urn

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

이것은 1924 년 2 월 5 일에서 2044 년 1 월 29 일 사이의 날짜에 적용됩니다.


그 "마법의"숫자는 무엇입니까?
tomsmeding

1
@tomsmeding, 압축을 위해 Base 36으로 인코딩 된 600 비트 정수입니다. 비트 필드로 나누어, 그것은 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)입니다. 발 오차항 범위 08관심 범위 (2044년에서 1924년까지) 및 룩업 테이블 (A)의 오차 항을 합산하여 평형 원으로 부호화 에러가 계산되고, 그래서, 하나 이상의하여 해마다 절대 변경 위에 테이블의 접두사.


Mathematica가 외부 리소스를 사용하고 있다는 점을 제외하고는 지금까지 가장 짧았습니다. +1
Eduard Florinescu

2

C #을, 630 611 604 572 570 바이트, 1백20년

(오프셋을 알고 있다면 1 년에 ~ 2⅔ 바이트 추가)

이것은 1900 년 1 월 31 일부터 2020 년 1 월 24 일 사이에 태어난 사람들에게 적합하며 그 범위를 벗어나는 경우가 많습니다. 보장 된 기간 동안 보너스 포인트가 있습니까?

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-Jan에 오프셋 테이블의 원점을 갖는 것입니다. 이것은 문자 수가 가장 적은 것으로 판명되었습니다.

우연히 입력이 문자열이라고 주장하면 22 문자를 추가하여 메소드 서명을 다음과 같이 변경하십시오.

string Z(string i){

그리고 라인을 추가하십시오 :

var d=DateTime.Parse(i);

EDITS :

  • 모든 문자열을 하나의 배열에 넣고 출력 선택기에 오프셋을 추가했습니다.
  • 일 오프셋을 1 월 28 일로 변경했습니다.
  • string.Split()Eduard Florinescu의 답변 에서 영감을 얻었습니다 .
  • 모든 배열을 인라인했습니다. 그것은 단지 2 자만 절약했습니다. :-/

변경하여 5 자 저장 " - "+new[]{"Yang","Yin"}[x%2]" - Y"+(x%2<1?"ang":"in"):)
Timwi

-1

Switch 문을 사용하여 PHP로 매우 간단 합니다 .

  • 계산은 당신이 원하는 한 ...

    <?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에 오신 것을 환영합니다. 코드는 완료되지 않은 연도 동안 만 작동합니다
Eduard Florinescu

사실입니다. 생각보다 어렵습니다…
MACboyet

공백을 제거하고 var를 이미 줄이십시오. 정보 주셔서 감사합니다
MACboyet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.