Chuyển đổi tỷ lệ phần trăm thành tỷ lệ đơn giản của người Viking


16

Bạn điều hành một trang web chính trị và đã xác định rằng mọi người có sự hiểu biết trực quan tốt hơn khi cơ hội giành chiến thắng hoặc thua cuộc bầu cử được biểu thị bằng tỷ lệ ("5 trong 7") so với khi nó được biểu thị bằng tỷ lệ phần trăm ("71%" ).

Nhưng bạn cũng không muốn hiển thị các tỷ lệ khó hiểu như "58 trong 82", bạn muốn chúng dễ hiểu hơn, ngay cả khi chúng không hoàn toàn chính xác.

Vì vậy, với tỷ lệ phần trăm từ 0,1% đến 99,9%, hãy trả về tỷ lệ "dễ hiểu" gần nhất " x trong y ", sử dụng các quy tắc sau :

  1. Hầu hết các giá trị (xem ngoại lệ bên dưới) sẽ trả về tỷ lệ gần nhất trong số 10 hoặc thấp hơn . 55% nên trả về "5 trong 9", chứ không phải "11 trong 20".
  2. Tỷ lệ nên được giảm đến các điều khoản thấp nhất của họ . 65% nên trả về "2 trong 3", chứ không phải "4 trong 6".
  3. Các giá trị dưới 10% sẽ trả về tỷ lệ gần nhất của mẫu " 1 trong n " trong đó n là một trong (10,12,15,20,30,40,50,60,70,80,90,100) . Ví dụ: 6% sẽ trả về "1 trong 15".
  4. Các giá trị trên 90% sẽ trả về tỷ lệ gần nhất của mẫu " n-1 in n " trong đó n là một trong (10,12,15,20,30,40,50,60,70,80,90,100) . Ví dụ: 98,7% sẽ trả về "79 trong 80".
  5. Các giá trị dưới 1% sẽ trả về " <1 trên 100 "
  6. Giá trị trên 99% sẽ trả về " > 99 trong 100 "

Hoặc, để suy nghĩ về nó theo cách khác, chương trình của bạn sẽ trả về tỷ lệ gần nhất từ ​​các đầu ra có thể sau (Tôi đã bao gồm các giá trị gần đúng của chúng để thuận tiện cho bạn):

<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

Các quy định khác:

  • Đầu vào số có thể nằm trong khoảng 0,1 đến 99,9 hoặc trong phạm vi 0,001 đến 0,999 , tùy theo điều kiện nào thuận tiện hơn. Bạn phải xử lý ít nhất 3 chữ số có nghĩa.
  • Bạn phải xuất tỷ lệ ("3 trong 4"), không phải là tỷ lệ tương đương ("3/4").
  • Nếu có hai tỷ lệ gần bằng với đầu vào, chương trình của bạn có thể trả về một tỷ lệ. 7,5% có thể trả về "1 trong 12" hoặc "1 trong 15".
  • Khoảng trắng hàng đầu / dấu và / hoặc dòng mới là tốt

Ví dụ :

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

Đây là một thử thách , mã ngắn nhất trong mỗi ngôn ngữ sẽ thắng.

(Tương tự, nhưng không trùng lặp: Chuyển đổi số thập phân thành phân số , Phân số gần nhất , Số dấu phẩy động gần đúng với độ chính xác n chữ số )


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"Điều đó có nghĩa là chúng tôi cũng có thể trở lại 7 in 100? Btw, 1 in 14gần với đầu vào hơn trong trường hợp này.
DimChtz

@DimChtz Không, vì vi phạm quy tắc 3 (các giá trị dưới 10% phải được biểu thị là "1 trong n ", đối với các giá trị cụ thể có thể có của n ).
BradC

Ồ, tôi đã không nhận thấy điều này. Được chứ.
DimChtz

2
Tôi muốn nó nếu chúng ta chỉ có thể xuất ra tử số và mẫu số dưới bất kỳ định dạng nào như một tuple / danh sách hoặc một cái gì đó, nhưng đã có câu trả lời cạnh tranh vì vậy tôi cho rằng đã quá muộn cho thử thách này. Tuy nhiên, đối với các thách thức trong tương lai, tôi sẽ xem xét định dạng I / O linh hoạt hơn vì một số ngôn ngữ mất khả năng cạnh tranh cao hơn các ngôn ngữ khác khi bạn yêu cầu xử lý chuỗi.
HyperNeutrino

1
@BradC - LOL. Tôi mới chỉ ở mức 538 và tôi hoàn toàn "Wow! Tôi phải thực hiện một thử thách chơi gôn từ việc này!"
Chas Brown

Câu trả lời:


6

T-SQL, 385 byte

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)

Đầu vào là thông qua bảng t có sẵn với trường số i , theo các tiêu chuẩn IO của chúng tôi .

Bảng đầu vào đó được nối với một bảng trong bộ nhớ được phân tích cú pháp từ một chuỗi thông qua STRING_SPLIT(phân tách các hàng) và PARSENAME(phân tách tử số và mẫu số thông qua .).

Bảng được sắp xếp theo khoảng cách từ giá trị đầu vào i và trả về hàng trên cùng, được định dạng phù hợp.


5

Than , 84 byte

NθF¹¹«F⊖ι⊞υ⟦⊕κι⟧≔⎇⊖ι∨×χι¹²¦¹⁵ιF²⊞υ⟦∨κ⊖ιι⟧»≔Eυ↔⁻θ∕§ι⁰§ι¹η≔⌕η⌊ηη×<‹θ·⁰¹×>›θ·⁹⁹⪫§υη in 

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Lấy đầu vào dưới dạng thập phân chứ không phải là tỷ lệ phần trăm. Giải trình:

Nθ

Nhập phân số.

F¹¹«

Chạy từ đến .n = 10n=0n=10

F⊖ι⊞υ⟦⊕κι⟧

Tạo tỷ lệ cho thành . n-11nn1n

≔⎇⊖ι∨×χι¹²¦¹⁵ι

Nhậnnth12,15,20...100n

F²⊞υ⟦∨κ⊖ιι⟧»

n1n1n

≔Eυ↔⁻θ∕§ι⁰§ι¹η

Tính giá trị thập phân của tất cả các tỷ lệ và lấy chênh lệch tuyệt đối với đầu vào ban đầu.

≔⌕η⌊ηη

1224

×<‹θ·⁰¹

<0.01

×>›θ·⁹⁹

>0.99

⪫§υη in 

Tham gia tử số và mẫu số của tỷ lệ thích hợp với invà in.


5

JavaScript (ES7), 164 159 144 byte

]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)

Hãy thử trực tuyến!

Làm sao?

p/q

d=(p/qr)2

mdm

q

Đã bình luận

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

4

Thạch , 58 byte

⁵R×⁵;12,15µ’,1,€)Ẏ;⁵Œc¤ð÷/ạ¥ÞḢj“ in ”
”<”>“”>.99$?<.01$?;Ç

Hãy thử trực tuyến!

-16 byte nhờ Arnauld (chỉ có thể thêm trước <>thay vì viết lại toàn bộ cụm từ)
-6 byte và sửa lỗi nhờ Jonathan Allan


@Arnauld Oh bạn nói đúng, không bao giờ nghĩ về điều đó: P Cảm ơn!
HyperNeutrino

0.3nên kết quả là 3 in 10không2 in 7
Jonathan Allan

Bạn chỉ nên loại bỏ µµ, không? EDIT - và sau đó chơi golf ÐṂṂvớiÞḢ
Jonathan Allan

thay đổi 9để giải quyết lỗi tôi tin.
Jonathan Allan

@Jonathan ALLan Oh rất tiếc, vâng tôi đã không sử dụng 10 làm mẫu số hợp lệ. Cảm ơn. Và không, loại bỏ mu kép không hoạt động vì sau đó "tối thiểu" được gắn vào phía bên phải của chức năng liên kết tối thiểu, đây chắc chắn không phải là điều tôi muốn, nhưng chỉ đặt một mu dường như không khắc phục được . Cảm ơn vì đã chơi gôn: D
HyperNeutrino

3

Python 2 , 261 278 261 237 177 byte

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

Hãy thử trực tuyến!


1
Python không hỗ trợ dấu chấm phẩy? Bạn có thể thay thế '\n 'bằng ';'... trừ khi tôi sai.
Dev

@BradC Đã sửa :)
TFeld

3

Sạch sẽ , 224 198 197 byte

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])

Hãy thử trực tuyến!

Giải thích:

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
  ]
 )

3

Thạch ,  53  52 byte

_.01,.99Ṡµ<0ịØ<ḣE⁵Ż×⁵+12,5Ṡ,’Ɗż€$Ẏ;⁵Œc¤÷/ạ¥Þ³Ḣj“ in 

Một chương trình đầy đủ in kết quả.

Hãy thử trực tuyến!

Hoặc xem bộ thử nghiệm

Lưu ý rằng bộ kiểm thử được thay đổi để biến mã thành một liên kết đơn âm bằng cách:

  1. sử dụng thanh ghi giữ một ca khúc của "đầu vào chương trình" hiện nay, với ³tới ®; và
  2. chốt danh sách mã ký tự cho "trong", với “ in tới“ in ”

Làm sao?

Bắt đầu với mã buộc bất kỳ in <hoặc >ký hiệu cần thiết nào và sau đó mã sẽ xây dựng tất cả các cặp mẫu số tử số (với một số phiên bản biểu mẫu không đơn giản, tất cả sau biểu mẫu đơn giản hóa của chúng) và in mục nhập được đánh giá phân chia tối thiểu bằng cách sử dụng ổn định sắp xếp tham gia với 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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.