Гольф від ненависників


20

Установка:

Соціальна мережа повідомляє, що кількість голосів за публікацію є двома способами: кількість чистих змін (загальна кількість - загальна кількість голосів), а відсоток голосів, які були прийняті , округлюються до найближчого цілого числа (.5 раундів вгору). Кількість чистих оновлень - це ціле число (не обов'язково додатне), а друге гарантовано буде цілим числом від 0 до +100 включно. Кількість оновлених і кількість повторних запитів є або нульовими, або позитивними 32-бітовими цілими числами (ви можете вказати підписані або неподписані). Припустимо, що якщо нульового загального числа голосів, відсоток, що перевищує, повідомляється як нуль.

Змагання:

З огляду на ці два цілі числа (чисті оновлені та% оновлені), яка найкоротша програма, яку ви можете написати, визначає найменшу кількість загальних змін, отриманих за повідомлення, з усіма вищевикладеними обмеженнями?

Обмеження введення гарантовано. Якщо вхід не відповідає обмеженням, зазначеним вище, поведінка програми залежить від вас. Бонусний кудо, якщо він не входить в нескінченний цикл або іншим чином виходить з ладу. Побачте повернути від’ємне число, якщо хочете отримати більше вказівок.

Загальні правила:

  • Це , тому найкоротше діюче рішення (вимірюється в байтах) виграє.
  • Не дозволяйте мовам коду-гольфу відштовхувати вас від публікації відповідей з не кодовими гольф-мовами. Спробуйте придумати якомога коротшу відповідь на "будь-яку" мову програмування. Бонусні кудо для веб-мови клієнта, як Javascript.
  • Якщо у вас є цікаві рішення на декількох мовах, опублікуйте їх окремо .
  • Для вашої відповіді застосовуються стандартні правила , тому вам дозволяється використовувати STDIN / STDOUT, функції / метод із відповідними параметрами та типом повернення, або повними програмами. Твій дзвінок.
  • Бійниці за замовчуванням заборонені.
  • Якщо можливо, додайте посилання з тестом для вашого коду.
  • Також додайте пояснення, як працює код.
  • Майте на увазі, що якщо ви робите цілу операцію поділу, яка скорочує (наприклад, 20/3 = 6), а не круги , це може бути не зовсім коректно.
  • Запрошуються додаткові тестові випадки, які вивчають крайові випадки вищезазначених обмежень.
  • Хоча очікуваний тип повернення є числовим, булеве "хибне" можна використовувати замість 0 .

Приклади тестових випадків:

Перший стовпець - це лише довідковий номер, включений для полегшення обговорення.

ref net  %up    answer
1   0    0   => 0    
2   -5   0   => 0    
3   -4   17  => 1    
4   -3   29  => 2    
5   -2   38  => 3    
6   -1   44  => 4    
7   0    50  => 1    
8   5    100 => 5    
9   4    83  => 5    
10  3    71  => 5    
11  2    63  => 5    
12  1    56  => 5    
13  1234 100 => 1234
14  800  90  => 894  (tip: don't refer to this as the "last test case;" others may be added.)

Цей нульовий загальний виборчий голос є досить химерним. Якщо є однакова кількість змін та знижок, відсотковий обмін становить 50%, за винятком 0%, коли немає голосів, порушуючи симетрію повороту-знищення.
xnor

2
@xnor 0/0, як правило, не визначено, тому необхідно зробити припущення. При такому виборі ви отримуєте автоматичний "відповідь = другий вхід", якщо другий вхід 0, і автоматичний "відповідь = перший вхід", якщо другий вхід 100.
WBT

1
Схожий тест запозичене з @nwellnhof: 1000, 100. Чи можете ви підтвердити, що очікувана відповідь 1000?
Арнольд

1
Захищені, бо ненависників треба ненавидіти :)
Hosch250

@Arnauld і nwellnhof: як зазначено в коментарі безпосередньо перед вашим, якщо другий вхід = 100, відповідь = перший ввід. Якщо 100 справді було округленим дещо нижчим відсотком, для отримання чистих голосів = перший внесок потрібно було б більше першого внеску, а цей виклик шукає найменшу кількість загальних змін.
WBT

Відповіді:


10

JavaScript (ES6), 47 байт

Приймає вхід у синтаксис currying (n)(p), де n - кількість чистих оновлень, а p - відсоток оновлених результатів. Може повернутися falseдля0 .

n=>p=>(g=u=>u/(u-n/2)*50+.5^p?g(u+1):u)(n>0&&n)

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

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

n => p => (          // given n and p
  g = u =>           // g = recursive function taking u = number of upvotes
    u / (u - n / 2)  //   compute u / (total_votes / 2)
    * 50 + .5        //   turn it into a percentage, add 1/2
    ^ p ?            //   XOR it with p, which gives 0 if the integer parts are matching
                     //   if the result is not equal to 0:
      g(u + 1)       //     try again with u + 1
    :                //   else:
      u              //     stop recursion and return u
)(n > 0 && n)        // initial call to g() with u = max(0, n)

Корпусні кромки

Нехай F n (u) = u / (u - n / 2) * 50 + 0,5

  • Якщо u = 0 і n = 0 , тоді F n (u) = NaN і F n (u) XOR p = p . Отже, повертаємо u = 0, якщо n = p = 0 (перша ітерація першого тестового випадку) або продовжуємо з рекурсією, якщо p! = 0 (перша ітерація 7-го тестового випадку).

  • Якщо u> 0 і u = n / 2 , то F n (u) = + Нескінченність і - знову ж таки - F n (u) XOR p = p . Якщо p = 0 , ми просто продовжуємо наступну ітерацію. (Це трапляється у 9 та 11 тестових випадках.)


Приємно! Ви отримуєте бонусні кудо за вибір мови та за включення пояснення + посилання на демонстрацію!
WBT

6

Стакс , 17 байт

ëI╩½• ╠☺Vì∞«S↑♠αS

Запустіть і налагоджуйте його

Це жорстока сила. Починається з 0 для надходження кандидатів і збільшується до тих пір, поки не задовольнить формулу.

Розпакований, неозорений та прокоментований, це виглядає приблизно так.

0       push zero
{       start filter block...
        candidate upvotes is on the stack
  cHx-  calculate candidate downvotes for denominator (upvotes * 2 - net)
  c1?   if denominator is zero, replace it with 1
  :_    floating point division
  AJ*   multiply by 100
  j     round to integer
  ;=    is equal to second input?
        increment until a match is found
}gs

Виконати цей


2

Чистота , 114 107 104 байт

import StdEnv
? =toReal o toInt
$a d#e= ?d
= ?a+until(\c#b= ~c*e/(e-100.0)
= ?(?100*b/(?b+c))==e)inc 0.0

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

Визначає функцію $ :: Int Int -> Real, де аргументи підписані цілими числами, а значення, що повертається, є поплавком подвійної точності, точно представленим 32-бітним цілим числом, підписаним.

Він перевіряє кожне значення cрівняння, b=-cd/(d+1)щоб знайти bзадовольняюче, a+c=bі b/(b+c)=d, оскільки найменше cпризводить до найменшого b, приймає перший елемент множини всіх рішень.


2

05AB1E , 13 байт [м'яко зламано]

*²·т-/ò²т;Qi1

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

Пояснення:

Щоб вирішити це, я припускав входи a, b і очікуваний результат x. Враховуючи інформацію в налаштуваннях, це дало мені рівняння:

 2x         100x
———— - a = ——————
 a           b

Перестановка для x дає

        ab
x = ——————————
     2b - 100

Єдиний тестовий випадок, для якого це не працює, це 0, 50 - я просто твердо кодувався, щоб перевірити це.

*²·т-/ò²т;Qi1     Implicit Inputs: a, b              STACK (bottom to top)
*                 Multiply the inputs together       [ab]
 ²·               Take the second input * 2          [ab, 2b]
   т-             Subtract 100                       [ab, 2b - 100]
     /ò           Divide and round                   [round(ab/(2b-100))]
       ²т;Qi1     If 2nd input = 50, push 1 to stack
                  { Implicitly output top item of stack [either 1, or round(...)] }

Для деяких входів це не працює правильно. 90% з 800 чистими голосами можна зробити з 894 голосами.
рекурсивна

@recursive Я знаю, що це таке. Він передбачає точно 90%, а не 89,5%.
Гено Раклін Ашер

Ну, ближче до 90,5% у цьому випадку, але так.
рекурсивна

1
Тепер я розумію, що це складніше, ніж я думав. Я подумаю над цим, але наразі позначу його як розбитий.
Гено Раклін Ашер

@GenoRacklinAsher Тепер я розумію, що це складніше, ніж я думав. Я подумаю над цим ... Це такі коментарі, які я люблю читати, розглядаючи їх як ознаку хорошої головоломки :-).
WBT

0

Перехід 1.10, 154 байти

func h(n,u float64)float64{if u==50{return 1};r:=Round(n*u/(2*u-100));s:=Round(n*(u+.5)/(2*u-99));v:=s/(2*s-n);if v>1||Round(v*100)!=u{return r};return s}

Спробуйте це на майданчику Go! (TIO працює Go 1.9, який не має математики. Раунд)

Безгольова версія

func haters(n, u float64) float64 {
    if u == 50 {
        return 1
    }
    r := Round(n * u / (2*u - 100))
    //Test the case where we were given a percentage that was rounded down (e.g. 90.4% given as 90%)
    //We test this by adding 0.5% to u. The denominator is just a simplified form of 2*(u+0.5) - 100
    s := Round(n * (u + .5) / (2*u - 99))
    //Check if s is a valid result
    v := s / (2*s - n)
    if v > 1 || Round(v*100) != u {
        return r
    }
    //s is strictly less than r, so we don't need to check the minimum.
    return s
}

В інтересах додавання пояснення, наведена вище формула для r може бути отримана шляхом одночасного розв’язання n=v-dі u = 100 * v/(v + d)для v, де v і d - кількість доповнених і нижчих рівнів відповідно. Виведена формула не визначена для v = 50, тому нам доведеться обробити цей випадок (що ми робимо з першим, якщо твердженням).

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