Ejemplo n.º 1
0
def part_2(path: Path) -> int:
    mat = Mat(read_file_to_int_matrix(path))

    # A mapping of cell (tuple row, col) to basin number
    cell_to_basin = {}
    # A mapping of basin number to a list of cells in that basin
    basin_dict = {}

    # Put each cell in it's own basin
    basin_count = 0
    for row in range(mat.row_count):
        for col in range(mat.col_count):
            if mat.get_cell(row, col) == 9:
                continue
            cell_to_basin[(row, col)] = basin_count
            basin_dict[basin_count] = [(row, col)]
            basin_count += 1

    def check_and_combine_basins(cell1, cell2):
        # If cell 1 and cell 2 are in different basins
        if cell2 in cell_to_basin and cell_to_basin[cell1] != cell_to_basin[
                cell2]:
            cell1_basin_num = cell_to_basin[cell1]
            cell2_basin_num = cell_to_basin[cell2]

            # Add everything in basin 2 into basin 1
            basin1 = basin_dict[cell1_basin_num]
            basin2 = basin_dict[cell2_basin_num]
            basin1.extend(basin2)

            # Update cell_to_basin that everything that was in basin 2 is  now in basin 1
            for cell_in_basin2 in basin2:
                cell_to_basin[cell_in_basin2] = cell1_basin_num

            # Remove basin 2
            basin_dict.pop(cell2_basin_num)
            return True
        return False

    # Keep combining until there're no more to combine
    combined_some = True
    while combined_some:
        combined_some = False

        for row in range(mat.row_count):
            for col in range(mat.col_count):
                if mat.get_cell(row, col) == 9:
                    continue

                for neighbor_row, neighbor_col in mat.cardinal_neighbors(
                        row, col):
                    combined_some = check_and_combine_basins(
                        (row, col),
                        (neighbor_row, neighbor_col)) or combined_some

    basins = list(basin_dict.values())
    basins.sort(key=len, reverse=True)

    return len(basins[0]) * len(basins[1]) * len(basins[2])
Ejemplo n.º 2
0
def flash(octos: Mat, row: int, col: int, flashed: Set) -> None:
    flashed.add((row, col))

    for neighbor_row, neighbor_col in octos.all_neighbors(row, col):
        new_val = octos.add(neighbor_row, neighbor_col, 1)

        if new_val == 10:
            flash(octos, neighbor_row, neighbor_col, flashed)
Ejemplo n.º 3
0
def part_2(path: Path) -> int:
    start = time.time()
    mat = read_file_to_int_matrix(path)
    mat = Mat(extend_mat(mat))
    target = (mat.row_count - 1, mat.col_count - 1)
    answer = sum(
        mat.get_cell(*cell) for cell in dijkstra(mat, (0, 0), target)[1:])
    print(time.time() - start)
    return answer
Ejemplo n.º 4
0
def process_step(octos: Mat) -> int:
    flashed = set()

    for row in range(octos.row_count):
        for col in range(octos.col_count):
            new_value = octos.add(row, col, 1)
            if new_value == 10:
                flash(octos, row, col, flashed)

    for row, col in flashed:
        octos.set_cell(row, col, 0)

    return len(flashed)
Ejemplo n.º 5
0
def dijkstra(mat: Mat, source: Tuple[int, int],
             target: Tuple[int, int]) -> List[Tuple[int, int]]:
    distances = {}
    prev = {}
    q = []

    for row in range(mat.row_count):
        for col in range(mat.col_count):
            prev[(row, col)] = None
            if (row, col) != source:
                distances[(row, col)] = float('inf')
                q.append((float('inf'), (row, col)))
            else:
                distances[source] = 0
                q.append((0, (row, col)))

    q.sort()
    seen = set()

    q_place = 0
    while q_place != len(q):
        _, u = q[q_place]
        seen.add(u)
        q_place += 1

        if u == target:
            break

        for v in mat.cardinal_neighbors(*u):
            if v in seen:
                continue

            alt = distances[u] + mat.get_cell(*v)
            if alt < distances[v]:
                distances[v] = alt
                prev[v] = u

                # Update v in q, maintaining sorted
                bisect.insort(q, (alt, v))

    s = []
    u = target
    if prev[u] or u == source:
        while u:
            s.append(u)
            u = prev[u]

    return s[::-1]
Ejemplo n.º 6
0
def part_1(path: Path) -> int:
    mat = Mat(read_file_to_int_matrix(path))

    def is_low_point():
        cell_val = mat.get_cell(row, col)
        for neighbor_row, neighbor_col in mat.cardinal_neighbors(row, col):
            if cell_val >= mat.get_cell(neighbor_row, neighbor_col):
                return False
        return True

    risk_total = 0
    for row in range(mat.row_count):
        for col in range(mat.col_count):
            if is_low_point():
                risk_total += mat.get_cell(row, col) + 1

    return risk_total
Ejemplo n.º 7
0
def part_2(path: Path) -> int:
    octos = Mat(read_file_to_int_matrix(path))
    total = octos.row_count * octos.col_count

    step_num = 1
    while process_step(octos) != total:
        step_num += 1
    return step_num
Ejemplo n.º 8
0
def load_zachary_karate_club():
    edges = []
    with open("../data/KarateClub.csv", 'r') as csvFile:
        for row in csvFile:
            edges.append(tuple(map(int, row.strip().split(";"))))

    vertices = []
    [[vertices.append(x) for x in edge if x not in vertices] for edge in edges]

    matrixValues = [[is_edge_between(edges, v, rId) for v in range(1, len(vertices) + 1)] for rId in range(1, len(vertices) + 1)]
    matrix = Mat(matrixValues)
    return matrix
Ejemplo n.º 9
0
def main():
    edges = []
    with open("../data/KarateClub.csv", 'r') as csvFile:
        for row in csvFile:
            edges.append(tuple(map(int, row.strip().split(";"))))

    #print(edges)
    vertices = []
    [[vertices.append(x) for x in edge if x not in vertices] for edge in edges]

    matrixValues = [[
        is_edge_between(edges, v, rId) for v in range(1,
                                                      len(vertices) + 1)
    ] for rId in range(1,
                       len(vertices) + 1)]
    matrix = Mat(matrixValues)

    matrix = matrix.set_inf_where_no_edge()
    distanceMatrix = matrix.get_floyd_distance_matrix()
    # print(matrix)
    closenessCentralityVector = distanceMatrix.closeness_centrality_for_vertices(
    )
    print(closenessCentralityVector)
Ejemplo n.º 10
0
def generate_random_network(vertexCount, edgeProbability):
    population = [0, 1]
    weights = [(1 - edgeProbability), edgeProbability]

    matrixValues = [[inf for c in range(vertexCount)]
                    for r in range(vertexCount)]

    for r in range(vertexCount):
        for c in range(r, vertexCount):
            if r == c:
                matrixValues[r][c] = 0
            elif matrixValues[r][c] == inf:
                edgeVal = choices(population, weights)[0]
                matrixValues[r][c] = edgeVal
                matrixValues[c][r] = edgeVal

    result = Mat(matrixValues)
    return result
Ejemplo n.º 11
0
def load_bipartite():
    lines = []

    #    with open("D:/gitrepos/dataAnalysisCourse/data/actorsAndMovies.txt") as dataset:
    with open("../data/actorsAndMovies.txt") as dataset:
        lines = dataset.readlines()

    labels = {}
    edges = []
    maxVertex = 0
    readingEdges = False
    for line in lines:
        line = line.strip()
        if line == "EDGES":
            readingEdges = True
            continue

        lineValues = line.split(";")
        if readingEdges:
            a = int(lineValues[0]) - 1
            b = int(lineValues[1]) - 1
            if a > maxVertex:
                maxVertex = a
            if b > maxVertex:
                maxVertex = b
            edges.append((a, b))
        else:
            labels[int(lineValues[0])] = lineValues[1].replace('"', "")

    rowCount = 10
    values = [[0 for c in range(len(labels))] for r in range(rowCount)]

    for edge in edges:
        (a, b) = edge
        values[a][b] = 1

    bm = Mat(values, tuple(labels.values()))
    return bm
Ejemplo n.º 12
0
def generate_small_world_network(startingSize, m, t):
    startingSize = 3
    resultSize = 3 + t
    currentSize = startingSize

    initial = Mat([[0, 1, 1], [1, 0, 1], [1, 1, 0]])
    vertexList = [0, 0, 1, 1, 2, 2]
    resultMatrix = Mat([[0 for c in range(resultSize)]
                        for r in range(resultSize)])
    resultMatrix.insert(initial)

    for step in range(t):
        newVertexIndex = startingSize + step
        vertexListSize = float(len(vertexList))
        population = range(currentSize)
        weights = [(float(vertexList.count(v)) / vertexListSize)
                   for v in population]

        neighbours = []
        for mStep in range(m):
            neighbour = choices(population, weights)[0]
            while neighbour in neighbours:
                neighbour = choices(population, weights)[0]
            neighbours.append(neighbour)

        assert len(neighbours) == m

        vertexList.append(newVertexIndex)
        vertexList.append(newVertexIndex)
        for n in neighbours:
            vertexList.append(n)
            resultMatrix.values[newVertexIndex][n] = 1
            resultMatrix.values[n][newVertexIndex] = 1

        currentSize += 1
        #print("Current size: " + str(currentSize))

    return resultMatrix
Ejemplo n.º 13
0
def part_1(path: Path) -> int:
    mat = Mat(read_file_to_int_matrix(path))
    target = (mat.row_count - 1, mat.col_count - 1)

    return sum(
        mat.get_cell(*cell) for cell in dijkstra(mat, (0, 0), target)[1:])
Ejemplo n.º 14
0
def part_1(path: Path) -> int:
    octos = Mat(read_file_to_int_matrix(path))

    return sum(process_step(octos) for _ in range(100))