- 8.9k
- 3
- 35
- 57
J - 44(削除) 44 (削除ここまで) 41 char
(":,th`st`nd`rd{::~10 ~4|4<.10(]*[(~|*|~:*])4>]-~)/@#:]100&|)
10 10(...)/@#:]100&|- First we take the argument (]) and find the tens and ones digit (10 10 #:). Then, we will insert(...)betweenreduce the twoinput modulo 100.(]*[10(~|*|~:*])4>]-~)- In this subexpression, but not the innermost one,]|will point tois the ones digitinput mod 10 and[the tens digit.[(~:*])4>]--~:is J for "not-equals", so this takes the result of4>]input (i.e. whether or not the one digit is less than 4mod 100) and multiplies it by the result oftens ~: (4>])minus 10. Why would anyone doYou don't get many trains as clean as this? Consider the following: one in J, so it's a treat to see here!- If we are checking 10, 11, 12, 13, then
tensis1(we are in the teens) andones~:is less than 4not-equals, sotens ~|~: (4>])-~is false andif the result is0*1=0. - If we are any other one of {X0, X1, X2, X3}, then clearly
tens ~: (4>])tens digit is true1 and we get out1*1=1true otherwise. - If
ones*is greater than fourjust multiplication, then4>]was0and it doesn't matter what happens toso we're taking the test anymoreinput mod 10 and multiplying by a boolean, wewhich will get0zero it out regardlessif false. - So to summarize,
[(~:*])4>]The result of this is1if we are in {X0, X1, X2"input mod 10, X3} but not inexcept 0 on the teens, and0otherwisetens".
- If we are checking 10, 11, 12, 13, then
]*4|4<.- Finally we multiply that result by the ones digit. So this product will beMin (0<.if) the number deserves a'th'suffixabove with 4, else its valueto clamp down larger values, and then reduce modulo 4 so that they all go to zero.th`st`nd`rd{::~- We use the modified ones-digit from above to Use that as an index into the list of suffixessuiffixes.0gets'th'Numbers ending in X1 or X2 or X3,1getsbut not in 1X, will find their suffix, and everything else will take the 0th suffix'st'th, and so on.":,- Finally, take the original numberinput, convert it to a string (":), and then prepend it toappend the suffix.
(":,th`st`nd`rd{::~10 ~4|4<.10(]*[(~|*|~:*])4>]-~)/@#:]100&|) 112 NB. single use
112th
(":,th`st`nd`rd{::~10 ~4|4<.10(]*[(~|*|~:*])4>]-~)/@#:]100&|) 1 2 3 4 5 NB. doing it wrong
|length error
| (":,th`st`nd`rd{::~10 ~4|4<.10(]*[(~|*|~:*])4>]-~)/@#:]100&|)1 2 3 4 5
NB. i.5 10 makes a 5x10 grid of increasing integers
NB. &.> to operate on each integer separately, and box the result after
(":,th`st`nd`rd{::~10 ~4|4<.10(]*[(~|*|~:*])4>]-~)/@#:]100&|)&.> i.5 10 NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+Alternative 41 char solution showing off a couple logical variants:
(":;@;st`nd`rd`th{~3<.10(|+3*|=-~)100|<:)
Previously I had an overlong explanation of this 44 char hunk of junk. 10 10#: takes the last two decimal digits and /@ puts logic between them.
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])
J - 44 char
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])
10 10(...)/@#:]- First we take the argument (]) and find the tens and ones digit (10 10 #:). Then, we will insert(...)between the two.(]*[(~:*])4>])- In this subexpression, but not the innermost one,]will point to the ones digit and[the tens digit.[(~:*])4>]-~:is J for "not-equals", so this takes the result of4>](i.e. whether or not the one digit is less than 4) and multiplies it by the result oftens ~: (4>]). Why would anyone do this? Consider the following:- If we are checking 10, 11, 12, 13, then
tensis1(we are in the teens) andonesis less than 4, sotens ~: (4>])is false and the result is0*1=0. - If we are any other one of {X0, X1, X2, X3}, then clearly
tens ~: (4>])is true and we get out1*1=1. - If
onesis greater than four, then4>]was0and it doesn't matter what happens to the test anymore, we will get0out regardless. - So to summarize,
[(~:*])4>]is1if we are in {X0, X1, X2, X3} but not in the teens, and0otherwise.
- If we are checking 10, 11, 12, 13, then
]*- Finally we multiply that result by the ones digit. So this product will be0if the number deserves a'th'suffix, else its value.th`st`nd`rd{::~- We use the modified ones-digit from above to index the list of suffixes.0gets'th',1gets'st', and so on.":,- Finally, take the original number, convert it to a string (":), and then prepend it to the suffix.
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 112 NB. single use
112th
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 1 2 3 4 5 NB. doing it wrong
|length error
| (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])1 2 3 4 5
NB. i.5 10 makes a 5x10 grid of increasing integers
NB. &.> to operate on each integer separately, and box the result after
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])&.> i.5 10 NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+
J - (削除) 44 (削除ここまで) 41 char
(":,th`st`nd`rd{::~4|4<.10(|*|~:-~)100&|)
100&|- First, reduce the input modulo 100.10(|*|~:-~)- In this subexpression,|is the input mod 10 and-~is the input (mod 100) minus 10. You don't get many trains as clean as this one in J, so it's a treat to see here!~:is not-equals, so|~:-~is false if the tens digit is 1 and true otherwise.*is just multiplication, so we're taking the input mod 10 and multiplying by a boolean, which will zero it out if false. The result of this is "input mod 10, except 0 on the tens".
4|4<.- Min (<.) the above with 4, to clamp down larger values, and then reduce modulo 4 so that they all go to zero.th`st`nd`rd{::~- Use that as an index into the list of suiffixes. Numbers ending in X1 or X2 or X3, but not in 1X, will find their suffix, and everything else will take the 0th suffixth.":,- Finally, take the original input, convert it to a string (":), and append the suffix.
(":,th`st`nd`rd{::~4|4<.10(|*|~:-~)100&|) 112 NB. single use
112th
(":,th`st`nd`rd{::~4|4<.10(|*|~:-~)100&|) 1 2 3 4 5 NB. doing it wrong
|length error
| (":,th`st`nd`rd{::~4|4<.10(|*|~:-~)100&|)1 2 3 4 5
NB. i.5 10 makes a 5x10 grid of increasing integers
NB. &.> to operate on each integer separately, and box the result after
(":,th`st`nd`rd{::~4|4<.10(|*|~:-~)100&|)&.> i.5 10 NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+Alternative 41 char solution showing off a couple logical variants:
(":;@;st`nd`rd`th{~3<.10(|+3*|=-~)100|<:)
Previously I had an overlong explanation of this 44 char hunk of junk. 10 10#: takes the last two decimal digits and /@ puts logic between them.
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])
J - 4744 char
(":,(4 2$'thstndrd')th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])
10 10(...)/@#:]- First we take the argument (]) and find the tens and ones digit (10 10 #:). Then, we will insert(...)between the two.(]*[(~:*])4>])- In this subexpression, but not the innermost one,]will point to the ones digit and[the tens digit.[(~:*])4>]-~:is J for "not-equals", so this takes the result of4>](i.e. whether or not the one digit is less than 4) and multiplies it by the result oftens ~: (4>]). Why would anyone do this? Consider the following:- If we are checking 10, 11, 12, 13, then
tensis1(we are in the teens) andonesis less than 4, sotens ~: (4>])is false and the result is0*1=0. - If we are any other one of {X0, X1, X2, X3}, then clearly
tens ~: (4>])is true and we get out1*1=1. - If
onesis greater than four, then4>]was0and it doesn't matter what happens to the test anymore, we will get0out regardless. - So to summarize,
[(~:*])4>]is1if we are in {X0, X1, X2, X3} but not in the teens, and0otherwise.
- If we are checking 10, 11, 12, 13, then
]*- Finally we multiply that result by the ones digit. ThisSo this product will be0if the number deserves a'th'suffix, else its value.4 2$'thstndrd'- This creates a 4-item list of the suffixes, each two characters wide.(...)th`st`nd`rd{::~- We use the modified ones-digit from above to index the list of suffixes.0gets'th',1gets'st', and so on.":,- Finally, take the original number, convert it to a string (":), and then prepend it to the suffix.
(":,(4 2$'thstndrd')th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 112 NB. single use
112th
(":,(4 2$'thstndrd')th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 1 2 3 4 5 NB. doing it wrong
|length error
| (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])1 2 3 4 5
st
nd
rd
th
th
NB. i.5 10 makes a 5x10 grid of increasing integers
NB. &.> to operate on each integer separately, and box the result after
(":,(4 2$'thstndrd')th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])&.> i.5 10 NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+
J - 47 char
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:])
10 10(...)/@#:]- First we take the argument (]) and find the tens and ones digit (10 10 #:). Then, we will insert(...)between the two.(]*[(~:*])4>])- In this subexpression, but not the innermost one,]will point to the ones digit and[the tens digit.[(~:*])4>]-~:is J for "not-equals", so this takes the result of4>](i.e. whether or not the one digit is less than 4) and multiplies it by the result oftens ~: (4>]). Why would anyone do this? Consider the following:- If we are checking 10, 11, 12, 13, then
tensis1(we are in the teens) andonesis less than 4, sotens ~: (4>])is false and the result is0*1=0. - If we are any other one of {X0, X1, X2, X3}, then clearly
tens ~: (4>])is true and we get out1*1=1. - If
onesis greater than four, then4>]was0and it doesn't matter what happens to the test anymore, we will get0out regardless. - So to summarize,
[(~:*])4>]is1if we are in {X0, X1, X2, X3} but not in the teens, and0otherwise.
- If we are checking 10, 11, 12, 13, then
]*- Finally we multiply that result by the ones digit. This product will be0if the number deserves a'th'suffix, else its value.4 2$'thstndrd'- This creates a 4-item list of the suffixes, each two characters wide.(...){~- We use the modified ones-digit from above to index the list of suffixes.0gets'th',1gets'st', and so on.":,- Finally, take the original number, convert it to a string (":), and then prepend it to the suffix.
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:]) 112 NB. single use
112th
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:]) 1 2 3 4 5 NB. doing it wrong
1 2 3 4 5
st
nd
rd
th
th
NB. i.5 10 makes a 5x10 grid of increasing integers
NB. &.> to operate on each integer separately, and box the result after
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:])&.> i.5 10 NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+
J - 44 char
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])
10 10(...)/@#:]- First we take the argument (]) and find the tens and ones digit (10 10 #:). Then, we will insert(...)between the two.(]*[(~:*])4>])- In this subexpression, but not the innermost one,]will point to the ones digit and[the tens digit.[(~:*])4>]-~:is J for "not-equals", so this takes the result of4>](i.e. whether or not the one digit is less than 4) and multiplies it by the result oftens ~: (4>]). Why would anyone do this? Consider the following:- If we are checking 10, 11, 12, 13, then
tensis1(we are in the teens) andonesis less than 4, sotens ~: (4>])is false and the result is0*1=0. - If we are any other one of {X0, X1, X2, X3}, then clearly
tens ~: (4>])is true and we get out1*1=1. - If
onesis greater than four, then4>]was0and it doesn't matter what happens to the test anymore, we will get0out regardless. - So to summarize,
[(~:*])4>]is1if we are in {X0, X1, X2, X3} but not in the teens, and0otherwise.
- If we are checking 10, 11, 12, 13, then
]*- Finally we multiply that result by the ones digit. So this product will be0if the number deserves a'th'suffix, else its value.th`st`nd`rd{::~- We use the modified ones-digit from above to index the list of suffixes.0gets'th',1gets'st', and so on.":,- Finally, take the original number, convert it to a string (":), and then prepend it to the suffix.
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 112 NB. single use
112th
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:]) 1 2 3 4 5 NB. doing it wrong
|length error
| (":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])1 2 3 4 5
NB. i.5 10 makes a 5x10 grid of increasing integers
NB. &.> to operate on each integer separately, and box the result after
(":,th`st`nd`rd{::~10 10(]*[(~:*])4>])/@#:])&.> i.5 10 NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+
J - 47 char
Nothing in J? This is an outrage!
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:])
Explained (note that 1 is boolean true in J and 0 is false):
10 10(...)/@#:]- First we take the argument (]) and find the tens and ones digit (10 10 #:). Then, we will insert(...)between the two.(]*[(~:*])4>])- In this subexpression, but not the innermost one,]will point to the ones digit and[the tens digit.[(~:*])4>]-~:is J for "not-equals", so this takes the result of4>](i.e. whether or not the one digit is less than 4) and multiplies it by the result oftens ~: (4>]). Why would anyone do this? Consider the following:- If we are checking 10, 11, 12, 13, then
tensis1(we are in the teens) andonesis less than 4, sotens ~: (4>])is false and the result is0*1=0. - If we are any other one of {X0, X1, X2, X3}, then clearly
tens ~: (4>])is true and we get out1*1=1. - If
onesis greater than four, then4>]was0and it doesn't matter what happens to the test anymore, we will get0out regardless. - So to summarize,
[(~:*])4>]is1if we are in {X0, X1, X2, X3} but not in the teens, and0otherwise.
- If we are checking 10, 11, 12, 13, then
]*- Finally we multiply that result by the ones digit. This product will be0if the number deserves a'th'suffix, else its value.4 2$'thstndrd'- This creates a 4-item list of the suffixes, each two characters wide.(...){~- We use the modified ones-digit from above to index the list of suffixes.0gets'th',1gets'st', and so on.":,- Finally, take the original number, convert it to a string (":), and then prepend it to the suffix.
Usage is obvious, though as-is the verb can only take one ordinal, not a list.
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:]) 112 NB. single use
112th
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:]) 1 2 3 4 5 NB. doing it wrong
1 2 3 4 5
st
nd
rd
th
th
NB. i.5 10 makes a 5x10 grid of increasing integers
NB. &.> to operate on each integer separately, and box the result after
(":,(4 2$'thstndrd'){~10 10(]*[(~:*])4>])/@#:])&.> i.5 10 NB. all better
+----+----+----+----+----+----+----+----+----+----+
|0th |1st |2nd |3rd |4th |5th |6th |7th |8th |9th |
+----+----+----+----+----+----+----+----+----+----+
|10th|11th|12th|13th|14th|15th|16th|17th|18th|19th|
+----+----+----+----+----+----+----+----+----+----+
|20th|21st|22nd|23rd|24th|25th|26th|27th|28th|29th|
+----+----+----+----+----+----+----+----+----+----+
|30th|31st|32nd|33rd|34th|35th|36th|37th|38th|39th|
+----+----+----+----+----+----+----+----+----+----+
|40th|41st|42nd|43rd|44th|45th|46th|47th|48th|49th|
+----+----+----+----+----+----+----+----+----+----+