Coding since 11yo, that makes it over 30 years now ~~~
Have a PhD in Comp Sci ~~~
Love to go on bike tours ~~~
I try to stay as generalist as I can in this crazy wide place coding is at now.
Here's a typescript implementation, and a ✨verbose-and-pretty✨ reference to check it against.
It's funny, but I take much more care with these little easy tasks than I used to. There's always more nuance than you expect and the implementations end up sitting at the bottom of your library being used for everything.
(btw, I tend to use ~~ as an alternative to of Math.floor because it's more succinct, and most often a little quicker)
I'll check my working by comparing with a naive implementation that's more readable and hopefully reliable out of the gate...
// Stringifying the ordinal is an easier way to get individual the parts of the year...functionsuffixForOrdinal_slowButSure(ordinal:number):string{constordinalString=String(ordinal),tens=+ordinalString.slice(-2,-1),ones=+ordinalString.slice(-1);if(tens==1)return'th';// i.e. 11th, not 11stif(ones==1)return'st';// 81stif(ones==2)return'nd';// 82ndif(ones==3)return'rd';// 83rdreturn'th';// anything else is 'th'. 45th}functionnameOfCentury_slowButSure(yearOrdinal:string|number):string{// When extracting the century we need to be working with the index, not ordinal.// That's why the weirdness about 2000 -> 20th, 2001 -> 21st// (The year 2000 as an ordinal has index 1999)constyearIndex=+yearOrdinal-1,yearIndexString=String(yearIndex),centuryIndex=+yearIndexString.slice(0,-2)||0,centuryOrdinal=centuryIndex+1;return`${centuryOrdinal}${suffixForOrdinal_slowButSure(centuryOrdinal)}`;}// Now do some 'testing' by comparing the implementations// This ensures that either both are right or both are wrong,// I'm pretty sure that the verbose one is as right as any static fixtures I could make.(functionhareVsTortoise(startYearOrdinal=1,endYearOrdinal=100000){for(letyearOrdinal=startYearOrdinal;yearOrdinal<=endYearOrdinal;yearOrdinal++){if(nameOfCentury(yearOrdinal)!==nameOfCentury_slowButSure(yearOrdinal)){console.error(`Conflicting answers for year ${yearOrdinal}:\n Hare: "${nameOfCentury(yearOrdinal)}"\n Tortoise: "${nameOfCentury_slowButSure(yearOrdinal)}"`);return;}}console.log(`Checked ${endYearOrdinal+1-startYearOrdinal} years, all seems good`);})();/*-->
Checked 100000 years, all seems good
[1,99,100,101,200,300,400,1000,1100,1200,1300,1400,1900,2000,2001,2020,10000,10100].forEach(year=>{console.log(`Year ${year} --> ${nameOfCentury(year)}`);});/*-->
Year 1 --> 1st
Year 99 --> 1st
Year 100 --> 1st
Year 101 --> 2nd
Year 200 --> 2nd
Year 300 --> 3rd
Year 400 --> 4th
Year 1000 --> 10th
Year 1100 --> 11th
Year 1200 --> 12th
Year 1300 --> 13th
Year 1400 --> 14th
Year 1900 --> 19th
Year 2000 --> 20th
Year 2001 --> 21st
Year 2020 --> 21st
Year 10000 --> 100th
Year 10100 --> 101st
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Here's a typescript implementation, and a ✨verbose-and-pretty✨ reference to check it against.
It's funny, but I take much more care with these little easy tasks than I used to. There's always more nuance than you expect and the implementations end up sitting at the bottom of your library being used for everything.
(btw, I tend to use
~~
as an alternative to ofMath.floor
because it's more succinct, and most often a little quicker)I'll check my working by comparing with a naive implementation that's more readable and hopefully reliable out of the gate...