13
\$\begingroup\$

Huge omega thanks to @wasif for emailing me this challenge idea in its basic form

Everyone knows that questions on StackExchange require tags - labels that allow posts to be grouped together by category. However, most of the time, I barely know which tags exist, because there's just so many of them. Henceforth, today's task is to tell me every single tag that exists on the Code Golf and Coding Challenges Stack Exchange.

The Challenge

Write a program or function that prints/returns a list of all available tags on https://codegolf.stackexchange.com As tags can be created/deleted at any time, simply hard-coding a list of tags is not a valid solution - the list must be correct at run-time regardless of when the program/function is executed. The tags avaliable can be seen here

Rules

  • As this is an challenge, internet connections are allowed. However, web requests can only be made to codegolf.stackexchange.com and api.stackexchange.com domains.
  • Output can be given in any convenient and reasonable format.
  • The tags can be in any order, so long as all current tags are returned.
  • The exact name of the tags must be used (e.g. code-golf is valid, code GOLF is not valid.)
  • And as usual, standard loopholes apply, shortest code wins

Example Program

import urllib.request
import regex

pobj = regex.compile('rel="tag">(.*)</a>')
page_number = 2
req = urllib.request.urlopen(f"https://codegolf.stackexchange.com/tags?page=1&tab=name")
data = req.read().decode('utf-8')
tags = []
while data.count("tag") != 43:
    tags += pobj.findall(data)
    req = urllib.request.urlopen(f"https://codegolf.stackexchange.com/tags?page={page_number}&tab=name")
    data = req.read().decode('utf-8')
    page_number += 1
    
print(tags)
\$\endgroup\$
10
  • \$\begingroup\$ Can we assume amount of tags stable enough? so we can hardcode page amount \$\endgroup\$
    – l4m2
    Apr 20, 2021 at 3:00
  • \$\begingroup\$ @l4m2 the program has to output every tag at time of execution, so hard coding probably isn't a valid option \$\endgroup\$
    – lyxal
    Apr 20, 2021 at 3:03
  • \$\begingroup\$ But it's unlikely that there's at some time lot more tags or lot less tags \$\endgroup\$
    – l4m2
    Apr 20, 2021 at 3:05
  • 3
    \$\begingroup\$ I must be getting old - what is the significance of omega in Huge omega thanks? \$\endgroup\$ Apr 20, 2021 at 18:06
  • 1
    \$\begingroup\$ Omega here is indeed a play on "mega", but also a tribute to Omega Flowey. @Makonede \$\endgroup\$
    – lyxal
    Jun 3, 2021 at 23:18

6 Answers 6

10
\$\begingroup\$

05AB1E, 60 57 56 bytes

[N>’¸¸.‚‹º.ŒŒ/›´?€¼=ƒËŠˆ&€®=ÿ’.wD2è'eQ#“e":"“¡¦ε'"¡н]\)

Outputs as a list of pages, where each page is a list of tags.

[N>’...’.wD2è'eQ#“e":"“¡¦ε'"¡н]\)  # trimmed program
[               #                  # while...
            è                      # character in...
        .wD                        # data of response from URL...
                                   # (implicit) "http://" concatenated with...
   ’...’                           # "api.stackexchange.com/tags?site=codegolf&page=ÿ"...
                                   # (implicit) with ÿ replaced by...
 N                                 # current index in loop...
  >                                # plus 1...
            è                      # at index...
           2                       # literal...
                #                  # is not...
               Q                   # equal to...
             'e                    # literal...
        .w                         # push data of response from URL...
                                   # (implicit) "http://" concatenated with...
   ’...’                           # "api.stackexchange.com/tags?site=codegolf&page=ÿ"...
                                   # (implicit) with ÿ replaced by...
 N                                 # current index in loop...
  >                                # plus 1...
                       ¡           # split by...
                 “e":"“            # literal...
                        ¦          # excluding the first...
                         ε         # with each element replaced by...
                             н     # first element of...
                                   # (implicit) current element in map...
                            ¡      # split by...
                          '"       # literal
                              ]    # exit map
                              ]    # exit infinite loop
                               \   # delete top element of stack
                                )  # push stack
                                   # implicit output
\$\endgroup\$
4
  • 3
    \$\begingroup\$ I was about to suggest using dictionary compression and then realised I was being a stupid idiot because I was looking at the unpacked strings in the explanation. Very well done! \$\endgroup\$
    – lyxal
    Apr 20, 2021 at 7:14
  • \$\begingroup\$ @Lyxal Thanks! I also just checked the source code and turns out that 05AB1E does in fact implicitly add http:// if it's not present, saving me three bytes. :) \$\endgroup\$
    – Makonede
    Apr 21, 2021 at 20:01
  • \$\begingroup\$ See the Jyxal answer, which beats this by 12 bytes. \$\endgroup\$
    – emanresu A
    Mar 7, 2022 at 3:22
  • \$\begingroup\$ See my comment on it. \$\endgroup\$
    – Makonede
    Mar 7, 2022 at 4:31
8
\$\begingroup\$

Jyxal 0.2.0, 44 bytes

0{›:`ȯø.⟩β•∵.•⅛/ɾƈ?λ→=%&λẋ=¬⋎»₅`%¨UøJht(ntt,

Jyxal-is-not-hosted-anywhere-so-read-the-readme-to-see-how-to-try-this

Fixed thanks to @emanresu A

Absolutely crushes 05AB1E. On my machine, it goes through the first 25 pages before getting a 403 and printing 4 forever. Unfortunately, Vyxal cannot decompress zipped responses so I kinda had to use Jyxal in place. This is heavily dependent on the ordering of the values in the JSON response.

0{›:`ȯø.⟩β•∵.•⅛/ɾƈ?λ→=%&λẋ=¬⋎»₅`%¨UøJht(ntt, # I don't need the 2 closing parens at the end.
0                                            # Push 0 (Jyxal does not have implicit input yet)
 {                                           # Loop forever
  ›                                          # And increment the number
                                %            # Replace all "%" in the string...
    `ȯø.⟩β•∵.•⅛/ɾƈ?λ→=%&λẋ=¬⋎»₅`             # "api.stackexchange.com/tags?page=%&site=codegolf"
   :                                         # With the current loop index
                                 ¨U          # Make a GET request to that URL...
                                   øJ        # And decode the JSON response
                                     h       # Get the first key-value pair...
                                      t      # And the second item; that is, the "items" array
                                       (n    # For each item in that array...
                                         t   # Get the last key-value pair and then...
                                          t  # Get the value
                                           , # Print that value
\$\endgroup\$
4
  • \$\begingroup\$ Nice! If you've implemented (26) yet you can save a byte with that. And if you've implemented ƛ (map) yet you can save a couple more bytes with that by removing the n. \$\endgroup\$
    – emanresu A
    Mar 7, 2022 at 3:01
  • \$\begingroup\$ I'm still in the lead, as yours assumes there are no more than 25 pages while mine works no matter how many. \$\endgroup\$
    – Makonede
    Mar 7, 2022 at 3:20
  • \$\begingroup\$ @Makonede (to seggan) replacing 25(n with {›: will make it work no matter how many. \$\endgroup\$
    – emanresu A
    Mar 7, 2022 at 6:26
  • \$\begingroup\$ @Makonede now I'm in the lead ;) Thanks emanresu A \$\endgroup\$
    – Seggan
    Mar 7, 2022 at 16:37
7
\$\begingroup\$

Python 3 + requests, 143 bytes

from requests import*
p=1
while[print(x["name"])for x in get(f"http://api.stackexchange.com/tags?page={p}&site=codegolf").json()["items"]]:p+=1

-19 bytes thanks to Jonathan Allan
-5 bytes thanks to dingledooper

\$\endgroup\$
7
  • 3
    \$\begingroup\$ Would while a:a=[print(x["name"])for...];p+=1 work? ...Edit: or even while[print(x["name"])for...]:p+=1? \$\endgroup\$ Apr 20, 2021 at 1:20
  • 1
    \$\begingroup\$ @JonathanAllan Yep, looks like it does! Thanks! \$\endgroup\$
    – hyper-neutrino
    Apr 20, 2021 at 1:22
  • \$\begingroup\$ -2 by using "https://api.stackexchange.com/2.2/tags?site=codegolf&page="+p instead of f"https://api.stackexchange.com/2.2/tags?page={p}&site=codegolf". \$\endgroup\$
    – Makonede
    Apr 20, 2021 at 1:38
  • \$\begingroup\$ @Makonede you can't add strings and integers in python \$\endgroup\$
    – hyper-neutrino
    Apr 20, 2021 at 1:42
  • \$\begingroup\$ @hyper-neutrino I knew that, just forgot that p was an int \$\endgroup\$
    – Makonede
    Apr 20, 2021 at 1:46
5
\$\begingroup\$

JavaScript (Firefox chrome), 135 bytes

f=async(i=1)=>(await((await fetch('http://codegolf.stackexchange.com/tags?page='+i)).text())).match(/[\w-]+(?=&#3)/g).map(alert)|f(i+1)
  1. Open Browser Console of Firefox; You may however open console on this page instead;
  2. Paste codes there;
  3. Invoke it by running f();
  4. Click to close many many alert's

Source codes for tags page contains line

<a href="/questions/tagged/code-golf" class="post-tag" title="show questions tagged &#39;code-golf&#39;" rel="tag">code-golf</a>

We match the text code-golf between &#39; by /[\w-]+(?=&#3)/g.

The recursion terminate when ith page contains no tags. While the match result is null, and .map on null cause an error.

\$\endgroup\$
6
  • 1
    \$\begingroup\$ Would that work on Run Snippet? \$\endgroup\$
    – l4m2
    Apr 20, 2021 at 9:30
  • \$\begingroup\$ @l4m2 As long as you have permission to access that domain. Either by executing on same origin or as chrome code. \$\endgroup\$
    – tsh
    Apr 20, 2021 at 10:28
  • \$\begingroup\$ I mean if so you'd make a run in your post? \$\endgroup\$
    – l4m2
    Apr 20, 2021 at 10:30
  • \$\begingroup\$ @l4m2 The code snippets in SE sites run under a different domain as I know \$\endgroup\$
    – tsh
    Apr 20, 2021 at 10:33
  • \$\begingroup\$ f=async i=>(await((await fetch('http://codegolf.stackexchange.com/tags?page='+-~i)).text())).match(/[\w-]+(?=&#3)/g).map(alert)|f(-~i)? \$\endgroup\$
    – l4m2
    Apr 20, 2021 at 23:24
4
\$\begingroup\$

JavaScript, 176 bytes

async _=>{t=[];i=1;do t.push(...(j=await (await fetch("http://api.stackexchange.com/2.2/tags?site=codegolf&page="+i++)).json()).items);while(j.has_more)return t.map(d=>d.name)}

Must be run on api.stackexchange.com subdomain; I use /docs for testing.

\$\endgroup\$
6
  • \$\begingroup\$ If you're going to run it on the api.stackexchange.com domain, why don't you use a relative path? \$\endgroup\$
    – Neil
    Apr 20, 2021 at 7:53
  • \$\begingroup\$ @Neil Something like this? storing info in URL bar should be disallowed \$\endgroup\$
    – l4m2
    Apr 20, 2021 at 9:33
  • 1
    \$\begingroup\$ @l4m2 Program already only works on the api.stackexchange.com domain, so I don't see the problem here. \$\endgroup\$
    – Neil
    Apr 20, 2021 at 10:21
  • \$\begingroup\$ @Neil It also runs on, for example, api.stackexchange.com/docs. Either way I think it'd be kind of cheaty to use a relative path anyway. \$\endgroup\$ Apr 20, 2021 at 12:32
  • \$\begingroup\$ Well, it only needs to be relative from http://api.stackexchange.com (because you don't know which page you're on) but that still saves 28 bytes... \$\endgroup\$
    – Neil
    Apr 20, 2021 at 15:28
3
\$\begingroup\$

Bash + wget + jq, 86

Assumes there are no more than 99 pages of results (currently 10 pages).

wget -qO- api.stackexchange.com/tags?site=codegolf\&page={1..99}|zcat|jq .items[].name

Testing this blew through my daily API requests limit pretty quick.

\$\endgroup\$
1
  • \$\begingroup\$ I'm glad you were able to connect to share you're answer. \$\endgroup\$
    – user974006
    Mar 8, 2022 at 5:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.