fix code implement while loop with dictionary in Swift code - swift

*/ write a function daysPastThisYear that takes the current date as the name of the current month and the current day, e.g., daysPastThisYear(month: "May", day: 12), and returns how many days have past since the beginning of the year. Use a "while" loop. Ignore leap years. You may user the following list and dictionary defined:
let monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
let monthDays = ["January": 31, "February": 29, "March": 31, "April": 30, "May": 31, "June": 30, "July": 31, "August": 31, "September": 30, "October": 31, "November": 30, "December": 31]
E.g.
print(daysPastThisYear(month: "January", day: 12))
// prints 12
*/
//My code so far:
func daysPastThisYear(monthNames: [String], monthDays: [String:Int]) -> Int {
let monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
let monthDays = ["January": 31, "February": 29, "March": 31, "April": 30, "May": 31, "June": 30, "July": 31, "August": 31, "September": 30, "October": 31, "November": 30, "December": 31]
var i = 0
while month != monthNames[i] {
i ++
}
totalDays = 0
while i > 0 {
totalDays = totalDays + monthDays[i - 1]
-= i
totalDays = totalDays + day
print(totalDays)
}
}
print(daysPastThisYear(month: "January", day: 12))
Im an new to coding
Tried to calculate the number of accumulated days implementing two while loops
Multiple errors when attemtong to run

Building on top of Leo Dabus's solution but using a while loop as requested
let monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
let monthDays = ["January": 31, "February": 29, "March": 31, "April": 30, "May": 31, "June": 30, "July": 31, "August": 31, "September": 30, "October": 31, "November": 30, "December": 31]
func daysPastThisYear(month: String, day: Int) -> Int {
var total = 0
var monthIndex = 0
// while loop though the monthNames array
while monthIndex <= (monthNames.count - 1) {
let monthName = monthNames[monthIndex]
if month == monthName {
total += day
break
} else {
total += monthDays[monthName] ?? 0
}
monthIndex += 1
}
return total
}

You can iterate the month names and each iteration just check if the month name is equal to the month, if not true add the number of days of the month to the total otherwise add the day to the total and break the loop. After the loop just return the total. Something like:
func daysPastThisYear(month: String, day: Int) -> Int {
var total = 0
for monthName in monthNames {
if month == monthName {
total += day
break
} else {
total += monthDays[monthName] ?? 0
}
}
return total
}
edit/update:
Using a while loop
func daysPastThisYear(month: String, day: Int) -> Int {
var total = 0
var index = 0
while monthNames.indices.contains(index) && month != monthNames[index] {
total += monthDays[monthNames[index]] ?? 0
index += 1
}
return total + day
}

Related

DateTime object to worded date [duplicate]

This question already has answers here:
How do I format a date with Dart?
(24 answers)
Closed 20 days ago.
How would I go about converting a datetime object (e.g. DateTime(2000, 1, 30)) to the worded date (January 30th, 2000)?
If you look at the documentation, you can see you have the following methods exposed:
Day property
Month property
Year property
To convert the month number into the name, you could just hold a mapping of month number to month name.
To handle the ending of each day (st/nd/rd/th), you could also create a helper method.
Then you can use:
DateTime date = new DateTime(2000, 1, 30);
String month = convertMonthToWord(date.month);
String wordedDate = month + date.day.toString() + date.year.toString();
Well there are a few ways to achieve this, as #tomerpacific said. Here's one of them:
String formatDate(DateTime date) {
List<String> months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
];
final day = date.day;
final month = months[date.month - 1];
final year = date.year;
String dayOrderThing = "th";
if (day % 10 == 1 && day != 11) {
dayOrderThing = "st";
}
if (day % 10 == 2 && day != 12) {
dayOrderThing = "nd";
}
if (day % 10 == 3 && day != 13) {
dayOrderThing = "rd";
}
return "$month $day$dayOrderThing, $year";
}

Rest one month in a date golang

Im trying to rest a month in a date in golang i have this example for march an February:
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
then a make this:
period := date.AddDate(0, -1, -0)
but the program give me:
original date: 2023-03-31 00:00:00 +0000 UTC
date after rest: 2023-03-03 00:00:00 +0000 UTC
And I expect:
2023-02-28 00:00:00 +0000 UTC
at the same time I want that this rest work for every month dynamically.
Thanks.
Just as the automatically transform that comes with go annoys you, you could also take advantage of this.
The trick is how to get the number of days in the previous month.
// as there is no 0 day, it means the last day of the previous mouth
totDay := time.Date(y, m, 0, 0, 0, 0, 0, time.UTC).Day()
The complete code is as follows:
package main
import (
"fmt"
"time"
)
func previousMouth(t time.Time) time.Time {
y, m, d := t.Date()
curTotDay := time.Date(y, m+1, 0, 0, 0, 0, 0, time.UTC).Day()
totDay := time.Date(y, m, 0, 0, 0, 0, 0, time.UTC).Day()
if d == curTotDay {
d = totDay
}
return time.Date(y, m-1, d, 0, 0, 0, 0, time.UTC)
}
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
fmt.Println(previousMouth(date))
}
Run it online: goplayground.
As others have mentioned in the comments, you cannot go back exactly one month from 31 March. You would end up at 31 February, but that date doesn't exist and is normalised to 3 March.
You can go back to the last day of the previous month, but you would get the same result if you started at 28 March, 29 March, 30 March or 31 March.
But if that is what you want, you can go back (or forward) any number of months, while clipping the day to remain within the number of days in that month.
func firstDayOfMonth(date time.Time) time.Time {
return date.AddDate(0, 0, -date.Day()+1)
}
func daysInMonth(date time.Time) int {
return date.AddDate(0, 1, -date.Day()).Day()
}
func AddMonthsClipped(date time.Time, months int) time.Time {
firstDate := firstDayOfMonth(date)
firstAdded := firstDate.AddDate(0, months, 0)
addDays, maxDays := date.Day(), daysInMonth(firstAdded)
if addDays > maxDays {
addDays = maxDays
}
return firstAdded.AddDate(0, 0, addDays-1)
}
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
fmt.Println(AddMonthsClipped(date, -1))
}
Go Playground: https://go.dev/play/p/JEihMdM0CHe
I found the answer:
package main
import (
"fmt"
"time"
)
func main() {
date := time.Date(2023, time.March, 31, 0, 0, 0, 0, time.UTC)
year, month, _ := date.Date()
endOfLastMonth := time.Date(year, month, 0, 0, 0, 0, 0, date.Location())
fmt.Println("This month: ", date)
fmt.Println("Lasth Month: ", endOfLastMonth)
}
Here the playground: https://go.dev/play/p/iTDFgtdOT9y
After working and working with the date, i made this. Thanks you all

Swift: How to check intersection with multiple sets?

I have a master set generated by 5 random numbers from 1 to 52; I would like to compare this master set with 13 other sets, each containing 4 numbers between 1 and 52.
Is there a way to check if there are any 2 sets, each containing 2 numbers from the master set?
import UIKit
var firstCard = 0
var secondCard = 0
var thirdCard = 0
var fourthCard = 0
var fifthCard = 0
func generateRandomNumber(_ from:Int, _ to:Int, _ qut:Int?) -> [Int]
{
var myRandomNumbers = [Int]()
var numberOfNumbers = qut
let lower = UInt32(from)
let higher = UInt32(to+1)
if numberOfNumbers == nil || numberOfNumbers! > (to-from) + 1
{
numberOfNumbers = (to-from) + 1
}
while myRandomNumbers.count != numberOfNumbers
{
let myNumber = arc4random_uniform(higher - lower) + lower
if !myRandomNumbers.contains(Int(myNumber))
{
myRandomNumbers.append(Int(myNumber))
}
}
return myRandomNumbers
}
let myArray = generateRandomNumber(1, 53, 5)
firstCard = myArray[0]
secondCard = myArray[1]
thirdCard = myArray[2]
fourthCard = myArray[3]
fifthCard = myArray[4]
let mainSetA = Set([firstCard, secondCard, thirdCard, fourthCard, fifthCard])
let setB: Set = [1, 2, 3, 4]
let setC: Set = [5, 6, 7, 8]
let setD: Set = [9, 10, 11, 12]
let setE: Set = [13, 14, 15, 16]
let setF: Set = [17, 18, 19, 20]
let setG: Set = [21, 22, 23, 24]
let setH: Set = [25, 26, 27, 28]
let setI: Set = [29, 30, 31, 32]
let setJ: Set = [33, 34, 35, 36]
let setK: Set = [37, 38, 39, 40]
let setL: Set = [41, 42, 43, 44]
let setM: Set = [45, 46, 47, 48]
let setN: Set = [49, 50, 51, 52]
no clue what to do next...
Something like this might help:
let mainSet = Set([1, 2, 3, 4])
Here I have three sets out of four that contain at least two items in the main set:
let inputs: [Set<Int>] = [
Set([9, 8, 7, 1]),
Set([9, 8, 1, 2]),
Set([9, 1, 2, 3]),
Set([9, 0, 3, 4])
]
Filter the input sets array, to find any where the intersection between that set and the main set is at least 2:
let matchingSets = inputs.filter {
$0.intersection(mainSet).count >= 2
}

Use words as tick labels with unequal intervals in D3.js

I am creating a D3.js plot of multiple years of data. I would like to use the month names as the the axis labels. I am currently using the number of days into the year corresponding with the first day of that month as the labels as shown in the screenshot of my x-axis:
I believe all the relevant code is shown below:
var margins = {'top' : 20, 'right' : 20, 'bottom' : 50, 'left' : 70};
var height = 500;
var width = 960;
var plotHeight = height - margins.top - margins.bottom;
var plotWidth = width - margins.right - margins.left;
var x = d3.scaleLinear()
.domain([0,366])
.range([margins.left, plotWidth]);
// I am not concerned with leap years
var monthDays = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var monthAbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var svg = d3.select('.svg').attr('width',width).attr('height',height);
svg.append('g').attr('transform', 'translate(0,' + plotHeight + ')').call(d3.axisBottom(x).tickValues(monthDays));
Is there some way to map the position on the x-axis to the correct month (i.e.: 31 to Feb.)? I have tried using d3.timeMonth/d3.timeMonths and ordinal scales but haven't found something suitable yet.
You can use tickFormat:
.tickFormat(function(d,i){ return monthAbr[i]})
Here is a working demo based on your code:
var margins = {'top' : 20, 'right' : 20, 'bottom' : 50, 'left' : 20};
var height = 100;
var width = 600;
var plotHeight = height - margins.top - margins.bottom;
var plotWidth = width - margins.right - margins.left;
var x = d3.scaleLinear()
.domain([0,366])
.range([margins.left, plotWidth]);
// I am not concerned with leap years
var monthDays = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
var monthAbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
var svg = d3.select('body').append("svg").attr('width',width).attr('height',height);
svg.append('g').attr('transform', 'translate(0,' + plotHeight + ')').call(d3.axisBottom(x).tickValues(monthDays).tickFormat(function(d,i){ return monthAbr[i]}));
<script src="https://d3js.org/d3.v4.min.js"></script>

Swift timezones with winter/summer times

I am working on a world clock, and i have gotten the times for various countries as so:
let date = NSDate();
var beltz = NSDateFormatter();
beltz.dateFormat = "HH:mm";
beltz.timeZone = NSTimeZone(name: "Europe/Brussels")
let belTzStr = beltz.stringFromDate(date);
println(belTzStr) //<-- correct time
My question is when summer/winter times adjust +- 1 hour, will this adjustment be reflected in the code by NSTimeZone? If not, how do i achieve this?
Consider this modified code:
let cal = NSCalendar.currentCalendar()
cal.timeZone = NSTimeZone(name: "America/Phoenix")!
let date = cal.dateWithEra(1, year: 2015, month: 12, day: 24, hour: 16, minute: 0, second: 0, nanosecond: 0)!
//date = NSDate();
var beltz = NSDateFormatter();
beltz.dateFormat = "dd MMMM HH:mm zzzz";
beltz.timeZone = NSTimeZone(name: "Europe/Brussels")
let belTzStr = beltz.stringFromDate(date);
print(belTzStr) //<-- correct time
I modified your code to add time as Phoenix AZ, which does not use summer time and added some extra formatting, especially the TZ to the printed data.
Now, if you use December (no DST in either region)
let date = cal.dateWithEra(1, year: 2015, month: 12, day: 24, hour: 16, minute: 0, second: 0, nanosecond: 0)!,
you get
25 December 00:00 Central European Standard Time
and if you use July (DST in EU)
let date = cal.dateWithEra(1, year: 2015, month: 7, day: 24, hour: 16, minute: 0, second: 0, nanosecond: 0)!,
you get
25 July 01:00 Central European Summer Time
So yes, it adjusts the TZ appropriately.