23
\$\begingroup\$

Generate me a QFP chip!

From the sandbox!

QFP is a type of form factor for an electrical component where pins come out the sides of a chip. Here are is a picture of a typical QFP component:
enter image description here

you can see that the general formula is to have 4 sides of equal numbers of pins.

Your challenge is to create a program that takes in an integer, thich represents the number of pins on one side, and creates an ASCII QFP component with numbered pins.

Input:

a single integer which represents the number of pins on one side

Output:

An ASCII QFP chip with an apropriate pinout.

Example:

input:1

  4
 ┌┴┐
1┤ ├3
 └┬┘
  2

input:2

  87
 ┌┴┴┐
1┤  ├6
2┤  ├5
 └┬┬┘
  34

input:12

   444444444333
   876543210987
  ┌┴┴┴┴┴┴┴┴┴┴┴┴┐
 1┤            ├36
 2┤            ├35
 3┤            ├34
 4┤            ├33
 5┤            ├32
 6┤            ├31
 7┤            ├30
 8┤            ├29
 9┤            ├28
10┤            ├27
11┤            ├26
12┤            ├25
  └┬┬┬┬┬┬┬┬┬┬┬┬┘
   111111122222
   345678901234

Rules:

  • all QFP chips must be enclosed and sealed as well as ascii provides. spacing is of utmost importance. Dust inside a microprocessor is bad stuff!
  • pin numbering must be done as in the examples (Read left to right, top to bottom, numbered counter clockwise)
  • You may start numbering at 0, but this must not affect the chip (an input of 12 still needs 12 pins per side)
  • The only valid characers in your output are 1,2,3,4,5,6,7,8,9,0,┌,┴,┐,├,┘,┬,└,┤, spaces, and newlines.
  • all encodings for languages are allowed, but your output MUST be consistent with the rules above.

This is a codegolf, and as such, The code with the least number of bytes wins! Good Luck!

\$\endgroup\$
  • 2
    \$\begingroup\$ Does zero need to be handled. \$\endgroup\$ – Magic Octopus Urn Dec 7 '16 at 22:11
  • 1
    \$\begingroup\$ No, you do not. \$\endgroup\$ – tuskiomi Dec 7 '16 at 23:24
  • \$\begingroup\$ Any upper limit on the input? \$\endgroup\$ – Arnauld Dec 8 '16 at 19:47
  • \$\begingroup\$ @Arnauld only limits should be overflows and language-based limits \$\endgroup\$ – tuskiomi Dec 8 '16 at 19:50
  • 1
    \$\begingroup\$ "all QFP chips must be enclosed and sealed as well as ascii provides." Half of the given characters aren't ASCII. \$\endgroup\$ – Jordan Dec 10 '16 at 14:49
3
\$\begingroup\$

Mathematica, 271 bytes

c=Table;d=StringPadLeft[#<>"\n",(b=IntegerLength[4a])+a+2]&/@(#)&;d@Reverse@#4<>{e=" "~c~b,"┌"<>"┴"~c~a,"┐
",({#,"┤"," "~c~a,"├",#2,"
"}&)~MapThread~{#,Reverse@#3},e,"└","┬"~c~a,"┘
",d@#2}&@@Partition[Characters@StringPadLeft[ToString/@Range[4#]],a=#]&

Anonymous function. Takes a number as input and returns a string as output. The non-box-drawing Unicode character is U+F3C7 (private use) for \[Transpose].

\$\endgroup\$
7
\$\begingroup\$

Kotlin, 397 393 bytes

Unnamed lambda.

You can try it here, but you'll have to paste the source in yourself because the editor doesn't seem to save programs in UTF-8 encoding. The ungolfed version is a full program, so you should be able to use that in its entirety.

Golfed

{n:Int->operator fun String.mod(x:Int){(1..x).map{print(this)}};val l={s:String->s.padStart(n/10+2)};var s=(1..n).map{"${n*4+1-it}".reversed()};val z={i:Int->l(" ")%1;s.map{print(it.getOrElse(i,{' '}))};"\n"%1};(s[0].length-1 downTo 0).map(z);l("┌")%1;"┴"%n;"┐\n"%1;(1..n).map{l("$it┤")%1;" "%n;"├${n*3+1-it}\n"%1};l("└")%1;"┬"%n;"┘\n"%1;s=(1..n).map{"${n+it}"};(0..s.last().length-1).map(z)}

(Sort of) Ungolfed

fun main(args: Array<String>) {
    var q = { n: Int ->
        operator fun String.mod(x: Int) {
            (1..x).map { print(this) }
        }

        val l = { s: String ->
            s.padStart(n / 10 + 2)
        }

        var s = (1..n).map { "${n * 4 + 1 - it}".reversed() }

        val z = { i: Int ->
            l(" ")%1
            s.map { print(it.getOrElse(i, { ' ' })) }
            "\n"%1
        }

        (s[0].length - 1 downTo 0).map(z)

        l("┌")%1
        "┴"%n
        "┐\n"%1

        (1..n).map { l("$it┤") % 1;" " % n;"├${n * 3 + 1 - it}\n" % 1 }

        l("└")%1
        "┬"%n
        "┘\n"%1

        s = (1..n).map { "${n + it}" }
        (0..s.last().length - 1).map(z)
    }

    q(30)
}

Saved a bunch of bytes by overloading the % operator and using it to print. I'll probably revisit this later - I think I can save quite a few bytes if I use mod or some other operator as a concatenation function. More interpolation and less print calls.

\$\endgroup\$
  • \$\begingroup\$ Sure, let me include a full program. \$\endgroup\$ – Tyler MacDonell Dec 8 '16 at 3:02
  • 1
    \$\begingroup\$ @tuskiomi You should be able to use the ungolfed version in its entirety now. \$\endgroup\$ – Tyler MacDonell Dec 8 '16 at 3:08
  • \$\begingroup\$ An excellent solution! \$\endgroup\$ – tuskiomi Dec 8 '16 at 15:34
3
\$\begingroup\$

Python 2, 352 343 331 bytes

def q(n,j=''.join,k='\n'.join,m=map):a,b,c,d=zip(*[iter(m(str,range(n*4)))]*n);l=len(`n-1`);r=lambda x:k(m(lambda s:' '*(l+1)+j(s),m(j,[m(lambda t:t or' ',v)for v in m(None,*x)])));return k([r(d[::-1]),' '*l+u'┌'+u'┴'*n+u'┐',k(x.rjust(l)+u'┤'+' '*n+u'├'+y for x,y in zip(a,c[::-1])),' '*l+u'└'+u'┬'*n+u'┘',r(b)])

Try it here. Note the file must start with the UTF-8 BOM \xef\xbb\xbf for the unicode literals to work in the standard CPython interpreter. These 3 bytes are counted against the size here. repl.it is already using unicode so the link just has the code shown here.

Thanks @tuskiomi for the encoding idea that saved 9 21 bytes.

Partially ungolfed:

def q(n):
  a,b,c,d = zip(*[iter(map(str,range(n*4)))]*n) # get numbers for sides
  l = len(`n-1`) # left padding
  r = lambda x: '\n'.join(
    map(lambda s: ' '*(l+1) + ''.join(s), # padding and row of digits
      map(''.join,
        [map(lambda t: t or ' ', v)  # rows of digits with spaces where missing
          for v in map(None, *x)]))
  )
  return '\n'.join([
    r(d[::-1]), # top row in reverse order
    ' '*l+u'\u250c'+u'\u2534'*n+u'\u2510', # top border
    # 1st, 3rd (reversed) side numbers
    '\n'.join(x.rjust(l) + u'\u2524'+ ' '*n + u'\u251c' + y for x,y in zip(a,c[::-1])),
     ' '*l+u'\u2514'+u'\u252c'*n+u'\u2518', # bottom border
    r(b) # bottom numbers
  ])
\$\endgroup\$
  • \$\begingroup\$ Consistent, and fast. Wonderful! \$\endgroup\$ – tuskiomi Dec 8 '16 at 16:15
  • \$\begingroup\$ strange. Online, this prints out perfectly. however on my computer's IDLE, it prints out literals instead of code points. Still a valid answer, but you may be able to golf it down further by using the actual characters instead of codepoints! \$\endgroup\$ – tuskiomi Dec 8 '16 at 19:55
  • \$\begingroup\$ I thought I would need # -*- coding: utf-8 -*- plus a newline to the top for the interpreter to accept it. The UTF-8 encoding of each of those characters is 3 bytes, so it wasn't enough to pay for the cost of the encoding directive. I just checked PEP 263 though and I can get away with just #coding=utf-8 and a newline so it will save some bytes. \$\endgroup\$ – Jake Cobb Dec 8 '16 at 20:17
  • 1
    \$\begingroup\$ The three-byte UTF-8 BOM apparently also works. \$\endgroup\$ – Jake Cobb Dec 8 '16 at 20:56
3
\$\begingroup\$

JavaScript (ES6), 295 284 bytes (268 chars), non-competing

n=>(a=[...(' '[r='repeat'](W=n+6)+`
`)[r](W++)],a.map((_,i)=>i<n*2&&([p,s,L,R,C]=i<n?[(i+3)*W-1,1,i+1,n*3-i,0]:[i-n+3-W,W,n*5-i,i+1,1],[...(' '+L).slice(-2)+'┤┴'[C]+' '[r](n)+'├┬'[C]+R].map(c=>a[p+=s]=c))),[2,3,W-4,W-3].map((p,i)=>a[W*p+2-6*(i&1)]='┌┐└┘'[i]),a.join``)

This code doesn't support pin numbers above 99 and therefore probably doesn't qualify as a fully valid entry. That's why I mark it as non-competing for now.

It could be easily modify to support an arbitrary large number of pins by using wider static margins around the chip. However, that may infringe the rules as well (not sure about that). Fully dynamic margins would cost significantly more bytes.

Demo

let f =

n=>(a=[...(' '[r='repeat'](W=n+6)+`
`)[r](W++)],a.map((_,i)=>i<n*2&&([p,s,L,R,C]=i<n?[(i+3)*W-1,1,i+1,n*3-i,0]:[i-n+3-W,W,n*5-i,i+1,1],[...(' '+L).slice(-2)+'┤┴'[C]+' '[r](n)+'├┬'[C]+R].map(c=>a[p+=s]=c))),[2,3,W-4,W-3].map((p,i)=>a[W*p+2-6*(i&1)]='┌┐└┘'[i]),a.join``)

console.log(f(2))
console.log(f(4))
console.log(f(12))

\$\endgroup\$
1
\$\begingroup\$

Java 11, 451 425 393 bytes

n->{int d=(n+"").length(),i,j=-1,l=(int)Math.log10(n*4);String p=" ".repeat(d),P=p+" ",r=P;for(;j++<l;r+="\n"+(j<l?P:p))for(i=n*4;i>n*3;)r+=(i--+"").charAt(j);r+="┌"+"┴".repeat(n)+"┐\n";for(i=0;i<n;r+="├"+(n*3-i+++1)+"\n")r+=p.substring((i+"").length())+i+"┤"+" ".repeat(n);r+=p+"└"+"┬".repeat(i)+"┘\n"+P;for(j=-1;j++<l;r+="\n"+P)for(i=n;i<n*2;)r+=(++i+"").charAt(j);return r;}

-26 bytes thanks to @ceilingcat.

Explanation:

Try it online.

n->{                      // Method with integer parameter and String return-type
  int d=(n+"").length(),  //  The amount of digits of the input
      i,j=-1,             //  Index integers
      l=(int)Math.log10(n*4);
                          //  Amount of digits of 4x the input, minus 1
  String p=" ".repeat(d), //  Padding String for the corners, set to `d` amount of spaces
         P=x+" ",         //  Padding String for the numbers, set to one additional space
         r=P;             //  Result-String, starting at `P` to pad the number
  for(;j++<l;             //  Loop `j` in the range (-1, l]:
      ;                   //    After every iteration:
       r+="\n"            //     Append a new-line, and padding spaces:
       +(j<l?P:p))        //      `p` if it's the last iteration; `P` otherwise
    for(i=n*4;i>n*3;      //   Inner loop `i` in the range [4n, 3n):
      r+=(i--+"")         //    Convert the current number to a String,
         .charAt(j));     //    and append the `j`'th digit to the result-String
  r+="┌"                  //  Append the top-left corner of the chip
     +"┴".repeat(n)       //  Append the top row of the chip
     +"┐\n";              //  Append the top-right corner of the chip, plus a new-line
  for(i=0;i<n             //  Loop `i` in the range [0, n):
      ;                   //    After every iteration:
       r+="├"             //     Append the right border of the chip
          +(n*3-i+++1)    //     Append the number
          +"\n")          //     And a trailing newline
    r+=p.substring((i+"").length())
                          //   Append padding spaces in front of the left number
       +i                 //   Append the current number
       +"┤"               //   Append the left border of the chip
       +" ".repeat(n);    //   Append the inner spaces
  r+=p                    //  Append padding spaces in front of the corner
     +"└"                 //  Append the bottom-left corner of the chip
     +"┬".repeat(i)       //  Append the bottom part of the chip
     +"┘\n"               //  Append the bottom-right corner of the chip, plus a new-line
     +P;                  //  Append padding spaces in front of the bottom number
  for(j=-1;j++<l;         //  Loop `j` in the range (-1, l]:
      ;                   //    After every iteration:
       r+="\n"            //     Append a new-line
          +P)             //     Append padding spaces for the number
    for(i=n;i<n*2;        //   Inner loop `i` in the range [n, 2n):
      r+=(++i+"")         //    Convert the current number to a String,
         .charAt(j));     //    and append the `j`'th digit to the result-String
  return r;}              //  Return the result-String
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.