diff --git a/solution/3600-3699/3626.Find Stores with Inventory Imbalance/README.md b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/README.md new file mode 100644 index 0000000000000..0669ab53ba123 --- /dev/null +++ b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/README.md @@ -0,0 +1,306 @@ +--- +comments: true +difficulty: 中等 +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README.md +tags: + - 数据库 +--- + + + +# [3626. 查找库存不平衡的店铺](https://leetcode.cn/problems/find-stores-with-inventory-imbalance) + +[English Version](/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README_EN.md) + +## 题目描述 + + + +

表:stores

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| store_id    | int     |
+| store_name  | varchar |
+| location    | varchar |
++-------------+---------+
+store_id 是这张表的唯一主键。
+每一行包含有关商店及其位置的信息。
+
+ +

表:inventory

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| inventory_id| int     |
+| store_id    | int     |
+| product_name| varchar |
+| quantity    | int     |
+| price       | decimal |
++-------------+---------+
+inventory_id 是这张表的唯一主键。
+每一行代表特定商店中某一特定产品的库存情况。
+
+ +

编写一个解决方案来查找库存不平衡的商店 - 即最贵商品的库存比最便宜商品少的商店。

+ + + +

返回结果表以不平衡比率降序排列,然后按商店名称升序排列。

+ +

结果格式如下所示。

+ +

 

+ +

示例:

+ +
+

输入:

+ +

stores 表:

+ +
++----------+----------------+-------------+
+| store_id | store_name     | location    |
++----------+----------------+-------------+
+| 1        | Downtown Tech  | New York    |
+| 2        | Suburb Mall    | Chicago     |
+| 3        | City Center    | Los Angeles |
+| 4        | Corner Shop    | Miami       |
+| 5        | Plaza Store    | Seattle     |
++----------+----------------+-------------+
+
+ +

inventory 表:

+ +
++--------------+----------+--------------+----------+--------+
+| inventory_id | store_id | product_name | quantity | price  |
++--------------+----------+--------------+----------+--------+
+| 1            | 1        | Laptop       | 5        | 999.99 |
+| 2            | 1        | Mouse        | 50       | 19.99  |
+| 3            | 1        | Keyboard     | 25       | 79.99  |
+| 4            | 1        | Monitor      | 15       | 299.99 |
+| 5            | 2        | Phone        | 3        | 699.99 |
+| 6            | 2        | Charger      | 100      | 25.99  |
+| 7            | 2        | Case         | 75       | 15.99  |
+| 8            | 2        | Headphones   | 20       | 149.99 |
+| 9            | 3        | Tablet       | 2        | 499.99 |
+| 10           | 3        | Stylus       | 80       | 29.99  |
+| 11           | 3        | Cover        | 60       | 39.99  |
+| 12           | 4        | Watch        | 10       | 299.99 |
+| 13           | 4        | Band         | 25       | 49.99  |
+| 14           | 5        | Camera       | 8        | 599.99 |
+| 15           | 5        | Lens         | 12       | 199.99 |
++--------------+----------+--------------+----------+--------+
+
+ +

输出:

+ +
++----------+----------------+-------------+------------------+--------------------+------------------+
+| store_id | store_name     | location    | most_exp_product | cheapest_product   | imbalance_ratio  |
++----------+----------------+-------------+------------------+--------------------+------------------+
+| 3        | City Center    | Los Angeles | Tablet           | Stylus             | 40.00            |
+| 1        | Downtown Tech  | New York    | Laptop           | Mouse              | 10.00            |
+| 2        | Suburb Mall    | Chicago     | Phone            | Case               | 25.00            |
++----------+----------------+-------------+------------------+--------------------+------------------+
+
+ +

解释:

+ + + +

结果表按不平衡比降序排序,然后以商店名升序排序。

+
+ + + +## 解法 + + + +### 方法一:窗口函数 + 连接 + +我们可以使用窗口函数来计算每个商店的最贵和最便宜商品,并且使用连接来筛选出库存不平衡的商店。具体步骤如下: + +1. **计算每个商店的最贵商品**:使用 `RANK()` 窗口函数按价格降序排列,并在数量相同的情况下按数量降序排列,选取排名第一的商品。 +2. **计算每个商店的最便宜商品**:使用 `RANK()` 窗口函数按价格升序排列,并在数量相同的情况下按数量降序排列,选取排名第一的商品。 +3. **筛选至少有 3 个不同商品的商店**:使用 `COUNT()` 窗口函数来统计每个商店的商品数量,并筛选出数量大于等于 3 的商店。 +4. **连接最贵和最便宜商品**:将最贵商品和最便宜商品的结果进行连接,确保最贵商品的数量小于最便宜商品的数量。 +5. **计算不平衡比**:计算最便宜商品数量与最贵商品数量的比率,并将其舍入到两位小数。 +6. **连接商店信息**:将结果与商店信息表进行连接,以获取商店名称和位置。 +7. **排序结果**:按不平衡比降序排列,然后按商店名称升序排列。 + + + +#### MySQL + +```sql +# Write your MySQL query statement below +WITH + T AS ( + SELECT + store_id, + product_name, + quantity, + RANK() OVER ( + PARTITION BY store_id + ORDER BY price DESC, quantity DESC + ) rk1, + RANK() OVER ( + PARTITION BY store_id + ORDER BY price, quantity DESC + ) rk2, + COUNT(1) OVER (PARTITION BY store_id) cnt + FROM inventory + ), + P1 AS ( + SELECT * + FROM T + WHERE rk1 = 1 AND cnt >= 3 + ), + P2 AS ( + SELECT * + FROM T + WHERE rk2 = 1 + ) +SELECT + s.store_id store_id, + store_name, + location, + p1.product_name most_exp_product, + p2.product_name cheapest_product, + ROUND(p2.quantity / p1.quantity, 2) imbalance_ratio +FROM + P1 p1 + JOIN P2 p2 ON p1.store_id = p2.store_id AND p1.quantity < p2.quantity + JOIN stores s ON p1.store_id = s.store_id +ORDER BY imbalance_ratio DESC, store_name; +``` + +#### Pandas + +```python +import pandas as pd + + +def find_inventory_imbalance( + stores: pd.DataFrame, inventory: pd.DataFrame +) -> pd.DataFrame: + # 首先筛选出至少有3个产品的店铺 + store_counts = inventory["store_id"].value_counts() + valid_stores = store_counts[store_counts >= 3].index + + # 找出每个店铺最贵的产品 + most_expensive = ( + inventory[inventory["store_id"].isin(valid_stores)] + .sort_values(["store_id", "price", "quantity"], ascending=[True, False, False]) + .groupby("store_id") + .first() + .reset_index() + ) + + # 找出每个店铺最便宜的产品 + cheapest = ( + inventory.sort_values( + ["store_id", "price", "quantity"], ascending=[True, True, False] + ) + .groupby("store_id") + .first() + .reset_index() + ) + + # 合并结果 + merged = pd.merge( + most_expensive, cheapest, on="store_id", suffixes=("_most", "_cheap") + ) + + # 筛选出最贵产品数量 < 最便宜产品数量的记录 + result = merged[merged["quantity_most"] < merged["quantity_cheap"]].copy() + + # 计算不平衡比例 + result["imbalance_ratio"] = ( + result["quantity_cheap"] / result["quantity_most"] + ).round(2) + + # 合并店铺信息 + result = pd.merge(result, stores, on="store_id") + + # 选择并重命名列 + result = result[ + [ + "store_id", + "store_name", + "location", + "product_name_most", + "product_name_cheap", + "imbalance_ratio", + ] + ].rename( + columns={ + "product_name_most": "most_exp_product", + "product_name_cheap": "cheapest_product", + } + ) + + # 按要求排序 + result = result.sort_values( + ["imbalance_ratio", "store_name"], ascending=[False, True] + ).reset_index(drop=True) + + return result +``` + + + + + + diff --git a/solution/3600-3699/3626.Find Stores with Inventory Imbalance/README_EN.md b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/README_EN.md new file mode 100644 index 0000000000000..0037658ce277e --- /dev/null +++ b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/README_EN.md @@ -0,0 +1,307 @@ +--- +comments: true +difficulty: Medium +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README_EN.md +tags: + - Database +--- + + + +# [3626. Find Stores with Inventory Imbalance](https://leetcode.com/problems/find-stores-with-inventory-imbalance) + +[中文文档](/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README.md) + +## Description + + + +

Table: stores

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| store_id    | int     |
+| store_name  | varchar |
+| location    | varchar |
++-------------+---------+
+store_id is the unique identifier for this table.
+Each row contains information about a store and its location.
+
+ +

Table: inventory

+ +
++-------------+---------+
+| Column Name | Type    |
++-------------+---------+
+| inventory_id| int     |
+| store_id    | int     |
+| product_name| varchar |
+| quantity    | int     |
+| price       | decimal |
++-------------+---------+
+inventory_id is the unique identifier for this table.
+Each row represents the inventory of a specific product at a specific store.
+
+ +

Write a solution to find stores that have inventory imbalance - stores where the most expensive product has lower stock than the cheapest product.

+ + + +

Return the result table ordered by imbalance ratio in descending order, then by store name in ascending order.

+ +

The result format is in the following example.

+ +

 

+

Example:

+ +
+

Input:

+ +

stores table:

+ +
++----------+----------------+-------------+
+| store_id | store_name     | location    |
++----------+----------------+-------------+
+| 1        | Downtown Tech  | New York    |
+| 2        | Suburb Mall    | Chicago     |
+| 3        | City Center    | Los Angeles |
+| 4        | Corner Shop    | Miami       |
+| 5        | Plaza Store    | Seattle     |
++----------+----------------+-------------+
+
+ +

inventory table:

+ +
++--------------+----------+--------------+----------+--------+
+| inventory_id | store_id | product_name | quantity | price  |
++--------------+----------+--------------+----------+--------+
+| 1            | 1        | Laptop       | 5        | 999.99 |
+| 2            | 1        | Mouse        | 50       | 19.99  |
+| 3            | 1        | Keyboard     | 25       | 79.99  |
+| 4            | 1        | Monitor      | 15       | 299.99 |
+| 5            | 2        | Phone        | 3        | 699.99 |
+| 6            | 2        | Charger      | 100      | 25.99  |
+| 7            | 2        | Case         | 75       | 15.99  |
+| 8            | 2        | Headphones   | 20       | 149.99 |
+| 9            | 3        | Tablet       | 2        | 499.99 |
+| 10           | 3        | Stylus       | 80       | 29.99  |
+| 11           | 3        | Cover        | 60       | 39.99  |
+| 12           | 4        | Watch        | 10       | 299.99 |
+| 13           | 4        | Band         | 25       | 49.99  |
+| 14           | 5        | Camera       | 8        | 599.99 |
+| 15           | 5        | Lens         | 12       | 199.99 |
++--------------+----------+--------------+----------+--------+
+
+ +

Output:

+ +
++----------+----------------+-------------+------------------+--------------------+------------------+
+| store_id | store_name     | location    | most_exp_product | cheapest_product   | imbalance_ratio  |
++----------+----------------+-------------+------------------+--------------------+------------------+
+| 3        | City Center    | Los Angeles | Tablet           | Stylus             | 40.00            |
+| 1        | Downtown Tech  | New York    | Laptop           | Mouse              | 10.00            |
+| 2        | Suburb Mall    | Chicago     | Phone            | Case               | 25.00            |
++----------+----------------+-------------+------------------+--------------------+------------------+
+
+ +

Explanation:

+ + + +

The Results table is ordered by imbalance ratio in descending order, then by store name in ascending order

+
+ + + +## Solutions + + + +### Solution 1: Window Functions + Joins + +We can use window functions to calculate the most expensive and cheapest products for each store, and use joins to filter out stores with inventory imbalance. The specific steps are as follows: + +1. **Calculate the most expensive product for each store**: Use the `RANK()` window function to sort by price in descending order, and in case of the same price, sort by quantity in descending order, selecting the product ranked first. +2. **Calculate the cheapest product for each store**: Use the `RANK()` window function to sort by price in ascending order, and in case of the same price, sort by quantity in descending order, selecting the product ranked first. +3. **Filter stores with at least 3 different products**: Use the `COUNT()` window function to count the number of products for each store, and filter out stores with a count greater than or equal to 3. +4. **Join most expensive and cheapest products**: Join the results of the most expensive and cheapest products, ensuring that the quantity of the most expensive product is less than the quantity of the cheapest product. +5. **Calculate imbalance ratio**: Calculate the ratio of the cheapest product quantity to the most expensive product quantity, and round it to two decimal places. +6. **Join store information**: Join the results with the store information table to get store names and locations. +7. **Sort results**: Sort by imbalance ratio in descending order, then by store name in ascending order. + + + +#### MySQL + +```sql +# Write your MySQL query statement below +WITH + T AS ( + SELECT + store_id, + product_name, + quantity, + RANK() OVER ( + PARTITION BY store_id + ORDER BY price DESC, quantity DESC + ) rk1, + RANK() OVER ( + PARTITION BY store_id + ORDER BY price, quantity DESC + ) rk2, + COUNT(1) OVER (PARTITION BY store_id) cnt + FROM inventory + ), + P1 AS ( + SELECT * + FROM T + WHERE rk1 = 1 AND cnt >= 3 + ), + P2 AS ( + SELECT * + FROM T + WHERE rk2 = 1 + ) +SELECT + s.store_id store_id, + store_name, + location, + p1.product_name most_exp_product, + p2.product_name cheapest_product, + ROUND(p2.quantity / p1.quantity, 2) imbalance_ratio +FROM + P1 p1 + JOIN P2 p2 ON p1.store_id = p2.store_id AND p1.quantity < p2.quantity + JOIN stores s ON p1.store_id = s.store_id +ORDER BY imbalance_ratio DESC, store_name; +``` + +#### Pandas + +```python +import pandas as pd + + +def find_inventory_imbalance( + stores: pd.DataFrame, inventory: pd.DataFrame +) -> pd.DataFrame: + # Step 1: Identify stores with at least 3 products + store_counts = inventory["store_id"].value_counts() + valid_stores = store_counts[store_counts >= 3].index + + # Step 2: Find most expensive product for each valid store + # Sort by price (descending) then quantity (descending) and take first record per store + most_expensive = ( + inventory[inventory["store_id"].isin(valid_stores)] + .sort_values(["store_id", "price", "quantity"], ascending=[True, False, False]) + .groupby("store_id") + .first() + .reset_index() + ) + + # Step 3: Find cheapest product for each store + # Sort by price (ascending) then quantity (descending) and take first record per store + cheapest = ( + inventory.sort_values( + ["store_id", "price", "quantity"], ascending=[True, True, False] + ) + .groupby("store_id") + .first() + .reset_index() + ) + + # Step 4: Merge the two datasets on store_id + merged = pd.merge( + most_expensive, cheapest, on="store_id", suffixes=("_most", "_cheap") + ) + + # Step 5: Filter for cases where cheapest product has higher quantity than most expensive + result = merged[merged["quantity_most"] < merged["quantity_cheap"]].copy() + + # Step 6: Calculate imbalance ratio (cheapest quantity / most expensive quantity) + result["imbalance_ratio"] = ( + result["quantity_cheap"] / result["quantity_most"] + ).round(2) + + # Step 7: Merge with store information to get store names and locations + result = pd.merge(result, stores, on="store_id") + + # Step 8: Select and rename columns for final output + result = result[ + [ + "store_id", + "store_name", + "location", + "product_name_most", + "product_name_cheap", + "imbalance_ratio", + ] + ].rename( + columns={ + "product_name_most": "most_exp_product", + "product_name_cheap": "cheapest_product", + } + ) + + # Step 9: Sort by imbalance ratio (descending) then store name (ascending) + result = result.sort_values( + ["imbalance_ratio", "store_name"], ascending=[False, True] + ).reset_index(drop=True) + + return result +``` + + + + + + diff --git a/solution/3600-3699/3626.Find Stores with Inventory Imbalance/Solution.py b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/Solution.py new file mode 100644 index 0000000000000..8a2f8ac9f84f0 --- /dev/null +++ b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/Solution.py @@ -0,0 +1,70 @@ +import pandas as pd + + +def find_inventory_imbalance( + stores: pd.DataFrame, inventory: pd.DataFrame +) -> pd.DataFrame: + # Step 1: Identify stores with at least 3 products + store_counts = inventory["store_id"].value_counts() + valid_stores = store_counts[store_counts >= 3].index + + # Step 2: Find most expensive product for each valid store + # Sort by price (descending) then quantity (descending) and take first record per store + most_expensive = ( + inventory[inventory["store_id"].isin(valid_stores)] + .sort_values(["store_id", "price", "quantity"], ascending=[True, False, False]) + .groupby("store_id") + .first() + .reset_index() + ) + + # Step 3: Find cheapest product for each store + # Sort by price (ascending) then quantity (descending) and take first record per store + cheapest = ( + inventory.sort_values( + ["store_id", "price", "quantity"], ascending=[True, True, False] + ) + .groupby("store_id") + .first() + .reset_index() + ) + + # Step 4: Merge the two datasets on store_id + merged = pd.merge( + most_expensive, cheapest, on="store_id", suffixes=("_most", "_cheap") + ) + + # Step 5: Filter for cases where cheapest product has higher quantity than most expensive + result = merged[merged["quantity_most"] < merged["quantity_cheap"]].copy() + + # Step 6: Calculate imbalance ratio (cheapest quantity / most expensive quantity) + result["imbalance_ratio"] = ( + result["quantity_cheap"] / result["quantity_most"] + ).round(2) + + # Step 7: Merge with store information to get store names and locations + result = pd.merge(result, stores, on="store_id") + + # Step 8: Select and rename columns for final output + result = result[ + [ + "store_id", + "store_name", + "location", + "product_name_most", + "product_name_cheap", + "imbalance_ratio", + ] + ].rename( + columns={ + "product_name_most": "most_exp_product", + "product_name_cheap": "cheapest_product", + } + ) + + # Step 9: Sort by imbalance ratio (descending) then store name (ascending) + result = result.sort_values( + ["imbalance_ratio", "store_name"], ascending=[False, True] + ).reset_index(drop=True) + + return result diff --git a/solution/3600-3699/3626.Find Stores with Inventory Imbalance/Solution.sql b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/Solution.sql new file mode 100644 index 0000000000000..491578ad6e9dd --- /dev/null +++ b/solution/3600-3699/3626.Find Stores with Inventory Imbalance/Solution.sql @@ -0,0 +1,40 @@ +# Write your MySQL query statement below +WITH + T AS ( + SELECT + store_id, + product_name, + quantity, + RANK() OVER ( + PARTITION BY store_id + ORDER BY price DESC, quantity DESC + ) rk1, + RANK() OVER ( + PARTITION BY store_id + ORDER BY price, quantity DESC + ) rk2, + COUNT(1) OVER (PARTITION BY store_id) cnt + FROM inventory + ), + P1 AS ( + SELECT * + FROM T + WHERE rk1 = 1 AND cnt >= 3 + ), + P2 AS ( + SELECT * + FROM T + WHERE rk2 = 1 + ) +SELECT + s.store_id store_id, + store_name, + location, + p1.product_name most_exp_product, + p2.product_name cheapest_product, + ROUND(p2.quantity / p1.quantity, 2) imbalance_ratio +FROM + P1 p1 + JOIN P2 p2 ON p1.store_id = p2.store_id AND p1.quantity < p2.quantity + JOIN stores s ON p1.store_id = s.store_id +ORDER BY imbalance_ratio DESC, store_name; diff --git a/solution/DATABASE_README.md b/solution/DATABASE_README.md index abb2b37a63832..964c524af920b 100644 --- a/solution/DATABASE_README.md +++ b/solution/DATABASE_README.md @@ -323,6 +323,7 @@ | 3601 | [寻找燃油效率提升的驾驶员](/solution/3600-3699/3601.Find%20Drivers%20with%20Improved%20Fuel%20Efficiency/README.md) | `数据库` | 中等 | | | 3611 | [查找超预订员工](/solution/3600-3699/3611.Find%20Overbooked%20Employees/README.md) | `数据库` | 中等 | | | 3617 | [查找具有螺旋学习模式的学生](/solution/3600-3699/3617.Find%20Students%20with%20Study%20Spiral%20Pattern/README.md) | | 困难 | | +| 3626 | [查找库存不平衡的店铺](/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README.md) | | 中等 | | ## 版权 diff --git a/solution/DATABASE_README_EN.md b/solution/DATABASE_README_EN.md index 9ae616d0819a1..6bfefc323fb47 100644 --- a/solution/DATABASE_README_EN.md +++ b/solution/DATABASE_README_EN.md @@ -321,6 +321,7 @@ Press Control + F(or Command + F on | 3601 | [Find Drivers with Improved Fuel Efficiency](/solution/3600-3699/3601.Find%20Drivers%20with%20Improved%20Fuel%20Efficiency/README_EN.md) | `Database` | Medium | | | 3611 | [Find Overbooked Employees](/solution/3600-3699/3611.Find%20Overbooked%20Employees/README_EN.md) | `Database` | Medium | | | 3617 | [Find Students with Study Spiral Pattern](/solution/3600-3699/3617.Find%20Students%20with%20Study%20Spiral%20Pattern/README_EN.md) | | Hard | | +| 3626 | [Find Stores with Inventory Imbalance](/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README_EN.md) | | Medium | | ## Copyright diff --git a/solution/README.md b/solution/README.md index 2147d5ecd32ba..523b6297026e1 100644 --- a/solution/README.md +++ b/solution/README.md @@ -3636,6 +3636,7 @@ | 3623 | [统计梯形的数目 I](/solution/3600-3699/3623.Count%20Number%20of%20Trapezoids%20I/README.md) | `几何`,`数组`,`哈希表`,`数学` | 中等 | 第 459 场周赛 | | 3624 | [位计数深度为 K 的整数数目 II](/solution/3600-3699/3624.Number%20of%20Integers%20With%20Popcount-Depth%20Equal%20to%20K%20II/README.md) | `线段树`,`数组` | 困难 | 第 459 场周赛 | | 3625 | [统计梯形的数目 II](/solution/3600-3699/3625.Count%20Number%20of%20Trapezoids%20II/README.md) | `几何`,`数组`,`哈希表`,`数学` | 困难 | 第 459 场周赛 | +| 3626 | [查找库存不平衡的店铺](/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README.md) | | 中等 | | ## 版权 diff --git a/solution/README_EN.md b/solution/README_EN.md index 215bde7e6e4a6..f37b846debc5b 100644 --- a/solution/README_EN.md +++ b/solution/README_EN.md @@ -3634,6 +3634,7 @@ Press Control + F(or Command + F on | 3623 | [Count Number of Trapezoids I](/solution/3600-3699/3623.Count%20Number%20of%20Trapezoids%20I/README_EN.md) | `Geometry`,`Array`,`Hash Table`,`Math` | Medium | Weekly Contest 459 | | 3624 | [Number of Integers With Popcount-Depth Equal to K II](/solution/3600-3699/3624.Number%20of%20Integers%20With%20Popcount-Depth%20Equal%20to%20K%20II/README_EN.md) | `Segment Tree`,`Array` | Hard | Weekly Contest 459 | | 3625 | [Count Number of Trapezoids II](/solution/3600-3699/3625.Count%20Number%20of%20Trapezoids%20II/README_EN.md) | `Geometry`,`Array`,`Hash Table`,`Math` | Hard | Weekly Contest 459 | +| 3626 | [Find Stores with Inventory Imbalance](/solution/3600-3699/3626.Find%20Stores%20with%20Inventory%20Imbalance/README_EN.md) | | Medium | | ## Copyright