Last active
January 20, 2022 08:21
-
-
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'
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Running this in a Swift Playground you get: