C #, 630 611 604 572 570 bytes, 120 anos
(adicione ~ 2⅔ bytes por ano adicional, se você souber o deslocamento)
Isso é bom para as pessoas nascidas de 31 de janeiro de 1900 a 24 de janeiro de 2020 e provavelmente cairá fora desse intervalo. Existem pontos de bônus para o número de anos cobertos?
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];
}
Ou condensado (com quebras de linha adicionais):
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];
}
Um dos truques era ter a origem da mesa de compensação em 28 de janeiro. Isso provou ter a menor contagem de caracteres.
Se por acaso insistir que a entrada é uma sequência, adicione 22 caracteres para alterar a assinatura do método para:
string Z(string i){
e adicione a linha:
var d=DateTime.Parse(i);
EDITAR% S:
- Coloque todas as seqüências de caracteres em uma matriz e inclua deslocamentos nos seletores de saída.
- Alterado o deslocamento do dia para 28 de janeiro.
string.Split()
Inspiração tirada da resposta de Eduard Florinescu .
- Inline todas as matrizes. Isso só me salvou 2 caracteres. : - /