Skip to content
Snippets Groups Projects
Commit 55264722 authored by Bruno Freitas Tissei's avatar Bruno Freitas Tissei
Browse files

[WIP] Add better Latex generator

parent 3f16da49
No related branches found
No related tags found
No related merge requests found
...@@ -15,7 +15,7 @@ struct ConvexHull { ...@@ -15,7 +15,7 @@ struct ConvexHull {
/// Finds, among v, the points that form a convex hull /// Finds, among v, the points that form a convex hull
/// @param v vector of points /// @param v vector of points
int run(const vector<dd> &v) { vector<int> run(const vector<dd> &v) {
int k = 0; int k = 0;
vector<int> ans(v.size() * 2); vector<int> ans(v.size() * 2);
...@@ -39,13 +39,7 @@ struct ConvexHull { ...@@ -39,13 +39,7 @@ struct ConvexHull {
// The ans vector contains the indices (relative to the sorted vector!) // The ans vector contains the indices (relative to the sorted vector!)
// of the points belonging to the convex hull // of the points belonging to the convex hull
ans.resize(k); ans.resize(k - 1);
return ans;
// Remove duplicates
sort(all(ans));
ans.erase(unique(all(ans)), ans.end());
// Return number of points in the convex hull
return k - 1;
} }
}; };
...@@ -2,21 +2,24 @@ ...@@ -2,21 +2,24 @@
/// ///
/// Complexity (Time): O(V log V) /// Complexity (Time): O(V log V)
/// Complexity (Space): O(V + E) /// Complexity (Space): O(V + E)
///
// Must be a tree
vector<int> graph[MAX];
/// The Centroid Decomposition of a tree is a tree where: /// The Centroid Decomposition of a tree is a tree where:
/// - Its root is the centroid of the original tree. /// - Its root is the centroid of the original tree.
/// - Its children are the centroid of each tree resulting from the removal /// - Its children are the centroid of each tree resulting from the removal
/// of the root from the original tree. /// of the root from the original tree.
///
/// The result is a tree with lg(n) height, where the path from a to b in /// The result is a tree with lg(n) height, where the path from a to b in
/// the original tree can be decomposed into the path from a to lca(a,b) and /// the original tree can be decomposed into the path from a to lca(a,b) and
/// from lca(a,b) to b, where lca(a,b) is the lowest common ancestor of a and b /// from lca(a,b) to b, where lca(a,b) is the lowest common ancestor of a and b
/// in the centroid decomposition. /// in the centroid decomposition.
///
/// This is useful because each one of the n^2 paths of the original tree is /// This is useful because each one of the n^2 paths of the original tree is
/// the concatenation of two paths in a set of O(n lg(n)) paths from a node to /// the concatenation of two paths in a set of O(n lg(n)) paths from a node to
/// all its ancestors in the centroid decomposition. /// all its ancestors in the centroid decomposition.
// Must be a tree
vector<int> graph[MAX];
struct CentroidDecomposition { struct CentroidDecomposition {
vector<int> par, size, marked; vector<int> par, size, marked;
...@@ -24,23 +27,21 @@ struct CentroidDecomposition { ...@@ -24,23 +27,21 @@ struct CentroidDecomposition {
/// @param N number of vertices /// @param N number of vertices
CentroidDecomposition(int N) : CentroidDecomposition(int N) :
par(N), size(N), marked(N) par(N), size(N), marked(N)
{ { init(); }
init();
}
void init() { void init() {
fill(all(marked), 0); fill(all(marked), 0);
// Assuming vertices are 0-indexed // Assuming vertices are 0-indexed
build(0, -1); build(0);
} }
/// Builds the centroid decomposition of the tree recursively. /// Builds the centroid decomposition of the tree recursively.
/// @param x initial node /// @param x initial node (root)
/// @param p parent node /// @param p parent node
void build(int x, int p) { void build(int x, int p = -1) {
int n = dfs(x, -1); int n = dfs(x);
int centroid = get_centroid(x, -1, n); int centroid = get_centroid(x, n);
marked[centroid] = 1; marked[centroid] = 1;
par[centroid] = p; par[centroid] = p;
...@@ -53,7 +54,7 @@ struct CentroidDecomposition { ...@@ -53,7 +54,7 @@ struct CentroidDecomposition {
/// Calculates size of every subtree (in the original tree). /// Calculates size of every subtree (in the original tree).
/// @param x initial node /// @param x initial node
/// @param p parent node /// @param p parent node
int dfs(int x, int p) { int dfs(int x, int p = -1) {
size[x] = 1; size[x] = 1;
for (auto i : graph[x]) for (auto i : graph[x])
if (i != p && !marked[i]) if (i != p && !marked[i])
...@@ -65,9 +66,9 @@ struct CentroidDecomposition { ...@@ -65,9 +66,9 @@ struct CentroidDecomposition {
/// Finds centroid by recursively searching for it in the subtree /// Finds centroid by recursively searching for it in the subtree
/// with more than n / 2 nodes in it. /// with more than n / 2 nodes in it.
/// @param x initial node /// @param x initial node
/// @param p parent node
/// @param n size of initial subtree /// @param n size of initial subtree
int get_centroid(int x, int p, int n) { /// @param p parent node
int get_centroid(int x, int n, int p = -1) {
for (auto i : graph[x]) for (auto i : graph[x])
if (i != p && size[i] > n / 2 && !marked[i]) if (i != p && size[i] > n / 2 && !marked[i])
return get_centroid(i, x, n); return get_centroid(i, x, n);
......
6
3 6 1 1
.@@..@
.....@
@.@.@@
4 3 1 1
@@@
@.@
@.@
@@@
4 5 1 1
.....
.....
.....
.....
4 4 1 1
..@@
..@@
@@..
@@..
3 4 2 2
@.@@
@@.@
@.@@
3 4 1 2
.@.@
@.@.
.@.@
File deleted
#!/bin/bash
#tex_file=$(mktemp)
python3 notebook/gen_latex.py # --header=notebook/header.tex --output=$tex_file
#pdflatex $tex_file -output-directory . &&
#pdflatex $tex_file -output-directory .
#mv tmp.pdf caderno.pdf
#rm tmp*
import os
import sys
import subprocess
import argparse
from pathlib import Path from pathlib import Path
dirs = [ class Tree:
'algorithms',
'misc',
'contests',
'problems'
]
parser = argparse.ArgumentParser() # Constructor.
parser.add_argument('--header', action='store', type=str, help='The text to parse.') # @param dirs list of directories to build Latex over
parser.add_argument('--output', action='store', type=str, help='The text to parse.') def __init__(self, dirs):
args = parser.parse_args() self.dirs = dirs;
self.tree = {}
self.build()
output = open(args.output, 'w') # Sorts the lists on tree leaves.
def sort(self, sub):
if type(sub) == list:
return sorted(sub)
else:
for i in sub:
sub[i] = self.sort(sub[i])
return sub
# Builds a tree represented as dict, with structure of files
# and directories.
def build(self):
for di in self.dirs:
path_list = Path(di).glob('**/*.cpp')
# Read Latex header for path in path_list:
with open(args.header) as f: branch = str(path).split('/')
data = f.readlines() curr = self.tree
# Print header to output for i in branch[:-2]:
for i in data: if not i in curr:
output.write(i) curr[i] = {}
curr = curr[i]
last_sections = [None] * 2 if not branch[-2] in curr:
curr[branch[-2]] = []
curr[branch[-2]].append(str(branch[-1]))
for di in dirs: self.tree = self.sort(self.tree)
path_list = Path(di).glob('**/*.cpp')
for path in path_list: def __getitem__(self, arg):
file_name = str(path) return self.tree[arg]
sections = file_name.replace('_', '\_').split('/')
# Sections[0] is [algorithms, contests, problems, misc] (sections)
if sections[0] != last_sections[0]:
output.write('\\newpage\n')
output.write('\\section{' + sections[0].capitalize() + '}\n')
# Sections[1] is name of constest or category of algorithm (subsections)
if sections[1] != last_sections[1]:
output.write('\\subsection{' + sections[1].capitalize() + '}\n')
# Parse source code
with open(file_name) as f:
source = f.readlines()
# Separate into comment and code, and define title
title = ""
in_comment = False
code, comment = [], []
for line in source:
if '/**' == line[0:3]:
in_comment = True
if in_comment:
if len(title) == 0 and len(comment) == 1:
title = line[3:]
comment.append(line)
else:
code.append(line)
if '*/' in line: def __iter__(self):
in_comment = False return iter(self.tree)
if len(sections) > 2:
output.write('\\subsubsection{' + title + '}\n')
in_complexity = 0 class LatexGenerator:
ctime, cspace = [], [] def __init__(self, tree):
for line in comment: self.tree = tree
if 'Complexity (time)' in line: self.hierarchy = ['chapter'] + [i*'sub' + 'section' for i in range(3)]
in_complexity = 1 self.gen_latex(tree, 0)
if 'Complexity (space)' in line:
in_complexity = 2
if in_complexity: # Prints elements in arr in Latex format.
ctime.append(line) def gen_code_latex(self, content, depth):
print('\\' + self.hierarchy[depth] + '{' + content + '}')
# Generates Latex for entire tree recursively
def gen_latex(self, sub, depth):
if type(sub) == list:
for i in sub:
self.gen_code_latex(i, depth)
else:
for i in sub:
self.gen_code_latex(i, depth)
self.gen_latex(sub[i], depth + 1)
# Remove first \n after header comment
code = code[1:]
#output.write('\\lstinputlisting[style=customcpp]{' + file_name + '}\n') def main():
output.write('\\begin{lstlisting}[style=customcpp]\n') dirs = [ 'algorithms', 'misc' ]
for i in code: tree = Tree(dirs)
output.write(i) tex = LatexGenerator(tree)
output.write('\\end{lstlisting}\n')
output.write('\\\n')
last_sections = sections
output.write('\\end{document}') if __name__ == "__main__":
main()
#!/bin/bash
tex_file=$(mktemp)
python3 notebook/gen_latex.py --header=notebook/header.tex --output=$tex_file
pdflatex $tex_file -output-directory . &&
pdflatex $tex_file -output-directory .
mv tmp.pdf caderno.pdf
rm tmp*
from pathlib import Path
dirs = [
'algorithms',
'misc',
'contests',
'problems'
]
# Returns a tree represented as dict, with structure of files
# and directories
def get_file_tree():
tree = {}
for di in dirs:
path_list = Path(di).glob('**/*.cpp')
for path in path_list:
branch = str(path).split('/')
curr = tree
for i in branch[:-2]:
if not i in curr:
curr[i] = {}
curr = curr[i]
if not branch[-2] in curr:
curr[branch[-2]] = []
curr[branch[-2]].append(str(branch[-1]))
return tree
# Print elements in arr in Latex format
def gen_code_latex(arr, depth):
for i in arr:
print('\\' + depth + '{' + i + '}')
# Generate Latex from tree
def gen_latex(tree):
stack = [ (tree, 0) ]
depth = ['chapter', 'section', 'subsection']
while len(stack) != 0:
x, h = stack.pop()
print(x)
#if type(x) == list:
# gen_code_latex(x, depth[h])
#print('\\' + depth[h] + '{' + i + '}')
for i in x:
stack.append((x[i], h + 1))
tree = get_file_tree()
for i in tree:
print(i)
for j in tree[i]:
print('\t' + j)
if type(tree[i]) != list:
for k in tree[i][j]:
print('\t\t' + k)
print()
print()
#print(tree)
#gen_latex(tree)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment