C (gcc), 128128 125 bytes
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;i=0;++i<n;p(y){,x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}p(x);} -3 bytes thanks to ceilingcat
Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Visit Stack ExchangeStack Internal
Knowledge at work
Bring the best of human thought and AI automation together at your work.
Explore Stack Internalp(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;i=0;++i<n;p(y){,x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}p(x);} -3 bytes thanks to ceilingcat
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}p(x);} p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;p(y),x-=y++)while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(x);} -3 bytes thanks to ceilingcat
p(_){printf("%d ",_);}f(n,x,y,i){x=n*n;y=1;for(i=0;++i<n;){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}p(x);} NOTE: The probability is very very far from uniform. See explanation for what I mean and a better means to test that it works (by making the distribution closer to uniform [but still a far cry from it]).
The basic idea is to only choose increasing numbers so as to not worry about duplicates. Whenever we pick a number we have a non-zero chance of 'skipping' it if allowable.
To decide if we can skip a number we need to know x the total left to be reached, k the number of elements we still have to use, and y the current candidate value. The smallest possible number that we could still pick would consist of $$y+(y+1)+(y+2)+...$$ added to the current value. In particular we require the above expression to be less than x. The formula will be $$\frac{k(k+1)}{2}+k(y+1)+y<x$$ Unfortunately we have to be a bit careful about rearranging this formula due to integer truncation in C, so I couldn't really find a way to golf it.
Nonetheless the logic is to have a chance to discard any y that satisfies the above equation.
p(_){printf("%d ",_);} // Define print(int) f(n,x,y,i){ // Define f(n,...) as the function we want x=n*n; // Set x to n^2 y=1; // Set y to 1 for(i=0;++i<n;){ // n-1 times do... while(rand()&& // While rand() is non-zero [very very likely] AND (n-i)* // (n-i) is the 'k' in the formula (n-i+1)/2+ // This first half takes care of the increment (n-i)*(y+1) // This second half takes care of the y+1 starting point +y<x) // The +y takes care of the current value of y y++; // If rand() returned non-zero and we can skip y, do so p(y); // Print y x-=y++; // Subtract y from the total and increment it }p(x);} // Print what's left over. The trick I mentioned to better test the code involves replacing rand()&& with rand()%2&& so that there is a 50-50 chance that any given y is skipped, rather than a 1 in RAND_MAX chance that any given y is used.