Skip to content

Instantly share code, notes, and snippets.

@lukestringer90
Last active January 20, 2022 08:21
Show Gist options
  • Save lukestringer90/cab08b19d2dc9b3a269e161e51c23013 to your computer and use it in GitHub Desktop.
Save lukestringer90/cab08b19d2dc9b3a269e161e51c23013 to your computer and use it in GitHub Desktop.
Calculate the days in a given year that are the most or least 'Blue'
import UIKit
enum Blueness: String {
case Most, Least
}
// Print out the days in a given year that are the most or least 'Blue'
func blueDays(`in` year: Int, blueness: Blueness) {
// Generate dates for each day for the given year
func days(inYear year: Int) -> [Date] {
let calendar = Calendar(identifier: .gregorian)
var comps = calendar.dateComponents([.day, .month, .year], from: Date())
comps.year = year
comps.day = 1
comps.month = 1
let jan1 = calendar.date(from: comps)!
comps.day = 31
comps.month = 12
let dec31 = calendar.date(from: comps)!
var days = [Date]()
var head = jan1
while head <= dec31 {
days.append(head)
head = Calendar.current.date(byAdding: .day, value: 1, to: head)!
}
return days
}
// Data type to wrap up all information about a colour
struct ColourComponenets {
let hex: String
let amountOfBlue: CGFloat
let colour: UIColor
var hexSixDigits: String {
let index = hex.index(hex.startIndex, offsetBy: 6)
return String(hex[..<index])
}
}
// Convert a hex into a color, capturing the blue RBG value in the componenets
// Assumes hex is 8 digits long
func colourComponenets(from hex: String) -> ColourComponenets {
let r, g, b, a: CGFloat
let scanner = Scanner(string: hex)
var hexNumber: UInt64 = 0
scanner.scanHexInt64(&hexNumber)
r = CGFloat((hexNumber & 0xff000000) >> 24)
g = CGFloat((hexNumber & 0x00ff0000) >> 16)
b = CGFloat((hexNumber & 0x0000ff00) >> 8)
a = CGFloat(hexNumber & 0x000000ff)
let colour = UIColor(red: r / 255, green: g / 255, blue: b / 255, alpha: a / 255)
return ColourComponenets(hex: hex, amountOfBlue: b, colour: colour)
}
// Lightweight type to bind a date to it's colour componenets
typealias DatAndColourComponents = (date: Date, colourComponenets: ColourComponenets)
// MAIN ALGORITHM
// Get all the days in the given year
let daysThisYear = days(inYear: year)
// Get the colour value for each day by converting the unix time stamp into a hex value
let colouredDays: [DatAndColourComponents] = daysThisYear.map { day in
let hex = String(Int(day.timeIntervalSince1970), radix: 16)
let comps = colourComponenets(from: hex)
return (day, comps)
}
// Find the days that have the most / least blueness
let sortedByBlue = colouredDays.sorted { a, b in
switch blueness {
case .Least: return a.colourComponenets.amountOfBlue < b.colourComponenets.amountOfBlue
case .Most : return a.colourComponenets.amountOfBlue > b.colourComponenets.amountOfBlue
}
}
let maxValue = sortedByBlue.first!.colourComponenets.amountOfBlue
let blueDays = sortedByBlue.filter { $0.colourComponenets.amountOfBlue == maxValue } // could be multiple days with the same blue value
// Print out the days
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "E d MMM"
print("\(blueness.rawValue) 'Blue' Days in \(year)")
for day in blueDays {
print("\t\(dateFormatter.string(from: day.date)). Blue \(day.colourComponenets.amountOfBlue), #\(day.colourComponenets.hexSixDigits)")
}
print("")
}
// Most and Least 'Blue' days in the next 5 years
blueDays(in: 2022, blueness: .Least)
blueDays(in: 2022, blueness: .Most)
blueDays(in: 2023, blueness: .Least)
blueDays(in: 2023, blueness: .Most)
blueDays(in: 2024, blueness: .Least)
blueDays(in: 2024, blueness: .Most)
blueDays(in: 2025, blueness: .Most)
blueDays(in: 2025, blueness: .Most)
blueDays(in: 2026, blueness: .Least)
blueDays(in: 2026, blueness: .Most)
blueDays(in: 2027, blueness: .Least)
blueDays(in: 2027, blueness: .Most)
@lukestringer90
Copy link
Author

lukestringer90 commented Jan 19, 2022

Running this in a Swift Playground you get:

Least 'Blue' Days in 2022
	Sun 9 Oct. Blue 0.0, #634200

Most 'Blue' Days in 2022
	Sat 17 Sep. Blue 255.0, #6324ff

Least 'Blue' Days in 2023
	Sun 11 Jun. Blue 0.0, #648500

Most 'Blue' Days in 2023
	Sat 18 Mar. Blue 255.0, #6414ff
	Sat 20 May. Blue 255.0, #6467ff
	Sun 10 Dec. Blue 255.0, #6574ff

Least 'Blue' Days in 2024
	Mon 1 Jan. Blue 0.0, #659200

Most 'Blue' Days in 2024
	Sun 13 Oct. Blue 255.0, #670aff

Most 'Blue' Days in 2025
	Mon 7 Jul. Blue 255.0, #686aff

Most 'Blue' Days in 2025
	Mon 7 Jul. Blue 255.0, #686aff

Least 'Blue' Days in 2026
	Tue 27 Jan. Blue 0.0, #697800
	Tue 31 Mar. Blue 0.0, #69cb00

Most 'Blue' Days in 2026
	Mon 5 Jan. Blue 255.0, #695aff

Least 'Blue' Days in 2027
	Wed 25 Aug. Blue 0.0, #6c6e00

Most 'Blue' Days in 2027
	Tue 3 Aug. Blue 255.0, #6c50ff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment