Data update

This commit is contained in:
Ingy döt Net 2025-08-11 18:05:26 -07:00
parent 4d5544505c
commit 4924dd0264
3073 changed files with 55820 additions and 4408 deletions

View file

@ -0,0 +1,83 @@
class Graph {
constructor(size) {
this.adjacencyLists = [];
this.vertices = [];
this.index = 0;
this.stack = [];
this.numbers = new Map();
this.lowlinks = new Map();
this.stronglyConnectedComponents = [];
for (let i = 0; i < size; i++) {
this.vertices.push(i);
this.adjacencyLists.push(new Set());
}
}
addDirectedEdge(from, to) {
this.adjacencyLists[from].add(to);
}
getSCC() {
for (const vertex of this.vertices) {
if (!this.numbers.has(vertex)) {
this.stronglyConnect(vertex);
}
}
return this.stronglyConnectedComponents;
}
stronglyConnect(vertex) {
this.numbers.set(vertex, this.index);
this.lowlinks.set(vertex, this.index);
this.index += 1;
this.stack.push(vertex);
for (const adjacent of this.adjacencyLists[vertex]) {
if (!this.numbers.has(adjacent)) {
this.stronglyConnect(adjacent);
this.lowlinks.set(vertex, Math.min(this.lowlinks.get(vertex), this.lowlinks.get(adjacent)));
} else if (this.stack.includes(adjacent)) {
this.lowlinks.set(vertex, Math.min(this.lowlinks.get(vertex), this.numbers.get(adjacent)));
}
}
if (this.lowlinks.get(vertex) === this.numbers.get(vertex)) {
const stronglyConnectedComponent = new Set();
let top;
do {
top = this.stack.pop();
stronglyConnectedComponent.add(top);
} while (top !== vertex);
this.stronglyConnectedComponents.push(stronglyConnectedComponent);
}
}
}
// Main function equivalent
function main() {
const graph = new Graph(8);
graph.addDirectedEdge(0, 1);
graph.addDirectedEdge(1, 2);
graph.addDirectedEdge(1, 7);
graph.addDirectedEdge(2, 3);
graph.addDirectedEdge(2, 6);
graph.addDirectedEdge(3, 4);
graph.addDirectedEdge(4, 2);
graph.addDirectedEdge(4, 5);
graph.addDirectedEdge(6, 3);
graph.addDirectedEdge(6, 5);
graph.addDirectedEdge(7, 0);
graph.addDirectedEdge(7, 6);
console.log("The strongly connected components are: ");
for (const component of graph.getSCC()) {
console.log(component);
}
}
// Run the main function
main();

200
Task/Tarjan/Zig/tarjan.zig Normal file
View file

@ -0,0 +1,200 @@
const std = @import("std");
const ArrayList = std.ArrayList;
const HashMap = std.HashMap;
const print = std.debug.print;
const Allocator = std.mem.Allocator;
// Simple graph representation using adjacency lists
const Graph = struct {
neighbors: ArrayList(ArrayList(usize)),
allocator: Allocator,
const Self = @This();
pub fn init(allocator: Allocator, size: usize) !Self {
var neighbors = ArrayList(ArrayList(usize)).init(allocator);
try neighbors.ensureTotalCapacity(size);
for (0..size) |_| {
try neighbors.append(ArrayList(usize).init(allocator));
}
return Self{
.neighbors = neighbors,
.allocator = allocator,
};
}
pub fn deinit(self: *Self) void {
for (self.neighbors.items) |*neighbor_list| {
neighbor_list.deinit();
}
self.neighbors.deinit();
}
pub fn addEdge(self: *Self, from: usize, to: usize) !void {
std.debug.assert(to < self.len());
try self.neighbors.items[from].append(to);
}
pub fn addEdges(self: *Self, from: usize, to: []const usize) !void {
const limit = self.len();
for (to) |vertex| {
std.debug.assert(vertex < limit);
try self.neighbors.items[from].append(vertex);
}
}
pub fn getEdges(self: *const Self, vertex: usize) []const usize {
return self.neighbors.items[vertex].items;
}
pub fn isEmpty(self: *const Self) bool {
return self.neighbors.items.len == 0;
}
pub fn len(self: *const Self) usize {
return self.neighbors.items.len;
}
};
const VertexState = struct {
index: usize,
low_link: usize,
on_stack: bool,
};
const Tarjan = struct {
graph: *const Graph,
index: usize,
stack: ArrayList(usize),
state: ArrayList(VertexState),
components: ArrayList(ArrayList(usize)),
allocator: Allocator,
const Self = @This();
const INVALID_INDEX: usize = std.math.maxInt(usize);
pub fn init(allocator: Allocator, graph: *const Graph) !Self {
var state = ArrayList(VertexState).init(allocator);
try state.ensureTotalCapacity(graph.len());
for (0..graph.len()) |_| {
try state.append(VertexState{
.index = INVALID_INDEX,
.low_link = INVALID_INDEX,
.on_stack = false,
});
}
return Self{
.graph = graph,
.index = 0,
.stack = ArrayList(usize).init(allocator),
.state = state,
.components = ArrayList(ArrayList(usize)).init(allocator),
.allocator = allocator,
};
}
pub fn deinit(self: *Self) void {
for (self.components.items) |*component| {
component.deinit();
}
self.components.deinit();
self.stack.deinit();
self.state.deinit();
}
pub fn walk(allocator: Allocator, graph: *const Graph) !ArrayList(ArrayList(usize)) {
var tarjan = try Self.init(allocator, graph);
defer tarjan.deinit();
return try tarjan.visitAll();
}
fn visitAll(self: *Self) !ArrayList(ArrayList(usize)) {
for (0..self.graph.len()) |vertex| {
if (self.state.items[vertex].index == INVALID_INDEX) {
try self.visit(vertex);
}
}
// Move components out to avoid double-free
var result = ArrayList(ArrayList(usize)).init(self.allocator);
try result.ensureTotalCapacity(self.components.items.len);
for (self.components.items) |component| {
try result.append(component);
}
// Clear the original components to avoid double-free
self.components.clearRetainingCapacity();
return result;
}
fn visit(self: *Self, v: usize) !void {
self.state.items[v].index = self.index;
self.state.items[v].low_link = self.index;
self.index += 1;
try self.stack.append(v);
self.state.items[v].on_stack = true;
for (self.graph.getEdges(v)) |w| {
if (self.state.items[w].index == INVALID_INDEX) {
try self.visit(w);
const w_low_link = self.state.items[w].low_link;
self.state.items[v].low_link = @min(self.state.items[v].low_link, w_low_link);
} else if (self.state.items[w].on_stack) {
const w_index = self.state.items[w].index;
self.state.items[v].low_link = @min(self.state.items[v].low_link, w_index);
}
}
if (self.state.items[v].low_link == self.state.items[v].index) {
var component = ArrayList(usize).init(self.allocator);
while (true) {
const w = self.stack.pop().?;
self.state.items[w].on_stack = false;
try component.append(w);
if (w == v) {
break;
}
}
try self.components.append(component);
}
}
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var graph = try Graph.init(allocator, 8);
defer graph.deinit();
try graph.addEdge(0, 1);
try graph.addEdge(2, 0);
try graph.addEdges(5, &[_]usize{ 2, 6 });
try graph.addEdge(6, 5);
try graph.addEdge(1, 2);
try graph.addEdges(3, &[_]usize{ 1, 2, 4 });
try graph.addEdges(4, &[_]usize{ 5, 3 });
try graph.addEdges(7, &[_]usize{ 4, 7, 6 });
var components = try Tarjan.walk(allocator, &graph);
defer {
for (components.items) |*component| {
component.deinit();
}
components.deinit();
}
for (components.items) |component| {
print("{any}\n", .{component.items});
}
}