Convert a percentage to a âsimpleâ ratio
Clash Royale CLAN TAG#URR8PPP
up vote
15
down vote
favorite
You run a political website, and have determined that people have a better intuitive understanding when the chance of winning or losing an election is expressed as a ratio ("5 in 7") than when it is expressed as a percentage ("71%").
But you also don't want to display confusing ratios like "58 in 82", you'd like them to be more easily understood, even if they aren't quite as precise.
So, given a percentage between 0.1% and 99.9%, return the closest "easy-to-understand" ratio "x in y", using the following rules:
- Most values (see exceptions below) should return the closest ratio out of 10 or lower. 55% should return "5 in 9", not "11 in 20".
- Ratios should be reduced to their lowest terms. 65% should return "2 in 3", not "4 in 6".
- Values under 10% should return the closest ratio of the form "1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 6% should return "1 in 15".
- Values over 90% should return the closest ratio of the form "n-1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 98.7% should return "79 in 80".
- Values under 1% should return "<1 in 100"
- Values over 99% should return ">99 in 100"
Or, to think about it another way, your program should return the closest ratio from the following possible outputs (I've included their approximate values for your convenience):
<1 in 100
1 in 100 = 1.00%
1 in 90 = 1.11%
1 in 80 = 1.25%
1 in 70 = 1.43%
1 in 60 = 1.67%
1 in 50 = 2.00%
1 in 40 = 2.50%
1 in 30 = 3.33%
1 in 20 = 5.00%
1 in 15 = 6.67%
1 in 12 = 8.33%
1 in 10 = 10.00%
1 in 9 = 11.11%
1 in 8 = 12.50%
1 in 7 = 14.29%
1 in 6 = 16.67%
1 in 5 = 20.00%
2 in 9 = 22.22%
1 in 4 = 25.00%
2 in 7 = 28.57%
3 in 10 = 30.00%
1 in 3 = 33.33%
3 in 8 = 37.50%
2 in 5 = 40.00%
3 in 7 = 42.86%
4 in 9 = 44.44%
1 in 2 = 50.00%
5 in 9 = 55.56%
4 in 7 = 57.14%
3 in 5 = 60.00%
5 in 8 = 62.50%
2 in 3 = 66.67%
7 in 10 = 70.00%
5 in 7 = 71.43%
3 in 4 = 75.00%
7 in 9 = 77.78%
4 in 5 = 80.00%
5 in 6 = 83.33%
6 in 7 = 85.71%
7 in 8 = 87.50%
8 in 9 = 88.89%
9 in 10 = 90.00%
11 in 12 = 91.67%
14 in 15 = 93.33%
19 in 20 = 95.00%
29 in 30 = 96.67%
39 in 40 = 97.50%
49 in 50 = 98.00%
59 in 60 = 98.33%
69 in 70 = 98.57%
79 in 80 = 98.75%
89 in 90 = 98.89%
99 in 100 = 99.00%
>99 in 100
Other stipulations:
- Numeric input can be in the range of 0.1 to 99.9 or in the range of 0.001 to 0.999, whichever is more convenient. You must handle at least 3 significant digits.
- You must output a ratio ("3 in 4"), not the equivalent fraction ("3/4").
- If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15".
- Leading/trailing white space and/or new lines are fine
Examples:
Input : Output
0.5 : <1 in 100
1.0 : 1 in 100
1.5 : 1 in 70
7.5 : 1 in 15 or 1 in 12 (either is acceptable)
9.2 : 1 in 10
13.1 : 1 in 8
29.2 : 2 in 7
29.3 : 3 in 10
52.7 : 1 in 2
52.8 : 5 in 9
72.0 : 5 in 7
73.9 : 3 in 4
88.8 : 8 in 9
90.8 : 9 in 10
94.2 : 19 in 20
98.7 : 79 in 80
98.9 : 89 in 90
99.0 : 99 in 100
99.1 : >99 in 100
This is a code-golf challenge, shortest code in each language wins.
(Similar to, but not duplicate of: Convert a decimal to a fraction, Closest fraction, Approximate floating point number with n-digit precision)
code-golf rational-numbers
add a comment |Â
up vote
15
down vote
favorite
You run a political website, and have determined that people have a better intuitive understanding when the chance of winning or losing an election is expressed as a ratio ("5 in 7") than when it is expressed as a percentage ("71%").
But you also don't want to display confusing ratios like "58 in 82", you'd like them to be more easily understood, even if they aren't quite as precise.
So, given a percentage between 0.1% and 99.9%, return the closest "easy-to-understand" ratio "x in y", using the following rules:
- Most values (see exceptions below) should return the closest ratio out of 10 or lower. 55% should return "5 in 9", not "11 in 20".
- Ratios should be reduced to their lowest terms. 65% should return "2 in 3", not "4 in 6".
- Values under 10% should return the closest ratio of the form "1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 6% should return "1 in 15".
- Values over 90% should return the closest ratio of the form "n-1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 98.7% should return "79 in 80".
- Values under 1% should return "<1 in 100"
- Values over 99% should return ">99 in 100"
Or, to think about it another way, your program should return the closest ratio from the following possible outputs (I've included their approximate values for your convenience):
<1 in 100
1 in 100 = 1.00%
1 in 90 = 1.11%
1 in 80 = 1.25%
1 in 70 = 1.43%
1 in 60 = 1.67%
1 in 50 = 2.00%
1 in 40 = 2.50%
1 in 30 = 3.33%
1 in 20 = 5.00%
1 in 15 = 6.67%
1 in 12 = 8.33%
1 in 10 = 10.00%
1 in 9 = 11.11%
1 in 8 = 12.50%
1 in 7 = 14.29%
1 in 6 = 16.67%
1 in 5 = 20.00%
2 in 9 = 22.22%
1 in 4 = 25.00%
2 in 7 = 28.57%
3 in 10 = 30.00%
1 in 3 = 33.33%
3 in 8 = 37.50%
2 in 5 = 40.00%
3 in 7 = 42.86%
4 in 9 = 44.44%
1 in 2 = 50.00%
5 in 9 = 55.56%
4 in 7 = 57.14%
3 in 5 = 60.00%
5 in 8 = 62.50%
2 in 3 = 66.67%
7 in 10 = 70.00%
5 in 7 = 71.43%
3 in 4 = 75.00%
7 in 9 = 77.78%
4 in 5 = 80.00%
5 in 6 = 83.33%
6 in 7 = 85.71%
7 in 8 = 87.50%
8 in 9 = 88.89%
9 in 10 = 90.00%
11 in 12 = 91.67%
14 in 15 = 93.33%
19 in 20 = 95.00%
29 in 30 = 96.67%
39 in 40 = 97.50%
49 in 50 = 98.00%
59 in 60 = 98.33%
69 in 70 = 98.57%
79 in 80 = 98.75%
89 in 90 = 98.89%
99 in 100 = 99.00%
>99 in 100
Other stipulations:
- Numeric input can be in the range of 0.1 to 99.9 or in the range of 0.001 to 0.999, whichever is more convenient. You must handle at least 3 significant digits.
- You must output a ratio ("3 in 4"), not the equivalent fraction ("3/4").
- If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15".
- Leading/trailing white space and/or new lines are fine
Examples:
Input : Output
0.5 : <1 in 100
1.0 : 1 in 100
1.5 : 1 in 70
7.5 : 1 in 15 or 1 in 12 (either is acceptable)
9.2 : 1 in 10
13.1 : 1 in 8
29.2 : 2 in 7
29.3 : 3 in 10
52.7 : 1 in 2
52.8 : 5 in 9
72.0 : 5 in 7
73.9 : 3 in 4
88.8 : 8 in 9
90.8 : 9 in 10
94.2 : 19 in 20
98.7 : 79 in 80
98.9 : 89 in 90
99.0 : 99 in 100
99.1 : >99 in 100
This is a code-golf challenge, shortest code in each language wins.
(Similar to, but not duplicate of: Convert a decimal to a fraction, Closest fraction, Approximate floating point number with n-digit precision)
code-golf rational-numbers
If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15"
Does that mean that we can return7 in 100
as well? Btw,1 in 14
is closer to the input in this case.
â DimChtz
Aug 29 at 14:48
@DimChtz No, as that violates rule 3 (values under 10% should be expressed as "1 in n", for specific possible values of n).
â BradC
Aug 29 at 14:50
Ohh, I didn't notice this. Okay.
â DimChtz
Aug 29 at 14:51
2
I'd like it if we could just output the numerator and denominator as any format like a tuple/list or something, but there are already competing answers so I suppose it's too late for this challenge. For future challenges though, I'd consider a more flexible I/O format because some languages lose more competitiveness than others when you require string handling.
â HyperNeutrino
Aug 29 at 21:12
1
@BradC - LOL. I was just at 538, and I was all "Wow! I gotta make a golfing challenge out of this!"
â Chas Brown
Aug 29 at 21:23
add a comment |Â
up vote
15
down vote
favorite
up vote
15
down vote
favorite
You run a political website, and have determined that people have a better intuitive understanding when the chance of winning or losing an election is expressed as a ratio ("5 in 7") than when it is expressed as a percentage ("71%").
But you also don't want to display confusing ratios like "58 in 82", you'd like them to be more easily understood, even if they aren't quite as precise.
So, given a percentage between 0.1% and 99.9%, return the closest "easy-to-understand" ratio "x in y", using the following rules:
- Most values (see exceptions below) should return the closest ratio out of 10 or lower. 55% should return "5 in 9", not "11 in 20".
- Ratios should be reduced to their lowest terms. 65% should return "2 in 3", not "4 in 6".
- Values under 10% should return the closest ratio of the form "1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 6% should return "1 in 15".
- Values over 90% should return the closest ratio of the form "n-1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 98.7% should return "79 in 80".
- Values under 1% should return "<1 in 100"
- Values over 99% should return ">99 in 100"
Or, to think about it another way, your program should return the closest ratio from the following possible outputs (I've included their approximate values for your convenience):
<1 in 100
1 in 100 = 1.00%
1 in 90 = 1.11%
1 in 80 = 1.25%
1 in 70 = 1.43%
1 in 60 = 1.67%
1 in 50 = 2.00%
1 in 40 = 2.50%
1 in 30 = 3.33%
1 in 20 = 5.00%
1 in 15 = 6.67%
1 in 12 = 8.33%
1 in 10 = 10.00%
1 in 9 = 11.11%
1 in 8 = 12.50%
1 in 7 = 14.29%
1 in 6 = 16.67%
1 in 5 = 20.00%
2 in 9 = 22.22%
1 in 4 = 25.00%
2 in 7 = 28.57%
3 in 10 = 30.00%
1 in 3 = 33.33%
3 in 8 = 37.50%
2 in 5 = 40.00%
3 in 7 = 42.86%
4 in 9 = 44.44%
1 in 2 = 50.00%
5 in 9 = 55.56%
4 in 7 = 57.14%
3 in 5 = 60.00%
5 in 8 = 62.50%
2 in 3 = 66.67%
7 in 10 = 70.00%
5 in 7 = 71.43%
3 in 4 = 75.00%
7 in 9 = 77.78%
4 in 5 = 80.00%
5 in 6 = 83.33%
6 in 7 = 85.71%
7 in 8 = 87.50%
8 in 9 = 88.89%
9 in 10 = 90.00%
11 in 12 = 91.67%
14 in 15 = 93.33%
19 in 20 = 95.00%
29 in 30 = 96.67%
39 in 40 = 97.50%
49 in 50 = 98.00%
59 in 60 = 98.33%
69 in 70 = 98.57%
79 in 80 = 98.75%
89 in 90 = 98.89%
99 in 100 = 99.00%
>99 in 100
Other stipulations:
- Numeric input can be in the range of 0.1 to 99.9 or in the range of 0.001 to 0.999, whichever is more convenient. You must handle at least 3 significant digits.
- You must output a ratio ("3 in 4"), not the equivalent fraction ("3/4").
- If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15".
- Leading/trailing white space and/or new lines are fine
Examples:
Input : Output
0.5 : <1 in 100
1.0 : 1 in 100
1.5 : 1 in 70
7.5 : 1 in 15 or 1 in 12 (either is acceptable)
9.2 : 1 in 10
13.1 : 1 in 8
29.2 : 2 in 7
29.3 : 3 in 10
52.7 : 1 in 2
52.8 : 5 in 9
72.0 : 5 in 7
73.9 : 3 in 4
88.8 : 8 in 9
90.8 : 9 in 10
94.2 : 19 in 20
98.7 : 79 in 80
98.9 : 89 in 90
99.0 : 99 in 100
99.1 : >99 in 100
This is a code-golf challenge, shortest code in each language wins.
(Similar to, but not duplicate of: Convert a decimal to a fraction, Closest fraction, Approximate floating point number with n-digit precision)
code-golf rational-numbers
You run a political website, and have determined that people have a better intuitive understanding when the chance of winning or losing an election is expressed as a ratio ("5 in 7") than when it is expressed as a percentage ("71%").
But you also don't want to display confusing ratios like "58 in 82", you'd like them to be more easily understood, even if they aren't quite as precise.
So, given a percentage between 0.1% and 99.9%, return the closest "easy-to-understand" ratio "x in y", using the following rules:
- Most values (see exceptions below) should return the closest ratio out of 10 or lower. 55% should return "5 in 9", not "11 in 20".
- Ratios should be reduced to their lowest terms. 65% should return "2 in 3", not "4 in 6".
- Values under 10% should return the closest ratio of the form "1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 6% should return "1 in 15".
- Values over 90% should return the closest ratio of the form "n-1 in n" where n is one of (10,12,15,20,30,40,50,60,70,80,90,100). For example, 98.7% should return "79 in 80".
- Values under 1% should return "<1 in 100"
- Values over 99% should return ">99 in 100"
Or, to think about it another way, your program should return the closest ratio from the following possible outputs (I've included their approximate values for your convenience):
<1 in 100
1 in 100 = 1.00%
1 in 90 = 1.11%
1 in 80 = 1.25%
1 in 70 = 1.43%
1 in 60 = 1.67%
1 in 50 = 2.00%
1 in 40 = 2.50%
1 in 30 = 3.33%
1 in 20 = 5.00%
1 in 15 = 6.67%
1 in 12 = 8.33%
1 in 10 = 10.00%
1 in 9 = 11.11%
1 in 8 = 12.50%
1 in 7 = 14.29%
1 in 6 = 16.67%
1 in 5 = 20.00%
2 in 9 = 22.22%
1 in 4 = 25.00%
2 in 7 = 28.57%
3 in 10 = 30.00%
1 in 3 = 33.33%
3 in 8 = 37.50%
2 in 5 = 40.00%
3 in 7 = 42.86%
4 in 9 = 44.44%
1 in 2 = 50.00%
5 in 9 = 55.56%
4 in 7 = 57.14%
3 in 5 = 60.00%
5 in 8 = 62.50%
2 in 3 = 66.67%
7 in 10 = 70.00%
5 in 7 = 71.43%
3 in 4 = 75.00%
7 in 9 = 77.78%
4 in 5 = 80.00%
5 in 6 = 83.33%
6 in 7 = 85.71%
7 in 8 = 87.50%
8 in 9 = 88.89%
9 in 10 = 90.00%
11 in 12 = 91.67%
14 in 15 = 93.33%
19 in 20 = 95.00%
29 in 30 = 96.67%
39 in 40 = 97.50%
49 in 50 = 98.00%
59 in 60 = 98.33%
69 in 70 = 98.57%
79 in 80 = 98.75%
89 in 90 = 98.89%
99 in 100 = 99.00%
>99 in 100
Other stipulations:
- Numeric input can be in the range of 0.1 to 99.9 or in the range of 0.001 to 0.999, whichever is more convenient. You must handle at least 3 significant digits.
- You must output a ratio ("3 in 4"), not the equivalent fraction ("3/4").
- If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15".
- Leading/trailing white space and/or new lines are fine
Examples:
Input : Output
0.5 : <1 in 100
1.0 : 1 in 100
1.5 : 1 in 70
7.5 : 1 in 15 or 1 in 12 (either is acceptable)
9.2 : 1 in 10
13.1 : 1 in 8
29.2 : 2 in 7
29.3 : 3 in 10
52.7 : 1 in 2
52.8 : 5 in 9
72.0 : 5 in 7
73.9 : 3 in 4
88.8 : 8 in 9
90.8 : 9 in 10
94.2 : 19 in 20
98.7 : 79 in 80
98.9 : 89 in 90
99.0 : 99 in 100
99.1 : >99 in 100
This is a code-golf challenge, shortest code in each language wins.
(Similar to, but not duplicate of: Convert a decimal to a fraction, Closest fraction, Approximate floating point number with n-digit precision)
code-golf rational-numbers
edited Aug 29 at 15:19
asked Aug 29 at 14:34
BradC
3,094521
3,094521
If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15"
Does that mean that we can return7 in 100
as well? Btw,1 in 14
is closer to the input in this case.
â DimChtz
Aug 29 at 14:48
@DimChtz No, as that violates rule 3 (values under 10% should be expressed as "1 in n", for specific possible values of n).
â BradC
Aug 29 at 14:50
Ohh, I didn't notice this. Okay.
â DimChtz
Aug 29 at 14:51
2
I'd like it if we could just output the numerator and denominator as any format like a tuple/list or something, but there are already competing answers so I suppose it's too late for this challenge. For future challenges though, I'd consider a more flexible I/O format because some languages lose more competitiveness than others when you require string handling.
â HyperNeutrino
Aug 29 at 21:12
1
@BradC - LOL. I was just at 538, and I was all "Wow! I gotta make a golfing challenge out of this!"
â Chas Brown
Aug 29 at 21:23
add a comment |Â
If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15"
Does that mean that we can return7 in 100
as well? Btw,1 in 14
is closer to the input in this case.
â DimChtz
Aug 29 at 14:48
@DimChtz No, as that violates rule 3 (values under 10% should be expressed as "1 in n", for specific possible values of n).
â BradC
Aug 29 at 14:50
Ohh, I didn't notice this. Okay.
â DimChtz
Aug 29 at 14:51
2
I'd like it if we could just output the numerator and denominator as any format like a tuple/list or something, but there are already competing answers so I suppose it's too late for this challenge. For future challenges though, I'd consider a more flexible I/O format because some languages lose more competitiveness than others when you require string handling.
â HyperNeutrino
Aug 29 at 21:12
1
@BradC - LOL. I was just at 538, and I was all "Wow! I gotta make a golfing challenge out of this!"
â Chas Brown
Aug 29 at 21:23
If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15"
Does that mean that we can return 7 in 100
as well? Btw, 1 in 14
is closer to the input in this case.â DimChtz
Aug 29 at 14:48
If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15"
Does that mean that we can return 7 in 100
as well? Btw, 1 in 14
is closer to the input in this case.â DimChtz
Aug 29 at 14:48
@DimChtz No, as that violates rule 3 (values under 10% should be expressed as "1 in n", for specific possible values of n).
â BradC
Aug 29 at 14:50
@DimChtz No, as that violates rule 3 (values under 10% should be expressed as "1 in n", for specific possible values of n).
â BradC
Aug 29 at 14:50
Ohh, I didn't notice this. Okay.
â DimChtz
Aug 29 at 14:51
Ohh, I didn't notice this. Okay.
â DimChtz
Aug 29 at 14:51
2
2
I'd like it if we could just output the numerator and denominator as any format like a tuple/list or something, but there are already competing answers so I suppose it's too late for this challenge. For future challenges though, I'd consider a more flexible I/O format because some languages lose more competitiveness than others when you require string handling.
â HyperNeutrino
Aug 29 at 21:12
I'd like it if we could just output the numerator and denominator as any format like a tuple/list or something, but there are already competing answers so I suppose it's too late for this challenge. For future challenges though, I'd consider a more flexible I/O format because some languages lose more competitiveness than others when you require string handling.
â HyperNeutrino
Aug 29 at 21:12
1
1
@BradC - LOL. I was just at 538, and I was all "Wow! I gotta make a golfing challenge out of this!"
â Chas Brown
Aug 29 at 21:23
@BradC - LOL. I was just at 538, and I was all "Wow! I gotta make a golfing challenge out of this!"
â Chas Brown
Aug 29 at 21:23
add a comment |Â
8 Answers
8
active
oldest
votes
up vote
6
down vote
T-SQL, 385 bytes
SELECT TOP 1IIF(i>.99,'>',IIF(i<.01,'<',''))+n+' in '+d
FROM t,(SELECT ISNULL(PARSENAME(value,2),'1')n,PARSENAME(value,1)d FROM
STRING_SPLIT('100,90,80,70,60,50,40,30,20,15,12,10,9,8,7,6,5,2.9,4,2.7,3.10,3,3.8,2.5,3.7,4.9,2,5.9,4.7,3.5,5.8,2.3,7.10,5.7,3.4,7.9,4.5,5.6,6.7,7.8,8.9,9.10,11.12,14.15,19.20,29.30,39.40,49.50,59.60,69.70,79.80,89.90,99.100',','))m
ORDER BY ABS(i-ABS(n)/d)
Input is via pre-existing table t with numeric field i, per our IO standards.
That input table is joined with an in-memory table parsed from a string via STRING_SPLIT
(which separates rows) and PARSENAME
(which separates numerator and denominator via .
).
The table is sorted by distance from the input value i, and returns the top row, formatted appropriately.
add a comment |Â
up vote
5
down vote
Charcoal, 84 bytes
NøFùùëFâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµùFòâÂÂÃÂ
â¦â¨úâÂÂùùâ§ÃȉÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷âÂÂâÂÂ÷âÂÂ÷÷ÃÂ<â¹ø÷â°ùÃÂ>âºø÷â¹â¹⪫çÃÂ
÷ in
Try it online! Link is to verbose version of code. Takes input as a decimal rather than a percentage. Explanation:
Nø
Input the fraction.
Fùùë
Run from $ n = 0 $ to $ n = 10 $.
FâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§
Generate ratios for $ frac 1 n $ to $ frac n - 1 n $.
âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµù
Get the $ n^th $ element of the list $ 12, 15, 20 ... 100 $ into $ n $.
FòâÂÂÃÂ
â¦â¨úâÂÂùùâ§û
Generate ratios for $ frac n - 1 n $ and $ frac 1 n $.
âÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷
Calculate the decimal values of all the ratios and take the absolute difference with the original input.
âÂÂâÂÂ÷âÂÂ÷÷
Find the index of the least absolute difference. In case of a tie (e.g. $ frac 1 2 $ and $ frac 2 4 $), take the ratio generated first.
ÃÂ<â¹ø÷â°ù
Print a <
if the input is less than $ 0.01 $.
ÃÂ>âºø÷â¹â¹
Print a >
if the input is greater than $ 0.99 $.
⪫çÃÂ
÷ in
Join the numerator and denominator of the appropriate ratio with in
and print.
add a comment |Â
up vote
5
down vote
JavaScript (ES7), 164 159 144 bytes
Expects an input ratio in $]0,1[$.
r=>(g=m=>--n+11?g((q=n>1?n*10:n+10-~'13'[n],d=((p=r<.1?1:r>.9?q-1:n<0&&r*q+.5|0)/q-r)**2)>m?m:(o=p+' in '+q,d)):r<.01?'<'+o:r>.99?'>'+o:o)(n=11)
Try it online!
How?
We try all possible ratios $p/q$. For each of them, we compute:
$$d=(p/q-r)^2$$
We update the best score $m$ (the lower, the better) each time $d$ is lower than or equal to $m$.
We go from the highest value of $q$ to the lowest one, so that a smaller denominator is preferred in case of a tie.
Commented
r => (g = m => // r = input; g() = recursive function, taking m = best score
--n + 11 ? // decrement n; if n is still greater than or equal to -10:
g( // do a recursive call to g():
( q = // compute q = denominator:
n > 1 ? // if n is greater than 1:
n * 10 // q = n * 10 (20, 30, ..., 100)
: // else:
n + 10 - ~'13'[n], // q = 12 if n = 0, 15 if n = 1, n + 11 if n < 0
d = (( // compute d = (p / q - r)ò:
p = // compute p = numerator:
r < .1 ? // if r is less than 0.01:
1 // p = 1
: // else:
r > .9 ? // if r is greater than 0.90:
q - 1 // p = q - 1
: // else:
n < 0 && // if n is negative (i.e. q is in [1,10]):
r * q + .5 | 0 // p = round(r * q)
// otherwise: p = 0 (which will be ignored)
) / q - r // compute p / q - r
) ** 2 // and square the result (cheaper than absolute value)
) > m ? // if d is greater than m:
m // leave m unchanged
: ( // else:
o = p + ' in ' + q, // update the output string o
d // and update m to d
)) // end of recursive call
: // else (all possible ratios have been tried out):
r < .01 ? '<' + o : // if r is less than 0.01, prefix with '<'
r > .99 ? '>' + o : // if r is greater than 0.99, prefix with '>'
o // otherwise, just return o
)(n = 11) // initial call to g() with m = n = 11
add a comment |Â
up vote
4
down vote
Jelly, 58 bytes
âµRÃÂâµ;12,15õâÂÂ,1,â¬)áºÂ;âµÃ
Âcäð÷/ạÃÂ¥ÃÂḢjâ in âÂÂ
âÂÂ<âÂÂ>âÂÂâÂÂ>.99$?<.01$?;ÃÂ
Try it online!
-16 bytes thanks to Arnauld (can just prepend the <
and >
instead of rewriting the whole phrase)
-6 bytes and bug-fixes thanks to Jonathan Allan
@Arnauld Oh you're right, never thought about that :P Thanks!
â HyperNeutrino
Aug 30 at 0:18
0.3
should result in3 in 10
not2 in 7
â Jonathan Allan
Aug 30 at 7:45
You should just remove theµµ
, no? EDIT - and then golfÃá¹Âá¹Â
toÃḢ
â Jonathan Allan
Aug 30 at 7:45
changing9
toâµ
should resolve the bug I believe.
â Jonathan Allan
Aug 30 at 8:09
@JonathanAllan Oh whoops, yep I wasn't using 10 as a valid denominator. Thanks. And no, removing the double mu doesn't work because then the "minimum" is attached to the right side of the dyadic link-min function which is definitely not what I want, but only putting one mu doesn't seem to fix it. Thanks for the golf though :D
â HyperNeutrino
Aug 31 at 15:06
 |Â
show 5 more comments
up vote
3
down vote
Python 2, 261 278 261 237 177 bytes
lambda n:' <>'[(n<.01)-(n>.99)]+'%d in %d'%min([(a,b)for b in[[12,15]+r(10,110,10),r(1,11)][.1<n<.9]for a in r([1,b-1][n>.9],[b,2][n<.1])],key=lambda(a,b):abs(1.*a/b-n))
r=range
Try it online!
1
Doesn't Python support semicolons? You could replace'n '
with';'
... unless I'm wrong.
â Dev
Aug 30 at 2:12
@BradC Fixed :)
â TFeld
Aug 30 at 6:49
add a comment |Â
up vote
3
down vote
Clean, 224 198 197 bytes
import StdEnv,Data.List,Text
t=toReal
$p=if(p<1.0)"<"if(p>99.0)">"""+snd(minimum[(abs(p-t n*1E2/t d),n<+" in "<+d)\i<-[10,12,15:[20,30..100]],(n,d)<-[(1,i),(i-1,i):diag2[1..10][1..10]]|gcd n d<2])
Try it online!
Explained:
t = toReal // give `toReal` a shorter name
$ p
= if(p < 1.0) // if the percentage is less than 1%
"<" // prepend "<"
if(p > 99.0) // if the percentage is > 99%
">" // prepend ">"
"" // otherwise prepend nothing
+ snd ( // to the second element of
minimum [ // the smallest item in a list composed of
( // pairs of
abs ( // the absolute value of
p - // the difference between the percentage
t n*1E2 / t d // and the ratio
)
, // associated with
n <+ " in " <+ d // the string representation of the ratio
) // in the form of a tuple
\ i <- [10, 12, 15: [20, 30..100]] // for every special denominator `i`
, (n, d) <- [(1, i), (i - 1, i): diag2 [1..10] [1..10]]
// for every ratio `n` : `d`
| gcd n d < 2 // where `n` / `d` cannot be further simplified
]
)
add a comment |Â
up vote
3
down vote
Jelly, Â 53Â 52 bytes
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in
A full program which prints the result.
Try it online!
Or see the test-suite
Note that the test-suite is altered to make the code a monadic link by:
- using the register keep a track of the current "program input", with
ó
toî
; and - closing the list of characters code for " in ", with
â in
toâ in âÂÂ
How?
Starts with code that forces any necessary printing of the <
or >
sign and then code which constructs all the numerator-denominator pairs (with some redundant not simplified form versions, all after their simplified form) and prints the minimally different division-evaluated entry using a stable sort joined with in
.
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in - Main Link: number in [0,1], n
.01,.99 - literal pair = [0.01, 0.99]
_ - subtract -> [n - 0.01, n - 0.99]
á¹ - sign (vectorises) (-1 if <0; 1 if >0; else 0)
õ - start a new monadic link
- call that X
<0 - less than zero? (vectorises)
ÃÂ< - literal list of characters = "<>"
á» - index into (vectorises) ("<<" if n < 0.01; ">>" if n >= 0.99; else "><")
E - all (of X) equal? (1 if ((n < 0.01) OR (n > 0.99)) else 0
ḣ - head to index ("<" if n < 0.01; ">" if n > 0.99; else "")
- (the following nilad forces a print of that)
âµ - literal 10
Ã
» - zero-range -> [0,1,2,3,4,5,6,7,8,9,10]
ÃÂâµ - multiply by 10 -> [0,10,20,30,40,50,60,70,80,90,100]
12,5 - literal pair = [12,5]
+ - add -> [12,15,20,30,40,50,60,70,80,90,100]
$ - last two links as a monad
ÃÂ - last three links as a monad
á¹ - sign -> [1,1,1,1,1,1,1,1,1,1,1]
â - decrement -> [11,14,19,29,39,49,59,69,79,89,99]
, - pair -> [[1,1,1,1,1,1,1,1,1,1,1],[11,14,19,29,39,49,59,69,79,89,99]]
Ã
¼â¬ - zip with for â¬ach -> [[[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100]],[[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]]
Ạ- tighten -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]
ä - nilad followed by link(s) as a nilad:
âµ - literal 10
Ã
Âc - unordered pairs -> [[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
; - concatenate -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
ÃÂ - sort by:
ÃÂ¥ - last two links as a dyad:
- ...(with right argument of
ó - the program input, n)
/ - reduce by:
÷ - division
ạ - absolute difference
Ḣ - head
â in - literal list of characters " in "
; - concatenate
- implicit print
add a comment |Â
up vote
2
down vote
Perl 6, 118 bytes
(^11 X*10))).min(abs $_-[/] @^a).join(' in ')
Try it online!
add a comment |Â
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
6
down vote
T-SQL, 385 bytes
SELECT TOP 1IIF(i>.99,'>',IIF(i<.01,'<',''))+n+' in '+d
FROM t,(SELECT ISNULL(PARSENAME(value,2),'1')n,PARSENAME(value,1)d FROM
STRING_SPLIT('100,90,80,70,60,50,40,30,20,15,12,10,9,8,7,6,5,2.9,4,2.7,3.10,3,3.8,2.5,3.7,4.9,2,5.9,4.7,3.5,5.8,2.3,7.10,5.7,3.4,7.9,4.5,5.6,6.7,7.8,8.9,9.10,11.12,14.15,19.20,29.30,39.40,49.50,59.60,69.70,79.80,89.90,99.100',','))m
ORDER BY ABS(i-ABS(n)/d)
Input is via pre-existing table t with numeric field i, per our IO standards.
That input table is joined with an in-memory table parsed from a string via STRING_SPLIT
(which separates rows) and PARSENAME
(which separates numerator and denominator via .
).
The table is sorted by distance from the input value i, and returns the top row, formatted appropriately.
add a comment |Â
up vote
6
down vote
T-SQL, 385 bytes
SELECT TOP 1IIF(i>.99,'>',IIF(i<.01,'<',''))+n+' in '+d
FROM t,(SELECT ISNULL(PARSENAME(value,2),'1')n,PARSENAME(value,1)d FROM
STRING_SPLIT('100,90,80,70,60,50,40,30,20,15,12,10,9,8,7,6,5,2.9,4,2.7,3.10,3,3.8,2.5,3.7,4.9,2,5.9,4.7,3.5,5.8,2.3,7.10,5.7,3.4,7.9,4.5,5.6,6.7,7.8,8.9,9.10,11.12,14.15,19.20,29.30,39.40,49.50,59.60,69.70,79.80,89.90,99.100',','))m
ORDER BY ABS(i-ABS(n)/d)
Input is via pre-existing table t with numeric field i, per our IO standards.
That input table is joined with an in-memory table parsed from a string via STRING_SPLIT
(which separates rows) and PARSENAME
(which separates numerator and denominator via .
).
The table is sorted by distance from the input value i, and returns the top row, formatted appropriately.
add a comment |Â
up vote
6
down vote
up vote
6
down vote
T-SQL, 385 bytes
SELECT TOP 1IIF(i>.99,'>',IIF(i<.01,'<',''))+n+' in '+d
FROM t,(SELECT ISNULL(PARSENAME(value,2),'1')n,PARSENAME(value,1)d FROM
STRING_SPLIT('100,90,80,70,60,50,40,30,20,15,12,10,9,8,7,6,5,2.9,4,2.7,3.10,3,3.8,2.5,3.7,4.9,2,5.9,4.7,3.5,5.8,2.3,7.10,5.7,3.4,7.9,4.5,5.6,6.7,7.8,8.9,9.10,11.12,14.15,19.20,29.30,39.40,49.50,59.60,69.70,79.80,89.90,99.100',','))m
ORDER BY ABS(i-ABS(n)/d)
Input is via pre-existing table t with numeric field i, per our IO standards.
That input table is joined with an in-memory table parsed from a string via STRING_SPLIT
(which separates rows) and PARSENAME
(which separates numerator and denominator via .
).
The table is sorted by distance from the input value i, and returns the top row, formatted appropriately.
T-SQL, 385 bytes
SELECT TOP 1IIF(i>.99,'>',IIF(i<.01,'<',''))+n+' in '+d
FROM t,(SELECT ISNULL(PARSENAME(value,2),'1')n,PARSENAME(value,1)d FROM
STRING_SPLIT('100,90,80,70,60,50,40,30,20,15,12,10,9,8,7,6,5,2.9,4,2.7,3.10,3,3.8,2.5,3.7,4.9,2,5.9,4.7,3.5,5.8,2.3,7.10,5.7,3.4,7.9,4.5,5.6,6.7,7.8,8.9,9.10,11.12,14.15,19.20,29.30,39.40,49.50,59.60,69.70,79.80,89.90,99.100',','))m
ORDER BY ABS(i-ABS(n)/d)
Input is via pre-existing table t with numeric field i, per our IO standards.
That input table is joined with an in-memory table parsed from a string via STRING_SPLIT
(which separates rows) and PARSENAME
(which separates numerator and denominator via .
).
The table is sorted by distance from the input value i, and returns the top row, formatted appropriately.
answered Aug 29 at 20:59
BradC
3,094521
3,094521
add a comment |Â
add a comment |Â
up vote
5
down vote
Charcoal, 84 bytes
NøFùùëFâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµùFòâÂÂÃÂ
â¦â¨úâÂÂùùâ§ÃȉÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷âÂÂâÂÂ÷âÂÂ÷÷ÃÂ<â¹ø÷â°ùÃÂ>âºø÷â¹â¹⪫çÃÂ
÷ in
Try it online! Link is to verbose version of code. Takes input as a decimal rather than a percentage. Explanation:
Nø
Input the fraction.
Fùùë
Run from $ n = 0 $ to $ n = 10 $.
FâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§
Generate ratios for $ frac 1 n $ to $ frac n - 1 n $.
âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµù
Get the $ n^th $ element of the list $ 12, 15, 20 ... 100 $ into $ n $.
FòâÂÂÃÂ
â¦â¨úâÂÂùùâ§û
Generate ratios for $ frac n - 1 n $ and $ frac 1 n $.
âÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷
Calculate the decimal values of all the ratios and take the absolute difference with the original input.
âÂÂâÂÂ÷âÂÂ÷÷
Find the index of the least absolute difference. In case of a tie (e.g. $ frac 1 2 $ and $ frac 2 4 $), take the ratio generated first.
ÃÂ<â¹ø÷â°ù
Print a <
if the input is less than $ 0.01 $.
ÃÂ>âºø÷â¹â¹
Print a >
if the input is greater than $ 0.99 $.
⪫çÃÂ
÷ in
Join the numerator and denominator of the appropriate ratio with in
and print.
add a comment |Â
up vote
5
down vote
Charcoal, 84 bytes
NøFùùëFâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµùFòâÂÂÃÂ
â¦â¨úâÂÂùùâ§ÃȉÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷âÂÂâÂÂ÷âÂÂ÷÷ÃÂ<â¹ø÷â°ùÃÂ>âºø÷â¹â¹⪫çÃÂ
÷ in
Try it online! Link is to verbose version of code. Takes input as a decimal rather than a percentage. Explanation:
Nø
Input the fraction.
Fùùë
Run from $ n = 0 $ to $ n = 10 $.
FâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§
Generate ratios for $ frac 1 n $ to $ frac n - 1 n $.
âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµù
Get the $ n^th $ element of the list $ 12, 15, 20 ... 100 $ into $ n $.
FòâÂÂÃÂ
â¦â¨úâÂÂùùâ§û
Generate ratios for $ frac n - 1 n $ and $ frac 1 n $.
âÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷
Calculate the decimal values of all the ratios and take the absolute difference with the original input.
âÂÂâÂÂ÷âÂÂ÷÷
Find the index of the least absolute difference. In case of a tie (e.g. $ frac 1 2 $ and $ frac 2 4 $), take the ratio generated first.
ÃÂ<â¹ø÷â°ù
Print a <
if the input is less than $ 0.01 $.
ÃÂ>âºø÷â¹â¹
Print a >
if the input is greater than $ 0.99 $.
⪫çÃÂ
÷ in
Join the numerator and denominator of the appropriate ratio with in
and print.
add a comment |Â
up vote
5
down vote
up vote
5
down vote
Charcoal, 84 bytes
NøFùùëFâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµùFòâÂÂÃÂ
â¦â¨úâÂÂùùâ§ÃȉÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷âÂÂâÂÂ÷âÂÂ÷÷ÃÂ<â¹ø÷â°ùÃÂ>âºø÷â¹â¹⪫çÃÂ
÷ in
Try it online! Link is to verbose version of code. Takes input as a decimal rather than a percentage. Explanation:
Nø
Input the fraction.
Fùùë
Run from $ n = 0 $ to $ n = 10 $.
FâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§
Generate ratios for $ frac 1 n $ to $ frac n - 1 n $.
âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµù
Get the $ n^th $ element of the list $ 12, 15, 20 ... 100 $ into $ n $.
FòâÂÂÃÂ
â¦â¨úâÂÂùùâ§û
Generate ratios for $ frac n - 1 n $ and $ frac 1 n $.
âÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷
Calculate the decimal values of all the ratios and take the absolute difference with the original input.
âÂÂâÂÂ÷âÂÂ÷÷
Find the index of the least absolute difference. In case of a tie (e.g. $ frac 1 2 $ and $ frac 2 4 $), take the ratio generated first.
ÃÂ<â¹ø÷â°ù
Print a <
if the input is less than $ 0.01 $.
ÃÂ>âºø÷â¹â¹
Print a >
if the input is greater than $ 0.99 $.
⪫çÃÂ
÷ in
Join the numerator and denominator of the appropriate ratio with in
and print.
Charcoal, 84 bytes
NøFùùëFâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµùFòâÂÂÃÂ
â¦â¨úâÂÂùùâ§ÃȉÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷âÂÂâÂÂ÷âÂÂ÷÷ÃÂ<â¹ø÷â°ùÃÂ>âºø÷â¹â¹⪫çÃÂ
÷ in
Try it online! Link is to verbose version of code. Takes input as a decimal rather than a percentage. Explanation:
Nø
Input the fraction.
Fùùë
Run from $ n = 0 $ to $ n = 10 $.
FâÂÂùâÂÂÃÂ
â¦âÂÂúùâ§
Generate ratios for $ frac 1 n $ to $ frac n - 1 n $.
âÂÂâÂÂâÂÂùâ¨ÃÂÃÂùùòæùâµù
Get the $ n^th $ element of the list $ 12, 15, 20 ... 100 $ into $ n $.
FòâÂÂÃÂ
â¦â¨úâÂÂùùâ§û
Generate ratios for $ frac n - 1 n $ and $ frac 1 n $.
âÂÂï¼¥ÃÂ
âÂÂâ»øâÂÂçùâ°çùù÷
Calculate the decimal values of all the ratios and take the absolute difference with the original input.
âÂÂâÂÂ÷âÂÂ÷÷
Find the index of the least absolute difference. In case of a tie (e.g. $ frac 1 2 $ and $ frac 2 4 $), take the ratio generated first.
ÃÂ<â¹ø÷â°ù
Print a <
if the input is less than $ 0.01 $.
ÃÂ>âºø÷â¹â¹
Print a >
if the input is greater than $ 0.99 $.
⪫çÃÂ
÷ in
Join the numerator and denominator of the appropriate ratio with in
and print.
answered Aug 29 at 20:50
Neil
75.1k744170
75.1k744170
add a comment |Â
add a comment |Â
up vote
5
down vote
JavaScript (ES7), 164 159 144 bytes
Expects an input ratio in $]0,1[$.
r=>(g=m=>--n+11?g((q=n>1?n*10:n+10-~'13'[n],d=((p=r<.1?1:r>.9?q-1:n<0&&r*q+.5|0)/q-r)**2)>m?m:(o=p+' in '+q,d)):r<.01?'<'+o:r>.99?'>'+o:o)(n=11)
Try it online!
How?
We try all possible ratios $p/q$. For each of them, we compute:
$$d=(p/q-r)^2$$
We update the best score $m$ (the lower, the better) each time $d$ is lower than or equal to $m$.
We go from the highest value of $q$ to the lowest one, so that a smaller denominator is preferred in case of a tie.
Commented
r => (g = m => // r = input; g() = recursive function, taking m = best score
--n + 11 ? // decrement n; if n is still greater than or equal to -10:
g( // do a recursive call to g():
( q = // compute q = denominator:
n > 1 ? // if n is greater than 1:
n * 10 // q = n * 10 (20, 30, ..., 100)
: // else:
n + 10 - ~'13'[n], // q = 12 if n = 0, 15 if n = 1, n + 11 if n < 0
d = (( // compute d = (p / q - r)ò:
p = // compute p = numerator:
r < .1 ? // if r is less than 0.01:
1 // p = 1
: // else:
r > .9 ? // if r is greater than 0.90:
q - 1 // p = q - 1
: // else:
n < 0 && // if n is negative (i.e. q is in [1,10]):
r * q + .5 | 0 // p = round(r * q)
// otherwise: p = 0 (which will be ignored)
) / q - r // compute p / q - r
) ** 2 // and square the result (cheaper than absolute value)
) > m ? // if d is greater than m:
m // leave m unchanged
: ( // else:
o = p + ' in ' + q, // update the output string o
d // and update m to d
)) // end of recursive call
: // else (all possible ratios have been tried out):
r < .01 ? '<' + o : // if r is less than 0.01, prefix with '<'
r > .99 ? '>' + o : // if r is greater than 0.99, prefix with '>'
o // otherwise, just return o
)(n = 11) // initial call to g() with m = n = 11
add a comment |Â
up vote
5
down vote
JavaScript (ES7), 164 159 144 bytes
Expects an input ratio in $]0,1[$.
r=>(g=m=>--n+11?g((q=n>1?n*10:n+10-~'13'[n],d=((p=r<.1?1:r>.9?q-1:n<0&&r*q+.5|0)/q-r)**2)>m?m:(o=p+' in '+q,d)):r<.01?'<'+o:r>.99?'>'+o:o)(n=11)
Try it online!
How?
We try all possible ratios $p/q$. For each of them, we compute:
$$d=(p/q-r)^2$$
We update the best score $m$ (the lower, the better) each time $d$ is lower than or equal to $m$.
We go from the highest value of $q$ to the lowest one, so that a smaller denominator is preferred in case of a tie.
Commented
r => (g = m => // r = input; g() = recursive function, taking m = best score
--n + 11 ? // decrement n; if n is still greater than or equal to -10:
g( // do a recursive call to g():
( q = // compute q = denominator:
n > 1 ? // if n is greater than 1:
n * 10 // q = n * 10 (20, 30, ..., 100)
: // else:
n + 10 - ~'13'[n], // q = 12 if n = 0, 15 if n = 1, n + 11 if n < 0
d = (( // compute d = (p / q - r)ò:
p = // compute p = numerator:
r < .1 ? // if r is less than 0.01:
1 // p = 1
: // else:
r > .9 ? // if r is greater than 0.90:
q - 1 // p = q - 1
: // else:
n < 0 && // if n is negative (i.e. q is in [1,10]):
r * q + .5 | 0 // p = round(r * q)
// otherwise: p = 0 (which will be ignored)
) / q - r // compute p / q - r
) ** 2 // and square the result (cheaper than absolute value)
) > m ? // if d is greater than m:
m // leave m unchanged
: ( // else:
o = p + ' in ' + q, // update the output string o
d // and update m to d
)) // end of recursive call
: // else (all possible ratios have been tried out):
r < .01 ? '<' + o : // if r is less than 0.01, prefix with '<'
r > .99 ? '>' + o : // if r is greater than 0.99, prefix with '>'
o // otherwise, just return o
)(n = 11) // initial call to g() with m = n = 11
add a comment |Â
up vote
5
down vote
up vote
5
down vote
JavaScript (ES7), 164 159 144 bytes
Expects an input ratio in $]0,1[$.
r=>(g=m=>--n+11?g((q=n>1?n*10:n+10-~'13'[n],d=((p=r<.1?1:r>.9?q-1:n<0&&r*q+.5|0)/q-r)**2)>m?m:(o=p+' in '+q,d)):r<.01?'<'+o:r>.99?'>'+o:o)(n=11)
Try it online!
How?
We try all possible ratios $p/q$. For each of them, we compute:
$$d=(p/q-r)^2$$
We update the best score $m$ (the lower, the better) each time $d$ is lower than or equal to $m$.
We go from the highest value of $q$ to the lowest one, so that a smaller denominator is preferred in case of a tie.
Commented
r => (g = m => // r = input; g() = recursive function, taking m = best score
--n + 11 ? // decrement n; if n is still greater than or equal to -10:
g( // do a recursive call to g():
( q = // compute q = denominator:
n > 1 ? // if n is greater than 1:
n * 10 // q = n * 10 (20, 30, ..., 100)
: // else:
n + 10 - ~'13'[n], // q = 12 if n = 0, 15 if n = 1, n + 11 if n < 0
d = (( // compute d = (p / q - r)ò:
p = // compute p = numerator:
r < .1 ? // if r is less than 0.01:
1 // p = 1
: // else:
r > .9 ? // if r is greater than 0.90:
q - 1 // p = q - 1
: // else:
n < 0 && // if n is negative (i.e. q is in [1,10]):
r * q + .5 | 0 // p = round(r * q)
// otherwise: p = 0 (which will be ignored)
) / q - r // compute p / q - r
) ** 2 // and square the result (cheaper than absolute value)
) > m ? // if d is greater than m:
m // leave m unchanged
: ( // else:
o = p + ' in ' + q, // update the output string o
d // and update m to d
)) // end of recursive call
: // else (all possible ratios have been tried out):
r < .01 ? '<' + o : // if r is less than 0.01, prefix with '<'
r > .99 ? '>' + o : // if r is greater than 0.99, prefix with '>'
o // otherwise, just return o
)(n = 11) // initial call to g() with m = n = 11
JavaScript (ES7), 164 159 144 bytes
Expects an input ratio in $]0,1[$.
r=>(g=m=>--n+11?g((q=n>1?n*10:n+10-~'13'[n],d=((p=r<.1?1:r>.9?q-1:n<0&&r*q+.5|0)/q-r)**2)>m?m:(o=p+' in '+q,d)):r<.01?'<'+o:r>.99?'>'+o:o)(n=11)
Try it online!
How?
We try all possible ratios $p/q$. For each of them, we compute:
$$d=(p/q-r)^2$$
We update the best score $m$ (the lower, the better) each time $d$ is lower than or equal to $m$.
We go from the highest value of $q$ to the lowest one, so that a smaller denominator is preferred in case of a tie.
Commented
r => (g = m => // r = input; g() = recursive function, taking m = best score
--n + 11 ? // decrement n; if n is still greater than or equal to -10:
g( // do a recursive call to g():
( q = // compute q = denominator:
n > 1 ? // if n is greater than 1:
n * 10 // q = n * 10 (20, 30, ..., 100)
: // else:
n + 10 - ~'13'[n], // q = 12 if n = 0, 15 if n = 1, n + 11 if n < 0
d = (( // compute d = (p / q - r)ò:
p = // compute p = numerator:
r < .1 ? // if r is less than 0.01:
1 // p = 1
: // else:
r > .9 ? // if r is greater than 0.90:
q - 1 // p = q - 1
: // else:
n < 0 && // if n is negative (i.e. q is in [1,10]):
r * q + .5 | 0 // p = round(r * q)
// otherwise: p = 0 (which will be ignored)
) / q - r // compute p / q - r
) ** 2 // and square the result (cheaper than absolute value)
) > m ? // if d is greater than m:
m // leave m unchanged
: ( // else:
o = p + ' in ' + q, // update the output string o
d // and update m to d
)) // end of recursive call
: // else (all possible ratios have been tried out):
r < .01 ? '<' + o : // if r is less than 0.01, prefix with '<'
r > .99 ? '>' + o : // if r is greater than 0.99, prefix with '>'
o // otherwise, just return o
)(n = 11) // initial call to g() with m = n = 11
edited Aug 30 at 7:01
answered Aug 29 at 16:13
Arnauld
63.5k580268
63.5k580268
add a comment |Â
add a comment |Â
up vote
4
down vote
Jelly, 58 bytes
âµRÃÂâµ;12,15õâÂÂ,1,â¬)áºÂ;âµÃ
Âcäð÷/ạÃÂ¥ÃÂḢjâ in âÂÂ
âÂÂ<âÂÂ>âÂÂâÂÂ>.99$?<.01$?;ÃÂ
Try it online!
-16 bytes thanks to Arnauld (can just prepend the <
and >
instead of rewriting the whole phrase)
-6 bytes and bug-fixes thanks to Jonathan Allan
@Arnauld Oh you're right, never thought about that :P Thanks!
â HyperNeutrino
Aug 30 at 0:18
0.3
should result in3 in 10
not2 in 7
â Jonathan Allan
Aug 30 at 7:45
You should just remove theµµ
, no? EDIT - and then golfÃá¹Âá¹Â
toÃḢ
â Jonathan Allan
Aug 30 at 7:45
changing9
toâµ
should resolve the bug I believe.
â Jonathan Allan
Aug 30 at 8:09
@JonathanAllan Oh whoops, yep I wasn't using 10 as a valid denominator. Thanks. And no, removing the double mu doesn't work because then the "minimum" is attached to the right side of the dyadic link-min function which is definitely not what I want, but only putting one mu doesn't seem to fix it. Thanks for the golf though :D
â HyperNeutrino
Aug 31 at 15:06
 |Â
show 5 more comments
up vote
4
down vote
Jelly, 58 bytes
âµRÃÂâµ;12,15õâÂÂ,1,â¬)áºÂ;âµÃ
Âcäð÷/ạÃÂ¥ÃÂḢjâ in âÂÂ
âÂÂ<âÂÂ>âÂÂâÂÂ>.99$?<.01$?;ÃÂ
Try it online!
-16 bytes thanks to Arnauld (can just prepend the <
and >
instead of rewriting the whole phrase)
-6 bytes and bug-fixes thanks to Jonathan Allan
@Arnauld Oh you're right, never thought about that :P Thanks!
â HyperNeutrino
Aug 30 at 0:18
0.3
should result in3 in 10
not2 in 7
â Jonathan Allan
Aug 30 at 7:45
You should just remove theµµ
, no? EDIT - and then golfÃá¹Âá¹Â
toÃḢ
â Jonathan Allan
Aug 30 at 7:45
changing9
toâµ
should resolve the bug I believe.
â Jonathan Allan
Aug 30 at 8:09
@JonathanAllan Oh whoops, yep I wasn't using 10 as a valid denominator. Thanks. And no, removing the double mu doesn't work because then the "minimum" is attached to the right side of the dyadic link-min function which is definitely not what I want, but only putting one mu doesn't seem to fix it. Thanks for the golf though :D
â HyperNeutrino
Aug 31 at 15:06
 |Â
show 5 more comments
up vote
4
down vote
up vote
4
down vote
Jelly, 58 bytes
âµRÃÂâµ;12,15õâÂÂ,1,â¬)áºÂ;âµÃ
Âcäð÷/ạÃÂ¥ÃÂḢjâ in âÂÂ
âÂÂ<âÂÂ>âÂÂâÂÂ>.99$?<.01$?;ÃÂ
Try it online!
-16 bytes thanks to Arnauld (can just prepend the <
and >
instead of rewriting the whole phrase)
-6 bytes and bug-fixes thanks to Jonathan Allan
Jelly, 58 bytes
âµRÃÂâµ;12,15õâÂÂ,1,â¬)áºÂ;âµÃ
Âcäð÷/ạÃÂ¥ÃÂḢjâ in âÂÂ
âÂÂ<âÂÂ>âÂÂâÂÂ>.99$?<.01$?;ÃÂ
Try it online!
-16 bytes thanks to Arnauld (can just prepend the <
and >
instead of rewriting the whole phrase)
-6 bytes and bug-fixes thanks to Jonathan Allan
edited Sep 2 at 2:53
answered Aug 29 at 21:26
HyperNeutrino
18.6k437147
18.6k437147
@Arnauld Oh you're right, never thought about that :P Thanks!
â HyperNeutrino
Aug 30 at 0:18
0.3
should result in3 in 10
not2 in 7
â Jonathan Allan
Aug 30 at 7:45
You should just remove theµµ
, no? EDIT - and then golfÃá¹Âá¹Â
toÃḢ
â Jonathan Allan
Aug 30 at 7:45
changing9
toâµ
should resolve the bug I believe.
â Jonathan Allan
Aug 30 at 8:09
@JonathanAllan Oh whoops, yep I wasn't using 10 as a valid denominator. Thanks. And no, removing the double mu doesn't work because then the "minimum" is attached to the right side of the dyadic link-min function which is definitely not what I want, but only putting one mu doesn't seem to fix it. Thanks for the golf though :D
â HyperNeutrino
Aug 31 at 15:06
 |Â
show 5 more comments
@Arnauld Oh you're right, never thought about that :P Thanks!
â HyperNeutrino
Aug 30 at 0:18
0.3
should result in3 in 10
not2 in 7
â Jonathan Allan
Aug 30 at 7:45
You should just remove theµµ
, no? EDIT - and then golfÃá¹Âá¹Â
toÃḢ
â Jonathan Allan
Aug 30 at 7:45
changing9
toâµ
should resolve the bug I believe.
â Jonathan Allan
Aug 30 at 8:09
@JonathanAllan Oh whoops, yep I wasn't using 10 as a valid denominator. Thanks. And no, removing the double mu doesn't work because then the "minimum" is attached to the right side of the dyadic link-min function which is definitely not what I want, but only putting one mu doesn't seem to fix it. Thanks for the golf though :D
â HyperNeutrino
Aug 31 at 15:06
@Arnauld Oh you're right, never thought about that :P Thanks!
â HyperNeutrino
Aug 30 at 0:18
@Arnauld Oh you're right, never thought about that :P Thanks!
â HyperNeutrino
Aug 30 at 0:18
0.3
should result in 3 in 10
not 2 in 7
â Jonathan Allan
Aug 30 at 7:45
0.3
should result in 3 in 10
not 2 in 7
â Jonathan Allan
Aug 30 at 7:45
You should just remove the
µµ
, no? EDIT - and then golf Ãá¹Âá¹Â
to ÃḢ
â Jonathan Allan
Aug 30 at 7:45
You should just remove the
µµ
, no? EDIT - and then golf Ãá¹Âá¹Â
to ÃḢ
â Jonathan Allan
Aug 30 at 7:45
changing
9
to âµ
should resolve the bug I believe.â Jonathan Allan
Aug 30 at 8:09
changing
9
to âµ
should resolve the bug I believe.â Jonathan Allan
Aug 30 at 8:09
@JonathanAllan Oh whoops, yep I wasn't using 10 as a valid denominator. Thanks. And no, removing the double mu doesn't work because then the "minimum" is attached to the right side of the dyadic link-min function which is definitely not what I want, but only putting one mu doesn't seem to fix it. Thanks for the golf though :D
â HyperNeutrino
Aug 31 at 15:06
@JonathanAllan Oh whoops, yep I wasn't using 10 as a valid denominator. Thanks. And no, removing the double mu doesn't work because then the "minimum" is attached to the right side of the dyadic link-min function which is definitely not what I want, but only putting one mu doesn't seem to fix it. Thanks for the golf though :D
â HyperNeutrino
Aug 31 at 15:06
 |Â
show 5 more comments
up vote
3
down vote
Python 2, 261 278 261 237 177 bytes
lambda n:' <>'[(n<.01)-(n>.99)]+'%d in %d'%min([(a,b)for b in[[12,15]+r(10,110,10),r(1,11)][.1<n<.9]for a in r([1,b-1][n>.9],[b,2][n<.1])],key=lambda(a,b):abs(1.*a/b-n))
r=range
Try it online!
1
Doesn't Python support semicolons? You could replace'n '
with';'
... unless I'm wrong.
â Dev
Aug 30 at 2:12
@BradC Fixed :)
â TFeld
Aug 30 at 6:49
add a comment |Â
up vote
3
down vote
Python 2, 261 278 261 237 177 bytes
lambda n:' <>'[(n<.01)-(n>.99)]+'%d in %d'%min([(a,b)for b in[[12,15]+r(10,110,10),r(1,11)][.1<n<.9]for a in r([1,b-1][n>.9],[b,2][n<.1])],key=lambda(a,b):abs(1.*a/b-n))
r=range
Try it online!
1
Doesn't Python support semicolons? You could replace'n '
with';'
... unless I'm wrong.
â Dev
Aug 30 at 2:12
@BradC Fixed :)
â TFeld
Aug 30 at 6:49
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Python 2, 261 278 261 237 177 bytes
lambda n:' <>'[(n<.01)-(n>.99)]+'%d in %d'%min([(a,b)for b in[[12,15]+r(10,110,10),r(1,11)][.1<n<.9]for a in r([1,b-1][n>.9],[b,2][n<.1])],key=lambda(a,b):abs(1.*a/b-n))
r=range
Try it online!
Python 2, 261 278 261 237 177 bytes
lambda n:' <>'[(n<.01)-(n>.99)]+'%d in %d'%min([(a,b)for b in[[12,15]+r(10,110,10),r(1,11)][.1<n<.9]for a in r([1,b-1][n>.9],[b,2][n<.1])],key=lambda(a,b):abs(1.*a/b-n))
r=range
Try it online!
edited Aug 30 at 7:24
answered Aug 29 at 15:07
TFeld
11.2k2833
11.2k2833
1
Doesn't Python support semicolons? You could replace'n '
with';'
... unless I'm wrong.
â Dev
Aug 30 at 2:12
@BradC Fixed :)
â TFeld
Aug 30 at 6:49
add a comment |Â
1
Doesn't Python support semicolons? You could replace'n '
with';'
... unless I'm wrong.
â Dev
Aug 30 at 2:12
@BradC Fixed :)
â TFeld
Aug 30 at 6:49
1
1
Doesn't Python support semicolons? You could replace
'n '
with ';'
... unless I'm wrong.â Dev
Aug 30 at 2:12
Doesn't Python support semicolons? You could replace
'n '
with ';'
... unless I'm wrong.â Dev
Aug 30 at 2:12
@BradC Fixed :)
â TFeld
Aug 30 at 6:49
@BradC Fixed :)
â TFeld
Aug 30 at 6:49
add a comment |Â
up vote
3
down vote
Clean, 224 198 197 bytes
import StdEnv,Data.List,Text
t=toReal
$p=if(p<1.0)"<"if(p>99.0)">"""+snd(minimum[(abs(p-t n*1E2/t d),n<+" in "<+d)\i<-[10,12,15:[20,30..100]],(n,d)<-[(1,i),(i-1,i):diag2[1..10][1..10]]|gcd n d<2])
Try it online!
Explained:
t = toReal // give `toReal` a shorter name
$ p
= if(p < 1.0) // if the percentage is less than 1%
"<" // prepend "<"
if(p > 99.0) // if the percentage is > 99%
">" // prepend ">"
"" // otherwise prepend nothing
+ snd ( // to the second element of
minimum [ // the smallest item in a list composed of
( // pairs of
abs ( // the absolute value of
p - // the difference between the percentage
t n*1E2 / t d // and the ratio
)
, // associated with
n <+ " in " <+ d // the string representation of the ratio
) // in the form of a tuple
\ i <- [10, 12, 15: [20, 30..100]] // for every special denominator `i`
, (n, d) <- [(1, i), (i - 1, i): diag2 [1..10] [1..10]]
// for every ratio `n` : `d`
| gcd n d < 2 // where `n` / `d` cannot be further simplified
]
)
add a comment |Â
up vote
3
down vote
Clean, 224 198 197 bytes
import StdEnv,Data.List,Text
t=toReal
$p=if(p<1.0)"<"if(p>99.0)">"""+snd(minimum[(abs(p-t n*1E2/t d),n<+" in "<+d)\i<-[10,12,15:[20,30..100]],(n,d)<-[(1,i),(i-1,i):diag2[1..10][1..10]]|gcd n d<2])
Try it online!
Explained:
t = toReal // give `toReal` a shorter name
$ p
= if(p < 1.0) // if the percentage is less than 1%
"<" // prepend "<"
if(p > 99.0) // if the percentage is > 99%
">" // prepend ">"
"" // otherwise prepend nothing
+ snd ( // to the second element of
minimum [ // the smallest item in a list composed of
( // pairs of
abs ( // the absolute value of
p - // the difference between the percentage
t n*1E2 / t d // and the ratio
)
, // associated with
n <+ " in " <+ d // the string representation of the ratio
) // in the form of a tuple
\ i <- [10, 12, 15: [20, 30..100]] // for every special denominator `i`
, (n, d) <- [(1, i), (i - 1, i): diag2 [1..10] [1..10]]
// for every ratio `n` : `d`
| gcd n d < 2 // where `n` / `d` cannot be further simplified
]
)
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Clean, 224 198 197 bytes
import StdEnv,Data.List,Text
t=toReal
$p=if(p<1.0)"<"if(p>99.0)">"""+snd(minimum[(abs(p-t n*1E2/t d),n<+" in "<+d)\i<-[10,12,15:[20,30..100]],(n,d)<-[(1,i),(i-1,i):diag2[1..10][1..10]]|gcd n d<2])
Try it online!
Explained:
t = toReal // give `toReal` a shorter name
$ p
= if(p < 1.0) // if the percentage is less than 1%
"<" // prepend "<"
if(p > 99.0) // if the percentage is > 99%
">" // prepend ">"
"" // otherwise prepend nothing
+ snd ( // to the second element of
minimum [ // the smallest item in a list composed of
( // pairs of
abs ( // the absolute value of
p - // the difference between the percentage
t n*1E2 / t d // and the ratio
)
, // associated with
n <+ " in " <+ d // the string representation of the ratio
) // in the form of a tuple
\ i <- [10, 12, 15: [20, 30..100]] // for every special denominator `i`
, (n, d) <- [(1, i), (i - 1, i): diag2 [1..10] [1..10]]
// for every ratio `n` : `d`
| gcd n d < 2 // where `n` / `d` cannot be further simplified
]
)
Clean, 224 198 197 bytes
import StdEnv,Data.List,Text
t=toReal
$p=if(p<1.0)"<"if(p>99.0)">"""+snd(minimum[(abs(p-t n*1E2/t d),n<+" in "<+d)\i<-[10,12,15:[20,30..100]],(n,d)<-[(1,i),(i-1,i):diag2[1..10][1..10]]|gcd n d<2])
Try it online!
Explained:
t = toReal // give `toReal` a shorter name
$ p
= if(p < 1.0) // if the percentage is less than 1%
"<" // prepend "<"
if(p > 99.0) // if the percentage is > 99%
">" // prepend ">"
"" // otherwise prepend nothing
+ snd ( // to the second element of
minimum [ // the smallest item in a list composed of
( // pairs of
abs ( // the absolute value of
p - // the difference between the percentage
t n*1E2 / t d // and the ratio
)
, // associated with
n <+ " in " <+ d // the string representation of the ratio
) // in the form of a tuple
\ i <- [10, 12, 15: [20, 30..100]] // for every special denominator `i`
, (n, d) <- [(1, i), (i - 1, i): diag2 [1..10] [1..10]]
// for every ratio `n` : `d`
| gcd n d < 2 // where `n` / `d` cannot be further simplified
]
)
edited Aug 30 at 8:42
answered Aug 29 at 23:53
ÃÂurous
5,2031931
5,2031931
add a comment |Â
add a comment |Â
up vote
3
down vote
Jelly, Â 53Â 52 bytes
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in
A full program which prints the result.
Try it online!
Or see the test-suite
Note that the test-suite is altered to make the code a monadic link by:
- using the register keep a track of the current "program input", with
ó
toî
; and - closing the list of characters code for " in ", with
â in
toâ in âÂÂ
How?
Starts with code that forces any necessary printing of the <
or >
sign and then code which constructs all the numerator-denominator pairs (with some redundant not simplified form versions, all after their simplified form) and prints the minimally different division-evaluated entry using a stable sort joined with in
.
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in - Main Link: number in [0,1], n
.01,.99 - literal pair = [0.01, 0.99]
_ - subtract -> [n - 0.01, n - 0.99]
á¹ - sign (vectorises) (-1 if <0; 1 if >0; else 0)
õ - start a new monadic link
- call that X
<0 - less than zero? (vectorises)
ÃÂ< - literal list of characters = "<>"
á» - index into (vectorises) ("<<" if n < 0.01; ">>" if n >= 0.99; else "><")
E - all (of X) equal? (1 if ((n < 0.01) OR (n > 0.99)) else 0
ḣ - head to index ("<" if n < 0.01; ">" if n > 0.99; else "")
- (the following nilad forces a print of that)
âµ - literal 10
Ã
» - zero-range -> [0,1,2,3,4,5,6,7,8,9,10]
ÃÂâµ - multiply by 10 -> [0,10,20,30,40,50,60,70,80,90,100]
12,5 - literal pair = [12,5]
+ - add -> [12,15,20,30,40,50,60,70,80,90,100]
$ - last two links as a monad
ÃÂ - last three links as a monad
á¹ - sign -> [1,1,1,1,1,1,1,1,1,1,1]
â - decrement -> [11,14,19,29,39,49,59,69,79,89,99]
, - pair -> [[1,1,1,1,1,1,1,1,1,1,1],[11,14,19,29,39,49,59,69,79,89,99]]
Ã
¼â¬ - zip with for â¬ach -> [[[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100]],[[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]]
Ạ- tighten -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]
ä - nilad followed by link(s) as a nilad:
âµ - literal 10
Ã
Âc - unordered pairs -> [[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
; - concatenate -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
ÃÂ - sort by:
ÃÂ¥ - last two links as a dyad:
- ...(with right argument of
ó - the program input, n)
/ - reduce by:
÷ - division
ạ - absolute difference
Ḣ - head
â in - literal list of characters " in "
; - concatenate
- implicit print
add a comment |Â
up vote
3
down vote
Jelly, Â 53Â 52 bytes
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in
A full program which prints the result.
Try it online!
Or see the test-suite
Note that the test-suite is altered to make the code a monadic link by:
- using the register keep a track of the current "program input", with
ó
toî
; and - closing the list of characters code for " in ", with
â in
toâ in âÂÂ
How?
Starts with code that forces any necessary printing of the <
or >
sign and then code which constructs all the numerator-denominator pairs (with some redundant not simplified form versions, all after their simplified form) and prints the minimally different division-evaluated entry using a stable sort joined with in
.
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in - Main Link: number in [0,1], n
.01,.99 - literal pair = [0.01, 0.99]
_ - subtract -> [n - 0.01, n - 0.99]
á¹ - sign (vectorises) (-1 if <0; 1 if >0; else 0)
õ - start a new monadic link
- call that X
<0 - less than zero? (vectorises)
ÃÂ< - literal list of characters = "<>"
á» - index into (vectorises) ("<<" if n < 0.01; ">>" if n >= 0.99; else "><")
E - all (of X) equal? (1 if ((n < 0.01) OR (n > 0.99)) else 0
ḣ - head to index ("<" if n < 0.01; ">" if n > 0.99; else "")
- (the following nilad forces a print of that)
âµ - literal 10
Ã
» - zero-range -> [0,1,2,3,4,5,6,7,8,9,10]
ÃÂâµ - multiply by 10 -> [0,10,20,30,40,50,60,70,80,90,100]
12,5 - literal pair = [12,5]
+ - add -> [12,15,20,30,40,50,60,70,80,90,100]
$ - last two links as a monad
ÃÂ - last three links as a monad
á¹ - sign -> [1,1,1,1,1,1,1,1,1,1,1]
â - decrement -> [11,14,19,29,39,49,59,69,79,89,99]
, - pair -> [[1,1,1,1,1,1,1,1,1,1,1],[11,14,19,29,39,49,59,69,79,89,99]]
Ã
¼â¬ - zip with for â¬ach -> [[[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100]],[[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]]
Ạ- tighten -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]
ä - nilad followed by link(s) as a nilad:
âµ - literal 10
Ã
Âc - unordered pairs -> [[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
; - concatenate -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
ÃÂ - sort by:
ÃÂ¥ - last two links as a dyad:
- ...(with right argument of
ó - the program input, n)
/ - reduce by:
÷ - division
ạ - absolute difference
Ḣ - head
â in - literal list of characters " in "
; - concatenate
- implicit print
add a comment |Â
up vote
3
down vote
up vote
3
down vote
Jelly, Â 53Â 52 bytes
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in
A full program which prints the result.
Try it online!
Or see the test-suite
Note that the test-suite is altered to make the code a monadic link by:
- using the register keep a track of the current "program input", with
ó
toî
; and - closing the list of characters code for " in ", with
â in
toâ in âÂÂ
How?
Starts with code that forces any necessary printing of the <
or >
sign and then code which constructs all the numerator-denominator pairs (with some redundant not simplified form versions, all after their simplified form) and prints the minimally different division-evaluated entry using a stable sort joined with in
.
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in - Main Link: number in [0,1], n
.01,.99 - literal pair = [0.01, 0.99]
_ - subtract -> [n - 0.01, n - 0.99]
á¹ - sign (vectorises) (-1 if <0; 1 if >0; else 0)
õ - start a new monadic link
- call that X
<0 - less than zero? (vectorises)
ÃÂ< - literal list of characters = "<>"
á» - index into (vectorises) ("<<" if n < 0.01; ">>" if n >= 0.99; else "><")
E - all (of X) equal? (1 if ((n < 0.01) OR (n > 0.99)) else 0
ḣ - head to index ("<" if n < 0.01; ">" if n > 0.99; else "")
- (the following nilad forces a print of that)
âµ - literal 10
Ã
» - zero-range -> [0,1,2,3,4,5,6,7,8,9,10]
ÃÂâµ - multiply by 10 -> [0,10,20,30,40,50,60,70,80,90,100]
12,5 - literal pair = [12,5]
+ - add -> [12,15,20,30,40,50,60,70,80,90,100]
$ - last two links as a monad
ÃÂ - last three links as a monad
á¹ - sign -> [1,1,1,1,1,1,1,1,1,1,1]
â - decrement -> [11,14,19,29,39,49,59,69,79,89,99]
, - pair -> [[1,1,1,1,1,1,1,1,1,1,1],[11,14,19,29,39,49,59,69,79,89,99]]
Ã
¼â¬ - zip with for â¬ach -> [[[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100]],[[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]]
Ạ- tighten -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]
ä - nilad followed by link(s) as a nilad:
âµ - literal 10
Ã
Âc - unordered pairs -> [[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
; - concatenate -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
ÃÂ - sort by:
ÃÂ¥ - last two links as a dyad:
- ...(with right argument of
ó - the program input, n)
/ - reduce by:
÷ - division
ạ - absolute difference
Ḣ - head
â in - literal list of characters " in "
; - concatenate
- implicit print
Jelly, Â 53Â 52 bytes
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in
A full program which prints the result.
Try it online!
Or see the test-suite
Note that the test-suite is altered to make the code a monadic link by:
- using the register keep a track of the current "program input", with
ó
toî
; and - closing the list of characters code for " in ", with
â in
toâ in âÂÂ
How?
Starts with code that forces any necessary printing of the <
or >
sign and then code which constructs all the numerator-denominator pairs (with some redundant not simplified form versions, all after their simplified form) and prints the minimally different division-evaluated entry using a stable sort joined with in
.
_.01,.99Ṡõ<0á»ÂÃÂ<ḣEâµÃ
»ÃÂâµ+12,5á¹ ,âÂÂÃÂÃ
¼â¬$áºÂ;âµÃ
Âcä÷/ạÃÂ¥ÃÂóḢjâ in - Main Link: number in [0,1], n
.01,.99 - literal pair = [0.01, 0.99]
_ - subtract -> [n - 0.01, n - 0.99]
á¹ - sign (vectorises) (-1 if <0; 1 if >0; else 0)
õ - start a new monadic link
- call that X
<0 - less than zero? (vectorises)
ÃÂ< - literal list of characters = "<>"
á» - index into (vectorises) ("<<" if n < 0.01; ">>" if n >= 0.99; else "><")
E - all (of X) equal? (1 if ((n < 0.01) OR (n > 0.99)) else 0
ḣ - head to index ("<" if n < 0.01; ">" if n > 0.99; else "")
- (the following nilad forces a print of that)
âµ - literal 10
Ã
» - zero-range -> [0,1,2,3,4,5,6,7,8,9,10]
ÃÂâµ - multiply by 10 -> [0,10,20,30,40,50,60,70,80,90,100]
12,5 - literal pair = [12,5]
+ - add -> [12,15,20,30,40,50,60,70,80,90,100]
$ - last two links as a monad
ÃÂ - last three links as a monad
á¹ - sign -> [1,1,1,1,1,1,1,1,1,1,1]
â - decrement -> [11,14,19,29,39,49,59,69,79,89,99]
, - pair -> [[1,1,1,1,1,1,1,1,1,1,1],[11,14,19,29,39,49,59,69,79,89,99]]
Ã
¼â¬ - zip with for â¬ach -> [[[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100]],[[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]]
Ạ- tighten -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100]]
ä - nilad followed by link(s) as a nilad:
âµ - literal 10
Ã
Âc - unordered pairs -> [[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
; - concatenate -> [[1,12],[1,15],[1,20],[1,30],[1,40],[1,50],[1,60],[1,70],[1,80],[1,90],[1,100],[11,12],[14,15],[19,20],[29,30],[39,40],[49,50],[59,60],[69,70],[79,80],[89,90],[99,100],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[1,10],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[2,10],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[3,10],[4,5],[4,6],[4,7],[4,8],[4,9],[4,10],[5,6],[5,7],[5,8],[5,9],[5,10],[6,7],[6,8],[6,9],[6,10],[7,8],[7,9],[7,10],[8,9],[8,10],[9,10]]
ÃÂ - sort by:
ÃÂ¥ - last two links as a dyad:
- ...(with right argument of
ó - the program input, n)
/ - reduce by:
÷ - division
ạ - absolute difference
Ḣ - head
â in - literal list of characters " in "
; - concatenate
- implicit print
edited Aug 31 at 18:48
answered Aug 29 at 18:43
Jonathan Allan
48k534158
48k534158
add a comment |Â
add a comment |Â
up vote
2
down vote
Perl 6, 118 bytes
(^11 X*10))).min(abs $_-[/] @^a).join(' in ')
Try it online!
add a comment |Â
up vote
2
down vote
Perl 6, 118 bytes
(^11 X*10))).min(abs $_-[/] @^a).join(' in ')
Try it online!
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Perl 6, 118 bytes
(^11 X*10))).min(abs $_-[/] @^a).join(' in ')
Try it online!
Perl 6, 118 bytes
(^11 X*10))).min(abs $_-[/] @^a).join(' in ')
Try it online!
answered Aug 30 at 10:42
nwellnhof
3,503714
3,503714
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f171417%2fconvert-a-percentage-to-a-simple-ratio%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
If there are two ratios equally close to the input, your program can return either one. 7.5% could return "1 in 12" or "1 in 15"
Does that mean that we can return7 in 100
as well? Btw,1 in 14
is closer to the input in this case.â DimChtz
Aug 29 at 14:48
@DimChtz No, as that violates rule 3 (values under 10% should be expressed as "1 in n", for specific possible values of n).
â BradC
Aug 29 at 14:50
Ohh, I didn't notice this. Okay.
â DimChtz
Aug 29 at 14:51
2
I'd like it if we could just output the numerator and denominator as any format like a tuple/list or something, but there are already competing answers so I suppose it's too late for this challenge. For future challenges though, I'd consider a more flexible I/O format because some languages lose more competitiveness than others when you require string handling.
â HyperNeutrino
Aug 29 at 21:12
1
@BradC - LOL. I was just at 538, and I was all "Wow! I gotta make a golfing challenge out of this!"
â Chas Brown
Aug 29 at 21:23