g | x | w | all
Bytes Lang Time Link
065Python250627T051413ZG B
096Swift 6250626T145746ZmacOSist
058Ruby250626T065806ZG B
075JavaScript Node.js250625T045300Zl4m2
076Python 3250624T103820ZJitse
01705AB1E250625T080807ZKevin Cr
070Python250625T054033ZAlbert.L
160Google Sheets250624T181614Zdoubleun
019Jelly250624T180449ZJonathan
301Python3250624T185000ZAjax1234
020Charcoal250624T151142ZNeil

Python, 65 bytes

lambda a,p:a//(w:=int((p+(p*p-16*a)**.5)/4))*('#'*w+'\n')+a%w*'#'

Attempt This Online!

How?

Port of my Ruby answer

Swift 6, 96 bytes

{a,p in{$0($0("#",0+a/$1)+"\n",$1)+$0("#",a%$1)}({String.init}(),(1...).first{a<=$0*(p/2-$0)}!)}

Try it on SwiftFiddle!

A port of @AlbertLang's answer, sans recursion.

Ruby, 70 58 bytes

->a,p{[?#*p=((p+(p*p-16*a)**0.5)/4).to_i]*(a/p)+[?#*a%=p]}

Try it online!

How

The perimeter of the shape will be the same as the perimeter of the enclosing rectangle. We search for the widest rectangle with the given perimeter and area at least a.

JavaScript (Node.js), 75 bytes

A=>P=>[1,...Array(P-2>>2)].map((_,i,z)=>z.map(j=>!(1+i>P/4|i*!j&&A--<P/2)))

Try it online!

-6 bytes Weird Glyphs

Python 3, 76 bytes

def f(a,p):
 i=h=p//4
 while i:i-=1;print(('#'*(a-h-~-p//4*i)+'#')[:p+2>>2])

Try it online!

A perimeter p can be achieved by placing all squares in a partially filled rectangle with size floor(p/4) by ceil(p/4).

-2 bytes thanks to Arnauld

-2 bytes thanks to Jonathan Allan

-2 bytes thanks to xnor

05AB1E, 17 bytes

4÷DŠ-‚'#×`¹<4÷ä`»

Inputs in the order \$perimeter,area\$.

Port of @Neil's Charcoal answer, which in turn is based on @Jitse's observations, so make sure to upvote both of those answers as well! (Outputs 90 degrees flipped in comparison, though.)

Try it online or verify all test cases.

Explanation:

                  #  E.g. inputs p=12,a=6
4÷                # Integer-divide the first (implicit) input-perimeter by 4
                  #  STACK: 3
  D               # Duplicate that value
                  #  STACK: 3, 3
   Š              # Triple-swap with the second (implicit) area
                  #  STACK: 3, 6, 3
    -             # Subtract the perimeter//4 from the area
                  #  STACK: 3, 3
     ‚            # Pair it together with the duplicated perimeter//4
                  #  STACK: [3,3]
      '#×        '# Convert each to strings with that many "#"
                  #  STACK: ["###","###"]
         `        # Pop and push both strings to the stack again
                  #  STACK: "###", "###"
          ¹<      # Push the first input-perimeter, and decrease it by 1
                  #  STACK: "###", "###", 11
            4÷    # Integer-divide that also by 4
                  #  STACK: "###", "###", 2
              ä   # (Try to) split the top string into that many equal-sized parts
                  #  STACK: "###", ["##","#"]
               `  # Pop and push all parts to the stack
                  #  STACK: "###", "##", "#"
                » # Join all strings on the stack by newlines
                  #  STACK: "###\n"
                  #         "##\n"
                  #         "#"
                  # (after which the result is output implicitly)

Python, 70 bytes

f=lambda a,c,w=1:a>w*(v:=c//2-w)and f(a,c,w+1)or(("\n"+v*"#")*w)[:a+w]

Attempt This Online!

Faulty Python, 70 bytes

f=lambda a,c,w=1:a>w*(c//2-w)and f(a,c,w+1)or(a//w*"#"+"\n")*w+a%w*"#"

Thanks to @doubleunary for spotting.

Attempt This Online!

Tries different rectangular layouts until it finds a working one.

Google Sheets, 160 bytes

=let(_,lambda(x,y,rept(join("
",rept("#",y)&"
"),x)),w,ceiling(B1/4),h,int(B1/4),l,int(A1/w),s,h-l,m,l*w+s-A1,b,s-(m<0),_(l-(m>0),w)&_(abs(m),w-(b=0)-1)&_(b,1))

Put \$a\$ in cell A1, \$p\$ in B1, and the formula in C1. Uses Jitse's dimensions. There are two inline line breaks in the lambda.

screenshot

Ungolfed:

=let(
  block_, lambda(x, y, rept(join(char(10), rept("#", y) & char(10)), x)),
  width, ceiling(B1 / 4),
  height, floor(B1 / 4),
  numLongRows, floor(A1 / width),
  numShortRows, height - numLongRows,
  numMidRows, numLongRows * width + numShortRows - A1,
  block_(numLongRows - (numMidRows > 0), width) & 
  block_(abs(numMidRows), width - (numShortRows - (numMidRows < 0) = 0) - 1) & 
  block_(numShortRows - (numMidRows < 0), 1)
)

Jelly, 19 bytes

ŒṗL,`jNƲạƝS⁼ʋƇṪ”#ẋY

A dyadic Link that accepts the area on the left and the perimeter on the right and yields a list of characters, or a full program that prints to stdout.

Try it online! Or see the test-suite.

How?

ŒṗL,`jNƲạƝS⁼ʋƇṪ”#ẋY - Link: Area; Perimeter
Œṗ                  - integer partitions of {Area}
             Ƈ      - keep those for which:
            ʋ       -   last four links as a dyad - f(Partition, Perimeter)
       Ʋ            -     last four links as a monad - f(Partition):
  L                 -       length of {Partition}
   ,`               -       pair with itself -> [L, L]
      N             -       negate {Partition}
     j              -       {[L, L]} join {negated Partition}
        ạƝ          -     absolute differences of the neighbours in {that}
          S         -     sum {these}
           ⁼        -     is {that} equal to {Perimeter}?
              Ṫ     - tail of {that} (one valid partition or 0)
               ”#ẋ  - repeat '#' {those} many times
                  Y - join {those} with newline characters
                    - (if a full program: implicit print)

Python3, 301 bytes

Naive approach.

E=enumerate
def f(a,p):
 q=[(a-i,[[1]*i])for i in range(a,0,-1)]
 for a,b in q:
  D={(x,y)for x,r in E(b)for y,v in E(r)if v}
  if 0==a and sum((x+X,y+Y)not in D for X,Y in[(1,0),(-1,0),(0,1),(0,-1)]for x,y in D)==p:return b
  q+=[(a-i,b+[[0]*(len(b[0])-i)+[1]*i])for i in range(1,min(a,len(b[0]))+1)]

Try it online!

Charcoal, 20 bytes

G↑÷N⁴#M→⪪×#⁻NLKA÷⊖θ⁴

Try it online! Link is to verbose version of code. Takes the perimeter as the first argument and the area as the second. Assumes the perimeter is even. Explanation: Uses @Jitse's observation that the perimeter can be gained from a partial rectangle that then is filled to the appropriate area.

G↑÷N⁴#M→

Integer divide the perimeter by 4 and draw that many #s upwards, then move right.

⪪×#⁻NLKA÷⊖⊖θ⁴

Input the area, subtract the count of #s output so far, then wrap the rest to the the width of integer dividing the decremented perimeter by 4.