#!/usr/bin/python #Import required libraries import sys import os from PIL import Image, ImageDraw, ImageShow, ImageFont import math import psutil import time from collections import defaultdict class Node: def __init__(self, rect, colour, index, node_size): self.rect = [rect[0], rect[1], rect[0] + node_size, rect[1] + node_size] self.pos = ((self.rect[0] + self.rect[2])/2, (self.rect[1] + self.rect[3])/2) self.colour = colour self.index = index def colour(index): array = ["red", "blue", "green"] return array[index % len(array)] class Sxiv(ImageShow.UnixViewer): def get_command_ex(self, file, **options): return ("bspc rule -a \* -o state=floating focus=off && sxiv",) * 2 node_size = 10 m, n = 600, 600 nodes = [] num_nodes = 9 assert(num_nodes % 3 == 0) ImageShow.register(Sxiv(), -1) font = ImageFont.truetype("Hack-Bold.ttf", node_size*3) im = Image.new('RGB', (m, n)) draw = ImageDraw.Draw(im) draw.rectangle([0, 0, m, n], "white") x_step = math.floor(m / num_nodes) - 10 y_step = math.floor(n / num_nodes) - 10 centerX = math.floor(m/2) centerY = math.floor(n/2) step = -math.floor(360 / num_nodes) radius = math.floor(n/2.5) for i in range(0, num_nodes): angle = (i * step) coordinates = [centerX + radius*math.cos(math.radians(angle)), centerY + radius*math.sin(math.radians(angle))] nodes.append(Node(coordinates, colour(i), i, node_size)) for i,node in enumerate(nodes): draw.rectangle(node.rect, fill=node.colour) draw.text(node.pos, str(node.index),font=font, fill="black") def connect_tuple(d, e): connect(d, e[0], e[1]) def connect(d, v, w): d.line([v.pos, w.pos], fill="black", width=math.floor(node_size/4)) def draw_tree(edges): local = im.copy() d = ImageDraw.Draw(local) for e in edges: connect(d, e[0], e[1]) local.show() def sort_edges(edges): return sorted(edges, key = lambda x: (x[0].index, x[1].index)) def to_indices(edge): return (edge[0].index, edge[1].index) def list_to_indices(edges): e = [] for edge in edges: e.append(to_indices(edge)) return e def has_crossing(edge, edges): new = to_indices(edge) if(new[0] > new[1]): new = new[::-1] for e in edges: exis = to_indices(e) if(exis[0] > exis[1]): exis = exis[::-1] if(exis[0] < new[0] < exis[1] and new[1] > exis[1]): return True if(exis[0] < new[1] < exis[1] and new[0] < exis[0]): return True return False def dfs(parents, visited, adj, node): visited.add(node) for adj_node in adj[node]: if adj_node not in visited: parents[adj_node] = node dfs(parents, visited, adj, adj_node) elif parents[node] != adj_node: return True def has_cycle(new_edge, edges): adj = defaultdict(set) es = [to_indices(e) for e in edges] es.append(to_indices(new_edge)) for x, y in es: adj[x].add(y) adj[y].add(x) visited = set() parents = [None] * len(adj) if dfs(parents, visited, adj, to_indices(new_edge)[0]): return True return False def construct_neighbourhood(edges, index): neighbourhood = [] i = 0 #print(list_to_indices(edges)) for e in edges: start = e[0].index #print("Testing: " + str(to_indices(e))) for new_target in range(start + 1, num_nodes): new_edge = (e[0], nodes[new_target]) if(e == new_edge): continue cropped_edges = edges[:] cropped_edges.remove(e) #print(list_to_indices(cropped_edges)) #print(to_indices(new_edge)) #input() if(new_target % 3 == e[0].index % 3): #print("isn't bicolored") continue if(has_crossing(new_edge, cropped_edges)): #print("has_crossing") continue if(has_cycle(new_edge, cropped_edges)): #print("has_cycle") continue cropped_edges.append(new_edge) #print("Added: " + str(list_to_indices(cropped_edges))) neighbourhood.append(sort_edges(cropped_edges)) if(i == index): return neighbourhood i = i + 1 return neighbourhood def degree(edges): #print("degree...") l = len(construct_neighbourhood(edges, sys.maxsize)) #print("done...") return l def get_jth_neighbour(edges, index): #print("Getting index: " + str(index)) return construct_neighbourhood(edges, index)[index] def is_from_root(edge): return abs(edge[0] - edge[1]) == 1 def get_largest_non_root_edge(edges): edges.reverse() print(edges) for e in edges: if not is_from_root(e): return e return edges def get_largest_missing_convex_edge(edges): difference = [e for e in root_tuples if e not in edges] return difference[-1] def get_parent(edges): sorted_edges = list_to_indices(sort_edges(edges)) e = get_largest_non_root_edge(sorted_edges) if type(e) is list: return list_to_indices(edges) sorted_edges.remove(e) sorted_edges.append(get_largest_missing_convex_edge(sorted_edges)) return sorted_edges def get_parent_in_nodes(edges): parent = get_parent(edges) p = [] for e in parent: p.append((nodes[e[0]], nodes[e[1]])) return sort_edges(p) root = [] for i in range(0, num_nodes - 1): root.append((nodes[i], nodes[i+1])) root_tuples = list_to_indices(root) draw_tree(root) assert(False) v = root j = 0 count = 1 while True: print("Current v: " + str(list_to_indices(v))) deg = degree(v) print(" degree = " + str(deg)) while(j != deg): j = j + 1 w = sort_edges(get_jth_neighbour(v, j - 1)) if(sort_edges(get_parent_in_nodes(w)) == sort_edges(v)): print("\t " + str(list_to_indices(w))) print("\t parent: " + str(list_to_indices(get_parent_in_nodes(w)))) v = w j = 0 count = count + 1 print(" Current w:" + str(list_to_indices(v))) print(" degree = " + str(deg) + " j = " + str(j)) deg = degree(v) if(v != root): w = v v = get_parent_in_nodes(w) j = 0 neighbours = construct_neighbourhood(v, sys.maxsize) n = neighbours[j] while(n != w): j = j + 1 n = neighbours[j] input() if(v == root and j == degree(root)): print(list_to_indices(v)) print(j) break #while True: # for tree in construct_neighbourhood(root, sys.maxsize): # im1 = im.copy() # d = ImageDraw.Draw(im1) # draw_tree(d, tree) # im1.show() # # input() # #for proc in psutil.process_iter(): # # if proc.name() == "sxiv": # # proc.kill() # assert(False)