Arranging pins on a microchip

Since no one has posted a "good quality question" recently, i feel it is my duty to...

You work at an electronics company in the design department. The designers that work with you have asked you to make a program that will calculate the optimum configuration of pins on a microchip they are designing. With your ninja golfing skills, you are confident you can handle it.

Your company also has these requirements for each chip:

• The chips your company makes are known as TQFP, they have pins on each edge, but none in the middle.
• Each chip must be square, and have the same number of pins on each side.
• If the chip doesn't have enough pins to be square, pins will be added.
• Extra pins are either a ground or voltage supply pin.
• Half are ground, half are voltage supply.
• If there is an odd number of extra pins, the odd one out is ground

Your program will take input as a single integer, which is the minimum number of pins the manufacturing needs. You will then output 4 integers:

• The number of pins (total)
• The number of pins per side
• The number of ground pins added
• The number of voltage supply pins added

Rules:

• You can use any language
• This is , to the shortest answer in bytes wins
• Bonus: -50 for printing an ASCII chip:

Something like this:

 +++++
+   +
+   +
+   +
+++++


(For example with an input of 20)

• By odd one out do you mean that if we need to add an odd number of pins that #ground = #voltagesupply + 1 or vice-versa? – Kaya Mar 16 '14 at 1:25
• You may want to add clarification for a point that confused me at first: the pins are at the perimeter of the square, not throughout the square area. – grovesNL Mar 16 '14 at 2:00
• mmm ...chip is an ASCII chip – Dr. belisarius Mar 16 '14 at 6:30
• One does have to grin at the sheer bravado of posting a question in a rush and then making bold claims that 'no one has posted a "good quality question" recently'. :D – Jonathan Van Matre Mar 16 '14 at 15:12
• Why does your example ASCII chip for n=20 pins have 16 pins? If we are supposed to draw a chip with n-4 pins instead of n then what do we draw in the case where n<=4? – Kaya Mar 17 '14 at 4:14

APL, 54 chars/bytes* – 50 = score 4

“Take this, Golfscript!” special edition

{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]}


Takes a number as input and returns the required output. Dialect is Dyalog with ⎕IO⎕ML←1 3

Explanation

{                        s←⌈⍵÷4 }  divide the # of pins by 4, take the ceiling and call it s
∘.{       }⍨⍳s         for each couple of naturals up to s compute a table with:
∨/⍺⍵∊1s             1 if either one of the two numbers is 1 or s, 0 otherwise
⊂' +'[1+                   ]   convert the 0 and 1s to space and + and enclose the table
then...
t←4×s            multiply the pins per side by 4 and call it t (for total)
h←2÷⍨⍵-⍨t                subtract the # of pins from it and divide by 2, call it h
t s(⌈h)(⌊h            )           make a vector with t, s, the ceiling of h, and its floor,
,——        and prepend it to the previously enclosed table of chars.


Examples

    {t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 0
0 0 0 0
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 1
4 1 2 1  +
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 2
4 1 1 1  +
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 3
4 1 1 0  +
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 4
4 1 0 0  +
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 5
8 2 2 1  ++
++
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 6
8 2 1 1  ++
++
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 7
8 2 1 0  ++
++
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 8
8 2 0 0  ++
++
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 9
12 3 2 1  +++
+ +
+++
{t s(⌈h)(⌊h←2÷⍨⍵-⍨t←4×s),⊂' +'[1+∘.{∨/⍺⍵∊1s}⍨⍳s←⌈⍵÷4]} 13
16 4 2 1  ++++
+  +
+  +
++++


*: Dyalog supports its own (legacy) single byte charset, where the APL symbols are mapped to the upper 128 byte values. Therefore the entire code can be stored in 54 bytes if needed.

Python: 6453 46 bytes

x=input()
m=x+3&~3
t=m-x
print m,m/4,t-t/2,t/2


Second Third attempt seems pretty minimal. Thanks for the help.

First attempt seems sort of long, we'll see what an hour or two of mulling it over will shave off of the byte count. Could also probably make it shorter if a function is allowed instead of program.

> python chip.py
9
(12, 3, 2, 1)


Also made a version that prints chips, seems like the -50 isn't worth it in python. Total score of 102-50=52.

x=input()
m=x+3&~3
n=m/4
t=m-x
s=['+'*-~n]
print'\n'.join(s+['+'+' '*~-n+'+']*~-n+s+[m,n,t-t/2,t/2])


Example:

> python chip.py
9
++++
+  +
+  +
++++
(12, 3, 2, 1)

• can't y=(4*m-x)/2 be written as y=2*m-x/2 (saving two bytes)? – Justin Mar 16 '14 at 1:37
• Isn't 9 enough pins for it to be square (3 by 3)? Or am I misunderstanding the question? – grovesNL Mar 16 '14 at 1:41
• @grovesNL most square chips I have seen only have pins round the edge, so the number of pins has to be divisible by 4. That's how I understood the question. – Level River St Mar 16 '14 at 1:51
• @steveverrill I see. I interpreted it as pins contained throughout a square area, not the perimeter. Thanks. – grovesNL Mar 16 '14 at 1:59
• Remove the brackets in print to save another byte! – devnull Mar 16 '14 at 9:55

Julia, 62 61 56 bytes

m(x)=(s=iceil(x/4);p=4s-x;(4s,s,iceil(p/2),ifloor(p/2)))


Very straightforward. And now down to 56 thanks to gggg's sharp eyes.

Outputs:

In [14]:
m(9),m(6),m(71),m(1),m(3)
Out[14]:
((12,3,2,1),(8,2,1,1),(72,18,1,0),(4,1,2,1),(4,1,1,0))


The ASCII chip bonus isn't worth the bytes it costs, but since I made it, here's all 190 bytes of it. Edit: I made the chip drawing before OP posted an example chip , so I'm sticking with my method. I think it looks better than plus signs, anyway.

m(x)=begin s=iceil(x/4)
p=4s-x
g=iceil(p/2)
v=ifloor(p/2)
b={x in[1,s]||y in[1,s+1]?"o":"."for x=1:s,y=1:s+1}
if g>0 b[1,1:g]="G" end
if v>0 b[s,s+2-v:s+1]="V" end
print(b,'\n')
return 4s,s,g,v end

m(29)

G G o o o o o o o
o . . . . . . . o
o . . . . . . . o
o . . . . . . . o
o . . . . . . . o
o . . . . . . . o
o . . . . . . . o
o o o o o o o o V

Out[7]:
(32,8,2,1)


This version of the chip gets it down to 115, which is still too long for the bonus to be worthwhile. And it requires the "corners have two pins even though one is shown" assumption of OP's example. I prefer my corrected version above which shows the exact number of each type of pin.

m(x)=((s=iceil(x/4);p=4s-x);b={x in[1,s]||y in[1,s]?"o":"."for x=1:s,y=1:s};print(b);(4s,s,iceil(p/2),ifloor(p/2)))


Question posters of the future, take note: bonuses often serve only to increase the advantage of terse languages.

• m(x)=(s=iceil(x/4);p=4s-x;(4s,s,iceil(p/2),ifloor(p/2))) is shorter, since Julia returns the result of the last statement. – gggg Mar 17 '14 at 17:38
• p(m,n)=(a="+";b="\n";c=a^m*b;c*(a*" "^(m-2)*a*b)^n*c) returns the ops pattern in a string the OPs pattern in 46 characters after the =, might be able to work it in for a small bonus if you can find any more efficiency. – gggg Mar 17 '14 at 17:50
• @gggg The p(m,n) function also requires a print statement to display correctly, so in the end my array constructor was the cheaper approach once you take out the necessary steps for the G and V pins...but still too long to get the bonus. – Jonathan Van Matre Mar 18 '14 at 12:28

Perl, 72 bytes

The input number is expected in STDIN, the result is written to STDOUT.

$_=<>;$==$_/4+!!($_%4);$a=4*$=-$_;@a=(4*$=,$=,$a-($-=$a/2),$-);print"@a"  Test: echo 4 | perl a.pl 4 1 0 0 echo 5 | perl a.pl 8 2 2 1 echo 6 | perl a.pl 8 2 1 1 echo 7 | perl a.pl 8 2 1 0  Ungolfed: $_=<>; # read input number from STDIN
$= =$_ / 4 + !!($_ % 4); # tricky way for ceil($_ % 4)
$a = 4 *$= - $_; # extra pins in$a
@a = (4 * $=, # total$=,                 # each side
$a - ($- = $a / 2), # ground, tricky way for$a - floor($a/2)$-                  # voltage
);
print "@a"                # print result, separated by spaces

• a.pl == APL?? :) – TheDoctor Mar 16 '14 at 3:30

GolfScript, score 5 (55 characters - 50 bonus)

~:^3+3~&.4/:&1$^-.)2/\2/]p&)'+'*n+'+'&(' '*'+'++n+&(*1$


The input is given on STDIN. The first part (until ]p) does the calculation while the rest is for the bonus.

Examples (run online):

> 20
[20 5 0 0]
++++++
+    +
+    +
+    +
+    +
++++++

> 9
[12 3 2 1]
++++
+  +
+  +
++++


J - 71 66 char -50 = 16 pts

Saves a bunch of bytes with the 50 bonus, so let's do that.

(((>.,<.)@-:@-@],~-,[:#2:1!:2~' +'{~1,~1,1,.~1,.0$~2#2-~-%4:)_4&|)  Some key bits: • _4&| - Take the input modulo -4: it's just like taking it mod 4, but you go into the range (-4,0]. • (>.,<.)@-:@-@] - Negate the residue mod -4 from before, halve it (-:), and take the ceiling (>.) and the floor (<.). • 1,~1,1,.~1,.0$~2# - We make a square array of zeroes, and then pin ones all around it: in front (,.), behind (,.~), on top (,) and below (,~).
• [:#2:1!:2~' +'{~ - After constructing the square array the way we like it, we use its values to select ({) out of the characters ' ' and '+', and then we print the matrix with 2:1!:2~. Finally, we get the original number back (the number of pins per side) with the length.

Usage:

   (((>.,<.)@-:@-@],~-,[:#2:1!:2~' +'{~1,~1,1,.~1,.0$~2#2-~-%4:)_4&|) 20 +++++ + + + + + + +++++ 20 5 0 0 (((>.,<.)@-:@-@],~-,[:#2:1!:2~' +'{~1,~1,1,.~1,.0$~2#2-~-%4:)_4&|) 9
+++
+ +
+++
12 3 2 1


The version without the ASCII-drawing portion is 30 characters:

   (((>.,<.)@-:@-@],~-,-%4:)_4&|) 86
88 22 1 1

• +1 (>.,<.) bah, I knew a stack-based language would take this one away from Python. @-@ I like your way of generating the chip. – Kaya Mar 17 '14 at 4:47
• @Kaya J isn't stack-based, actually, it just has a very terse and high-level style. Though I imagine Golfscript would have a field day with this. – algorithmshark Mar 17 '14 at 7:24

Python (103):

from math import*
a=int(raw_input());c=ceil(a**.5);b=c**2;z=(b-a)/2;d=ceil(z);e=floor(z);print (b,c,d,e)


Not the shortest, but it does what it's supposed to.

• I initially interpreted the question this way too, see groveNL's comment on the question above: You may want to add clarification for a point that confused me at first: the pins are at the perimeter of the square, not throughout the square area. It seems the goal is to find the next multiple of four rather than the next perfect square. – Kaya Mar 16 '14 at 15:30

K - 68 char -50 = 18 pts

This solution mimics the J methods somewhat, but has an APL-like way of shaving off characters.

{0:(" +"1,|1,)'+r#,1 0,|~!r:-2+q:_(x-:m:x!-4)%4;x,q,-1 1*_.5 -.5*m}


Explained:

• x-:m:x!-4 - Take x mod -4, putting it into the range (-4,0]. Now, assign this to m (for modulus), and reassign x to x subtract m.

• r:-2+q:_(x)%4 - Divide x by 4 and floor it, converting it from unnecessary float to integer. Assign this to q, and assign two less than this to r.

• 1 0,|~!r - Take the integers less than r, starting from 0. Logical negate every integer, leaving a 1 in the 0 place and 0 everywhere else. Reverse the list, and then prepend 1 0. Now, the list will be r+2 = q items long, and the first and last are a 1.

• +r#, - Make r copies of this list, and transpose the resulting matrix, which is now r wide and q high.

• 0:(" +"1,|1,)' - Append 1 to the front and back of each row, and then use the placement of the 0s and 1s to select characters out of " +". This creates an ASCII chip, which we print out to console with 0:.

• _.5 -.5*m - Take m from before, halve it, and then floor it and its negation. K doesn't have a ceiling function, so you have to emulate ceiling by flooring the negative, and negating that again.

• x,q,-1 1* - Flip the sign on the negative number of the two, and then append x and q from before to the list. This then goes on to be the return value.

Usage:

  {0:(" +"1,|1,)'+r#,1 0,|~!r:-2+q:_(x-:m:x!-4)%4;x,q,-1 1*_.5 -.5*m} 20
+++++
+   +
+   +
+   +
+++++
20 5 0 0
{0:(" +"1,|1,)'+r#,1 0,|~!r:-2+q:_(x-:m:x!-4)%4;x,q,-1 1*_.5 -.5*m} 9
+++
+ +
+++
12 3 2 1


The version with no ASCII drawing is 34 characters:

  {x,_%[x-:m;4],-1 1*_.5 -.5*m:x!-4} 86
88 22 1 1
`