Shuffle a Struct (Beginner) - struct

Hey i'm currently trying to create a card game in c++ but i've run into some issues. I've created my deck using a struct called CardStruct. My question first has to do with the shuffeling of a struct. I've tried to shuffle it but I keep getting repeating cards. (You can see my attempt at the end of the code).
struct CardStruct
{
int value;
char suit;
};
int main()
{
srand(time(0));
CardStruct Deck[52] = { { 2, char(6) }, { 3, char(6) }, { 4, char(6) }, { 5, char(6) }, { 6, char(6) }, { 7, char(6) }, { 8, char(6) }, { 9, char(6) }, { 10, char(6) }, { 11, char(6) }, { 12, char(6) }, { 13, char(6) },{ 2, char(5) }, { 3, char(5) }, { 4, char(5) }, { 5, char(5) }, { 6, char(5) }, { 7, char(5) }, { 8, char(5) }, { 9, char(5) }, { 10, char(5) }, { 11, char(5) }, { 12, char(5) }, { 13, char(5) }, { 2, char(4) }, { 3, char(4) }, { 4, char(4) }, { 5, char(4) }, { 6, char(4) }, { 7, char(4) }, { 8, char(4) }, { 9, char(4) }, { 10, char(4) }, { 11, char(4) }, { 12, char(4) }, { 13, char(4) }, { 2, char(3) }, { 3, char(3) }, { 4, char(3) }, { 5, char(3) }, { 6, char(3) }, { 7, char(3) }, { 8, char(3) }, { 9, char(3) }, { 10, char(3) }, { 11, char(3) }, { 12, char(3) }, { 13, char(3) } };
// printCards(Deck);
for (int i = 0; i < 52; i++)
{
int index = rand() % 52;
cout << Deck[index].value << Deck[index].suit << endl;
}

Instead of
{ 2, char(6) }
use
{ 2, 'K' }
K being any char you want.

Related

Array formations

Here i have a array of objects. I want the each grade as seperate array and inside the array i want the grade based section and subjects.
If teacher is taking a grade i want the schema as which grade they take and what section, inside that what subject they are taking.
var user = [
RowDataPacket { grade_id: 3, subject_id: 3, section_id: 747 },
RowDataPacket { grade_id: 4, subject_id: 3, section_id: 748 },
RowDataPacket { grade_id: 5, subject_id: 3, section_id: 749 },
RowDataPacket { grade_id: 6, subject_id: 3, section_id: 750 },
RowDataPacket { grade_id: 7, subject_id: 3, section_id: 751 },
RowDataPacket { grade_id: 8, subject_id: 3, section_id: 752 },
RowDataPacket { grade_id: 7, subject_id: 4, section_id: 751 }
]
Desired / target schema
let gradeDetails = [{
grade_id: 3,
section_details: [{
section_id: 747,
subject_details: [{subject_id: 3}]
}]
}, {
.
.
.
}, {
grade_id: 7
section_details: [{
section_id: 751,
subject_details: [
{subject_id: 3},
{subject_id: 4}
]
}]
}, {
grade_id: 8,
section_details: [{
section_id: 752,
subject_details: [{subject_id: 3}]
]}
}];
The below code snippet may be one way to achieve the desired result:
Code Sample
const getGradeDetailsArray = (arr = user) => {
const resultArr = [];
for (const grade of (new Set(arr.map(obj => obj.grade_id)))) {
const resObj = {
grade_id: grade,
section_details: arr.filter(
obj => obj.grade_id === grade
).map(
obj => ({
section_id: obj.section_id,
subject_details: [{ subject_id: obj.subject_id }]
})
)
};
resultArr.push(resObj)
};
return resultArr;
};
Explanation
Initialize the result as an empty-array named resultArr
Obtain unique grade_ids by using new Set() and iterate over each grade
For each grade, construct an object to be pushed to the result
grade_id is set to grade
section_details is set as an array filtered by matching grade_id
subect_details is an array with exactly one element (ie, the subject_id).
Return the resultArr
Code Snippet
const user = [
{ grade_id: 3, subject_id: 3, section_id: 747 },
{ grade_id: 4, subject_id: 3, section_id: 748 },
{ grade_id: 5, subject_id: 3, section_id: 749 },
{ grade_id: 6, subject_id: 3, section_id: 750 },
{ grade_id: 7, subject_id: 3, section_id: 751 },
{ grade_id: 8, subject_id: 3, section_id: 752 },
{ grade_id: 7, subject_id: 4, section_id: 751 },
];
const getGradeDetailsArray = (arr = user) => {
const resultArr = [];
for (const grade of (new Set(arr.map(obj => obj.grade_id)))) {
const resObj = {
grade_id: grade,
section_details: arr.filter(
obj => obj.grade_id === grade
).map(
obj => ({
section_id: obj.section_id,
subject_details: [{ subject_id: obj.subject_id }]
})
)
};
resultArr.push(resObj)
};
return resultArr;
};
console.log(getGradeDetailsArray());
const newGetGradeDetails = (arr = user) => (
Object.entries(
arr.reduce((fin, itm) => ({
...fin,
[itm.grade_id]: {
...fin[itm.grade_id],
[itm.section_id]: {
...(fin && fin[itm.grade_id] && fin[itm.grade_id][itm.section_id]
? fin[itm.grade_id][itm.section_id]
: {}
),
subjects: [
...(fin && fin[itm.grade_id] &&
fin[itm.grade_id][itm.section_id] &&
fin[itm.grade_id][itm.section_id].subjects &&
Array.isArray(fin[itm.grade_id][itm.section_id].subjects)
? fin[itm.grade_id][itm.section_id].subjects
: []
),
itm.subject_id
]
}
}
}) ,{})
).map(([kg, vg]) => ({
grade_id: kg,
section_details: Object.entries(vg).map(([kse, vse]) => ({
section_id: kse,
subject_details: vse.subjects.map(su => ({
subject_id: su
}))
}))
}))
);
console.log('\n\tUpdated as per comments noted below\n\n', newGetGradeDetails());
Edit: Added new method to account for changes requested on comments below.

How to generate time series data from existing data in mongodb

I have to generate this report.
In my MongoDB database I have a collection of orders like this:
[
{
_id: "mongoId", // 5f5ea6276ba53b06944de28c
createdAt: "2020-09-15T23:07:19.370Z",
totalPrice: 34, // is calculated from the client (quantity * price)
orderDetail: [
{
_id: "product-A-Id", // 5f5ea403e91ed91a44b62c92
quantity: 4,
price: 5.5,
},
{
_id: "product-B-Id",
quantity: 1,
price: 3.5,
},
{
_id: "product-C-Id",
quantity: 1,
price: 8.5,
},
],
},
{
_id: "mongoId",
createdAt: "2020-09-15T23:08:20.370Z",
totalPrice: 15.5,
orderDetail: [
{
_id: "product-C-Id",
quantity: 3,
price: 3,
},
{
_id: "product-D-Id",
quantity: 1,
price: 6.5,
},
],
},
{
_id: "mongoId",
createdAt: "2020-09-15T23:09:25.370Z",
totalPrice: 22.5,
orderDetail: [
{
_id: "product-D-Id",
quantity: 5,
price: 4.5,
},
],
},
]
To make this I have to generate time series data each two hours from timestamp now (in every request), the example of response desired is this:
[
{
id: "sales",
data: [
{
x: "00:00",
y: 150,
},
{
x: "22:00",
y: 100,
},
{
x: "20:00",
y: 150,
},
{
x: "18:00",
y: 50,
},
{
x: "16:00",
y: 100,
},
],
},
]
Using nodejs and express like framework I could generate sales of the last 2 hours:
const valueDateRange = 2 * 60 * 60 * 1000; // 2 hours
const currentPeriod = new Date(new Date().getTime() - valueDateRange);
// The last 2 hours sales
const calculateTotalSales = await Order.aggregate([
{
$match: { createdAt: { $gte: currentPeriod } },
},
{
$group: { _id: null, TotalAmount: { $sum: "$totalPrice" } },
},
]);
But now how to generate the time series data each 2 hours, so much thanks for the attention
The cleanest way I've found is to rework each docs date using the modulo operator to group them by hour blocks. You can easily change if you need bigger blocks in the future.
https://mongoplayground.net/p/aYAJKL_5dMD (I added extra sample data)
db.orders.aggregate([
{$addFields: {
date: {
$let: {
vars: {
hour: {$hour: '$createdAt'},
remainder: {$mod: [
{$hour: '$createdAt'},
2 // Two hour blocks, can be 2,3,4,6,8,12
]},
},
in: {
$dateFromParts: {
year: {$year: '$createdAt'},
month: {$month: '$createdAt'},
day: {$dayOfMonth: '$createdAt'},
hour: {$subtract: ['$$hour', '$$remainder']}
}
}
}
}
}},
{$group: {
_id: '$date',
x: {$last: '$date'},
y: {$sum: '$totalPrice'}
}}
]);
Update:
After reading your question again, I think your looking for total per hour regardless of the day. You can do so like this:
https://mongoplayground.net/p/cpW9JKllDIN
const totals = await db.orders.aggregate([
{$addFields: {
hour: {
$let: {
vars: {
hour: {$hour: '$createdAt'},
remainder: {$mod: [
{$hour: '$createdAt'},
2 // Two hour blocks, can be 2,3,4,6,8,12
]},
},
in: {$subtract: ['$$hour', '$$remainder']}
}
}
}},
{$group: {
_id: '$hour',
x: {$last: '$hour'},
y: {$sum: '$totalPrice'}
}}
])
Then to include hours that have no sales you can map an array:
let points = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22].map(x => {
let total = totals.find(t => t.x === x);
return {
x: `${x < 10 ? `0${x}` : x}:00`,
y: total ? total.y : 0
};
});
After trying many times, I ended up with this code, I hope it helps someone in the future, to prove it, make sure you have the updated data at the time you make the request, otherwise it would result 0 because compare the dates with the current moment.
Mongo Playgournd
node.js: v12.5.0
express: "^4.17.1"
Mongodb version v4.2.3
router.get("/orders", async (req, res) => {
let valueDateRange = 24 * 60 * 60 * 1000; // 24 hours
const current = new Date();
const previous = new Date(new Date().getTime() - valueDateRange);
try {
const order = await Order.aggregate([
{
$match: {
createdAt: { $lt: current, $gte: previous },
},
},
{
$sort: { createdAt: 1 },
},
{
$group: {
_id: null,
docs: {
$push: {
createdAt: "$createdAt",
totalPrice: "$totalPrice",
missing: false,
},
},
start: {
$first: {
$toInt: {
$divide: [
{
$subtract: [
{ $toLong: "$$NOW" },
{ $multiply: [24, 60, 60, 1000] },
],
},
1000,
],
},
},
},
end: {
$last: { $toInt: { $divide: [{ $toLong: "$$NOW" }, 1000] } },
},
},
},
{
$addFields: {
docs: {
$map: {
input: {
$range: [
{ $toInt: "$start" },
{ $add: [{ $toInt: "$end" }, 7200] }, // 2 hours range
7200,
],
},
as: "ts",
in: {
ts_exists: {
$filter: {
input: "$docs",
as: "d",
cond: {
$and: [
{
$gte: [
{
$toInt: {
$divide: [{ $toLong: "$$d.createdAt" }, 1000],
},
},
{ $subtract: ["$$ts", 7200] },
],
},
{
$lt: [
{
$toInt: {
$divide: [{ $toLong: "$$d.createdAt" }, 1000],
},
},
"$$ts",
],
},
],
},
},
},
ts: "$$ts",
},
},
},
},
},
{
$unwind: "$docs",
},
{
$project: {
_id: 0,
y: {
$reduce: {
input: "$docs.ts_exists",
initialValue: 0,
in: { $add: ["$$value", "$$this.totalPrice"] },
},
},
x: {
$dateToString: {
format: "%Y-%m-%d %H:%M",
date: { $toDate: { $multiply: ["$docs.ts", 1000] } },
},
},
},
},
]);
const firstDeleted = order.shift(); // the first always send 0, therefore I delete it
res.send(order);
} catch (error) {
res.send(error);
}
});
Returns data every 2 hours, if there is no quantity put it 0
[
{
"y": 0,
"x": "2020-09-15 18:24"
},
{
"y": 0,
"x": "2020-09-15 20:24"
},
{
"y": 0,
"x": "2020-09-15 22:24"
},
{
"y": 0,
"x": "2020-09-16 00:24"
},
{
"y": 0,
"x": "2020-09-16 02:24"
},
{
"y": 0,
"x": "2020-09-16 04:24"
},
{
"y": 0,
"x": "2020-09-16 06:24"
},
{
"y": 0,
"x": "2020-09-16 08:24"
},
{
"y": 0,
"x": "2020-09-16 10:24"
},
{
"y": 0,
"x": "2020-09-16 12:24"
},
{
"y": 0,
"x": "2020-09-16 14:24"
},
{
"y": 3,
"x": "2020-09-16 16:24"
}
]

Merging Area objects based on Similar Id

I am getting this output :
"Area":
[{
"AreaId": 2,
"AreaName":xyz,
"Data":
[{
"AssetId":somevalue,
"ActionId":somevalue,
}]
},
{
"AreaId": 2,
"AreaName":xyz,
"Data":
[{
"AssetId":somevalue,
"ActionId":somevalue,
}]
}]
But I want it merging to be like this :
"Area":[{
"AreaId": 2,
"AreaName":xyz,
"Data":
[{
"AssetId":somevalue,
"ActionId":somevalue,
},
{
"AssetId":someothervalue,
"ActionId":someothervalue,
}]
You could use groupBy of loadash. Code will look something like this
const {groupBy} = require("lodash");
const input = [
{
AreaId: 2,
AreaName: "Bedroom",
Data: [
{
Id: 7,
AssetId: 1,
Asset: "TubeLight",
ActionId: 1,
Action: "Clean",
TenantChargeBack: 0,
TenantChargeType: "%",
TenantChargeValue: 25,
Notes: "",
FilePath: "AWS_Bucket_Name/filename.jpg"
}
]
},
{
AreaId: 2,
AreaName: "Bedroom",
Data: [
{
Id: 8,
AssetId: 1,
Asset: "Bed",
ActionId: 3,
Action: "Repair",
TenantChargeBack: 1,
TenantChargeType: "%",
TenantChargeValue: 50,
Notes: "",
FilePath: "AWS_Bucket_Name/filename.jpg"
}
]
},
{
AreaId: 3,
AreaName: "Bathroom",
Data: [
{
Id: 9,
AssetId: null,
Asset: null,
ActionId: 2,
Action: "Replace",
TenantChargeBack: 1,
TenantChargeType: "$",
TenantChargeValue: 100,
Notes: "",
FilePath: "AWS_Bucket_Name/filename.jpg"
}
]
},
{
AreaId: 3,
AreaName: "Bathroom",
Data: [
{
Id: 10,
AssetId: 6,
Asset: "Jaar",
ActionId: 3,
Action: "Repair",
TenantChargeBack: 1,
TenantChargeType: "$",
TenantChargeValue: 100,
Notes: "",
FilePath: "AWS_Bucket_Name/filename.jpg"
}
]
},
{
AreaId: 2,
AreaName: "Bedroom",
Data: [
{
Id: 11,
AssetId: null,
Asset: null,
ActionId: 1,
Action: "Clean",
TenantChargeBack: 1,
TenantChargeType: "$",
TenantChargeValue: 50,
Notes: "",
FilePath: null
}
]
}
];
const groupedData = groupBy(input, i => i.AreaId);
const result = Object.keys(groupedData).map(j => {
const combined = groupedData[j];
return combined.reduce((a, b) => {
return {
"AreaId": a.AreaId,
"AreaName": a.AreaName,
"Data": a.Data.concat(b.Data)
};
})
});
console.log(JSON.stringify(result));

MongoDB get remaining seats of restaurant

I've problem to find remaining seats of particular restaurant in a particular Date range
Let me define my problem. Suppose I've a collection it called booking
In this have a following fields:
Booking ID
User ID
Restaurant ID
Booking Start Date (date saved in Timestamp)
Booking End Date (date saved in Timestamp)
Booked Seat
If there are 50 seats in restaurant. And I want to check available seats of a particular date range for example the date range is 6-12(This range in timestamp)"(Start Date) - (End Date)"
How to calculate the total remaining seats of restaurant.
If anyone have any idea please let me know.
Thanks in advance
Code is here
const where = {};
where.restaurant_id = 126;
where.user_id = 1;
where.start_date = { $gte: 6 };
where.end_date = { $gte: 12 };
const remainingSeats = getSeatsAvailability(where);
function getSeatsAvailability(where) {
return new Promise((resolve, reject) => {
bookingModel.find(where, (err, details) => {
if (err) { reject(err); } else { resolve(details); }
});
});
}
So, What I have Visualized is the below diagram, so there are basically four cases to be covered:
x y
a-----------|---------b |
a-|------------|---b
| a-------b |
| a-----|--------b
So the formulae are:
1. a<x, a<y | b>x, b<y
2. a<x, a<y | b>x, b>y
3. a>x, a<y | b>x, b>y
4. a>x, a<y | b<y, b>x
I am pasting an ROUGH example, take it as a hint to solve the problem at hand:
db.collection.aggregate([
{
$match: {
$or: [
{
a: {
$lte: 3,
$lte: 9
},
$or: [
{
b: {
$gte: 3,
$lte: 9
}
},
{
b: {
$gte: 3,
$gte: 9
}
}
]
},
{
a: {
$gte: 3,
$lte: 9
},
$or: [
{
b: {
$gte: 3,
$gte: 9
}
},
{
b: {
$gte: 3,
$lte: 9
}
}
]
}
],
r: 1
}
},
{
$group: {
_id: null,
sum_booked: {
$sum: "$c"
}
}
},
{
$project: {
seats_left: {
$subtract: [
50,
"$sum_booked"
]
}
}
}
])
The example dataset that I have tested on:
[
{
a: 1,
b: 10,
c: 10,
r: 1,
},
{
a: 2,
b: 5,
c: 15,
r: 1
},
{
a: 5,
b: 10,
c: 10,
r: 1
},
{
a: 7,
b: 15,
c: 15,
r: 12 <<<<========/////DIFF REST ID
}
]
Output:
[
{
"_id": null,
"seats_left": 15
}
]
db.booking.aggregate([{
$match: {
BookingStartDate: { $lte: date_range_end },
BookingEndDate: { $gte: date_range_start },
RestaurantID: restaurant_id
}
},
{
$group: {
_id: '$RestaurantID',
TotalBookedSeat: { $sum: '$BookedSeat' }
}
},
{
$project: {
LeftSeat: { $subtract: [50, '$TotalBookedSeat'] },
_id: 0
}
}
])
{ "_id" : ObjectId("5d8479f6902a52448029a6d0"), "bid" : 1, "uid" : 1, "rid" : 126, "bsd" : 1, "bed" : 10, "bs" : 10 }
{ "_id" : ObjectId("5d847a11902a52448029a6d1"), "bid" : 2, "uid" : 1, "rid" : 126, "bsd" : 2, "bed" : 5, "bs" : 15 }
{ "_id" : ObjectId("5d847a24902a52448029a6d2"), "bid" : 3, "uid" : 1, "rid" : 126, "bsd" : 5, "bed" : 10, "bs" : 10 }
{ "_id" : ObjectId("5d847a34902a52448029a6d3"), "bid" : 4, "uid" : 1, "rid" : 126, "bsd" : 7, "bed" : 15, "bs" : 15 }
db.booking.aggregate([{ $match: { bsd: { $lte: 12 }, bed: { $gte: 6 }, rid: 126 } }, { $group: { _id: '$rid', total_seat_sold: { $sum: '$bs' } } }])
The result of the above is 35, then 15 seats left.
This time it will works I think.

How I can get sum all values custom field mongoose?

I have schema:
{
userName: String
postCount: Number,
commentCount: Number,
abuseCount: Number,
}
I need get sum all users counts all fields in result
example
{
"userName": "John"
"postCount": 5,
"commentCount": 1,
"abuseCount": 4,
}, {
"userName": "Bob"
"postCount": 11,
"commentCount": 41,
"abuseCount": 3,
}, {
"userName": "Alex"
"postCount": 2,
"commentCount": 15,
"abuseCount": 6,
}
result must be ~
{
"postCount": 18, (sum all postCount field users)
"commentCount": 57,
"abuseCount": 10,
}
How I can do this? Thx!

Resources