Перетворити відсоток у коефіцієнт "простий"


16

Ви керуєте політичним веб-сайтом і визначили, що люди краще розуміють, коли шанс на перемогу чи програш на виборах виражається у співвідношенні ("5 на 7"), ніж коли він виражається у відсотках ("71%" ).

Але ви також не хочете відображати заплутані співвідношення на зразок "58 на 82", ви хочете, щоб їх було легше зрозуміти, навіть якщо вони не такі точні.

Отже, даючи відсоток від 0,1% до 99,9%, поверніть найближче співвідношення "легко зрозуміти" " x in y ", використовуючи такі правила :

  1. Більшість значень (див. Винятки нижче) повинні повертати найближче співвідношення з 10 або нижче . 55% повинні повернути "5 на 9", а не "11 на 20".
  2. Коефіцієнти слід зменшити до найнижчих . 65% повинні повернути "2 в 3", а не "4 в 6".
  3. Значення під 10% повинні повернути найближче співвідношення форми " 1 в n ", де n є одним із (10,12,15,20,30,40,50,60,70,80,90,100) . Наприклад, 6% повинні повернути "1 на 15".
  4. Значення понад 90% повинні повернути найближче співвідношення форми " n-1 в n ", де n є одним із (10,12,15,20,30,40,50,60,70,80,90,100) . Наприклад, 98,7% повинні повернути "79 за 80".
  5. Значення під 1% мають повернути " <1 на 100 "
  6. Значення понад 99% повинні повернути " > 99 на 100 "

Або, подумавши про це іншим способом, ваша програма повинна повернути найближче співвідношення з наступних можливих результатів (я включив їх приблизні значення для вашої зручності):

<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

Інші умови:

  • Числовий введення може знаходитися в діапазоні від 0,1 до 99,9 або в межах від 0,001 до 0,999 , що б зручніше. Ви повинні обробити принаймні 3 значущі цифри.
  • Потрібно вивести співвідношення ("3 в 4"), а не еквівалентну дріб ("3/4").
  • Якщо два співвідношення однаково близькі до вхідних, ваша програма може повернути будь-яке. 7,5% може повернути "1 на 12" або "1 на 15".
  • Простий / простір білого простору та / або нові лінії добре

Приклади :

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

Це виклик з , найкоротший код на кожній мові виграє.

(Аналогічно, але не дублікат: Перетворення десяткової у дріб , Найближчий дріб , Орієнтовний номер з плаваючою комою з n-знаковою точністю )


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"Чи означає це, що ми також можемо повернутися 7 in 100? Btw, 1 in 14ближче до вводу в цьому випадку.
DimChtz

@DimChtz Ні, оскільки це порушує правило 3 (значення під 10% повинні бути виражені як "1 в n ", для конкретних можливих значень n ).
БредК

О, я цього не помічав. Добре.
DimChtz

2
Мені б хотілося, щоб ми могли просто вивести чисельник та знаменник як будь-який формат, наприклад, кортеж / список чи щось подібне, але відповіді вже є, тому я вважаю, що для цього завдання вже пізно. Для майбутніх проблем я б розглядав більш гнучкий формат вводу / виводу, оскільки деякі мови втрачають більшу конкурентоспроможність, ніж інші, коли вам потрібна обробка рядків.
HyperNeutrino

1
@BradC - LOL. Мені було всього 538, і я був усім "Вау! Я повинен зробити з цього завдання з гольфу!"
Час Браун

Відповіді:


6

T-SQL, 385 байт

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)

Введення здійснюється за допомогою вже існуючої таблиці t з числовим полем i , відповідно до наших стандартів введення-виведення .

Ця таблиця введення поєднується з таблицею в пам'яті, розібраною з рядка через STRING_SPLIT(який розділяє рядки) та PARSENAME(який відокремлює чисельник та знаменник через .).

Таблиця сортується за відстані від вхідного значення i та повертає верхній рядок, відформатований відповідним чином.


5

Вугілля деревне , 84 байти

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Вводиться як десяткова, а не як процентна. Пояснення:

Nθ

Введіть дріб.

F¹¹«

н=0н=10

F⊖ι⊞υ⟦⊕κι⟧

1нн-1н

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

нтгод12,15,20...100н

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

н-1н1н

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

Обчисліть десяткові значення всіх співвідношень і візьміть абсолютну різницю з вихідним введенням.

≔⌕η⌊ηη

1224

×<‹θ·⁰¹

<0,01

×>›θ·⁹⁹

>0,99

⪫§υη in 

Приєднайтесь до чисельника та знаменника відповідного співвідношення з inта надрукуйте.


5

JavaScript (ES7), 164 159 144 байт

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

Спробуйте в Інтернеті!

Як?

p/q

г=(p/q-r)2

мгм

q

Прокоментував

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

Желе , 58 байт

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

Спробуйте в Інтернеті!

-16 байт завдяки Арнолду (може просто передбачити <і >замість того, щоб переписати цілу фразу)
-6 байт і виправлення помилок завдяки Джонатану Аллану


@Arnauld О, ти правий, ніколи не думав про це: P Спасибі!
HyperNeutrino

0.3має призвести до 3 in 10не2 in 7
Джонатан Аллан

Вам слід просто зняти µµ, ні? EDIT - а потім гольф ÐṂṂдоÞḢ
Джонатан Аллан

перехід 9до повинен вирішити помилку, я вважаю.
Джонатан Аллан

@JonathanAllan О, так, так, я не використовував 10 як дійсний знаменник. Спасибі. І ні, видалення подвійного mu не працює, тому що тоді "мінімум" прикріплений до правої сторони діадичної функції link-min, що точно не те, що я хочу, але лише наведення одного mu, схоже, не виправить це . Спасибі за гольф, хоча: D
HyperNeutrino

3

Пітон 2 , 261 278 261 237 177 байт

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

Спробуйте в Інтернеті!


1
Чи не підтримує Python крапки з комою? Ви могли б замінити '\n 'з ';'... якщо я не помиляюся.
Дев

@BradC Виправлено :)
TFeld

3

Очистити , 224 198 197 байт

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

Спробуйте в Інтернеті!

Пояснили:

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

Желе ,  53  52 байти

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

Повна програма, яка друкує результат.

Спробуйте в Інтернеті!

Або дивіться тестовий набір

Зауважте, що тестовий набір змінено, щоб зробити код монадичним посиланням:

  1. використовуючи регістр, слідкуйте за поточним "входом програми", з ³до ®; і
  2. закриття списку символьних кодів для "в", з “ in до“ in ”

Як?

Починається з коду, який примушує будь-яку необхідну друк знаку <або, >а потім код, який створює всі пари чисельник-знаменник (з деякими надмірними, не спрощеними версіями форм, усі після спрощеної форми) та друкує мінімально інший запис, що оцінюється поділом, використовуючи стабільний сортувати з 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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.