Assign array to magic hexagon

Hello to everyone;

x y z
a b c d
e f g h i
J k l m
n o p

The following code assigns and lists the numbers 1 to 19 with all rows and diagonals totaling 38.

i know almost nothing about c++

how do i get this code to deal with the following sequence (6,12,18,24,30,36,42,48,54,60,66,72,78,84,90,96,102,108,114) instead of numbers 1 to 19
naturally the total will be 228, not 38 thanks.

#include <stdio.h>
#define LOOP(V) for(int V=1;V<20;V++){if(m&1<<V){m&=~(1<<V);
#define ENDLOOP(V) m|=1<<V;}}
#define SET(V,e) int V=e;if(m&1<<V){m&=~(1<<V);
#define UNSET(V) m|=1<<V;}
int main() {
int m=1048574;
LOOP(A);
LOOP(B);
SET(C,38-A-B);
LOOP(D);
SET(H,38-A-D);
LOOP(G);
SET(L,38-C-G);
LOOP(E);
SET(F,38-D-E-G);
LOOP(I);
SET(M,38-B-E-I);
SET(Q,38-H-M);
LOOP(J);
SET(N,38-C-F-J-Q);
SET(R,38-D-I-N);
SET(S,38-Q-R);
SET(P,38-L-S);
SET(K,38-B-F-P);
SET(O,38-M-N-P);
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S);
UNSET(O);
UNSET(K);
UNSET(P);
UNSET(S);
UNSET(R);
UNSET(N);
ENDLOOP(J);
UNSET(Q);
UNSET(M);
ENDLOOP(I);
UNSET(F);
ENDLOOP(E);
UNSET(L);
ENDLOOP(G);
UNSET(H);
ENDLOOP(D);
UNSET(C);
ENDLOOP(B);
ENDLOOP(A);
}

output;
3 17 18 19 7 1 11 16 2 5 6 9 12 4 8 14 10 13 15
3 19 16 17 7 2 12 18 1 5 4 10 11 6 8 13 9 14 15
9 11 18 14 6 1 17 15 8 5 7 3 13 4 2 19 10 12 16
9 14 15 11 6 8 13 18 1 5 4 10 17 7 2 12 3 19 16
10 12 16 13 4 2 19 15 8 5 7 3 14 6 1 17 9 11 18
10 13 15 12 4 8 14 16 2 5 6 9 19 7 1 11 3 17 18
15 13 10 14 8 4 12 9 6 5 2 16 11 1 7 19 18 17 3
15 14 9 13 8 6 11 10 4 5 1 18 12 2 7 17 16 19 3
16 12 10 19 2 4 13 3 7 5 8 15 17 1 6 14 18 11 9
16 19 3 12 2 7 17 10 4 5 1 18 13 8 6 11 15 14 9
18 11 9 17 1 6 14 3 7 5 8 15 19 2 4 13 16 12 10
18 17 3 11 1 7 19 9 6 5 2 16 14 8 4 12 15 13 10
Last edited on
The program is taken from
https://codegolf.stackexchange.com/questions/6304/solve-the-magic-hexagon
The author might have been playing code golf, but the program is very comprehensible anyway.

Literally all you need to do is change the line that says
1
2
3
printf("%d %d %d %d %d %d %d %d %d %d %d "
       "%d %d %d %d %d %d %d %d\n",
       A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S);
Into
1
2
3
4
printf("%d %d %d %d %d %d %d %d %d %d %d "
       "%d %d %d %d %d %d %d %d\n",
       A*6, B*6, C*6, D*6, E*6, F*6, G*6, H*6, I*6, J*6,
       K*6, L*6, M*6, N*6, O*6, P*6, Q*6, R*6, S*6);
To multiply all the outputs by 6.

Afterward the first line of the output would be
18 102 108 114 42 6 66 96 12 30 36 54 72 24 48 84 60 78 90
corresponding to the hexagon
//     018 102 108
//   114 042 006 066
// 096 012 030 036 054
//   072 024 048 084
//     060 078 090 

The numbers in the hexagon are decimal.

Note that 1048574 = 0xffffe
Last edited on
Made a bit less stupid:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <array>

typedef std::array<bool, 40> mask_t;
typedef std::array<int, 20> indices_t;

const int actions[][4] = {
    {-1, -1, -1, -1}, //0
    {-1, -1, -1, -1}, //1
    { 0,  1, -1, -1}, //2
    {-1, -1, -1, -1}, //3
    { 0,  3, -1, -1}, //4
    {-1, -1, -1, -1}, //5
    { 2,  5, -1, -1}, //6
    {-1, -1, -1, -1}, //7
    { 3,  7,  5, -1}, //8
    {-1, -1, -1, -1}, //9
    { 1,  7,  9, -1}, //10
    { 4, 10, -1, -1}, //11
    {-1, -1, -1, -1}, //12
    { 2,  8, 11, 12}, //13
    { 3,  9, 13, -1}, //14
    {11, 14, -1, -1}, //15
    { 6, 15, -1, -1}, //16
    { 1,  8, 16, -1}, //17
    {10, 13, 16, -1}, //18
};

const int print_order[] = {0, 1, 2, 3, 7, 8, 5, 4, 9, 12, 17, 6, 10, 13, 18, 16, 11, 14, 15};

void loop(int level, mask_t &mask, indices_t &indices);

void loop2(int level, mask_t &mask, indices_t &indices){
    auto i = indices[level] - 1;
    if (i < 0 || !mask[i])
        return;
    mask[i] = false;
    loop(level + 1, mask, indices);
    mask[i] = true;
}

void loop(int level, mask_t &mask, indices_t &indices){
    if (level >= 19){
        for (auto i : print_order)
            std::cout << indices[i] << ' ';
        std::cout << std::endl;
        return;
    }
    auto &a = actions[level];
    if (a[0] < 0){
        for (int i = 1; i <= 20; i++){
            indices[level] = i;
            loop2(level, mask, indices);
        }
    }else{
        int i = 38;
        for (auto index : a)
            if (index >= 0)
                i -= indices[index];
        indices[level] = i;
        loop2(level, mask, indices);
    }
}

int main(){
    mask_t mask;
    for (int i = 0; i < 40; i++)
        mask[i]= i < 20;
    indices_t indices;
    loop(0, mask, indices);
    return 0;
}
Last edited on
yes, the code is from there, I deliberately multiplied by 6 as an example.

my goal is to be able to try different series that the user can enter
and being able to do the 127 cell one

dear helios, your code is giving Segmentation error and interesting output

row and diagonal sums should be arranged so that they are equal

.........56 61 70 67 51
........55 45 36 48 53 68
......74 37 26 29 27 39 73
....62 42 33 19 16 31 38 64
..58 57 22 20 15 18 23 43 49
...63 47 28 21 17 30 34 65
.....71 35 24 32 25 46 72
.......59 44 40 41 52 69
.........54 60 75 66 50

sums=305
Last edited on
I've put up a fixed version. Someone thought it was cute to make negative shifts and to test bits higher than 20.
your code also runs fast but still listed from 1 to 19

my c++ knowledge just copy paste and get the output
i run it via online editor

where do i have to enter my array manually for my first code
so I can modify it and make a magic square too
Topic archived. No new replies allowed.