Integers, Assemble!
Python 2, 210 200 bytes
Edit: Works now!
Fills from top to bottom, left to right, starting with the largest numbers. Then, transpose and do it again. Then transpose and print. I had to pad with spaces for the transposition to work, since the lines aren't to their full length yet.
I had trouble getting a nested exec
working (to do exec'exec"..."*w\n;...'*2
. If someone can figure it out, let me know.
n,w,h=input()
s=[""]*h
for x in 1,2:
exec"for i in range(h):l=len(s[i]+`n`)<=w;s[i]+=`n`*l;n-=l\n"*w;s=[r.replace(" ","")for r in map(lambda x:`x`[2::5],zip(*[r.ljust(w)for r in s]))];w,h=h,w
print s
Try it online - Uses a modified function so it can run multiple test cases more easily (and it couldn't use exec
). Uncomment the other version and modify stdin to see it run.
Less golfed:
def f(n,w,h):
s=[""]*h
for x in 1,2:
for j in[0]*w:
for i in range(h):
l=len(s[i]+`n`)<=w
s[i]+=`n`*l
n-=l
s=[r.ljust(w)for r in s]
s=map(lambda x:`x`[2::5],zip(*s))
s=[r.replace(' ','')for r in s]
w,h=h,w
print"\n".join(s)
JavaScript, 284 259 245 241 240 223 209 205 bytes
// Golfed
let f = (N,W,H)=>eval('a=Array(H).fill("");while(N)g:{s=""+N--;d=s[L="length"];for(i in a)if(a[i][L]+d<=W){a[i]+=s;break g}for(p=0;d;++p){l=a[p][L];for(k=p+d;k>p;)l=a[--k][L]-l?W:l;while(l<W&&d)a[p+--d]+=s[d]}}a');
// Ungolfed
(N,W,H) => {
a = Array(H).fill(""); // Create `H` empty rows.
while (N) g : {
s = "" + N--; // Convert the number to a string.
d = s[L="length"]; // Count the digits in the number.
// Loop through the rows trying to fit the number in horizontally.
for (i in a) {
if (a[i][L] + d <= W) { // If it fits.
a[i] += s; // Append the number to the row.
break g; // This is what a goto statement looks like in JavaScript.
}
}
// Loop through the rows trying to fit the number in vertically.
for (p = 0; d; ++p) {
l = a[p][L]; // Get the length of the row.
// Find `d` adjacent rows of the same length.
for (k = p + d; k > p; ) {
// If `a[--k][L] == l`, continue.
// Else set `l` to `W` so the next loop doesn't run.
l = a[--k][L] - l ? W : l;
}
// Put the characters in position.
while (l < W && d)
a[p+--d] += s[d];
}
}
return a;
}
let test_data = [[1,1,1],
[6,6,1],
[6,2,3],
[10,1,11],
[10,11,1],
[11,13,1],
[27,9,5],
[183,21,21],
[184,2,222],
[200,41,12],
[1003,83,35]];
for (let test of test_data)
console.log(f(test[0],test[1],test[2]));
Pyth, 35 bytes
juum+WghHl+dQd~tQN<+.TGmkeHeH)_BvzY
Credits to mbomb007. I used his algorithm. Originally I only wanted to help Steven H., but then I really wanted to see a short version.
Takes N
on the first line, and W,H
on the second line: Try it online: Demonstration
Found a nasty bug in the Pyth implementation of .[
(my own fault, since I implemented it). Gotta fix it tomorrow. This resulted in +3 bytes.
Explanation:
juum+WghHl+dQd~tQN<+.TGmkeHeH)_BvzY
Y start with the empty list []
I'll perform all operations on this list.
Sometimes it is called G, sometimes N.
vz read the second line and evaluate it: [W, H]
_B bifurcate it with reverse: [[W, H], [H, W]]
u for each pair H in ^:
.TG transpose G
+ mkeH append H[1] empty strings
< eH use only the first H[1] strings
lets call this result N
u ) modify N, until it doesn't change anymore:
m N map each d in N to:
WghHl+dQ if H[0] >= len(d+Q):
+ d Q d + Q
~t and decrement Q by 1
d else:
d
j at the end print every row on a separate line