Hitung tanda Zodiak Cina

10

Mengingat bahwa Tahun Baru Cina akan tiba, inilah tantangan untuk menghitung Zodiak Cina, elemen, dan Taijitu untuk tanggal tertentu.

Masukan harus berupa tanggal:

1/31/2014

Tanggal yang digunakan di sini adalah gaya AS mm/dd/yyyy, tetapi mungkin juga gaya ISO-8601: yyyy-mm-ddsehingga gaya input tanggal tidak ketat.

Keluarannya harus berupa tanda binatang di Zodiak Tiongkok termasuk elemen yang sesuai dengan tanggal, dan timpalan Taijitu :

Horse - Wood - Yang

Tabel yang memperlihatkan hubungan Zodiak - unsur - Taijitu dapat dilihat di sini: Zodiak Cina - Tahun

Format output tidak ketat tetapi harus mengandung hewan, elemen dan komponen Taijitu, dan harus dibatasi dalam beberapa cara.

Contoh output yang valid untuk tanggal di atas mungkin termasuk:

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

Program Anda harus mengembalikan hasil yang valid untuk rentang minimal 100 tahun, termasuk tanggal hari ini. Ini berarti perlu paling tidak dua siklus 60 tahun ( Sexagenary ).

Eduard Florinescu
sumber
3
Apakah Anda memiliki tautan yang nyaman untuk bagaimana menghitung awal tahun zodiak?
Hand-E-Food
3
Anda tidak tahu bagaimana cara menghitung tahun zoda tetapi "tampaknya cukup sederhana". Mungkin kita harus menutup pertanyaan ini untuk saat ini, dan membukanya kembali ketika Anda memiliki detail kecil yang dikerjakan?
1
Satu hal yang perlu diperhatikan adalah selalu termasuk antara 21 Januari dan 21 Februari.
Justin
3
Tabel yang Anda tautkan tidak ada gunanya kecuali Anda menambahkan batasan bahwa itu tidak perlu untuk memberikan hasil yang benar untuk tanggal di luar rentang itu.
Peter Taylor
2
Eduard Florinescu, dua hal yang harus Anda jelaskan dalam pertanyaan: 1) rentang tanggal input seperti yang ditunjukkan @PeterTaylor, dan 2) apakah format output harus persis seperti yang Anda tentukan dalam contoh Anda? Setiap karakter penting jadi buatlah tujuan ini. Terima kasih.
Darren Stone

Jawaban:

4

Mathematica 63

Oke, ini mungkin sudah tua, tetapi berfungsi (input tanggal ambigu dalam banyak kasus):

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

Contoh:

z@"1/31/2014"

"Kuda (Yang Wood)"

Yves Klett
sumber
Luasnya Mathematica membuat saya takjub. Format output Anda salah, tapi saya yakin itu mudah diperbaiki.
Darren Stone
1
@ DarrenStone itu agak memalukan karena Mathematica hanya memanggil W | A. Apakah Anda pikir outputnya harus pas dengan format OP?
Yves Klett
Sepertinya jawaban lain diformat persis seperti contoh keluaran pertanyaan dan tentu saja dibutuhkan kode tambahan untuk melakukannya dalam bahasa apa pun. Tapi itu benar-benar pertanyaan untuk @EduardFlorinescu
Darren Stone
@ DarrenStone benar. Ini tentu akan menambah sedikit overhead. W&C ...
Yves Klett
4

C # - 357 337 339 byte

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

Diformat:

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");
}
Mormegil
sumber
+1 Juga, Anda dapat menyimpan lebih dari 20 karakter dengan menghindari string.Format.
Hand-E-Food
Ya, benar, terima kasih, saya mencoba bermain golf berbagai s% 2 == 0 dll, dan melupakan yang besar. :-) Dan, sebenarnya, itu persis 20 karakter, IIANM.
Mormegil
4

Python 2: 360 * 387 586 594 - Karakter

Dikurangi lebih jauh

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]

Kode di atas berfungsi untuk interval berikut: 5 Feb 1924 - 31 Des 2043

Contoh: setelah menempelkan kode di atas dalam kursor python interpreter

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

dan kemudian tekan Enter, masukkan tanggal seperti ini

6/13/2018

dan kemudian tekan Enterlagi, hasilnya akan menjadi

Dog Earth Yang


* Mengurangi 27 byte lebih lanjut dengan bantuan Brian melihat komentar.

Eduard Florinescu
sumber
2
Apakah Anda memperhatikan nomor base-36 Anda mengandung "matematika" dua kali? :)
Timwi
1
@Timwi: D Tidak, saya tidak, dan itu bagus dan seram!
Eduard Florinescu
Eduard, bisakah Anda menjelaskan bagian d = int (base 36 number)? Saya menemukan jawaban Anda melakukan penelitian di stackoverflow untuk masalah yang sama. Saya perlu memperluas perhitungan tahun ke kisaran tahun 1500 - 2043. Terima kasih sebelumnya atas bantuannya.
Luis Miguel
1
Anda dapat menyimpan 23 karakter lainnya dengan beberapa optimasi mikro. Lihat reddit.com/r/Python/comments/2oqobw/…
Brian
1
@Timwi 1math6dan 2math6. Bahkan 5 sebelumnya dan 3 berikut dicerminkan dengan karakter yang berbeda di antara. Itu 3spooky5me.
Magic Gurita Guci
3

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

Ini akan berlaku untuk tanggal antara 5 Februari 1924 dan 29 Jan 2044.

Darren Stone
sumber
Apa nomor "ajaib" itu?
mulai
1
@tommeding, ini adalah bilangan bulat 600-bit yang dikodekan dalam Basis 36 untuk kekompakan. Dipecah menjadi bitfields, ini adalah tabel hari pertama kalender lunar untuk setiap tahun antara tahun 1924 dan 1944.
Darren Stone
3

GolfScript (212 karakter)

Ini menggunakan karakter yang tidak dapat dicetak, jadi inilah output dari 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/=

Program setara yang menggunakan string lolos dan karenanya sedikit lebih lama adalah:

'-'/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/=

Bagian yang menarik adalah komputasi, mengingat tanggalnya, apakah itu sebelum atau sesudah Tahun Baru Cina yang jatuh pada tahun Gregorian itu. Mengambil inspirasi dari algoritma perhitungan Paskah yang telah saya gunakan pada pertanyaan sebelumnya, saya mencari perhitungan yang cukup sederhana dari tanggal Tahun Baru. Pada akhirnya saya telah pergi dengan formula sederhana yang membuat saya hampir sampai di sana, ditambah tabel pencarian untuk istilah kesalahan.

Perhitungan sederhana adalah day_of_year = 21 + (19 * year % 30). Rentang jangka kesalahan dari 0ke 8atas kisaran bunga (1924-2044), dan tidak pernah berubah dari tahun ke tahun oleh lebih dari satu, sehingga tabel dikodekan dalam terner seimbang dan kesalahan dihitung dengan menjumlahkan hal kesalahan dari awalan tabel.

Peter Taylor
sumber
Bagus, terpendek sejauh ini, kecuali untuk Mathematica yang menggunakan sumber daya eksternal. +1
Eduard Florinescu
2

C #, 630 611 604 572 570 byte, 120 tahun

(tambahkan ~ 2⅔ byte per tahun tambahan jika Anda tahu offsetnya)

Ini bagus untuk orang yang lahir 31-Jan-1900 hingga 24-Jan-2020 dan kemungkinan akan crash di luar kisaran itu. Apakah ada poin bonus untuk jumlah tahun yang dicakup?

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

Atau kental (dengan jeda baris ditambahkan):

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

Salah satu triknya adalah memiliki asal meja offset pada 28 Januari. Ini terbukti memiliki jumlah karakter terendah.

Jika kebetulan itu bersikeras input adalah string, tambahkan 22 karakter untuk mengubah metode tanda tangan ke:

string Z(string i){

dan tambahkan baris:

var d=DateTime.Parse(i);

EDIT:

  • Letakkan semua string dalam satu array dan tambahkan offset ke selektor output.
  • Mengubah hari diimbangi menjadi 28-Jan.
  • string.Split()Inspirasi diambil dari jawaban Eduard Florinescu .
  • Susun semua array. Itu hanya menyelamatkan saya 2 karakter. : - /
Makanan Tangan
sumber
Simpan 5 karakter dengan mengubah " - "+new[]{"Yang","Yin"}[x%2]ke " - Y"+(x%2<1?"ang":"in"):)
Timwi
-1

Cukup lurus ke depan dengan PHP menggunakan pernyataan Switch .

  • Perhitungan sejauh yang Anda inginkan ...

    <?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.';
    
MACboyet
sumber
1
Selamat datang di PPCG! Kami mengharuskan semua jawaban untuk menjadi pesaing serius , jadi dalam hal kode-golf, kami memerlukan jawaban untuk berupaya memperpendek kode. Misalnya, satu nama variabel huruf, menghapus spasi putih, dll.
Perwujudan Ketidaktahuan
1
Selamat datang di PPCG, kode Anda hanya berfungsi selama bertahun-tahun tanpa tanggal yang lengkap
Eduard Florinescu
itu benar. Itu lebih sulit daripada yang saya kira ...
MACboyet
menghapus spasi dan mempersingkat var sudah. terima kasih atas informasinya
MACboyet