Yüzdeyi “basit” orana dönüştürme


16

Politik bir web sitesi işletiyorsunuz ve seçim kazanma veya kaybetme şansı, yüzde ("% 71" olarak ifade edilen orandan ("% 7") bir oran olarak ifade edildiğinde insanların daha sezgisel bir anlayışa sahip olduğunu belirlediniz. ).

Ama aynı zamanda "58'de 82" gibi kafa karıştırıcı oranlar göstermek istemezsiniz, o kadar kesin olmasalar bile daha kolay anlaşılmasını istersiniz.

Bu nedenle, % 0,1 ile% 99,9 arasında bir yüzde verildiğinde , aşağıdaki kuralları kullanarak en yakın "anlaşılması kolay" oranı " x cinsinden " döndürün :

  1. Çoğu değer (aşağıdaki istisnalara bakın) en yakın oranı 10 veya daha düşük olarak döndürmelidir . % 55'i "20'de 11" değil "9'da 5" döndürmelidir.
  2. Oranlar en düşük terimlere indirilmelidir . % 65'i "3'te 2" değil, "4'te 6" döndürmelidir.
  3. % 10 altındaki değerler döndürmelidir "formunun en yakın oran n 1 burada" N (10,12,15,20,30,40,50,60,70,80,90,100) biridir . Örneğin,% 6'sı "1'de 15" değerini döndürmelidir.
  4. % 90 üzerinde değerler döndürmelidir yakın formunun oranı " n-1 n " burada n, (10,12,15,20,30,40,50,60,70,80,90,100) biridir . Örneğin,% 98,7'si "80'de 79" döndürmelidir.
  5. % 1 altında Değerler "dönmelidir 100'de <1 "
  6. % 99 üzerinde Değerler "dönmelidir 100'de 99> "

Ya da başka bir şekilde düşünmek için, programınız aşağıdaki olası çıktılardan en yakın oranı döndürmelidir (size kolaylık olması için yaklaşık değerlerini ekledim):

<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

Diğer koşullar:

  • Sayısal giriş , hangisi daha uygunsa, 0,1 ila 99,9 aralığında veya 0,001 ila 0,999 aralığında olabilir . En az 3 önemli basamak kullanmalısınız.
  • Eşdeğer kesir ("3/4") değil, bir oran ("4'te 3") vermelisiniz .
  • Girişe eşit derecede yakın iki oran varsa, programınız bunlardan birini döndürebilir. % 7.5'i "1'de 12" veya "1'de 15" döndürür.
  • Öncü / sondaki boşluk ve / veya yeni çizgiler iyi

Örnekler :

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

Bu bir mücadelesi, her dilde en kısa kod kazanır.

(Şuna benzer, ancak çoğaltılmaz: Ondalık kesiri kesire dönüştürme , En yakın kesir , n basamaklı kesinlik ile yaklaşık kayan nokta sayı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"Bu da geri dönebileceğimiz anlamına mı geliyor 7 in 100? Btw, 1 in 14bu durumda girişe daha yakındır.
DimChtz

@DimChtz Hayır, bu kural 3'ü ihlal ettiği için (% 10'un altındaki değerler n'nin olası olası değerleri için "1'de n " olarak ifade edilmelidir ).
BradC

Ohh, bunu fark etmedim. Tamam.
DimChtz

2
Pay ve paydayı bir tuple / list veya herhangi bir format gibi herhangi bir format olarak çıkarabilseydik, ama zaten rakip cevaplar var, bu yüzden bu meydan okuma için çok geç olduğunu düşünüyorum. Gelecekteki zorluklar için, daha esnek bir G / Ç formatı düşünürüm, çünkü dize işlemeye ihtiyaç duyduğunuzda bazı diller diğerlerinden daha fazla rekabet gücünü kaybeder.
HyperNeutrino

1
@BradC - LOL. Ben sadece 538 yaşındaydım ve hep "Vay be! Bundan bir golf zorluğu yapmak zorundayım!"
Chas Brown

Yanıtlar:


6

T-SQL, 385 bayt

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)

Girdi önceden var masa üzeri olan t Sayısal alan ile i , bizim IO standartlarına göre .

Bu giriş tablosu, bir dizeden STRING_SPLIT(satırları ayıran) ve PARSENAME(pay ve paydayı ayıran ) bir dizeden ayrıştırılmış bir bellek içi tablo ile birleştirilir ..

Tablo, giriş değerinden i mesafeye göre sıralanır ve uygun şekilde biçimlendirilmiş en üst satırı döndürür.


5

Kömür , 84 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Girdiyi yüzde yerine ondalık olarak alır. Açıklama:

Nθ

Kesiri girin.

F¹¹«

n=0n=10

F⊖ι⊞υ⟦⊕κι⟧

için oranlar oluşturun1nn-1n

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

nth12,15,20...100n

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

için oranlar oluşturn-1n1n

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

Tüm oranların ondalık değerlerini hesaplayın ve orijinal giriş ile mutlak farkı alın.

≔⌕η⌊ηη

1224

×<‹θ·⁰¹

<0.01

×>›θ·⁹⁹

>0.99

⪫§υη in 

Uygun oranın pay ve paydasına katılın inve yazdırın.


5

JavaScript (ES7), 164 159 144 bayt

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

Çevrimiçi deneyin!

Nasıl?

p/q

d=(p/q-r)2

mdm

q

Yorumlananlar

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

Jöle , 58 bayt

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

Çevrimiçi deneyin!

-16 (sadece başa ekleyebilir Arnauld sayesinde bayt <ve >bunun yerine tüm ifadeyi yeniden yazmak)
-6 Jonathan Allan'a bayt ve hata düzeltmeleri sayesinde


@Arnauld Oh, haklısın, bunu hiç düşünmedim: P Thanks!
HyperNeutrino

0.3yol açmalıdır 3 in 10değil2 in 7
Jonathan Allan

Sadece çıkarmalısın µµ, değil mi? DÜZENLEME - ve sonra golf ÐṂṂiçinÞḢ
Jonathan Allan

Değişen 9için inanıyorum hatayı çözmelidir.
Jonathan Allan

@JonathanAllan Hata! Evet, 10'u geçerli bir payda olarak kullanmıyordum. Teşekkürler. Ve hayır, çift mu'nın çıkarılması işe yaramaz çünkü o zaman "minimum", kesinlikle istediğim gibi olmayan ikili bağlantı-min fonksiyonunun sağ tarafına eklenir, ancak sadece bir mu koymak düzeltmek gibi görünmüyor . Golf için teşekkürler: D
HyperNeutrino

3

Python 2 , 261 278 261 237 177 bayt

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

Çevrimiçi deneyin!


1
Python noktalı virgülleri desteklemiyor mu? Yanlış olduğum sürece ... '\n 'ile değiştirebilirsiniz ';'.
Dev

@BradC Sabit :)
TFeld

3

Temiz , 224 198197 bayt

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

Çevrimiçi deneyin!

Açıklaması:

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

Jöle ,  53  52 bayt

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

Sonucu basan tam bir program.

Çevrimiçi deneyin!

Veya test takımına bakın

Test paketinin kodu monadik bir bağlantı haline getirmek için değiştirildiğini unutmayın:

  1. ile, güncel "programı girişi" bir takip kaydının kullanılmasıyla ³için ®; ve
  2. ile, "içinde" için karakterler kodun listenin kapatılması “ in için“ in ”

Nasıl?

<Veya >işaretinin gerekli herhangi bir şekilde yazdırılmasını zorlayan kodla başlar ve sonra tüm payda payda çiftlerini (basitleştirilmiş formlarından sonra bazı basitleştirilmiş olmayan form sürümleriyle) oluşturan ve kararlı bir şekilde en az farklı bölüm değerlendirmeli girişi basan kodla başlar sıralamaya katıldı 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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.