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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
' Challenge 101
'
' TASK #1 � Pack a Spiral
' Submitted by: Stuart Little
'
' You are given an array @A of items (integers say, but they can be anything).
'
' Your task is to pack that array into an MxN matrix spirally counterclockwise,
' as tightly as possible.
'
' �Tightly� means the absolute value |M-N| of the difference has to be as small
' as possible.
const max_numbers as integer = 100
dim shared number_list(max_numbers) as integer
dim shared number_rect(max_numbers,max_numbers) as integer
dim shared num_width as integer, rect_width as integer, rect_height as integer
dim shared num_numbers as integer
' collect from command line
sub collect_numbers()
dim i as integer
i = 1
do while command(i)<>""
number_list(i) = val(command(i))
if len(command(i))>num_width then
num_width = len(command(i))
end if
num_numbers = i
i = i + 1
loop
end sub
' get smallest rectangle
sub smallest_rect(byref rect_width as integer, byref rect_height as integer)
dim i as integer
rect_width = 1
rect_height = num_numbers
for i=1 to num_numbers
if (num_numbers mod i) = 0 then
rect_width = i
rect_height = int(num_numbers / i)
if rect_width >= rect_height then exit for
end if
next
end sub
' pack the numbers in a spiral
sub pack_numbers(rect_width as integer, rect_height as Integer)
dim row as integer, col as integer, idx as integer
' fill matrix with -1 - to mark places that are free
for row=1 to rect_height
for col=1 to rect_width
number_rect(row, col) = -1
next
next
idx = 1
row = rect_height
col = 1
do while idx <= num_numbers
' go East
do while col <= rect_width
if number_rect(row, col) >= 0 then exit do
number_rect(row, col) = number_list(idx)
idx = idx + 1
col = col + 1
loop
col = col - 1
row = row - 1
' go North
do while row >= 1
if number_rect(row, col) >= 0 then exit do
number_rect(row, col) = number_list(idx)
idx = idx + 1
row = row - 1
loop
row = row + 1
col = col - 1
' go West
do while col >= 1
if number_rect(row, col) >= 0 then exit do
number_rect(row, col) = number_list(idx)
idx = idx + 1
col = col - 1
loop
col = col + 1
row = row + 1
' go South
do while row <= rect_height
if number_rect(row, col) >= 0 then exit do
number_rect(row, col) = number_list(idx)
idx = idx + 1
row = row + 1
loop
row = row - 1
col = col + 1
loop
end sub
' print the rectangle
sub print_rect(rect_width as integer, rect_height as Integer)
dim row as integer, col as integer
for row=1 to rect_height
for col=1 to rect_width
print right(space(10) & str(number_rect(row, col)), num_width+1);
next
print
next
end sub
' main
collect_numbers
smallest_rect rect_width, rect_height
pack_numbers rect_width, rect_height
print_rect rect_width, rect_height
|