Ich verzweifle hier an einem Problem bzw suche eine möglichst elegante Lösung dafür.
Gegeben sei eine Liste von positiven (Ganz-)Zahlen, die für die Spaltenbreiten einer Tabelle stehen. Weiterhin gibt es eine Maximalbreite, die von der Tabelle eingenommen werden darf. Betrachtet werden sollen nur die Fälle, in denen die Summe der Spaltenbreiten die Maximalbreite überschreitet.
Es gilt nun, die Spalten so zu verkleinern, dass die komplette Tabelle in die vorgegebene Gesamtbreite passt. Dabei sollen möglichst gleich breite Spalten herauskommen¹, aber die anfangs vorgegebenen Spaltenbreiten sollen nicht überschritten werden. Anders gesagt: Eine Spalte kann nur verkleinert werden oder gleich bleiben, jedoch niemals breiter sein als die Vorgabe.
Mein Ansatz ist, die Spalten absteigend nach ihrer Breite zu sortieren (also höchste Breite zuerst). Dann wird auf Basis des Offset (= max. Breite - Gesamtbreite) schrittweise verkleinert bis der Offset bei 0 liegt und es somit passt. Das ist aber sehr umständlich, unübersichtlich, aufwändig, fehleranfällig und einfach nur doof. Gibt es da einen schlauen mathematischen Ansatz, um vorab möglichst viele Annahmen treffen zu können, sodass Iterationsschritte und Code eingespart werden können?
Ich freue mich über Hinweise aller Art. Wenn noch Fragen zum Vorgehen bestehen, stellt sie.

EDIT (Fußnote):
¹ Also was ich nicht möchte, ist dass man z.B. die größte Spalte einfach von 30 auf sagen wir mal 3 verkleinert und dies zusammen mit viel breiteren Spalten als Lösung sieht. Vielmehr soll quasi die breiteste Spalte auf die Breite der zweitgrößten gebracht werden und wenn das nicht passt, dann sollen die beiden auf die Breite der drittgrößten gebracht werden, usw. Jedoch das große Aber: Die Lösung soll immer die komplette Gesamtbreite ausnutzen. Beim letzten Angleichen kann es also gut sein, dass gar nicht bis zur nächsten Spaltenbreite heruntergangen werden muss, sondern weniger (gleichmäßige) Verkleinerung für die in Frage kommenden Spalten ausreicht. Spätestens da wird es also etwas tricky.