Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Setup
- import pandas as pd
- import numpy as np
- pd.set_option('display.notebook_repr_html', False, 'expand_frame_repr', False, 'display.max_colwidth', 50)
- # This gives me the largest odd number whose
- # square is less than or equal to n
- last_odd_root = lambda n: int((n - 1) ** .5 + 1) // 2 * 2 - 1
- # This takes the custom tuple returned by
- # spiral_num and returns the Manhatten Distance
- spiral_distance = lambda t: t[0] + abs(t[1][1])
- def spiral_num(n):
- """This returns a custom tuple that describes the
- position of n in terms of a radius and angle"""
- a = last_odd_root(n)
- head = a ** 2 # gives the end point of last layer
- tail = n - head # how many since last layer
- size = a + 1 # length of a side of current layer
- radius = size // 2 # distance of current layer from origin
- theta = ( # two values, the first enumerates
- tail // size % 4, # which of the four sections we're in
- tail % size - radius # and where along section we're in
- )
- return radius, theta
- def cartesian_coords(p):
- """Convert custom tuples to Cartesian coordinates relative to (0, 0)"""
- radius, (leg, loc) = p
- signs = [0, -1, 0, 1]
- _sign = signs[leg]
- sign = signs[(leg - 1) % 4]
- sign_ = signs[(leg - 2) % 4]
- x = loc * _sign + radius * sign
- y = loc * sign + radius * sign_
- return x, y
- def cartesian_to_indices(origin, x, y):
- """Convert Cartesion coordinates to array indices"""
- return origin - y, origin + x
- def convolve(p, tracker):
- """Sum all neighbors"""
- result = 0
- for i in [-1, 0, 1]:
- for j in [-1, 0, 1]:
- result += tracker.get((p[0] + i, p[1] + j), 0)
- return result
- ##########################################################################################
- # Solve Problem
- ##########################################################################################
- # My input
- x = 277678
- tracker = {(0, 0): 1}
- for n in range(2, x + 1):
- p = cartesian_coords(spiral_num(n))
- tracker[p] = convolve(p, tracker)
- if tracker[p] > x:
- print(n, x, tracker[p])
- break
- # 59 277678 279138
- ##########################################################################################
- # Look at results
- ##########################################################################################
- pd.Series(tracker).unstack(fill_value=0).iloc[:, ::-1].T
- # -3 -2 -1 0 1 2 3 4
- # 4 0 0 0 0 0 279138 266330 130654
- # 3 6591 6444 6155 5733 5336 5022 2450 128204
- # 2 13486 147 142 133 122 59 2391 123363
- # 1 14267 304 5 4 2 57 2275 116247
- # 0 15252 330 10 1 1 54 2105 109476
- # -1 16295 351 11 23 25 26 1968 103128
- # -2 17008 362 747 806 880 931 957 98098
- # -3 17370 35487 37402 39835 42452 45220 47108 48065
- ##########################################################################################
- # More fun!
- ##########################################################################################
- def create_spiral(n, show_tup=False):
- k = last_odd_root(n + 1)
- df = pd.DataFrame('', index=range(k), columns=range(k))
- for i_ in range(2, k ** 2 + 1):
- tup = spiral_num(i_)
- i, j = cartesian_to_indices(k // 2, *cartesian_coords(tup))
- df.iat[i, j] = tup if show_tup else i_
- return df
- print(create_spiral(400), create_spiral(169, 1), sep='\n' * 2)
- # 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
- # 0 325 324 323 322 321 320 319 318 317 316 315 314 313 312 311 310 309 308 307
- # 1 326 257 256 255 254 253 252 251 250 249 248 247 246 245 244 243 242 241 306
- # 2 327 258 197 196 195 194 193 192 191 190 189 188 187 186 185 184 183 240 305
- # 3 328 259 198 145 144 143 142 141 140 139 138 137 136 135 134 133 182 239 304
- # 4 329 260 199 146 101 100 99 98 97 96 95 94 93 92 91 132 181 238 303
- # 5 330 261 200 147 102 65 64 63 62 61 60 59 58 57 90 131 180 237 302
- # 6 331 262 201 148 103 66 37 36 35 34 33 32 31 56 89 130 179 236 301
- # 7 332 263 202 149 104 67 38 17 16 15 14 13 30 55 88 129 178 235 300
- # 8 333 264 203 150 105 68 39 18 5 4 3 12 29 54 87 128 177 234 299
- # 9 334 265 204 151 106 69 40 19 6 2 11 28 53 86 127 176 233 298
- # 10 335 266 205 152 107 70 41 20 7 8 9 10 27 52 85 126 175 232 297
- # 11 336 267 206 153 108 71 42 21 22 23 24 25 26 51 84 125 174 231 296
- # 12 337 268 207 154 109 72 43 44 45 46 47 48 49 50 83 124 173 230 295
- # 13 338 269 208 155 110 73 74 75 76 77 78 79 80 81 82 123 172 229 294
- # 14 339 270 209 156 111 112 113 114 115 116 117 118 119 120 121 122 171 228 293
- # 15 340 271 210 157 158 159 160 161 162 163 164 165 166 167 168 169 170 227 292
- # 16 341 272 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 291
- # 17 342 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
- # 18 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
- # 0 1 2 3 4 5 6 7 8 9 10 11 12
- # 0 (6, (2, -6)) (6, (1, 5)) (6, (1, 4)) (6, (1, 3)) (6, (1, 2)) (6, (1, 1)) (6, (1, 0)) (6, (1, -1)) (6, (1, -2)) (6, (1, -3)) (6, (1, -4)) (6, (1, -5)) (6, (1, -6))
- # 1 (6, (2, -5)) (5, (2, -5)) (5, (1, 4)) (5, (1, 3)) (5, (1, 2)) (5, (1, 1)) (5, (1, 0)) (5, (1, -1)) (5, (1, -2)) (5, (1, -3)) (5, (1, -4)) (5, (1, -5)) (6, (0, 5))
- # 2 (6, (2, -4)) (5, (2, -4)) (4, (2, -4)) (4, (1, 3)) (4, (1, 2)) (4, (1, 1)) (4, (1, 0)) (4, (1, -1)) (4, (1, -2)) (4, (1, -3)) (4, (1, -4)) (5, (0, 4)) (6, (0, 4))
- # 3 (6, (2, -3)) (5, (2, -3)) (4, (2, -3)) (3, (2, -3)) (3, (1, 2)) (3, (1, 1)) (3, (1, 0)) (3, (1, -1)) (3, (1, -2)) (3, (1, -3)) (4, (0, 3)) (5, (0, 3)) (6, (0, 3))
- # 4 (6, (2, -2)) (5, (2, -2)) (4, (2, -2)) (3, (2, -2)) (2, (2, -2)) (2, (1, 1)) (2, (1, 0)) (2, (1, -1)) (2, (1, -2)) (3, (0, 2)) (4, (0, 2)) (5, (0, 2)) (6, (0, 2))
- # 5 (6, (2, -1)) (5, (2, -1)) (4, (2, -1)) (3, (2, -1)) (2, (2, -1)) (1, (2, -1)) (1, (1, 0)) (1, (1, -1)) (2, (0, 1)) (3, (0, 1)) (4, (0, 1)) (5, (0, 1)) (6, (0, 1))
- # 6 (6, (2, 0)) (5, (2, 0)) (4, (2, 0)) (3, (2, 0)) (2, (2, 0)) (1, (2, 0)) (1, (0, 0)) (2, (0, 0)) (3, (0, 0)) (4, (0, 0)) (5, (0, 0)) (6, (0, 0))
- # 7 (6, (2, 1)) (5, (2, 1)) (4, (2, 1)) (3, (2, 1)) (2, (2, 1)) (1, (3, -1)) (1, (3, 0)) (1, (0, -1)) (2, (0, -1)) (3, (0, -1)) (4, (0, -1)) (5, (0, -1)) (6, (0, -1))
- # 8 (6, (2, 2)) (5, (2, 2)) (4, (2, 2)) (3, (2, 2)) (2, (3, -2)) (2, (3, -1)) (2, (3, 0)) (2, (3, 1)) (2, (0, -2)) (3, (0, -2)) (4, (0, -2)) (5, (0, -2)) (6, (0, -2))
- # 9 (6, (2, 3)) (5, (2, 3)) (4, (2, 3)) (3, (3, -3)) (3, (3, -2)) (3, (3, -1)) (3, (3, 0)) (3, (3, 1)) (3, (3, 2)) (3, (0, -3)) (4, (0, -3)) (5, (0, -3)) (6, (0, -3))
- # 10 (6, (2, 4)) (5, (2, 4)) (4, (3, -4)) (4, (3, -3)) (4, (3, -2)) (4, (3, -1)) (4, (3, 0)) (4, (3, 1)) (4, (3, 2)) (4, (3, 3)) (4, (0, -4)) (5, (0, -4)) (6, (0, -4))
- # 11 (6, (2, 5)) (5, (3, -5)) (5, (3, -4)) (5, (3, -3)) (5, (3, -2)) (5, (3, -1)) (5, (3, 0)) (5, (3, 1)) (5, (3, 2)) (5, (3, 3)) (5, (3, 4)) (5, (0, -5)) (6, (0, -5))
- # 12 (6, (3, -6)) (6, (3, -5)) (6, (3, -4)) (6, (3, -3)) (6, (3, -2)) (6, (3, -1)) (6, (3, 0)) (6, (3, 1)) (6, (3, 2)) (6, (3, 3)) (6, (3, 4)) (6, (3, 5)) (6, (0, -6))
Advertisement
Add Comment
Please, Sign In to add comment