home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
progs
/
bfd.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
3KB
|
121 lines
############################################################################
#
# File: bfd.icn
#
# Subject: Program to compute best-fit-descending bin packing
#
# Author: Gregg M. Townsend
#
# Date: December 4, 1996
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Usage: bpack binsize [options] [file]
#
# Input: one entry per line, size in decimal followed by anything else
# (anything else presumably being a file name or something)
#
# Output: all the input lines, unchanged but reordered,
# with an empty line before each bin and a total afterward
#
# Options:
# -t don't output anything except unannotated totals
# -n don't output anything except the *number* of bins
# -b i don't output anything except the details from bin i
#
############################################################################
#
# Links: options
#
############################################################################
# possible options to add later: optional quantization and padding values
# (e.g. to use with tar(1) you'd need it to round up to the next
# 128 bytes and add 128 bytes for each file header -- or whatever)
link options
record obj(size,detail)
global opts, binsize
procedure main(args)
local ifile, line, n, d
local objlist, bins, o, b
opts := options(args, "tnb+")
binsize := integer(args[1]) | stop("usage: ", &progname, " binsize")
if *args > 1 then
ifile := open(args[2]) | stop("can't open ", args[2])
else
ifile := &input
objlist := []
while line := read(ifile) do line ? {
tab(many(' \t'))
n := integer(tab(many(&digits))) | next
tab(many(' \t'))
d := trim(tab(0), ' \t')
put(objlist, obj(n, d))
}
objlist := sortf(objlist, 1)
bins := []
while o := pull(objlist) do {
n := bestfit(bins, o.size)
put(bins[n].detail, o)
bins[n].size +:= o.size
}
if \opts["n"] then {
write(*bins)
return
}
if \opts["t"] then {
every write((!bins).size)
return
}
if n := \opts["b"] then {
b := bins[n] | stop("no bin ", n, "; only " *bins, " bins")
every write((!b.detail).detail)
return
}
while b := get(bins) do {
write()
while o := get(b.detail) do
write(right(o.size, 12), "\t", o.detail)
write(right(b.size, 12), "\t--total--")
}
end
procedure bestfit(bins, sz)
local b, i, n, d, best
every i := 1 to *bins do {
b := bins[i]
d := binsize - b.size - sz
if d < 0 | d > \best then
next
best := d
n := i
}
if \n then
return n
else {
put(bins, obj(0, []))
return *bins
}
end