leetcode

Leetcode problem solutions
git clone https://git.sinitax.com/sinitax/leetcode
Log | Files | Refs | sfeed.txt

add (4979B)


      1#!/usr/bin/env python3
      2
      3from inscriptis import annotation
      4import inscriptis, re, requests, sys
      5from bs4 import BeautifulSoup
      6from glob import glob
      7
      8name = sys.argv[1] or sys.exit(1)
      9
     10def reorder(text, width):
     11    chunks = text.split("\n\n")
     12    out = []
     13    for i,c in enumerate(chunks):
     14        if (":" in c or "* " in c) and "Follow-up" not in c:
     15            for l in c.split("\n"):
     16                prefix = len(l) - len(l.replace("-", " ").lstrip())
     17                indent = l[:prefix]
     18                if i > 0 and chunks[i-1].startswith("*Example "):
     19                    indent = "  " + indent
     20                l2 = []
     21                for w in l[prefix:].split(" "):
     22                    if len(" ".join(l2 + [w])) > width:
     23                        out.append(indent + " ".join(l2))
     24                        indent = indent.replace("-", " ")
     25                        l2 = []
     26                    l2.append(w)
     27                if l == "" or l2 != []:
     28                    out.append(indent + " ".join(l2))
     29            out.append("")
     30            continue
     31        words = re.split(" |\n|\t", c)
     32        line = ""
     33        for w in words:
     34            if w == "":
     35                continue
     36            if len(line) + len(w) + 1 > width:
     37                out.append(line)
     38                while len(w) > width:
     39                    out.append(w[:width])
     40                    w = w[80:]
     41                line = ""
     42            line += "" if line == "" else " "
     43            line += w;
     44        if i == len(chunks) - 1:
     45            out.append(line)
     46        else:
     47            out.append(line)
     48            out.append("")
     49    return out
     50
     51json_data = {
     52    'query': '\n    query questionContent($titleSlug: String!) {\n  question(titleSlug: $titleSlug) {\n    content\n    mysqlSchemas\n    dataSchemas\n  }\n}\n    ',
     53    'variables': {
     54        'titleSlug': name,
     55    },
     56    'operationName': 'questionContent',
     57}
     58r = requests.post('https://leetcode.com/graphql/', json=json_data)
     59description_html = r.json()["data"]["question"]["content"]
     60description_info = inscriptis.get_annotated_text(description_html,
     61    inscriptis.ParserConfig(annotation_rules = {"strong": ["emphasis"]}))
     62emphasis = sorted(description_info["label"], key=lambda v: v[0])
     63description = description_info["text"]
     64offset = 0
     65for start,end,_ in emphasis:
     66    inner = description[start+offset:end+offset]
     67    left = len(inner) - len(inner.lstrip())
     68    description = description[:start+offset+left] \
     69        + "*" + inner[left:] \
     70        + "*" + description[end+offset:]
     71    offset += 2
     72lines = description.split("\n")
     73plen = min([len(l) - len(l.lstrip()) for l in lines if l.strip() != ""])
     74lines = [l[plen:].rstrip() for l in lines]
     75lines = re.sub("\n\n+", "\n\n", "\n".join(lines)).split("\n")
     76lines = reorder("\n".join(lines), 76)
     77#lines = "\n".join(lines).strip().split("\n")
     78description_comment = "\n".join(["/// " + l if l != "" else "///" for l in lines])
     79
     80json_data = {
     81    'query': '\n    query questionTitle($titleSlug: String!) {\n  question(titleSlug: $titleSlug) {\n    questionId\n    questionFrontendId\n    title\n    titleSlug\n    isPaidOnly\n    difficulty\n    likes\n    dislikes\n    categoryTitle\n  }\n}\n    ',
     82    'variables': {
     83        'titleSlug': name,
     84    },
     85    'operationName': 'questionTitle',
     86}
     87r = requests.post('https://leetcode.com/graphql/', json=json_data)
     88num = int(r.json()["data"]["question"]["questionFrontendId"])
     89title = r.json()["data"]["question"]["title"]
     90difficulty = r.json()["data"]["question"]["difficulty"]
     91info_comment = f"/// {num}. {title} ({difficulty})\n///"
     92header_comment = info_comment + "\n" + description_comment
     93
     94json_data = {
     95    'query': '\n    query questionEditorData($titleSlug: String!) {\n  question(titleSlug: $titleSlug) {\n    questionId\n    questionFrontendId\n    codeSnippets {\n      lang\n      langSlug\n      code\n    }\n    envInfo\n    enableRunCode\n    hasFrontendPreview\n    frontendPreviews\n  }\n}\n    ',
     96    'variables': {
     97        'titleSlug': name,
     98    },
     99    'operationName': 'questionEditorData',
    100}
    101r = requests.post('https://leetcode.com/graphql/', json=json_data)
    102solution_impl = next(c for c in r.json()["data"]["question"]["codeSnippets"] if c["lang"] == "Rust")["code"]
    103
    104main_footer = """
    105#[cfg(test)]
    106mod tests {
    107    use crate::Solution;
    108
    109    #[test]
    110    fn test() {
    111    }
    112}
    113"""
    114with open(f"src/bin/{num:04}-{name}.rs", "w+") as f:
    115    f.write(header_comment + "\n\n")
    116    f.write("use leetcode::*;\n\n")
    117    f.write("struct Solution {}\n\n")
    118    f.write(solution_impl + "\n\n")
    119    f.write("pub fn main() {\n}\n")
    120    f.write(main_footer)
    121
    122cargo_header = """[package]
    123name = "leetcode"
    124version = "0.1.0"
    125edition = "2021"
    126"""
    127with open("Cargo.toml", "w+") as f:
    128    f.write(cargo_header)
    129    f.write("\n")
    130    for path in glob("src/bin/*.rs"):
    131        num = int(path.rsplit("/",1)[1].split("-",1)[0])
    132        f.write("[[bin]]\n")
    133        f.write(f"name = \"{num}\"\n")
    134        f.write(f"path = \"{path}\"\n")
    135        f.write("\n")