Skip to content

Commit f7744d1

Browse files
authored
Merge pull request #75 from iamAntimPal/Branch-1
Branch 1
2 parents e7be90f + d33a1c4 commit f7744d1

File tree

3 files changed

+187
-1
lines changed

3 files changed

+187
-1
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import pandas as pd
2+
3+
def game_play_analysis(activity: pd.DataFrame) -> pd.DataFrame:
4+
# Get first login date for each player
5+
first_login = activity.groupby("player_id")["event_date"].min().reset_index()
6+
first_login.columns = ["player_id", "first_login"]
7+
8+
# Merge first login date with original table
9+
merged = activity.merge(first_login, on="player_id")
10+
11+
# Filter players who logged in the next day
12+
next_day_logins = merged[
13+
(merged["event_date"] - merged["first_login"]).dt.days == 1
14+
]["player_id"].nunique()
15+
16+
# Total unique players
17+
total_players = activity["player_id"].nunique()
18+
19+
# Calculate fraction
20+
fraction = round(next_day_logins / total_players, 2)
21+
22+
return pd.DataFrame({"fraction": [fraction]})

LeetCode SQL 50 Solution/550. Game Play Analysis IV/550. Game Play Analysis IV.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Table: Activity
77
+--------------+---------+
88
| player_id | int |
99
| device_id | int |
10-
| event_date | date |
10+
-- | event_date | date |
1111
| games_played | int |
1212
+--------------+---------+
1313
(player_id, event_date) is the primary key (combination of columns with unique values) of this table.
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# **550. Game Play Analysis IV**
2+
3+
## **Problem Statement**
4+
You are given a table named `Activity`, which logs the gaming activity of players.
5+
6+
### **Activity Table**
7+
```rb
8+
+--------------+---------+
9+
| Column Name | Type |
10+
+--------------+---------+
11+
| player_id | int |
12+
| device_id | int |
13+
| event_date | date |
14+
| games_played | int |
15+
+--------------+---------+
16+
```
17+
- **(player_id, event_date)** is the **primary key**.
18+
- Each row contains:
19+
- `player_id`: The ID of the player.
20+
- `event_date`: The date when the player logged in.
21+
- `games_played`: The number of games played before logging out.
22+
23+
### **Task:**
24+
Find the **fraction** of players who logged in **again** the day after their **first login date**, rounded to **2 decimal places**.
25+
26+
---
27+
28+
## **Example 1:**
29+
### **Input:**
30+
#### **Activity Table**
31+
```rb
32+
+-----------+-----------+------------+--------------+
33+
| player_id | device_id | event_date | games_played |
34+
+-----------+-----------+------------+--------------+
35+
| 1 | 2 | 2016-03-01 | 5 |
36+
| 1 | 2 | 2016-03-02 | 6 |
37+
| 2 | 3 | 2017-06-25 | 1 |
38+
| 3 | 1 | 2016-03-02 | 0 |
39+
| 3 | 4 | 2018-07-03 | 5 |
40+
+-----------+-----------+------------+--------------+
41+
```
42+
### **Output:**
43+
```rb
44+
+-----------+
45+
| fraction |
46+
+-----------+
47+
| 0.33 |
48+
+-----------+
49+
```
50+
### **Explanation:**
51+
- `player_id = 1`: First login on **2016-03-01**, logs in again on **2016-03-02**
52+
- `player_id = 2`: First login on **2017-06-25**, no next-day login ❌
53+
- `player_id = 3`: First login on **2016-03-02**, no next-day login ❌
54+
55+
Total players = **3**, Players who logged in the next day = **1****1 / 3 = 0.33**
56+
57+
---
58+
59+
## **Solution Approaches**
60+
61+
### **SQL Solution (Using `JOIN` & `DATEDIFF`)**
62+
```sql
63+
SELECT
64+
ROUND((
65+
SELECT COUNT(DISTINCT a.player_id)
66+
FROM Activity a
67+
INNER JOIN (
68+
SELECT player_id, MIN(event_date) AS first_login
69+
FROM Activity
70+
GROUP BY player_id
71+
) b
72+
ON a.player_id = b.player_id
73+
AND DATEDIFF(a.event_date, b.first_login) = 1
74+
) /
75+
(SELECT COUNT(DISTINCT player_id) FROM Activity), 2) AS fraction;
76+
```
77+
**Explanation:**
78+
1. **Find First Login Date per Player**
79+
- `MIN(event_date) AS first_login`
80+
- **Grouped by** `player_id`
81+
2. **Find Players Who Logged in on the Next Day**
82+
- **Join** the table with itself.
83+
- Use `DATEDIFF(a.event_date, b.first_login) = 1` to check next-day logins.
84+
- Count unique `player_id`s.
85+
3. **Calculate Fraction**
86+
- Divide by total distinct `player_id`s.
87+
- Round to **2 decimal places**.
88+
89+
---
90+
91+
### **Alternative SQL Solution (Using `EXISTS`)**
92+
```sql
93+
SELECT ROUND(
94+
(SELECT COUNT(DISTINCT player_id)
95+
FROM Activity a
96+
WHERE EXISTS (
97+
SELECT 1 FROM Activity b
98+
WHERE a.player_id = b.player_id
99+
AND DATEDIFF(b.event_date, a.event_date) = 1
100+
)) /
101+
(SELECT COUNT(DISTINCT player_id) FROM Activity), 2) AS fraction;
102+
```
103+
**Explanation:**
104+
- Checks if a player has **ANY** login exactly **one day after**.
105+
- Uses `EXISTS` to optimize performance.
106+
107+
---
108+
109+
### **Pandas Solution**
110+
```python
111+
import pandas as pd
112+
113+
def game_play_analysis(activity: pd.DataFrame) -> pd.DataFrame:
114+
# Get first login date for each player
115+
first_login = activity.groupby("player_id")["event_date"].min().reset_index()
116+
first_login.columns = ["player_id", "first_login"]
117+
118+
# Merge first login date with original table
119+
merged = activity.merge(first_login, on="player_id")
120+
121+
# Filter players who logged in the next day
122+
next_day_logins = merged[
123+
(merged["event_date"] - merged["first_login"]).dt.days == 1
124+
]["player_id"].nunique()
125+
126+
# Total unique players
127+
total_players = activity["player_id"].nunique()
128+
129+
# Calculate fraction
130+
fraction = round(next_day_logins / total_players, 2)
131+
132+
return pd.DataFrame({"fraction": [fraction]})
133+
```
134+
**Explanation:**
135+
1. **Find First Login Date**
136+
- Group by `player_id`, get `min(event_date)`.
137+
2. **Merge with Original Table**
138+
- Check if `event_date - first_login = 1 day`.
139+
3. **Count Unique Players**
140+
- Divide by total unique `player_id`s.
141+
142+
---
143+
144+
## **File Structure**
145+
```
146+
📂 LeetCode550
147+
│── 📜 problem_statement.md
148+
│── 📜 sql_solution.sql
149+
│── 📜 sql_exists_solution.sql
150+
│── 📜 pandas_solution.py
151+
│── 📜 README.md
152+
```
153+
- `problem_statement.md` → Contains the problem description.
154+
- `sql_solution.sql` → SQL solution using **JOIN & DATEDIFF**.
155+
- `sql_exists_solution.sql` → SQL solution using **EXISTS**.
156+
- `pandas_solution.py` → Pandas solution.
157+
- `README.md` → Overview of problem and solutions.
158+
159+
---
160+
161+
## **Useful Links**
162+
- [LeetCode Problem 550](https://leetcode.com/problems/game-play-analysis-iv/)
163+
- [SQL `DATEDIFF()`](https://www.w3schools.com/sql/func_mysql_datediff.asp)
164+
- [Pandas `.groupby()`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html)

0 commit comments

Comments
 (0)