Визначте, чи є виклик вартим відповіді


21

Я дуже випадковий гольфіст коду, і не часто бачу повідомлення, поки вони не з’являться на бічній панелі "Гарячі запитання до мережі" на StackOverflow. Зазвичай я запізнююсь на гру, і оскільки єдиною мовою, яку я знаю, є Python, мало сенсу в мені відповідати, оскільки вже є кілька відповідей Python. Ваше завдання полягає в тому, щоб з'ясувати, чи варто мені відповісти на запитання.

Вхід:

  • Ваш код (функція або програма) буде приймати один вхідний параметр i

Вихід:

  • Значення Truthy або Falsey для ідентифікатора запитання i. Виведіть Truthy, якщо запитання має більше 5 відповідей, більше 3 балів запитань та одну чи меншу відповідь на Python (різниці між версією немає).

Правила / Роз'яснення:

  • Формат введення може бути будь-яким розумним (stdin, файл, командний рядок), але його слід вказати у вашій відповіді. Типи даних та провідна / відстала пробіли не мають значення.
  • Припустимо, ідентифікатор питання дійсний для codegolf.stackexchange.com.
  • Ігноруйте вимоги щодо конкретних мов. (тобто, якщо запитання відповідає голосам і відповідям, і немає відповідей Python, оскільки це лише Java, воно все одно призводить до Truthy).
  • Відповідь кваліфікується як відповідь Python, якщо "python" (нечутливий до регістру) виникає де-небудь перед першим новим рядком повідомлення.
  • Це код гольфу, тому найкоротший код у байтах виграє.

Зразки справ *

id = 79082 => True
id = 78591 => False (less than 5 answers, also hella hard)
id = 78410 => True
id = 76428 => False (greater than 1 Python answer)
id = 78298 => False (not high enough question score)

* Підтверджено під час публікації, можливо, змінилось


Я також знаю лише Python ...
Р. Кап

В основному я знаю і Python.
user48538

Я повинен почати вивчати деякі інші мови.
Р. Кап

5
@ R.Kap, цей виклик був би чудовим часом для початку!
wnnmaw

2
На цей виклик варто відповісти, мабуть.
Rɪᴋᴇʀ

Відповіді:


8

05AB1E , 167 160 159 158 156 154 143 байт

Чорт, майже до тих пір, як звичайна мова ...

Лайно ... довше зараз бити відповідь Рубі на 1 байт.

Тепер довше, ніж відповідь Рубі, правда! .

Напевно, я повинен зараз лягти спати.

Дякуємо @wnnmaw за збереження 1 байта і спасибі @R. Kap для збереження ще 2 байти!

Код:

’£Ø ˆå§¾.‡¢ as g;#.¾¿„–(g.ˆåƒÛ('·Ç://ÐÏg.´¢/q/'+•œ_#()).‚Ø())’.e©’„à="Ž»"’DU¢®…ƒŠ‡¡`99£þs\®X¡¦vy’„à="‚¬-„¹"’¡¦'>¡¦¦¬l’±¸’¢s\}rUV)O2‹X5›Y3›)P

Або з більшою читанністю:

’£Ø ˆå§¾.‡¢ as g;#.¾¿„–(g.ˆåƒÛ('·Ç://ÐÏg.´¢/q/'+•œ_#()).‚Ø())’
 .e©
’„à="Ž»"’
 DU¢®
“ƒŠ‡“
 ¡`99£þs\®X¡¦
v
 y’„à="‚¬-„¹"’¡¦'>¡¦¦¬l’±¸’¢s\}rUV)O2‹X5›Y3›)P

Пояснення:

Перш за все, тут стискається багато тексту, що перекладається на старий добрий Python. Нестиснений варіант:

"import urllib.request as g
 f=g.urlopen('http://ppcg.lol/q/'+pop_#())
 #.append(f.read())"
.e©“class="answer"“¢®"useful and clear"¡`99£þs\®“class="answer"“¡¦vy“class="post-text"“¡¦'>¡¦¦¬l"python"¢s\}rUV)O2‹X5›Y3›)P

Ця частина:

import urllib.request as g
stack.append(g.urlopen('http://ppcg.lol/q/'+pop_stack()).read())`

насправді з'являється значення стека, копіюється в URL-адресу і витягує всі HTML-дані. Дані HTML висуваються вгорі стека за допомогою #.append(f.read()).

Ми підраховуємо кількість відповідей , підраховуючи кількість випадків class="answer".

Щоб підрахувати кількість голосів, ми просто розділили дані на «корисні та зрозумілі» та збережемо лише знаки цифр у [0:99]використанні ®"useful and clear"¡`99£þ. Це кількість доповнень.

Врешті-решт, нам потрібно перевірити кожну відповідь, чи "Python"існує текст до завершального тексту заголовка. Щоб отримати всі відповіді, ми просто розділимо дані на class="post-text"них і знову розділимо їх <. Ми видаляємо перші два елементи, щоб отримати частину, в якій відображається мова, і перевіряємо, чи в цій рядку є нижня літера.

Отже, тепер наш стек виглядає так для id = 79273:

`[6, '14', 0, 0, 0, 1, 0, 0]`
  │    │   └───────┬──────┘
  │    │           │
  │    │   is python answer?
  │    │
  │    └── number of upvotes
  │
  └─── number of answers

Це також можна побачити, -dякщо прапор ebug увімкнено в інтерпретаторі.

Отже, справа лише в обробці даних:

rUV)O2‹X5›Y3›)P

r                # Reverse the stack
 U               # Pop the number of answers value and store into X
  V              # Pop the number of upvotes value and store into Y
   )O            # Wrap everything together and sum it all up
     2‹          # Check if smaller than 2
       X5›       # Push X and check if greater than 5
          Y3›    # Push Y and check if greater than 3
             )P  # Wrap everything into an array and take the product.
                   This results into 1 if and only if all values are 1 (and not 0).

Використовує кодування CP-1252 . Ви можете завантажити перекладача тут .


12
Мені подобається "більш читабельна" версія; ці додаткові розриви ліній дійсно мають значення! ;)
Wildcard

@Wildcard Вони дійсно мають значення;)
Ерік Аутгольфер

Чи можете ви зберегти байти за допомогою ppcg.lol/q/idстиснення?
wnnmaw

@wnnmaw Дякую, зараз я лише на 1 байт від відповіді Рубі: стор.
Аднан

1
О ні! Я не думаю, що я можу вирізати достатньо кутів, щоб зберегти 7 байтів, які мені потрібні, щоб знову випереджати ... Напевно, мені просто доводиться влаштовуватися на друге місце
Value Ink

5

Python 3.5, 280 272 260 242 240 байт:

( Дякую Аднану за хитрість щодо використання *оператора у порівняннях, що призводить до 2 збережених байтів! )

def g(o):import urllib.request as u,re;R=re.findall;w=bytes.decode(u.urlopen('http://ppcg.lol/q/'+o).read());print((len(R('(?:<h[0-9]>|<p>).*python',w.lower()))<2)*(int(R('(?<="vote-count-post ">)[0-9]+',w)[0])>3)*w.count('answercell">')>5)

Досить просто. Використовує вбудовану urllibбібліотеку Python для переходу на сайт питання, а потім використовує регулярні вирази для пошуку підрахунку голосів, підрахунку відповідей та підрахунку конкретних відповідей Python у декодованому тексті, поверненому з веб-сайту. Нарешті, ці значення порівнюються з умовами, необхідними для повернення truthyзначення, а якщо вони задовольняють усім умовам, то Trueповертаються. Інакше Falseє.

Єдине, що мене тут може турбувати, - це те, що регулярні вирази дають багато уваги з точки зору кількості відповідей конкретного пітона для збереження байтів, тому це може бути дещо неточним часом, хоча це, мабуть, досить добре для цілі цього виклику. Однак, якщо ви хочете набагато точніше, я додав його нижче, хоча його довше, ніж вище. Один, показаний нижче, наразі складає 298 байт, оскільки він використовує набагато довший регулярний вираз - той, який ви не могли знати, скільки часу знадобилося мені для виявлення - для підрахунку відповідей Python, ніж мої вихідні функції заради точності. Цей повинен працювати приблизно як мінімум від 80% до 90% усіх тестових випадків.

def g(o):import urllib.request as u,re;R=re.findall;w=bytes.decode(u.urlopen('http://ppcg.lol/q/'+o).read());print(len(R('(?<=answercell">).*?(?:<h[0-9]>|<strong>)[^\n]*python[^\n]*(?=</h[0-9]>|</strong>)',w.lower()))<2and int(R('(?<="vote-count-post ">)[0-9]+',w)[0])>3and w.count('answercell">')>5)

Але що з тими питаннями з кількома сторінками відповідей? Жодне з перерахованих вище не спрацює дуже добре в цій ситуації, якщо, скажімо, 1 відповідь пітона є на першій сторінці, а інша - на другій. Що ж, я вирішив вирішити цю проблему, створивши іншу версію моєї функції (показану нижче), яка перевіряє кожну сторінку відповідей, якщо існує декілька, на відповіді Python, і це зробило досить добре у багатьох тестових випадках I кинули на це. Ну, без зайвих прихильностей, ось нова і оновлена ​​функція:

def g(o):
 import urllib.request as u,re;R=re.findall;w=bytes.decode(u.urlopen('http://ppcg.lol/q/'+o).read());t=0if len(re.findall('="go to page ([0-9]+)">',w))<1else max([int(i)for i in re.findall('="go to page ([0-9]+)">',w)])
 if t<1:print(len(R('(?<=answercell">).*?(?:<h[0-9]>|<strong>)[^\n]*python[^\n]*(?=</h[0-9]>|</strong>)',w.lower(),re.DOTALL))<2and int(R('(?<="vote-count-post ">)[0-9]+',w)[0])>3and w.count('answercell">')>5)
 else:
  P=[];U=[];K=[]
  for i in range(2,t+2):P.append(len(R('(?<=answercell">).*?(?:<h[0-9]>|<strong>)[^\n]*python[^\n]*(?=</h[0-9]>|</strong>)',w.lower(),re.DOTALL)));U.append(int(R('(?<="vote-count-post ">)[0-9]+',w)[0]));K.append(w.count('answercell">'));w=bytes.decode(u.urlopen('http://ppcg.lol/questions/'+o+'/?page='+str(i)).read())
  print(sum(P)<2and U[0]>3and sum(K)>5);print('# Python answers: ',sum(P));print('# Votes: ',U[0]);print('# Answers: ',sum(K))

Досить довго, чи не так? Я насправді не дуже збирався з цим кодом для гольфу, хоча, якщо ви хочете, я можу трохи більше пограти в гольф. Інакше я люблю це, і не могла бути щасливішою. О, я майже забув, як додатковий бонус, це також виводить загальну кількість відповідей Python на питання, загальну кількість голосів на питання, і загальну кількість відповідей на питання, якщо питання idвідповідає на запитання з більш ніж 1 сторінкою відповідей. В іншому випадку, якщо питання складається лише з однієї сторінки відповідей, воно просто виводить truthy/falsyзначення. Я дійсно трохи захопився цим викликом.

Кожен з них бере питання id у вигляді рядка .

Я би розміщував Try It Online!тут посилання для кожної функції, але, на жаль, ні, repl.itні Ideoneдопускати отримання ресурсів через urllibбібліотеку Python .


Ви можете скористатися http://codegolf.stackexchange.com/q/цим питанням. Також http://обов’язково?
Марв

Ideone та repl.it не дозволяють отримувати зовнішні ресурси a la urllib.
Мего

@Mego Dang ... ну тоді, мабуть, людям доведеться підтвердити, що це працює, використовуючи власні інтерпретатори Python.
Р. Кап

@Marv Так, мабуть, так і є. В іншому випадку я отримую unknown url typeпомилку.
Р. Кап

6
ppcg.lol/q/idтакож працює
видалено

4

Юлія, 275 байт

using Requests
f(q,p=(s,t)->JSON.parse(readall(get("https://api.stackexchange.com/2.2/questions/$q$s",query=Dict(:site=>"codegolf",:filter=>"$t"))))["items"],x=p("","")[1])=x["answer_count"]>5&&x["score"]>3&&count(i->ismatch(r"python",i["body"]),p("/answers","!9YdnSMKKT"))<2

Це функція, яка приймає ціле число і повертає булеве значення. Він підключається до API обміну стеками, і кожен запуск функції робить 2 запити API, тому не запускайте його занадто багато разів, інакше ви будете вичерпати квоти на 300 запитів на день.

Безголівки:

using Requests

function f(q)
    # Define a function that takes two strings and returns a Dict
    # that connects to the SE API
    p = (s,t) -> JSON.parse(readall(get("https://api.stackexchange.com/2.2/questions/$q$s",
        query = Dict(:site => "codegolf", :filter=> "$t"))))["items"]

    # Get the question object
    x = p("", "")[1]

    # Get all answers using the `withbody` API filter
    y = p("/answers", "!9YdnSMKKT")

    x["answer_count"] > 3 && x["score"] > 5 &&
        count(i -> ismatch(r"python", i["body"], y) < 2
end

Мені не було відомо про фільтр API "withbody"! +1. Якщо це економить байти на моїй відповіді Рубі, чи можу я використовувати і цей трюк?
Значення чорнила

1
@ KevinLau-notKenny Звичайно! Робіть те, що вам потрібно зробити в ім'я гольфу. : P
Олексій А.

Я не хотів плагіатувати = 3, але, на жаль, дізнавшись про ppcg.lolкоротке посилання на всі речі codegolf, версії API просто не вистачало
Value Ink

4

Ракетка, 339 байт

(λ(q)((λ(h)((λ(g)((λ(j)(and(>(h j'score)3)(>(h j'answer_count)5)(<(for/sum([a(g"~a/answers"q)]#:when(regexp-match #rx"(?i:python)"(h a'body)))1)2)))(car(g"~a"q))))(λ(s d)(define-values(x y b)(http-sendrecv"api.stackexchange.com"(format"/2.2/questions/~a?site=codegolf&filter=withbody"(format s d))))(h(read-json b)'items))))hash-ref))

Ще багато для гольфу.


1
Бий мене до цього! : P
кіт

TODO: зробіть ракетку, подібну до гольфу. :)
Вінні

1
339 байт, з яких 68 - парен ... тому для LISP для гольфу потрібні короткі ідентифікатори та без паронів. Не дуже LISPy :(
кіт

4

Ruby + HTTParty , 170 146 145 142 139 138 + 11 ( -rhttpartyпрапор) = 181 157 156 153 150 149 байт

Я не думаю, що немає жодних крайових випадків, які могли б спричинити розрив моїх регексів, сподіваюся ...

Оновлено до короткого посилання, наданого @WashingtonGuedes, і виявив, що HTTParty не скаржиться, якщо я почну з //замістьhttp:// .

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

@manatwork вказав на випадкове доповнення персонажів, яке я залишив, і заради гольфу, i слід сприймати як Струну.

Оновлені реджекси. Однакової довжини. -1 байт, вирізавши парен.

->i{/"up.*?(\d+)/=~s=HTTParty.get("//ppcg.lol/q/"+i)
$1.to_i>3&&(a=s.scan /st.*xt".*\n(.*)/).size>5&&a[1..-1].count{|e|e[0]=~/python/i}<2}

Додаткові примітки:

  • Перший рядок відповіді (який повинен містити мову відповідно до специфікації) - це два рядки після HTML-тегу з класом "post-text", з яким ми відповідали st.*xt". Більш безпечна версія додала б місця після неї, але ми жертвуємо цим заради гольфу.
  • HTTParty використовується над net/httpвласними модулями через належне керування переадресацією для вказаної URL-адреси.
  • "up*?\dбула найкоротшою послідовністю, яку я знайшов, що відповідала кількості голосів. Нам потрібен лише перший, тому вдячні відповіді на це не впливають.

3
ppcg.lol/q/#{i}також працює
видалено

@WashingtonGuedes ppcg.ga/q#{i}можливо? (Я не знаю Рубі)
Ерік Атголфер

@ ΈρικΚωνσταντόπουλος ppcg.ga - це не перенаправлення на макіяж, спробуйте самі - ppcg.ga/q/79273
Timtech

@Timtech Так ppcg.lol/q#{i}застосовано, я думаю? ( a/#bте саме, що a#b)
Ерік Атголфер

1
Це "руйнує /"e-c.*?(\d+)/регулярний вираз. До речі, вимога скаже про вхід , що «типи даних (...) не має значення.» Так що краще передати параметр як я рядок, так що ви можете замінити заміну з конкатенацией: "//ppcg.lol/q/"+i.
манатство

3

Гроовий, 179 161 157

{i->t=new URL("http://ppcg.lol/q/$i").text;a=0;p=0;(t=~/"(?i)p.{25}>\n.*python/).each{p++};(t=~/(?m)v.{13}t ">(\d+)/).each{if(it[1].toLong()>3)a++};a>5&&p<2}

Завдяки Timtech збережено 17 символів.

Визначення ключового слова також не потрібно.


Ви можете замінити codegolf.stackexchange.com на ppcg.lol
Timtech

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