GraphViz Dot Prevent Ranks From Overlapping - graphviz

I'm using graphviz to visualize an AST tree in a compiler project I'm doing but a big problem with this is that the trees can get quite large, with some nodes having a lot of children.
What this causes to happen is some parent nodes will be hugely separated from their parents, because their children force them to.
It looks like this:
My question is, is it possible to make it so that all nodes with only one child stay directly above the node below it? So, the "decl f" node will be right above the "assignment" node, while that assignment node stays directly above the "additive" node.
I tried to do this with invisible edges and strong weights between, say in this case, the "decl f" and "additive" nodes, but that ends up offsetting the "assignment" node so it doesnt collide with the invisible edge.
The code is automatically generated, but I'll still put the output here. This output is for this graph:
digraph "ast tree" {
graph [bb="0,0,1767.5,377",
bgcolor=grey12,
concentrate=true,
splines=true
];
node [color=1,
colorscheme=rdylbu11,
fontcolor=white,
height=0,
label="\N",
margins=0.08,
shape=box,
width=0
];
edge [arrowhead=none,
color=white,
colorscheme=rdylbu11,
constraint=true,
penwidth=0.5
];
1 [height=0.31944,
label=program,
pos="270,365.5",
width=0.88889];
2 [height=0.31944,
label=function,
pos="230,306.5",
width=0.86111];
1 -> 2 [color=1,
pos="262.48,353.78 255.32,343.59 244.63,328.35 237.49,318.17"];
10 [color=5,
height=0.31944,
label=function,
pos="396,306.5",
width=0.86111];
1 -> 10 [color=5,
pos="293.4,353.91 316.04,343.67 350.13,328.25 372.72,318.03"];
3 [height=0.31944,
label=scope,
pos="135,247.5",
width=0.69444];
2 -> 3 [color=1,
pos="212.13,294.78 195.15,284.59 169.75,269.35 152.79,259.17"];
4 [height=0.31944,
label=scope,
pos="39,188.5",
width=0.69444];
3 -> 4 [color=1,
pos="116.94,235.78 99.78,225.59 74.112,210.35 56.976,200.17"];
8 [color=3,
height=0.31944,
label="return statement",
pos="135,188.5",
width=1.4583];
3 -> 8 [color=3,
pos="135,235.78 135,225.59 135,210.35 135,200.17"];
5 [height=0.31944,
label="decl a",
pos="39,129.5",
width=0.69444];
4 -> 5 [color=1,
pos="39,176.78 39,166.59 39,151.35 39,141.17"];
6 [height=0.31944,
label=assignment,
pos="39,70.5",
width=1.0833];
5 -> 6 [color=1,
pos="39,117.78 39,107.59 39,92.348 39,82.173"];
7 [height=0.31944,
label="literal 0",
pos="39,11.5",
width=0.77778];
6 -> 7 [color=1,
pos="39,58.779 39,48.588 39,33.348 39,23.173"];
9 [color=3,
height=0.31944,
label="literal 0",
pos="122,129.5",
width=0.77778];
8 -> 9 [color=3,
pos="132.55,176.78 130.23,166.59 126.75,151.35 124.43,141.17"];
11 [color=5,
height=0.31944,
label=scope,
pos="445,247.5",
width=0.69444];
10 -> 11 [color=5,
pos="405.22,294.78 413.98,284.59 427.08,269.35 435.82,259.17"];
12 [color=5,
height=0.31944,
label="decl a",
pos="253,188.5",
width=0.69444];
11 -> 12 [color=5,
pos="419.9,239.05 383.1,228.12 314.91,207.88 278.11,196.95"];
15 [color=7,
height=0.31944,
label="decl b",
pos="331,188.5",
width=0.70833];
11 -> 15 [color=7,
pos="423.82,235.91 403.35,225.67 372.5,210.25 352.06,200.03"];
18 [color=9,
height=0.31944,
label="decl c",
pos="404,188.5",
width=0.69444];
11 -> 18 [color=9,
pos="437.29,235.78 429.96,225.59 419,210.35 411.68,200.17"];
24 [color=4,
height=0.31944,
label="decl d",
pos="486,188.5",
width=0.70833];
11 -> 24 [color=4,
pos="452.71,235.78 460.04,225.59 471,210.35 478.32,200.17"];
32 [color=3,
height=0.31944,
label="decl e",
pos="575,188.5",
width=0.69444];
11 -> 32 [color=3,
pos="469.15,235.91 492.5,225.67 527.68,210.25 550.98,200.03"];
42 [color=6,
height=0.31944,
label="decl f",
pos="662,188.5",
width=0.66667];
11 -> 42 [color=6,
pos="470.32,239.85 512.47,228.78 596.47,206.71 637.84,195.85"];
54 [color=2,
height=0.31944,
label="return statement",
pos="767,188.5",
width=1.4583];
11 -> 54 [color=2,
pos="470.27,242.03 522.68,232.75 644.17,211.24 714.36,198.82"];
13 [color=5,
height=0.31944,
label=assignment,
pos="207,129.5",
width=1.0833];
12 -> 13 [color=5,
pos="244.35,176.78 236.12,166.59 223.82,151.35 215.61,141.17"];
14 [color=5,
height=0.31944,
label="literal 0",
pos="194,70.5",
width=0.77778];
13 -> 14 [color=5,
pos="204.55,117.78 202.23,107.59 198.75,92.348 196.43,82.173"];
16 [color=7,
height=0.31944,
label=assignment,
pos="303,129.5",
width=1.0833];
15 -> 16 [color=7,
pos="325.73,176.78 320.73,166.59 313.24,151.35 308.24,141.17"];
17 [color=7,
height=0.31944,
label="idRHS a",
pos="273,70.5",
width=0.90278];
16 -> 17 [color=7,
pos="297.36,117.78 291.99,107.59 283.97,92.348 278.62,82.173"];
19 [color=9,
height=0.31944,
label=assignment,
pos="399,129.5",
width=1.0833];
18 -> 19 [color=9,
pos="403.06,176.78 402.17,166.59 400.83,151.35 399.94,141.17"];
20 [color=9,
height=0.31944,
label=additive,
pos="354,70.5",
width=0.83333];
19 -> 20 [color=9,
pos="390.54,117.78 382.49,107.59 370.46,92.348 362.43,82.173"];
21 [color=9,
height=0.31944,
label="idRHS a",
pos="214,11.5",
width=0.90278];
20 -> 21 [color=9,
pos="328,58.912 302.85,48.674 264.96,33.25 239.87,23.031"];
22 [color=11,
height=0.31944,
label="+",
pos="277,11.5",
width=0.34722];
20 -> 22 [color=11,
pos="339.52,58.779 325.23,48.201 303.59,32.183 289.88,22.037"];
23 [color=2,
height=0.31944,
label="idRHS b",
pos="341,11.5",
width=0.91667];
20 -> 23 [color=2,
pos="351.55,58.779 349.23,48.588 345.75,33.348 343.43,23.173"];
25 [color=4,
height=0.31944,
label=assignment,
pos="495,129.5",
width=1.0833];
24 -> 25 [color=4,
pos="487.69,176.78 489.3,166.59 491.71,151.35 493.31,141.17"];
26 [color=4,
height=0.31944,
label=additive,
pos="520,70.5",
width=0.83333];
25 -> 26 [color=4,
pos="499.7,117.78 504.17,107.59 510.86,92.348 515.32,82.173"];
27 [color=4,
height=0.31944,
label="idRHS a",
pos="425,11.5",
width=0.90278];
26 -> 27 [color=4,
pos="502.13,58.779 485.15,48.588 459.75,33.348 442.79,23.173"];
28 [color=6,
height=0.31944,
label="+",
pos="488,11.5",
width=0.34722];
26 -> 28 [color=6,
pos="513.98,58.779 508.26,48.588 499.7,33.348 493.99,23.173"];
29 [color=8,
height=0.31944,
label="idRHS b",
pos="552,11.5",
width=0.91667];
26 -> 29 [color=8,
pos="526.02,58.779 531.74,48.588 540.3,33.348 546.01,23.173"];
30 [color=10,
height=0.31944,
label="+",
pos="616,11.5",
width=0.34722];
26 -> 30 [color=10,
pos="538.06,58.779 557.07,47.492 586.51,30.01 603.24,20.077"];
31 [height=0.31944,
label="idRHS c",
pos="679,11.5",
width=0.90278];
26 -> 31 [color=1,
pos="549.53,58.912 578.09,48.674 621.12,33.25 649.62,23.031"];
33 [color=3,
height=0.31944,
label=assignment,
pos="591,129.5",
width=1.0833];
32 -> 33 [color=3,
pos="578.01,176.78 580.87,166.59 585.15,151.35 588,141.17"];
34 [color=3,
height=0.31944,
label=additive,
pos="921,70.5",
width=0.83333];
33 -> 34 [color=3,
pos="630.26,119.74 633.21,119.13 636.15,118.55 639,118 730.37,100.48 839.18,83.682 890.86,75.944"];
35 [color=3,
height=0.31944,
label="idRHS a",
pos="762,11.5",
width=0.90278];
34 -> 35 [color=3,
pos="891.47,58.912 862.91,48.674 819.88,33.25 791.38,23.031"];
36 [color=5,
height=0.31944,
label="+",
pos="825,11.5",
width=0.34722];
34 -> 36 [color=5,
pos="902.94,58.779 883.93,47.492 854.49,30.01 837.76,20.077"];
37 [color=7,
height=0.31944,
label="idRHS b",
pos="889,11.5",
width=0.91667];
34 -> 37 [color=7,
pos="914.98,58.779 909.26,48.588 900.7,33.348 894.99,23.173"];
38 [color=9,
height=0.31944,
label="+",
pos="953,11.5",
width=0.34722];
34 -> 38 [color=9,
pos="927.02,58.779 932.74,48.588 941.3,33.348 947.01,23.173"];
39 [color=11,
height=0.31944,
label="idRHS c",
pos="1016,11.5",
width=0.90278];
34 -> 39 [color=11,
pos="938.87,58.779 955.85,48.588 981.25,33.348 998.21,23.173"];
40 [color=2,
height=0.31944,
label="+",
pos="1079,11.5",
width=0.34722];
34 -> 40 [color=2,
pos="951.1,60.584 979.15,51.97 1022,38.045 1058,23 1060.7,21.869 1063.6,20.544 1066.2,19.223"];
41 [color=4,
height=0.31944,
label="idRHS d",
pos="1143,11.5",
width=0.91667];
34 -> 41 [color=4,
pos="951.4,61.694 992.85,51.053 1066.8,32.061 1109.7,21.048"];
43 [color=6,
height=0.31944,
label=assignment,
pos="687,129.5",
width=1.0833];
42 -> 43 [color=6,
pos="666.7,176.78 671.17,166.59 677.86,151.35 682.32,141.17"];
44 [color=6,
height=0.31944,
label=additive,
pos="1449,70.5",
width=0.83333];
43 -> 44 [color=6,
pos="726.21,119.42 729.17,118.89 732.13,118.41 735,118 998.22,80.853 1320.3,73.317 1418.9,71.845"];
45 [color=6,
height=0.31944,
label="idRHS a",
pos="1227,11.5",
width=0.90278];
44 -> 45 [color=6,
pos="1418.6,61.694 1376.9,50.992 1302.3,31.843 1259.6,20.859"];
46 [color=8,
height=0.31944,
label="+",
pos="1290,11.5",
width=0.34722];
44 -> 46 [color=8,
pos="1419,60.43 1391,51.709 1348.2,37.714 1312,23 1309,21.788 1305.9,20.371 1302.9,18.976"];
47 [color=10,
height=0.31944,
label="idRHS b",
pos="1354,11.5",
width=0.91667];
44 -> 47 [color=10,
pos="1431.1,58.779 1414.1,48.588 1388.7,33.348 1371.8,23.173"];
48 [height=0.31944,
label="+",
pos="1418,11.5",
width=0.34722];
44 -> 48 [color=1,
pos="1443.2,58.779 1437.6,48.588 1429.3,33.348 1423.8,23.173"];
49 [color=3,
height=0.31944,
label="idRHS c",
pos="1481,11.5",
width=0.90278];
44 -> 49 [color=3,
pos="1455,58.779 1460.7,48.588 1469.3,33.348 1475,23.173"];
50 [color=5,
height=0.31944,
label="+",
pos="1544,11.5",
width=0.34722];
44 -> 50 [color=5,
pos="1466.9,58.779 1485.7,47.492 1514.8,30.01 1531.4,20.077"];
51 [color=7,
height=0.31944,
label="idRHS d",
pos="1608,11.5",
width=0.91667];
44 -> 51 [color=7,
pos="1478.5,58.912 1507.1,48.674 1550.1,33.25 1578.6,23.031"];
52 [color=9,
height=0.31944,
label="+",
pos="1672,11.5",
width=0.34722];
44 -> 52 [color=9,
pos="1479.2,64.634 1519,57.739 1591,43.627 1650,23 1653,21.939 1656.2,20.582 1659.2,19.199"];
53 [color=11,
height=0.31944,
label="idRHS e",
pos="1735,11.5",
width=0.90278];
44 -> 53 [color=11,
pos="1479.3,64.384 1525.7,56.405 1617.1,40.129 1694,23 1696.7,22.393 1699.5,21.735 1702.4,21.054"];
55 [color=2,
height=0.31944,
label="literal 0",
pos="772,129.5",
width=0.77778];
54 -> 55 [color=2,
pos="767.94,176.78 768.83,166.59 770.17,151.35 771.06,141.17"];
}

(you might also look at the circo & twopi engines)
The trick to getting nodes to line-up vertically is to assign a unique group attribute (https://graphviz.org/docs/attrs/group/) to each of these sets of nodes. Like so:
digraph "ast tree" {
graph [bb="0,0,1767.5,377",
bgcolor=grey12,
concentrate=true,
splines=true
];
node [color=1,
colorscheme=rdylbu11,
fontcolor=white,
height=0,
label="\N",
margins=0.08,
shape=box,
width=0
];
edge [arrowhead=none,
color=white,
colorscheme=rdylbu11,
constraint=true,
penwidth=0.5
];
1 [height=0.31944,
label=program,
pos="270,365.5",
width=0.88889];
2 [height=0.31944,
label=function,
pos="230,306.5",
width=0.86111];
1 -> 2 [color=1,
pos="262.48,353.78 255.32,343.59 244.63,328.35 237.49,318.17"];
10 [color=5,
height=0.31944,
label=function,
pos="396,306.5",
width=0.86111];
1 -> 10 [color=5,
pos="293.4,353.91 316.04,343.67 350.13,328.25 372.72,318.03"];
3 [height=0.31944,
label=scope,
pos="135,247.5",
width=0.69444];
2 -> 3 [color=1,
pos="212.13,294.78 195.15,284.59 169.75,269.35 152.79,259.17"];
4 [height=0.31944,
label=scope,
pos="39,188.5",
width=0.69444];
3 -> 4 [color=1,
pos="116.94,235.78 99.78,225.59 74.112,210.35 56.976,200.17"];
8 [color=3,
height=0.31944,
label="return statement",
pos="135,188.5",
width=1.4583];
3 -> 8 [color=3,
pos="135,235.78 135,225.59 135,210.35 135,200.17"];
5 [height=0.31944,
label="decl a",
pos="39,129.5",
width=0.69444];
4 -> 5 [color=1,
pos="39,176.78 39,166.59 39,151.35 39,141.17"];
6 [height=0.31944,
label=assignment,
pos="39,70.5",
width=1.0833];
5 -> 6 [color=1,
pos="39,117.78 39,107.59 39,92.348 39,82.173"];
7 [height=0.31944,
label="literal 0",
pos="39,11.5",
width=0.77778];
6 -> 7 [color=1,
pos="39,58.779 39,48.588 39,33.348 39,23.173"];
9 [color=3,
height=0.31944,
label="literal 0",
pos="122,129.5",
width=0.77778];
8 -> 9 [color=3,
pos="132.55,176.78 130.23,166.59 126.75,151.35 124.43,141.17"];
11 [color=5,
height=0.31944,
label=scope,
pos="445,247.5",
width=0.69444];
10 -> 11 [color=5,
pos="405.22,294.78 413.98,284.59 427.08,269.35 435.82,259.17"];
12 [color=5,
height=0.31944,
label="decl a",
pos="253,188.5",
width=0.69444];
11 -> 12 [color=5,
pos="419.9,239.05 383.1,228.12 314.91,207.88 278.11,196.95"];
15 [color=7,
height=0.31944,
label="decl b",
pos="331,188.5",
width=0.70833];
11 -> 15 [color=7,
pos="423.82,235.91 403.35,225.67 372.5,210.25 352.06,200.03"];
18 [color=9,
height=0.31944,
label="decl c",
pos="404,188.5",
width=0.69444];
11 -> 18 [color=9,
pos="437.29,235.78 429.96,225.59 419,210.35 411.68,200.17"];
24 [color=4,
height=0.31944,
label="decl d",
pos="486,188.5",
width=0.70833];
11 -> 24 [color=4,
pos="452.71,235.78 460.04,225.59 471,210.35 478.32,200.17"];
32 [color=3,
height=0.31944,
label="decl e",
pos="575,188.5",
width=0.69444];
11 -> 32 [color=3,
pos="469.15,235.91 492.5,225.67 527.68,210.25 550.98,200.03"];
42 [color=6,
height=0.31944,
label="decl f",
pos="662,188.5",
width=0.66667];
11 -> 42 [color=6,
pos="470.32,239.85 512.47,228.78 596.47,206.71 637.84,195.85"];
54 [color=2,
height=0.31944,
label="return statement",
pos="767,188.5",
width=1.4583];
11 -> 54 [color=2,
pos="470.27,242.03 522.68,232.75 644.17,211.24 714.36,198.82"];
13 [color=5,
height=0.31944,
label=assignment,
pos="207,129.5",
width=1.0833];
12 -> 13 [color=5,
pos="244.35,176.78 236.12,166.59 223.82,151.35 215.61,141.17"];
14 [color=5,
height=0.31944,
label="literal 0",
pos="194,70.5",
width=0.77778];
13 -> 14 [color=5,
pos="204.55,117.78 202.23,107.59 198.75,92.348 196.43,82.173"];
16 [color=7,
height=0.31944,
label=assignment,
pos="303,129.5",
width=1.0833];
15 -> 16 [color=7,
pos="325.73,176.78 320.73,166.59 313.24,151.35 308.24,141.17"];
17 [color=7,
height=0.31944,
label="idRHS a",
pos="273,70.5",
width=0.90278];
16 -> 17 [color=7,
pos="297.36,117.78 291.99,107.59 283.97,92.348 278.62,82.173"];
19 [color=9,
height=0.31944,
label=assignment,
pos="399,129.5",
width=1.0833];
18 -> 19 [color=9,
pos="403.06,176.78 402.17,166.59 400.83,151.35 399.94,141.17"];
20 [color=9,
height=0.31944,
label=additive,
pos="354,70.5",
width=0.83333];
19 -> 20 [color=9,
pos="390.54,117.78 382.49,107.59 370.46,92.348 362.43,82.173"];
21 [color=9,
height=0.31944,
label="idRHS a",
pos="214,11.5",
width=0.90278];
20 -> 21 [color=9,
pos="328,58.912 302.85,48.674 264.96,33.25 239.87,23.031"];
22 [color=11,
height=0.31944,
label="+",
pos="277,11.5",
width=0.34722];
20 -> 22 [color=11,
pos="339.52,58.779 325.23,48.201 303.59,32.183 289.88,22.037"];
23 [color=2,
height=0.31944,
label="idRHS b",
pos="341,11.5",
width=0.91667];
20 -> 23 [color=2,
pos="351.55,58.779 349.23,48.588 345.75,33.348 343.43,23.173"];
25 [color=4,
height=0.31944,
label=assignment,
pos="495,129.5",
width=1.0833];
24 -> 25 [color=4,
pos="487.69,176.78 489.3,166.59 491.71,151.35 493.31,141.17"];
26 [color=4,
height=0.31944,
label=additive,
pos="520,70.5",
width=0.83333];
25 -> 26 [color=4,
pos="499.7,117.78 504.17,107.59 510.86,92.348 515.32,82.173"];
27 [color=4,
height=0.31944,
label="idRHS a",
pos="425,11.5",
width=0.90278];
26 -> 27 [color=4,
pos="502.13,58.779 485.15,48.588 459.75,33.348 442.79,23.173"];
28 [color=6,
height=0.31944,
label="+",
pos="488,11.5",
width=0.34722];
26 -> 28 [color=6,
pos="513.98,58.779 508.26,48.588 499.7,33.348 493.99,23.173"];
29 [color=8,
height=0.31944,
label="idRHS b",
pos="552,11.5",
width=0.91667];
26 -> 29 [color=8,
pos="526.02,58.779 531.74,48.588 540.3,33.348 546.01,23.173"];
30 [color=10,
height=0.31944,
label="+",
pos="616,11.5",
width=0.34722];
26 -> 30 [color=10,
pos="538.06,58.779 557.07,47.492 586.51,30.01 603.24,20.077"];
31 [height=0.31944,
label="idRHS c",
pos="679,11.5",
width=0.90278];
26 -> 31 [color=1,
pos="549.53,58.912 578.09,48.674 621.12,33.25 649.62,23.031"];
33 [color=3,
height=0.31944,
label=assignment,
pos="591,129.5",
width=1.0833];
32 -> 33 [color=3,
pos="578.01,176.78 580.87,166.59 585.15,151.35 588,141.17"];
34 [color=3,
height=0.31944,
label=additive,
pos="921,70.5",
width=0.83333];
33 -> 34 [color=3,
pos="630.26,119.74 633.21,119.13 636.15,118.55 639,118 730.37,100.48 839.18,83.682 890.86,75.944"];
35 [color=3,
height=0.31944,
label="idRHS a",
pos="762,11.5",
width=0.90278];
34 -> 35 [color=3,
pos="891.47,58.912 862.91,48.674 819.88,33.25 791.38,23.031"];
36 [color=5,
height=0.31944,
label="+",
pos="825,11.5",
width=0.34722];
34 -> 36 [color=5,
pos="902.94,58.779 883.93,47.492 854.49,30.01 837.76,20.077"];
37 [color=7,
height=0.31944,
label="idRHS b",
pos="889,11.5",
width=0.91667];
34 -> 37 [color=7,
pos="914.98,58.779 909.26,48.588 900.7,33.348 894.99,23.173"];
38 [color=9,
height=0.31944,
label="+",
pos="953,11.5",
width=0.34722];
34 -> 38 [color=9,
pos="927.02,58.779 932.74,48.588 941.3,33.348 947.01,23.173"];
39 [color=11,
height=0.31944,
label="idRHS c",
pos="1016,11.5",
width=0.90278];
34 -> 39 [color=11,
pos="938.87,58.779 955.85,48.588 981.25,33.348 998.21,23.173"];
40 [color=2,
height=0.31944,
label="+",
pos="1079,11.5",
width=0.34722];
34 -> 40 [color=2,
pos="951.1,60.584 979.15,51.97 1022,38.045 1058,23 1060.7,21.869 1063.6,20.544 1066.2,19.223"];
41 [color=4,
height=0.31944,
label="idRHS d",
pos="1143,11.5",
width=0.91667];
34 -> 41 [color=4,
pos="951.4,61.694 992.85,51.053 1066.8,32.061 1109.7,21.048"];
43 [color=6,
height=0.31944,
label=assignment,
pos="687,129.5",
width=1.0833];
42 -> 43 [color=6,
pos="666.7,176.78 671.17,166.59 677.86,151.35 682.32,141.17"];
44 [color=6,
height=0.31944,
label=additive,
pos="1449,70.5",
width=0.83333];
43 -> 44 [color=6,
pos="726.21,119.42 729.17,118.89 732.13,118.41 735,118 998.22,80.853 1320.3,73.317 1418.9,71.845"];
45 [color=6,
height=0.31944,
label="idRHS a",
pos="1227,11.5",
width=0.90278];
44 -> 45 [color=6,
pos="1418.6,61.694 1376.9,50.992 1302.3,31.843 1259.6,20.859"];
46 [color=8,
height=0.31944,
label="+",
pos="1290,11.5",
width=0.34722];
44 -> 46 [color=8,
pos="1419,60.43 1391,51.709 1348.2,37.714 1312,23 1309,21.788 1305.9,20.371 1302.9,18.976"];
47 [color=10,
height=0.31944,
label="idRHS b",
pos="1354,11.5",
width=0.91667];
44 -> 47 [color=10,
pos="1431.1,58.779 1414.1,48.588 1388.7,33.348 1371.8,23.173"];
48 [height=0.31944,
label="+",
pos="1418,11.5",
width=0.34722];
44 -> 48 [color=1,
pos="1443.2,58.779 1437.6,48.588 1429.3,33.348 1423.8,23.173"];
49 [color=3,
height=0.31944,
label="idRHS c",
pos="1481,11.5",
width=0.90278];
44 -> 49 [color=3,
pos="1455,58.779 1460.7,48.588 1469.3,33.348 1475,23.173"];
50 [color=5,
height=0.31944,
label="+",
pos="1544,11.5",
width=0.34722];
44 -> 50 [color=5,
pos="1466.9,58.779 1485.7,47.492 1514.8,30.01 1531.4,20.077"];
51 [color=7,
height=0.31944,
label="idRHS d",
pos="1608,11.5",
width=0.91667];
44 -> 51 [color=7,
pos="1478.5,58.912 1507.1,48.674 1550.1,33.25 1578.6,23.031"];
52 [color=9,
height=0.31944,
label="+",
pos="1672,11.5",
width=0.34722];
44 -> 52 [color=9,
pos="1479.2,64.634 1519,57.739 1591,43.627 1650,23 1653,21.939 1656.2,20.582 1659.2,19.199"];
53 [color=11,
height=0.31944,
label="idRHS e",
pos="1735,11.5",
width=0.90278];
44 -> 53 [color=11,
pos="1479.3,64.384 1525.7,56.405 1617.1,40.129 1694,23 1696.7,22.393 1699.5,21.735 1702.4,21.054"];
55 [color=2,
height=0.31944,
label="literal 0",
pos="772,129.5",
width=0.77778];
54 -> 55 [color=2,
pos="767.94,176.78 768.83,166.59 770.17,151.35 771.06,141.17"];
}
Giving:

Related

An allocation problem of people into groups getting them to meet as little as possible

I have been trying to solve this for quite a while without success.
I have not found (I searched though) theory that could help me on wikipedia.
Here is the problem.
I have a group of n players (more than 7)
I have a game (diplomacy for those who know !) that requires 7 players, one for these roles : E,F,G,I,A,R and T (countries in fact)
I want to set up a tournament (many games).
There will be n games.
(*) Every player gets into 7 different games, with different role each time
(**) Every game gets 7 different players
=> That is very easy to do.
However, when things get tough, is when you want to limit interactions between players.
What I want is any player to interact (interact = play in same game) at most with one other player.
(In other words, I want to prevent players from making such deals : "I help you in game A, you help me in game B")
So:
Question 1 : For which n is this possible ? (obviously at least 50)
Question 2 : When it is possible, how do you do it ?
Question 3 : What is the algo to minimize these interactions when it is not possible ?
For the record, I did implement a try-and-error program in python (using recursion), working quite well, but I never can get maximum intearctions between players limited to 1 (endless calculations)
thanks for any help !
PS This is no homework, it is for actually designing game tournaments :-)
I did some doodling and I think; If I understand you correctly, that you can do the following:
28 people to do the 7 roles/7 games meeting other players only once.
If the position of a person in the following games is allocated to distinct roles then no person plays the same role in the games they play.
Python
# -*- coding: utf-8 -*-
"""
https://stackoverflow.com/questions/71143133/an-allocation-problem-of-people-into-groups-getting-them-to-meet-as-little-as-po
Created on Sat Feb 19 21:15:02 2022
#author: paddy3118
By hand to get the algo:
0 roles, 0 people for 0 interactions
1 role, 1 person
2 roles, 3 people: p0+p1, p1+p2
3 roles, 012, 134, 235 = 6 people
4 roles, 0123, 1456, 2478, 3579 = 10 people
"""
from itertools import count
def new_person():
yield from count()
def people_allocation(roles: int=4):
games, new_p = [], count()
for i in range(roles):
game = []
games.append(game)
for j in range(i):
game.append(games[j][i])
for _ in range(i, roles):
game.append(next(new_p))
return games, next(new_p)
for roles in range(8):
print(f"Roles = {roles}:")
games, people = people_allocation(roles)
print(f" Takes {people} people in the following games")
print(' ',
', '.join('+'.join(f"P{x}" for x in game) for game in games))
Output
Roles = 0:
Takes 0 people in the following games
Roles = 1:
Takes 1 people in the following games
P0
Roles = 2:
Takes 3 people in the following games
P0+P1, P1+P2
Roles = 3:
Takes 6 people in the following games
P0+P1+P2, P1+P3+P4, P2+P4+P5
Roles = 4:
Takes 10 people in the following games
P0+P1+P2+P3, P1+P4+P5+P6, P2+P5+P7+P8, P3+P6+P8+P9
Roles = 5:
Takes 15 people in the following games
P0+P1+P2+P3+P4, P1+P5+P6+P7+P8, P2+P6+P9+P10+P11, P3+P7+P10+P12+P13, P4+P8+P11+P13+P14
Roles = 6:
Takes 21 people in the following games
P0+P1+P2+P3+P4+P5, P1+P6+P7+P8+P9+P10, P2+P7+P11+P12+P13+P14, P3+P8+P12+P15+P16+P17, P4+P9+P13+P16+P18+P19, P5+P10+P14+P17+P19+P20
Roles = 7:
Takes 28 people in the following games
P0+P1+P2+P3+P4+P5+P6, P1+P7+P8+P9+P10+P11+P12, P2+P8+P13+P14+P15+P16+P17, P3+P9+P14+P18+P19+P20+P21, P4+P10+P15+P19+P22+P23+P24, P5+P11+P16+P20+P23+P25+P26, P6+P12+P17+P21+P24+P26+P27
Assuming that n ≥ 78 or so, the following simple hill climbing algorithm with periodic restarts will return a solution.
The algorithmic idea is to initialize games where each player plays each role exactly once, then drive the number of conflicts to zero (where a conflict is a player playing two roles in a single game, or two players meeting each other more than once) by choosing two random games and a random role and swapping the players involved. We restart every 107 steps because that seems to work well in practice.
Doubtless we could do a little better with constraint programming.
#include <algorithm>
#include <array>
#include <cstdlib>
#include <iostream>
#include <random>
#include <vector>
constexpr int r = 7;
int main() {
int n;
std::cin >> n;
if (n <= r * (r - 1)) {
return EXIT_FAILURE;
}
std::uniform_int_distribution<int> uniform_game(0, n - 1);
std::uniform_int_distribution<int> uniform_role(0, r - 1);
std::random_device device;
std::default_random_engine engine(device());
while (true) {
std::vector<std::array<int, r>> games(n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < r; j++) {
games[i][j] = (i + j) % n;
}
}
int badness = 0;
std::vector<std::vector<int>> pair_counts(n, std::vector<int>(n, 0));
auto count = [&badness, &games, &pair_counts](int i, int j, int increment) {
for (int k = 0; k < r; k++) {
if (k == j) continue;
auto [a, b] = std::minmax(games[i][j], games[i][k]);
badness -= pair_counts[a][b] > (a != b ? 2 : 0);
pair_counts[a][b] += increment;
badness += pair_counts[a][b] > (a != b ? 2 : 0);
}
};
for (int i = 0; i < n; i++) {
for (int j = 0; j < r; j++) {
count(i, j, 1);
}
}
for (long t = 0; t < 10000000; t++) {
int i1;
int i2;
do {
i1 = uniform_game(engine);
i2 = uniform_game(engine);
} while (i1 == i2);
int j = uniform_role(engine);
auto swap_players = [&]() {
count(i2, j, -2);
count(i1, j, -2);
std::swap(games[i1][j], games[i2][j]);
count(i1, j, 2);
count(i2, j, 2);
};
int old_badness = badness;
swap_players();
if (old_badness < badness) {
swap_players();
} else if (badness < old_badness) {
std::cerr << badness << '\n';
}
if (badness <= 0) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < r; j++) {
if (j) std::cout << ' ';
std::cout << games[i][j];
}
std::cout << '\n';
}
return EXIT_SUCCESS;
}
}
}
}
Sample output:
21 38 61 75 77 2 22
70 31 75 7 15 59 69
28 52 29 73 59 23 40
61 45 16 65 35 15 55
12 72 44 45 46 14 10
57 1 3 38 11 6 49
20 6 7 26 0 74 18
54 73 67 58 6 55 75
73 77 63 36 3 0 45
37 57 55 28 34 43 7
17 46 36 66 16 7 48
74 9 24 22 17 73 15
36 50 4 69 28 65 6
59 62 12 32 24 20 51
38 8 59 17 10 19 39
6 53 21 70 13 71 56
55 33 49 59 5 27 36
15 71 33 54 43 18 29
60 36 8 40 71 51 67
19 49 9 34 45 53 60
41 26 73 21 72 35 19
14 64 42 15 57 63 62
44 11 23 27 9 16 21
2 7 68 9 63 52 54
35 18 2 3 60 64 17
29 17 50 41 31 61 57
47 10 32 25 75 28 35
30 48 64 6 32 39 44
46 22 71 35 20 31 11
43 76 41 11 47 60 14
56 2 1 33 74 10 37
51 41 39 0 33 70 34
32 5 18 31 23 76 68
65 43 53 8 27 46 73
63 44 26 5 70 24 28
62 75 66 71 44 3 41
16 69 54 13 22 41 5
58 19 52 57 36 22 70
42 25 22 44 55 56 76
4 30 35 51 76 13 9
72 13 17 62 40 77 43
53 16 10 68 50 58 64
64 47 70 55 38 40 20
50 59 14 48 1 9 71
40 63 19 76 69 1 12
24 35 69 56 68 57 27
67 34 15 72 56 66 32
68 3 46 37 25 21 59
77 54 47 19 4 44 31
76 67 38 46 52 50 33
25 15 77 1 51 26 23
3 61 40 4 53 5 74
45 51 74 29 48 68 47
75 0 57 23 30 8 72
13 27 28 14 19 67 2
9 20 72 42 65 33 3
49 58 48 20 41 37 77
22 12 37 67 39 47 53
26 42 11 61 37 36 13
1 60 5 39 29 75 46
48 40 65 10 54 34 26
23 66 60 50 42 54 24
8 74 13 63 49 32 50
27 29 58 12 7 38 42
7 4 45 24 64 25 8
71 24 30 47 2 49 16
31 28 56 60 12 48 0
10 23 62 49 67 69 61
34 21 31 30 58 62 1
66 70 27 18 61 30 25
0 37 76 64 66 29 65
69 39 43 2 26 45 58
39 65 25 74 62 11 52
5 56 20 52 14 17 30
33 68 6 77 8 12 66
11 55 51 53 18 72 63
52 32 0 43 21 42 4
18 14 34 16 73 4 38
Eventually I think I solved this problem.
I explain it here to help any other person facing such a problem.
I used two "classical" algorithms.
try-and-error to get a first configuration of low quality, with iterations that tries first those players with fewest intearctions and which are already in more games
hill-climibing to improve quality of configuration (making swaps between a conflicting and not conflicting player, or two conflicting players if all players are conflicting) and selecting randomly, keeping the result of swap only if it increases quality - quality is worst number of conflicts (2 usually) and number of occurences)
I reach the following conclusion :
always a solution above 100
never a solution below 90
Thanks for all support you provided !

In SwiftUI Textfield inside HStack which is inside VStack generates runtime Error in macOS

I'm working with Xcode 12.3 and MacOS 11.1.
A Textfield is embedded in a HStack and this one is embedded in a VStack.
struct ContentView: View {
#State var username: String = ""
var body: some View {
VStack {
HStack() {
Text("Enter Username:")
TextField("", text: $username)
}
Text("Your username: \(username)")
}
}
}
The code runs without any problems as an iOS-App.
However, compiling the code as a MacOS-App results in a runtime error.
2021-01-23 23:18:29.835048+0100 TestMacSwiftUI[6349:280606] [General] ERROR: Setting
<_TtC7SwiftUIP33_C58093E7172B0A541A997680E343D0D516_SystemTextField: 0x7fa1666294b0> as the first responder for window
<NSWindow: 0x7fa166606110>, but it is in a different window ((null))! This would eventually crash when the view is freed.
The first responder will be set to nil.
0 AppKit 0x00007fff22c5a499 -[NSWindow _validateFirstResponder:] + 449
1 AppKit 0x00007fff22c5a294 -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff22d7e72b -[NSWindow _realMakeFirstResponder:] + 338
3 SwiftUI 0x00007fff42d8627b $s7SwiftUI11FocusBridgeC04moveC02toyAA0C4ItemV_tF + 155
4 SwiftUI 0x00007fff42d86fad $s7SwiftUI11FocusBridgeC27hostDidBecomeFirstResponder33_74086170859BF7C5D78394D4DEE7E0F9LLyyF + 861
5 SwiftUI 0x00007fff42d85b97 $s7SwiftUI11FocusBridgeC23firstResponderDidChange2to04rootF0ySo11NSResponderCSg_AA0F4Node_pSgtF + 583
6 SwiftUI 0x00007fff42c7102b $s7SwiftUI13NSHostingViewC12observeValue10forKeyPath2of6change7contextySSSg_ypSgSDySo05NSKeyf6ChangeH0aypGSgSvSgtFyycfU_ + 299
7 SwiftUI 0x00007fff42632c8c $sIeg_ytIegr_TR + 12
8 SwiftUI 0x00007fff42c79631 $sIeg_ytIegr_TRTA + 17
9 SwiftUI 0x00007fff42b61374 $s7SwiftUI6UpdateO3endyyFZ + 436
10 SwiftUI 0x00007fff42c70e85 $s7SwiftUI13NSHostingViewC12observeValue10forKeyPath2of6change7contextySSSg_ypSgSDySo05NSKeyf6ChangeH0aypGSgSvSgtF + 805
11 SwiftUI 0x00007fff42c71159 $s7SwiftUI13NSHostingViewC12observeValue10forKeyPath2of6change7contextySSSg_ypSgSDySo05NSKeyf6ChangeH0aypGSgSvSgtFTo + 249
12 Foundation 0x00007fff21188ab8 NSKeyValueNotifyObserver + 327
13 Foundation 0x00007fff2124fe45 NSKeyValueDidChange + 431
14 Foundation 0x00007fff212f0539 NSKeyValueDidChangeWithPerThreadPendingNotifications + 146
15 AppKit 0x00007fff22d7e72b -[NSWindow _realMakeFirstResponder:] + 338
16 AppKit 0x00007fff22d93adf -[NSWindow _selectFirstKeyView] + 758
17 AppKit 0x00007fff22d9310f -[NSWindow _setUpFirstResponder] + 189
18 AppKit 0x00007fff22d90577 -[NSWindow _doWindowWillBeVisibleAsSheet:] + 153
19 AppKit 0x00007fff22d8e4bd -[NSWindow _reallyDoOrderWindowAboveOrBelow:relativeTo:findKey:forCounter:force:isModal:] + 1317
20 AppKit 0x00007fff22d8dc42 -[NSWindow _reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 135
21 AppKit 0x00007fff22d8cc52 -[NSWindow _doOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 289
22 AppKit 0x00007fff22d8cad0 -[NSWindow orderWindow:relativeTo:] + 155
23 AppKit 0x00007fff22d806f1 -[NSWindow makeKeyAndOrderFront:] + 60
24 TestMacSwiftUI 0x000000010e887d21 $s14TestMacSwiftUI11AppDelegateC29applicationDidFinishLaunchingyy10Foundation12NotificationVF + 3169
25 TestMacSwiftUI 0x000000010e887f62 $s14TestMacSwiftUI11AppDelegateC29applicationDidFinishLaunchingyy10Foundation12NotificationVFTo + 146
26 CoreFoundation 0x00007fff2041dfec __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
27 CoreFoundation 0x00007fff204b989b ___CFXRegistrationPost_block_invoke + 49
28 CoreFoundation 0x00007fff204b980f _CFXRegistrationPost + 454
29 CoreFoundation 0x00007fff203eebde _CFXNotificationPost + 723
30 Foundation 0x00007fff2115dabe -[NSNotificationCenter postNotificationName:object:userInfo:] + 59
31 AppKit 0x00007fff22c4cf6d -[NSApplication _postDidFinishNotification] + 305
32 AppKit 0x00007fff22c4ccbb -[NSApplication _sendFinishLaunchingNotification] + 208
33 AppKit 0x00007fff22c49eb2 -[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:] + 541
34 AppKit 0x00007fff22c49b07 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 665
35 Foundation 0x00007fff21189056 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 308
36 Foundation 0x00007fff21188ec6 _NSAppleEventManagerGenericHandler + 80
37 AE 0x00007fff26201ed9 _AppleEventsCheckInAppWithBlock + 15850
38 AE 0x00007fff262015f4 _AppleEventsCheckInAppWithBlock + 13573
39 AE 0x00007fff261fa260 aeProcessAppleEvent + 452
40 HIToolbox 0x00007fff286bd612 AEProcessAppleEvent + 54
41 AppKit 0x00007fff22c44276 _DPSNextEvent + 2048
42 AppKit 0x00007fff22c425af -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1366
43 AppKit 0x00007fff22c34b0a -[NSApplication run] + 586
44 AppKit 0x00007fff22c08df2 NSApplicationMain + 816
45 TestMacSwiftUI 0x000000010e8882d4 $sSo21NSApplicationDelegateP6AppKitE4mainyyFZ + 36
46 TestMacSwiftUI 0x000000010e88829e $s14TestMacSwiftUI11AppDelegateC5$mainyyFZ + 46
47 TestMacSwiftUI 0x000000010e888309 main + 41
48 libdyld.dylib 0x00007fff2034b621 start + 1
49 ??? 0x0000000000000003 0x0 + 3

how to sort the numbers 1, ... n lexicographically without converting the numbers to string?

Assume I have input n how I can print this sequence without convert the number to string?
i.e:-
n = 100
Output :- 1 10 100 11 12 13 14 15 16 17 18 19 2 20 ...
n = 15 Output :- 1 10 11 12 13 14 15 2 3 4 5 6 7 8 9
n = 20 Output :- 1 10 11 12 13 15 15 16 17 18 19 2 20 3 4 5 6 7 8 9
What is the main factor here?
My initial solution that will print the 1's followed by 0's or 2's followed by 0's
int n = 100;
for (int i = 1; i <= n; i++) {
int x = i;
while (x <= n) {
System.out.println(x);
x *= 10;
}
}
I figured out the solution:-
You can call it with initial k = 1
for example printnum(15, 1
void printnums(int n, int k) {
if (k > n) {
return;
}
for (int i = 0; i < 10; i++) {
if (k <= n) {
System.out.println(k);
k *= 10;
printnums(n, k);
k /= 10;
k++;
if (k % 10 == 0) return;
}
}
}
I don't know if there are more optimized one?
Here a condensed solution in Python based on the OP's own answer:
def genRangeLexiSorted(n, k=1):
for i in range(k, min(k+10-k%10, n+1)):
yield i
for j in genRangeLexiSorted(n, 10*i):
yield j
def printnums(n):
print(*list(genRangeLexiSorted(n)))
Then the calls
printnums(1)
printnums(9)
printnums(11)
printnums(20)
printnums(100)
give the following outputs:
1
1 2 3 4 5 6 7 8 9
1 10 11 2 3 4 5 6 7 8 9
1 10 11 12 13 14 15 16 17 18 19 2 20 3 4 5 6 7 8 9
1 10 100 11 12 13 14 15 16 17 18 19 2 20 21 22 23 24 25 26 27 28 29 3 30 31 32 33 34 35 36 37 38 39 4 40 41 42 43 44 45 46 47 48 49 5 50 51 52 53 54 55 56 57 58 59 6 60 61 62 63 64 65 66 67 68 69 7 70 71 72 73 74 75 76 77 78 79 8 80 81 82 83 84 85 86 87 88 89 9 90 91 92 93 94 95 96 97 98 99

How i can improve the code?

I'm beginner in programming. Could i use two elements in golang for-loops? If you know answer, or material which i should read, please help me.
package main
import (
"fmt"
)
func main() {
x := []int{
48, 96, 86, 68,
57, 82, 63, 70,
37, 34, 83, 27,
19, 97, 9, 17,
}
for a := 0, b := 1; a++, b++ {
if x[a] > x[b] {
x = append(x[:1], x[1+1:]...)
fmt.Println("x[1+1:]x)", x)
} else {
x = append(x[:0], x[0+1:]...)
fmt.Println("x[0+1:]x)", x)
}
}
}
Yes, you can, although it's unnecessary in this case.
The syntax function fixes the syntax and other errors in your code so that your code runs and produces output. The idiom function rewrites your code in a more idiomatic form.
package main
import (
"fmt"
)
func syntax() {
x := []int{
48, 96, 86, 68,
57, 82, 63, 70,
37, 34, 83, 27,
19, 97, 9, 17,
}
for a, b := 0, 1; a < len(x) && b < len(x); a, b = a+1, b+1 {
if x[a] > x[b] {
x = append(x[:1], x[1+1:]...)
fmt.Println("x[1+1:]x)", x)
} else {
x = append(x[:0], x[0+1:]...)
fmt.Println("x[0+1:]x)", x)
}
}
}
func idiom() {
x := []int{
48, 96, 86, 68,
57, 82, 63, 70,
37, 34, 83, 27,
19, 97, 9, 17,
}
for i := 1; i < len(x); i++ {
if x[i-1] > x[i] {
x = append(x[:1], x[1+1:]...)
fmt.Println("x[1+1:]x)", x)
} else {
x = append(x[:0], x[0+1:]...)
fmt.Println("x[0+1:]x)", x)
}
}
}
func main() {
syntax()
fmt.Println()
idiom()
}
Output:
$ go run beginner.go
x[0+1:]x) [96 86 68 57 82 63 70 37 34 83 27 19 97 9 17]
x[1+1:]x) [96 68 57 82 63 70 37 34 83 27 19 97 9 17]
x[0+1:]x) [68 57 82 63 70 37 34 83 27 19 97 9 17]
x[0+1:]x) [57 82 63 70 37 34 83 27 19 97 9 17]
x[1+1:]x) [57 63 70 37 34 83 27 19 97 9 17]
x[1+1:]x) [57 70 37 34 83 27 19 97 9 17]
x[0+1:]x) [70 37 34 83 27 19 97 9 17]
x[0+1:]x) [37 34 83 27 19 97 9 17]
x[0+1:]x) [96 86 68 57 82 63 70 37 34 83 27 19 97 9 17]
x[1+1:]x) [96 68 57 82 63 70 37 34 83 27 19 97 9 17]
x[0+1:]x) [68 57 82 63 70 37 34 83 27 19 97 9 17]
x[0+1:]x) [57 82 63 70 37 34 83 27 19 97 9 17]
x[1+1:]x) [57 63 70 37 34 83 27 19 97 9 17]
x[1+1:]x) [57 70 37 34 83 27 19 97 9 17]
x[0+1:]x) [70 37 34 83 27 19 97 9 17]
x[0+1:]x) [37 34 83 27 19 97 9 17]
Follow the link to take A Tour of Go.

NULL in a RubyCocoa application?

I'm creating an application in RubyCocoa and I have this code:
fileContents = OSX::NSAttributedString.alloc.initWithData_options_documentAttributes_error_(data, null, null, outError)
It gives me this error:
2009-12-31 19:42:54.317 Ruby Text[3791:a0f] MyDocument#readFromData_ofType_error_: OSX::OCMessageSendException: Can't get Objective-C method signature for selector 'null' of receiver #<MyDocument:0x2aaa8a class='MyDocument' id=0x2770e20>
/Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc/oc_wrapper.rb:50:in `ocm_send'
/Library/Frameworks/RubyCocoa.framework/Resources/ruby/osx/objc/oc_wrapper.rb:50:in `method_missing'
/Users/myname/Documents/Ruby Text/build/Debug/Ruby Text.app/Contents/Resources/MyDocument.rb:44:in `readFromData_ofType_error_'
/Users/myname/Documents/Ruby Text/build/Debug/Ruby Text.app/Contents/Resources/rb_main.rb:22:in `NSApplicationMain'
/Users/myname/Documents/Ruby Text/build/Debug/Ruby Text.app/Contents/Resources/rb_main.rb:22
2009-12-31 19:42:54.320 Ruby Text[3791:a0f] HIToolbox: ignoring exception 'Can't get Objective-C method signature for selector 'null' of receiver #<MyDocument:0x2aaa8a class='MyDocument' id=0x2770e20>' that raised inside Carbon event dispatch
(
0 CoreFoundation 0x97b0940a __raiseError + 410
1 libobjc.A.dylib 0x943ff509 objc_exception_throw + 56
2 CoreFoundation 0x97b53a21 -[NSException raise] + 17
3 RubyCocoa 0x00010ddc rbobj_call_ruby + 764
4 RubyCocoa 0x0000dbda install_ovmix_methods + 2218
5 libffi.dylib 0x97bceb9f ffi_closure_SYSV_inner + 177
6 libffi.dylib 0x97bce9c2 ffi_closure_SYSV + 34
7 AppKit 0x9135aac0 -[NSDocument readFromURL:ofType:error:] + 743
8 AppKit 0x91247955 -[NSDocument initWithContentsOfURL:ofType:error:] + 311
9 AppKit 0x912474f9 -[NSDocumentController makeDocumentWithContentsOfURL:ofType:error:] + 383
10 AppKit 0x912472b1 -[NSDocumentController openDocumentWithContentsOfURL:display:error:] + 886
11 AppKit 0x912457bf -[NSDocumentController _openDocumentsWithContentsOfURLs:display:presentErrors:] + 169
12 AppKit 0x9135ee87 -[NSDocumentController openDocument:] + 352
13 AppKit 0x9103af86 -[NSApplication sendAction:to:from:] + 112
14 AppKit 0x9103ae39 -[NSMenuItem _corePerformAction] + 435
15 AppKit 0x9103ab2a -[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 174
16 AppKit 0x9103aa16 -[NSMenu performActionForItemAtIndex:] + 65
17 AppKit 0x9103a9c9 -[NSMenu _internalPerformActionForItemAtIndex:] + 50
18 AppKit 0x9103a92f -[NSMenuItem _internalPerformActionThroughMenuIfPossible] + 97
19 AppKit 0x9103a873 -[NSCarbonMenuImpl _carbonCommandProcessEvent:handlerCallRef:] + 336
20 AppKit 0x9102ef79 NSSLMMenuEventHandler + 404
21 HIToolbox 0x97719e29 _ZL23DispatchEventToHandlersP14EventTargetRecP14OpaqueEventRefP14HandlerCallRec + 1567
22 HIToolbox 0x977190f0 _ZL30SendEventToEventTargetInternalP14OpaqueEventRefP20OpaqueEventTargetRefP14HandlerCallRec + 411
23 HIToolbox 0x9773b981 SendEventToEventTarget + 52
24 HIToolbox 0x97767e3b _ZL18SendHICommandEventmPK9HICommandmmhPKvP20OpaqueEventTargetRefS5_PP14OpaqueEventRef + 448
25 HIToolbox 0x9778cb20 SendMenuCommandWithContextAndModifiers + 66
26 HIToolbox 0x9778cad7 SendMenuItemSelectedEvent + 121
27 HIToolbox 0x9778c9d3 _ZL19FinishMenuSelectionP13SelectionDataP10MenuResultS2_ + 152
28 HIToolbox 0x9775c212 _ZL14MenuSelectCoreP8MenuData5PointdmPP13OpaqueMenuRefPt + 440
29 HIToolbox 0x9775b9a9 _HandleMenuSelection2 + 465
30 HIToolbox 0x9775b7c7 _HandleMenuSelection + 53
31 AppKit 0x910284ba _NSHandleCarbonMenuEvent + 285
32 AppKit 0x90ffd076 _DPSNextEvent + 2304
33 AppKit 0x90ffc306 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 156
34 AppKit 0x90fbe49f -[NSApplication run] + 821
35 AppKit 0x90fb6535 NSApplicationMain + 574
36 libffi.dylib 0x97bce91d ffi_call_SYSV + 29
37 libffi.dylib 0x97bcec49 ffi_call + 138
38 RubyCocoa 0x0001c94e rb_ffi_dispatch + 2558
39 RubyCocoa 0x0001554c find_bs_method + 1020
40 libruby.1.dylib 0x00044dfa rb_rescue + 800
41 libruby.1.dylib 0x0004fac0 rb_proc_call + 1452
42 libruby.1.dylib 0x000507db rb_proc_call + 4807
43 libruby.1.dylib 0x0004bb0c rb_provided + 7165
44 libruby.1.dylib 0x0005b83d rb_eval_string + 262
45 libruby.1.dylib 0x0005b86e ruby_exec + 22
46 libruby.1.dylib 0x0005b89a ruby_run + 42
47 RubyCocoa 0x00012931 RBApplicationMain + 337
48 Ruby Text 0x00001f4d main + 47
49 Ruby Text 0x00001ef2 start + 54
)
I tried everything (including nil, OSX::NULL, OSX::nil, null(), NULL, etc).
Can anyone help me? Thanks.
In RubyCocoa, a method will return the method's return value and then any double indirection arguments (source):
fileContents, docAttributes, error = OSX::NSAttributedString.alloc.initWithData_options_documentAttributes_error_(data, options)
In MacRuby, you need to create a pointer to an object and pass that to the method (source):
error = Pointer.new_with_type(‘#’)
NSFileManager.defaultManager.attributesOfItemAtPath path, error:error

Resources