Определить, стоит ли отвечать на вызов


21

Я очень случайный игрок в код и не часто вижу сообщения, пока они не появятся на боковой панели «Горячие сетевые вопросы» в StackOverflow. Обычно я опаздываю к игре, и поскольку единственный язык, который я знаю, это Python, я не вижу смысла отвечать, поскольку уже есть несколько ответов Python. Ваша задача - выяснить, стоит ли мне отвечать на вопрос.

Входные данные:

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

Выход:

  • Значение True или Falsey для идентификатора вопроса i. Выведите Truthy, если у вопроса более 5 ответов, более 3 баллов и один или менее ответов в Python (без различия между версиями).

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

  • Формат ввода может быть любым разумным (стандартный, файл, командная строка), но должен быть указан в вашем ответе. Типы данных и начальные / конечные пробелы не имеют значения.
  • Предположим, что идентификатор вопроса действителен для codegolf.stackexchange.com.
  • Игнорировать требования к конкретному языку. (т. е. если вопрос встречает голоса и ответы и не имеет ответов Python, потому что это только Java, это все равно приводит к Истине).
  • Ответ квалифицируется как ответ 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 байта

Блин, почти как обычный язык ...

Дерьмо ... дольше бьет ответ Ruby на 1 байт.

Теперь дольше, чем ответ Руби, аааа! ,

Я, наверное, должен идти спать прямо сейчас.

Спасибо @wnnmaw за сохранение 1 байта и спасибо @R. Кап за сохранение еще 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 Они действительно имеют значение;)
Эрик Outgolfer

Не могли бы вы сохранить байты с помощью ppcg.lol/q/idсжатия?
wnnmaw

@wnnmaw Спасибо, теперь я всего в 1 байте от ответа Ruby: с.
Аднан

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есть.

Единственное, что меня может беспокоить здесь, это то, что регулярные выражения дают много общего с точки зрения количества конкретных ответов Python для сохранения байтов, так что иногда это может быть немного неточным, хотя, вероятно, этого достаточно для цели этого вызова. Однако, если вы хотите гораздо более точный, я добавил один ниже, хотя он длиннее, чем выше. Показанный ниже размер в настоящее время составляет 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 находится на первой странице, а другой на второй. Что ж, я взял на себя смелость решить эту проблему, создав другую версию моей функции (показанной ниже), которая проверяет каждую страницу ответов, если существует несколько, на наличие ответов Python, и это хорошо сработало во многих тестовых примерах. бросил на это. Ну, без дальнейших церемоний, вот новая и обновленная функция:

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разрешить извлечение ресурсов с помощью языка Python urllibбиблиотеки.


Вы можете использовать, http://codegolf.stackexchange.com/q/чтобы получить вопрос. Также http://обязательно?
Марв

Ideone и repl.it не позволяют извлекать внешние ресурсы в качестве альтернативы.
Мего

@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 Stack Exchange, и при каждом запуске функции выполняется 2 запроса API, поэтому не запускайте его слишком много раз, иначе вы исчерпаете квоту в 300 запросов в день.

Ungolfed:

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. Если это сэкономит байты на моем ответе Ruby, могу ли я использовать этот трюк?
Value Ink

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}может быть? (Я не знаю Руби)
Эрик Outgolfer

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

@Timtech Так ppcg.lol/q#{i}что применимо я думаю? (так a/#bже, как a#b)
Эрик Outgolfer

1
"Губит /"e-c.*?(\d+)/регулярное выражение. Кстати, требование скажет о входе , что «типы данных (...) не имеет значения.» Так что лучше передать параметр как я строка, так что вы можете заменить замену с конкатенацией: "//ppcg.lol/q/"+i.
manatwork

3

Groovy, 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 символов сохранены.

Ключевое слово def также не обязательно.


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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.