Projection Area of 3D Shapes

🏠 ⬅️ ➡️

You are given an n x n grid where we place some 1 x 1 x 1 cubes that are axis-aligned with the x, y, and z axes.

Each value v = grid[i][j] represents a tower of v cubes placed on top of the cell (i, j).

We view the projection of these cubes onto the xy, yz, and zx planes.

A projection is like a shadow, that maps our 3-dimensional figure to a 2-dimensional plane. We are viewing the "shadow " when looking at the cubes from the top, the front, and the side.

Return the total area of all three projections.

Example 1:

Input: grid = [[1,2],[3,4]] Output: 17 Explanation: Here are the three projections ( "shadows ") of the shape made with each axis-aligned plane.

Example 2:

Input: grid = [[2]] Output: 5

Example 3:

Input: grid = [[1,0],[0,2]] Output: 8

Constraints:

  • n == grid.length == grid[i].length
  • 1 <= n <= 50
  • 0 <= grid[i][j] <= 50

Note: This problem is from LeetCode.
Compiled
Executed
Correct
program main
    implicit none

    integer, parameter :: n = 2
    integer :: i, j, v
    integer, dimension(n, n) :: grid
    integer :: total_area

    ! Example 1
    grid = reshape([1, 2, 3, 4], shape=[n, n])
    write (*, '(a, i0)') 'Example 1: ', total_area(grid)

    ! Example 2
    grid = reshape([2], shape=[n, n])
    write (*, '(a, i0)') 'Example 2: ', total_area(grid)

    ! Example 3
    grid = reshape([1, 0, 0, 2], shape=[n, n])
    write (*, '(a, i0)') 'Example 3: ', total_area(grid)

contains

    function total_area(grid) result(total)
        implicit none
        integer, intent(in) :: grid(:, :)
        integer :: total
        integer :: i, j, v

        total = 0
        do i = 1, size(grid, 1)
            do j = 1, size(grid, 2)
                v = grid(i, j)
                if (v > 0) then
                    total = total + v * (v + 1)
                end if
            end do
        end do
    end function total_area

end program main
Compiled
Executed
Correct
module shape_area
    implicit none
    private
    public :: shape_area
contains
    function shape_area(grid) result(total_area)
        integer, intent(in) :: grid(:, :)
        integer :: total_area
        integer :: i, j, v
        integer :: xy_area, yz_area, zx_area

        ! Calculate the area of the xy projection
        xy_area = 0
        do i = 1, size(grid, 1)
            do j = 1, size(grid, 2)
                v = grid(i, j)
                xy_area = xy_area + v * (v + 1) / 2
            end do
        end do

        ! Calculate the area of the yz projection
        yz_area = 0
        do i = 1, size(grid, 1)
            do j = 1, size(grid, 2)
                v = grid(i, j)
                yz_area = yz_area + v * (v + 1) / 2
            end do
        end do

        ! Calculate the area of the zx projection
        zx_area = 0
        do i = 1, size(grid, 1)
            do j = 1, size(grid, 2)
                v = grid(i, j)
                zx_area = zx_area + v * (v + 1) / 2
            end do
        end do

        ! Total area is the sum of the areas of the three projections
        total_area = xy_area + yz_area + zx_area
    end function shape_area
end module shape_area

program test_shape_area
    use shape_area
    implicit none
    integer, parameter :: n = 2
    integer, parameter :: grid(n, n) = reshape([1, 2, 3, 4], [n, n])
    integer :: total_area

    total_area = shape_area(grid)
    write (*, *) "Total area: ", total_area

    ! Test with a single cube
    total_area = shape_area(reshape([2], [1, 1]))
    write (*, *) "Total area: ", total_area

    ! Test with a single row
    total_area = shape_area(reshape([1, 0], [1, 2]))
    write (*, *) "Total area: ", total_area
end program test_shape_area
🌐 Data from online sources
def carFleet(target: int, position: List[int], speed: List[int]) -> int:
    cars = sorted(zip(position, speed), reverse=True)
    fleets = 0
    last_arrival = -1

    for pos, sp in cars:
        arrival = (target - pos) / sp
        if arrival > last_arrival:
            fleets += 1
            last_arrival = arrival

    return fleets
First, we create a `cars` data structure containing the car's position and speed, sorted in descending order by position. This ensures that we examine the cars from the front of the road (i.e., closest to the target) to the back.

Next, we initialize a fleets counter and a last_arrival variable to keep track of the last car's arrival time at the destination.

Then, we iterate through the sorted cars. For each car, we calculate its arrival time as (target - position) / speed. If this car's arrival time is greater than the last car's arrival time (i.e., arrival > last_arrival), then it is considered a new car fleet, and we will increment the fleets counter. We update the last_arrival variable for the next iteration.

Finally, we return the total number of car fleets that will arrive at the destination.

🌐 Data from online sources
int carFleet(int target, vector<int>& position, vector<int>& speed) {
    int n = position.size();
    vector<pair<int, int>> cars;
    for (int i = 0; i < n; ++i) {
        cars.emplace_back(position[i], speed[i]);
    }
    sort(cars.begin(), cars.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
        return a.first > b.first;
    });

    int fleets = 0;
    double last_arrival = -1;
    for (int i = 0; i < n; ++i) {
        double arrival = (double)(target - cars[i].first) / cars[i].second;
        if (arrival > last_arrival) {
            ++fleets;
            last_arrival = arrival;
        }
    }

    return fleets;
}
First, we create a `cars` data structure containing the car's position and speed, sorted in descending order by position. This ensures that we examine the cars from the front of the road (i.e., closest to the target) to the back.

Next, we initialize a fleets counter and a last_arrival variable to keep track of the last car's arrival time at the destination.

Then, we iterate through the sorted cars. For each car, we calculate its arrival time as (target - position) / speed. If this car's arrival time is greater than the last car's arrival time (i.e., arrival > last_arrival), then it is considered a new car fleet, and we will increment the fleets counter. We update the last_arrival variable for the next iteration.

Finally, we return the total number of car fleets that will arrive at the destination.