Konversikan persentase ke rasio “sederhana”

16

Anda menjalankan situs web politik , dan telah menentukan bahwa orang-orang memiliki pemahaman intuitif yang lebih baik ketika peluang menang atau kalahnya pemilihan dinyatakan sebagai rasio ("5 dalam 7") daripada ketika itu dinyatakan sebagai persentase ("71%" ).

Tetapi Anda juga tidak ingin menampilkan rasio yang membingungkan seperti "58 in 82", Anda ingin agar rasio tersebut lebih mudah dipahami, bahkan jika rasio tersebut tidak terlalu tepat.

Jadi, mengingat persentase antara 0,1% dan 99,9%, kembalikan rasio "mudah dimengerti" terdekat " x in y ", dengan menggunakan aturan berikut :

  1. Sebagian besar nilai (lihat pengecualian di bawah) harus mengembalikan rasio terdekat dari 10 atau lebih rendah . 55% harus mengembalikan "5 in 9", bukan "11 in 20".
  2. Rasio harus dikurangi ke tingkat terendah . 65% harus mengembalikan "2 in 3", bukan "4 in 6".
  3. Nilai di bawah 10% harus mengembalikan rasio terdekat dari bentuk " 1 dalam n " di mana n adalah salah satu dari (10,12,15,20,30,40,50,60,70,80,80,90,100) . Misalnya, 6% harus mengembalikan "1 dalam 15".
  4. Nilai lebih dari 90% harus mengembalikan rasio terdekat dari bentuk " n-1 in n " di mana n adalah salah satu dari (10,12,15,20,30,40,50,60,70,80,80,90,100) . Misalnya, 98,7% harus mengembalikan "79 in 80".
  5. Nilai di bawah 1% harus mengembalikan " <1 dalam 100 "
  6. Nilai lebih dari 99% harus mengembalikan " > 99 dalam 100 "

Atau, kalau dipikir-pikir dengan cara lain, program Anda harus mengembalikan rasio terdekat dari kemungkinan keluaran berikut (saya telah memasukkan nilai perkiraannya untuk kenyamanan Anda):

<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

Ketentuan lainnya:

  • Input numerik dapat berada dalam kisaran 0,1 hingga 99,9 atau dalam kisaran 0,001 hingga 0,999 , mana yang lebih nyaman. Anda harus menangani setidaknya 3 digit signifikan.
  • Anda harus menghasilkan rasio ("3 in 4"), bukan fraksi yang setara ("3/4").
  • Jika ada dua rasio yang sama dekat dengan input, program Anda dapat mengembalikan keduanya. 7,5% dapat mengembalikan "1 dalam 12" atau "1 dalam 15".
  • Ruang putih terkemuka / tertinggal dan / atau garis baru baik-baik saja

Contoh :

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

Ini adalah tantangan , kode terpendek dalam setiap bahasa menang.

(Mirip dengan, tetapi bukan duplikat dari: Konversi desimal menjadi pecahan , pecahan terdekat , Perkiraan angka floating point dengan presisi n-digit )

BradC
sumber
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"Apakah itu berarti kita dapat kembali 7 in 100juga? Btw, 1 in 14lebih dekat dengan input dalam hal ini.
DimChtz
@DimChtz Tidak, karena itu melanggar aturan 3 (nilai di bawah 10% harus dinyatakan sebagai "1 in n ", untuk kemungkinan nilai spesifik n ).
BradC
Ohh, aku tidak memperhatikan ini. Baik.
DimChtz
2
Saya suka jika kita bisa menampilkan pembilang dan penyebut sebagai format seperti tuple / daftar atau sesuatu, tetapi sudah ada jawaban yang bersaing jadi saya kira sudah terlambat untuk tantangan ini. Untuk tantangan di masa depan, saya akan mempertimbangkan format I / O yang lebih fleksibel karena beberapa bahasa kehilangan daya saing lebih dari yang lain ketika Anda membutuhkan penanganan string.
HyperNeutrino
1
@BradC - LOL. Saya baru berusia 538, dan saya semua "Wow! Saya harus membuat tantangan golf dari ini!"
Chas Brown

Jawaban:

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)

Input adalah melalui tabel t yang sudah ada sebelumnya dengan bidang numerik i , sesuai standar IO kami .

Tabel input tersebut digabungkan dengan tabel dalam-memori yang diuraikan dari sebuah string via STRING_SPLIT(yang memisahkan baris) dan PARSENAME(yang memisahkan pembilang dan penyebut via .).

Tabel diurutkan berdasarkan jarak dari nilai input i , dan mengembalikan baris atas, diformat dengan tepat.

BradC
sumber
5

Arang , 84 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil input sebagai desimal daripada persentase. Penjelasan:

Nθ

Masukkan fraksi.

F¹¹«

n=0n=10

F⊖ι⊞υ⟦⊕κι⟧

1nn-1n

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

nth12,15,20...100n

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

n-1n1n

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

Hitung nilai desimal semua rasio dan ambil perbedaan absolut dengan input asli.

≔⌕η⌊ηη

1224

×<‹θ·⁰¹

<0,01

×>›θ·⁹⁹

>0,99

⪫§υη in 

Bergabunglah dengan pembilang dan penyebut rasio yang sesuai dengan indan cetak.

Neil
sumber
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)

Cobalah online!

Bagaimana?

hal/q

d=(hal/q-r)2

mdm

q

Berkomentar

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
Arnauld
sumber
4

Jelly , 58 byte

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

Cobalah online!

-16 bytes berkat Arnauld (hanya bisa menambahkan <dan >alih-alih menulis ulang seluruh frasa)
-6 byte dan perbaikan bug berkat Jonathan Allan

HyperNeutrino
sumber
@Arnauld Oh Anda benar, tidak pernah memikirkan hal itu: P Terima kasih!
HyperNeutrino
0.3harus menghasilkan 3 in 10tidak2 in 7
Jonathan Allan
Anda hanya harus menghapus µµ, bukan? EDIT - dan kemudian golf ÐṂṂkeÞḢ
Jonathan Allan
mengubah 9ke harus menyelesaikan bug yang saya percaya.
Jonathan Allan
@ JonathanAllan Oh whoops, ya saya tidak menggunakan 10 sebagai penyebut yang valid. Terima kasih. Dan tidak, menghapus mu ganda tidak berfungsi karena "minimum" melekat pada sisi kanan fungsi tautan-min diad yang jelas bukan yang saya inginkan, tetapi hanya menempatkan satu mu sepertinya tidak memperbaikinya . Terima kasih untuk golfnya: 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

Cobalah online!

TFeld
sumber
1
Bukankah Python mendukung titik koma? Anda bisa menggantinya '\n 'dengan ';'... kecuali saya salah.
Dev
@BradC Tetap :)
TFeld
3

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

Cobalah online!

Dijelaskan:

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
  ]
 )
Suram
sumber
3

Jelly ,  53  52 byte

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

Program lengkap yang mencetak hasilnya.

Cobalah online!

Atau lihat test-suite

Perhatikan bahwa test-suite diubah untuk membuat kode tautan monadik dengan:

  1. menggunakan register, simpan "input program" saat ini, dengan ³untuk ®; dan
  2. menutup daftar kode karakter untuk "in", dengan “ in ke“ in ”

Bagaimana?

Mulai dengan kode yang memaksa pencetakan <atau >tanda yang diperlukan dan kemudian kode yang membangun semua pasangan pembilang-penyebut (dengan beberapa versi formulir yang tidak disederhanakan, semua setelah formulir yang disederhanakan) dan mencetak entri yang dievaluasi divisi yang berbeda secara berbeda menggunakan stabil. semacam bergabung dengan 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
Jonathan Allan
sumber
2

Perl 6 , 118 byte

{'<'x(.01>$_)~'>'x($_>.99)~(|(1..9 X ^11),|map({|(1,$_-1 X$_)},12,15,|(^11 X*10))).min({abs $_-[/] @^a}).join(' in ')}

Cobalah online!

nwellnhof
sumber