2017-07-21 3 views
0

Ich versuche, ein Array mit eindeutigen Zahlen zu füllen (ausgenommen 0) in einer solchen Art und Weise:Hexagonal Füllung von 2D-Array

# range(0, 37) 
[[ 0, 0, 0, 36, 19, 20, 21], 
[ 0, 0, 35, 18, 7, 8, 22], 
[ 0, 34, 17, 6, 1, 9, 23], 
[33, 16, 5, 0, 2, 10, 24], 
[32, 15, 4, 3, 11, 25, 0], 
[31, 14, 13, 12, 26, 0, 0], 
[30, 29, 28, 27, 0, 0, 0]] 

(Dies stellt als 2D-Array hex grid)

Wie die Größe des 2D-Arrays (Breite und Höhe) herausfinden, bevor es gefüllt ist? Wie bestimmt man die Koordinate, an der die nächste ganze Zahl platziert werden soll?

Dank @ Błotosmętek ich nun in der Lage bin, die Größe des Arrays, um herauszufinden:

def array_size(n): 
    k = 0 
    while n > 0: 
     k += 1 
     n -= 6 * k 
    return 2 * k + 1 
+1

Was haben Sie versucht? –

+0

@EricDuminil Nicht viel. Ich habe die Frage aktualisiert, weiß aber noch nicht, wo ich anfangen soll – Spacehug

Antwort

0

meine eigene Frage zu beantworten:

Um herauszufinden, wie die Werte in bestimmten Weise zu platzieren, müssen wir Koordinaten für jedes Delta, um herauszufinden, Artikel.

Aus Gründen der Erklärung werde ich n = 60 Elemente verwenden.

Um das zu tun, müssen wir die Größe des Arrays wissen, dass wir bekommen, kann dies durch das, was @ Błotosmętek erreicht werden vorgeschlagen:

def array_size(n): 
k = 0 
while n > 0: 
    k += 1 
    n -= 6 * k 
return 2 * k + 1 

array_size = array_size(n) 

(By the way, danke für große Heads-up.) Nun müssen wir die Koordinaten für die Array-Zentrum, das ist ziemlich einfach:

# This is (4, 4), the exact coordinates we need for said amount of items (60) 
array_center = (array_size // 2, array_size // 2) 

Als nächstes bekommen wir die Deltas. Ich bin nicht sicher, dass dies der beste Weg, dies zu tun ist, aber trotzdem:

def get_coordinates_delta(n): 
    x = [0] 
    x_ones = 1 
    x_zeroes = 1 
    while len(x) <= n: 
     x += ([1] * x_ones + [0] * x_zeroes + [-1] * (x_ones + 1) + [0] * x_zeroes) 
     x_ones += 2 
     x_zeroes += 1 

    y = [0, -1] 
    y_ones = 2 
    y_zeroes = 1 
    while len(y) <= n: 
     y += ([1] * y_ones + [0] * y_zeroes + [-1] * (y_ones + 1) + [0] * y_zeroes) 
     y_ones += 2 
     y_zeroes += 1 
    return [x for x in zip(x[:n], y[:n])] 

coordinates_delta = get_coordinates_delta(n) 

Und jetzt das Spaßteil, wir alles setzen wir auf das Gitter haben:

def fill_matrix(): 
    matrix = [[0] * array_size for _ in range(array_size)] 
    x, y = array_center 
    for item, (dx, dy) in zip(range(n), coordinates_delta): 
     x += dx 
     y += dy 
     matrix[y][x] = item 
    return matrix 

matrix = fill_matrix()  

Voila,

for line in matrix: 
    print(line) 

gibt uns dies:

[ 0, 0, 0, 0, 0, 37, 38, 39, 40] 
[ 0, 0, 0, 59, 36, 19, 20, 21, 41] 
[ 0, 0, 58, 35, 18, 7, 8, 22, 42] 
[ 0, 57, 34, 17, 6, 1, 9, 23, 43] 
[56, 33, 16, 5, 0, 2, 10, 24, 44] 
[55, 32, 15, 4, 3, 11, 25, 45, 0] 
[54, 31, 14, 13, 12, 26, 46, 0, 0] 
[53, 30, 29, 28, 27, 47, 0, 0, 0] 
[52, 51, 50, 49, 48, 0, 0, 0, 0] 
2

Sie np.put nutzen könnten Werte an dem Ziel indices.This zu platzieren ist meine Lösung, ändern Sie es als Sie wünschen

import numpy as np 

a = np.empty(49) 
b = np.arange(0, 48, 1) 
ind = np.arange(len(a)) 
np.put(a, ind, b) 
a1 = np.reshape(a, (7, 7), order='F') 
print(a1) 

Und haben Sie dieses Array

[[ 0. 7. 14. 21. 28. 35. 42.] 
[ 1. 8. 15. 22. 29. 36. 43.] 
[ 2. 9. 16. 23. 30. 37. 44.] 
[ 3. 10. 17. 24. 31. 38. 45.] 
[ 4. 11. 18. 25. 32. 39. 46.] 
[ 5. 12. 19. 26. 33. 40. 47.] 
[ 6. 13. 20. 27. 34. 41. 0.]] 
+0

Danke, jetzt weiß ich, wie man Werte setzt. Haben Sie eine Idee, wie Sie sie aus der Mitte und in hexagonaler Weise platzieren können? – Spacehug

+0

Dann akzeptiere die Antwort! – MishaVacic

0

die Abmessungen Berechnung i s relativ einfach: beachte, dass dein kleinstes "Sechseck" ein Element ist, dann füge du 6 Elemente hinzu, dann 12, dann 18 ... jede Schleife um das Zentrum addiert 6 * k Zahlen, wobei k = 1, 2, ... und die Dimensionen für k Schleifen sind 2 * k + 1 durch 2 * k + 1. So sollte Ihre Funktion wie folgt funktionieren:

def array_size(n): 
    k = 0 
    while n > 0: 
     k += 1 
     n -= 6 * k 
    return 2 * k + 1 

so zum Beispiel array_size(36) == 7.

Jetzt ist Ihre Zahlen richtig platzieren eine andere Geschichte ...

N=36 
n=array_size(N) 
t = [ ['.'] * n for _ in range(n) ] 

x = y = (n-1)//2 
d = ((0, 1), (-1, 1), (-1, 0), (0, -1), (1, -1), (1, 0)) 
k = 0 
t[y][x] = 0 
y -= 1 
x += 1 
t[y][x] = 1 
i = 1 
while i<N: 
    nx = x + d[k][0] 
    ny = y + d[k][1] 
    px = x + d[(k+1) % 6][0] 
    py = y + d[(k+1) % 6][1] 
    if t[py][px] != '.': 
     x, y = nx, ny 
     i += 1 
     t[y][x] = i 
    else: 
     k = (k+1) % 6 

for row in t: 
    print("".join(("{:>3} ".format(p if p != '.' else 0) for p in row))) 
print() 
+0

Das ist großartig, danke. Obwohl ich "n - = 1" vor der Schleife hinzufügen würde, da 37, 19 und 7 Kacheln keinen leeren Platz hinzufügen sollten. Ich werde deine Antwort auffrischen, sobald ich 15 Ruf habe :) – Spacehug

+0

Also, wo willst du 37 in einem 7 x 7-Array? 'n 'hier ist die letzte Zahl, ** nicht ** die Gesamtanzahl der Zahlen (die um 1 größer ist, seit du beginnst von 0 zu zählen) –

+0

Oh, Entschuldigung, du hast Recht. Ich habe das gleiche Array auf meinem Whiteboard, aber von 1, nicht 0. Ich habe mich verwirrt. – Spacehug