Code Golf: Chinese zodiac cycle
Let's do a round of code golf! Last one was very popular!
The Chinese zodiac is a repeating cycle of 12 years, with each year being represented by an animal and an element that changes every 2 years.
The animals are: Rat, Ox, Tiger, Rabbit, Dragon, Snake, Horse, Goat, Monkey, Rooster, Dog and Pig.
The elements are: Wood, Fire, Earth, Metal and Water.
Your task is to write a function that receives a year, and returns the element and the animal that year represent.
Let's use the year 1924 as start point, in the Chinese zodiac the element was Wood and the animal was Rat.
Input
2023
Output
"Water Rabbit"
Note
Rules
- The signature of the contest entry MUST be:
Class codeGolf.ChineseZodiac { ClassMethod Calendar(y As %Integer) As %String { q " "// Your solution here } }
- It is forbidden to modify class/signature, including but not limited to:
- Adding inheritance
- Setting default argument values
- Adding class elements (Parameters, Methods, Includes, etc).
- It is forbidden to refer to non-system code from your entry. For example, this is not a valid entry:
ClassMethod Build(f As %Integer) { W ##class(myPackage.myClass).test(a) }
- The use of
$ZWPACK
and$ZWBPACK
is also discouraged. - You can use this test case:
Class codeGolf.unittests.ChineseZodiac Extends %UnitTest.TestCase { Method TestSolutions() { Do $$$AssertEquals(##class(codeGolf.ChineseZodiac).Calendar(1972), "Water Rat") Do $$$AssertEquals(##class(codeGolf.ChineseZodiac).Calendar(1934), "Wood Dog") Do $$$AssertEquals(##class(codeGolf.ChineseZodiac).Calendar(2023), "Water Rabbit") Do $$$AssertEquals(##class(codeGolf.ChineseZodiac).Calendar(2043), "Water Pig") Do $$$AssertEquals(##class(codeGolf.ChineseZodiac).Calendar(1961), "Metal Ox") Do $$$AssertEquals(##class(codeGolf.ChineseZodiac).Calendar(2002), "Water Horse") Do $$$AssertEquals(##class(codeGolf.ChineseZodiac).Calendar(2016), "Fire Monkey") } }
First bid:
ClassMethod Calendar(y As %Integer) As %String { s a=$lfs("Monkey,Rooster,Dog,Pig,Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Metal,Water,Wood,Fire,Earth") q $li(a,y\2#5+13)_" "_$li(a,y#12+1) }
132
{
q $p("Metal7Water7Wood7Fire7Earth",7,y#10\2+1)_" "_$p("Monkey7Rooster7Dog7Pig7Rat7Ox7Tiger7Rabbit7Dragon7Snake7Horse7Goat",7,y#12+1)
}
great idea:: integers as separators!
just realized the separating blank broke the line in display.
Class codeGolf.ChineseZodiac { ClassMethod Calendar(y As %Integer) As %String { Set startYear = 1924 Set animals = "Rat,Ox,Tiger,Rabbit,Dragon,Snake,Horse,Goat,Monkey,Rooster,Dog,Pig" Set elements = "Wood,Fire,Earth,Metal,Water" Set diff = y - startYear If diff < 0 Quit "Invalid Year" Set animalIndex = (diff + 12) % 12 Set elementIndex = (diff / 2) % 5 Set animal = $List(animals, animalIndex + 1) Set element = $List(elements, elementIndex + 1) Quit element_" "_animal } }
the code fails already for start year 1924 <NULL VALUE>
and is in principle wrong 🙁