It is possible to create a convenience initializer for left, right, top, bottom with defaults of 0 for each (which are missing from the standard initializer) by choosing a different argument order than the standard initializer:

import UIKit

```
```extension UIEdgeInsets {

public init(left: CGFloat = 0, right: CGFloat = 0, top: CGFloat = 0, bottom: CGFloat = 0) {

self.init(top: top, left: left, bottom: bottom, right: right)

}

public init(horizontal: CGFloat = 0, vertical: CGFloat = 0) {

self.init(top: vertical, left: horizontal, bottom: vertical, right: horizontal)

}

public init(all: CGFloat) {

self.init(top: all, left: all, bottom: all, right: all)

}

}

let insets1 = UIEdgeInsets(horizontal: 5)

print(insets1)

`let insets2 = UIEdgeInsets(left: 3)`

print(insets2)

Cheers,

Thorsten

I also kind of like the convenience properties for `UIEdgeInsets.vertical`

. It looks like a neat trick.

But then again, I’d rather have a convenience initializer for these to ensure boundaries are upheld properly; you can set one of the vertical properties and then overwrite with the `vertical`

property or vice versa, and the order will matter. As the saying goes, as long as it’s allowed to write `= [\.top: 12, .\vertical: 5]`

, someone will write exactly that, and it will probably be future you. š

With `init(vertical: CGFloat = 0, horizontal: CGFloat = 0)`

, there’s less room for confusion and accidental error. In the end, one of Swift’s superpowers is how little code you need to write to express intent.

Cheers,

Christian

I find the keypath plus ~= interesting (I rarely use that operator or keypaths) but I don’t get why use a keypath when you can do:

let filtered2NoKp = values2.filter({ $0.numnum ~= .thatOneInterestingValue })

Would the keypath approach be more useful for more deeply nested structs/enum?

Cheers,

Christian

Of course it doesn’t works for the second half of day 3.

This is the code in swift for Playground

```
```func compute1(_ value:Int) {

let c = (Int(sqrt(Double(value - 1))) + 1) / 2

let start = (c * 2 - 1) * (c * 2 - 1) + 1

let offset = (value - start) % (c * 2)

let result = c + abs(offset + 1 - c)

print("\(value) -> \(result)")

}

`compute1(12)`

compute1(23)

compute1(1024)

I see numbers like circles (or squares) around the 1. c is the circle number.

circle 1 contains numbers from 2 to 9, circle 2, numbers from 10 to 25, etc…

if x is the initial value, its circle can be known with c = Int( (Int(srqt(x-1)) + 1) / 2 )

then the first number in the circle is start = (2c-1)^2 + 1

the count of numbers in a circle is 8c,

the offset of the value from the begin of the circle = value – start

By symmetry, you can limite the calcul to the first quarter of the circle. To do that, I get the modulo 2c of the offset.

To move from the center to the circle, you must first move c steps (to left, right top or bottom) than a number of step depending of the offset of the position of the value from the center of the quarter of the circle. these steps can be get with abs(offset + 1 – c)

Thank you for posting about this. I wouldn’t have heard about it otherwise.

]]>`...`

to make it look pretty?Seems like each line got wrapped in … š ]]>

-- Possible steps (Up, Down, Left, Right)

data Step = U | D | L | R deriving (Eq, Show)
-- Steps to build the spiral starting from center

spiral :: [Step]

spiral = concat $ zipWith replicate spiralStepCounts (cycle [R, U, L, D])

where

spiralStepCounts = dup [1..]

dup (x:xs) = x:x:dup xs

-- Coordinates of the spiral

coords :: [Step] -> [(Int, Int)]

coords = scanl coord (0, 0)

where

coord (x, y) step = case step of

R -> (x + 1, y)

L -> (x - 1, y)

U -> (x, y + 1)

D -> (x, y - 1)

-- Part 1

-- Number of steps needed to reach position n

spiralDistance n = numSteps $ coords spiral !! (n - 1)

where

numSteps (x, y) = abs x + abs y

resultDay3Part1 = spiralDistance 265149

-- Part 2

type Storage = Map (Int, Int) Int

storage = scanl store initial (tail $ coords spiral)

where

initial = Map.insert (0, 0) 1 Map.empty

store s pos = Map.insert pos (value s pos) s

value s pos = sum $ mapMaybe (\d -> Map.lookup (offset pos d) s) neighbors

offset (dx, dy) (x, y) = (x + dx, y + dy)

neighbors = [(dx, dy) | dx <- [-1, 0, 1], dy <- [-1, 0, 1]]

storageValues = map maximum storage

`resultDay3Part2 = head $ dropWhile (<= 265149) storageValues`