134
\$\begingroup\$

... Not that you would, would you? The task is simple, output the following text:

 ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________ 
||` |||1 |||2 |||3 |||4 |||5 |||6 |||7 |||8 |||9 |||0 |||- |||= |||BS    ||
||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
 ________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ 
||TAB   |||Q |||W |||E |||R |||T |||Y |||U |||I |||O |||P |||[ |||] |||\ ||
||______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__||
|/______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|
 _________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________ 
||CAPS   |||A |||S |||D |||F |||G |||H |||J |||K |||L |||; |||' |||ENTER ||
||_______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
|/_______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
 ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________ 
||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT    ||
||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________||
|/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\|

This is the keyboard of the future because in the future spaces are irrelevant, so are spacebars.


To make things a little bit easier on you:

  1. 0123456789ABC...XYZ-=[]\;',./ - These chars are on keys of length 6 (including padding).
  2. TAB / BS / ENTER - These keys are of length 10 (including padding).
  3. CAPS - This key is of length 11 (including padding).
  4. SHIFT - This key is of length 13 (including padding, on both sides).

Each individual key looks more or less like this:

 ____ 
||* ||
||__||
|/__\|

However, you should make note that two consecutive keys are not:

 ____  ____ 
||* ||||* ||
||__||||__||
|/__\||/__\|

But they are "conjoined":

 ____ ____ 
||* |||* ||
||__|||__||
|/__\|/__\|

This challenge shouldn't be too bad, best of luck to you; don't miss out on abusing the repetition! But don't underestimate the "special" keys either ;).


Winning?

Shortest code wins because it's you know.

\$\endgroup\$
18
  • 52
    \$\begingroup\$ Gotta admit I'm surprised not many people are concerned about futuristic keyboards not containing spaces... \$\endgroup\$ Commented Dec 13, 2016 at 0:05
  • 105
    \$\begingroup\$ I guess spaces weren't the final frontier after all. \$\endgroup\$ Commented Dec 13, 2016 at 4:59
  • 56
    \$\begingroup\$ "TASTE" is the german word for "key" :) \$\endgroup\$
    – QBrute
    Commented Dec 13, 2016 at 8:59
  • 40
    \$\begingroup\$ "TASTE" is the Norwegian word for "typing" :) \$\endgroup\$ Commented Dec 13, 2016 at 14:13
  • 37
    \$\begingroup\$ But it's the English word for "flavour". Here. \$\endgroup\$
    – Mr Lister
    Commented Dec 13, 2016 at 14:15

32 Answers 32

126
+600
\$\begingroup\$

V, 189, 179, 175, 164, 161, 157, 155, 149, 145, 141, 135 bytes

¬19É`A0-=BS´ 
TAB³ qwertyuiop[]\
CAPS³ asdfghjkl;'ENTER 
SHIFT´ ÄJizxcvbnm,./Í„A-Z ]/Õ& 
ÍÓ«ü$/|||&
òÙÓ„|]/_
ÙÓ׫/Ü|¯
kkPÓ/_ _
kòÎx$x

Try it online!

This answer is now tweetable!


Watch it run! This is a slightly modified version that updates as it runs so you can sorta see how it works. This is an outdated version since I haven't gotten around to re-recording it yet, but the general approach is identical.

This is probably the longest V answer ever written. It certainly didn't help that V's interpreter is extremely slow. It took me around an hour to write the first revision, but I've been repeatedly coming back to it to shave a couple bytes off each time. Since the full keyboard is 1215 bytes, currently this answer is 91% shorter than the output, so I'm pretty happy with the results.

Since this contains some unprintable characters, and a lot of gross non-ASCII, here's a hexdump:

00000000: ac31 39c9 6041 302d 3d42 53b4 200a 5441  .19.`A0-=BS. .TA
00000010: 42b3 2071 7765 7274 7975 696f 705b 5d5c  B. qwertyuiop[]\
00000020: 0a43 4150 53b3 2061 7364 6667 686a 6b6c  .CAPS. asdfghjkl
00000030: 3b27 454e 5445 5220 0a53 4849 4654 b420  ;'ENTER .SHIFT. 
00000040: 1bc4 4a69 7a78 6376 626e 6d2c 2e2f 1bcd  ..Jizxcvbnm,./..
00000050: 8441 2d5a 205d 2fd5 2620 0acd d3ab fc24  .A-Z ]/.& .....$
00000060: 2f7c 7c7c 260a f2d9 d384 7c5d 2f5f 0ad9  /|||&.....|]/_..
00000070: d3d7 ab2f dc7c af0a 6b6b 50d3 2f5f 205f  .../.|..kkP./_ _
00000080: 0a6b f2ce 7824 78                        .k..x$x

How the heck does it work?

Alright, this explanation is gonna be a doozy. You ready? First off, we need enter the letters so we can build up the keys around them. This is

¬19É`A0-=BS´ 
TAB³ qwertyuiop[]\
CAPS³ asdfghjkl;'ENTER 
SHIFT´ <esc>ÄJizxcvbnm,./<esc>

Which inserts:

`1234567890-=BS    
TAB   qwertyuiop[]\
CAPS   asdfghjkl;'ENTER 
SHIFT    zxcvbnm,./SHIFT  

It enters it pretty straightforward, but there are a few tricks that we use to save characters. For example, ¬19 enters "123456789", ³ enters three spaces, and we duplicate the shift so that we don't need to enter it multiple times.

Note how the letters are lowercase here. This is so that we can easily distinguish between the uppercase keys like "ENTER" and the single letters. Writing them this way makes it easier to tell which characters to put a bar before, and only adds one byte to convert them to lowercase later. So we do a substitute command to convert these to uppercase, and add one space after each of them:

Í               " Globally replace
 [^A-Z ]        " Anything but a uppercase alphabet character or a space
        /       " with
         Õ&     " The matched pattern made uppercase, followed by a space

Now, we take each key sequence (any run of non-whitespace), and put three bars before and after them:

Í           " Globally replace
 Ó«         "   Any number of non-space characters
   ü        "   or
    $       "   an end of line
     /      " with
      |||   "    Three bars 
         &  "    And the matched pattern

At this point, the buffer looks like this:

|||` |||1 |||2 |||3 |||4 |||5 |||6 |||7 |||8 |||9 |||0 |||- |||= |||BS    |||
|||TAB   |||Q |||W |||E |||R |||T |||Y |||U |||I |||O |||P |||[ |||] |||\ |||
|||CAPS   |||A |||S |||D |||F |||G |||H |||J |||K |||L |||; |||' |||ENTER |||
|||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT    |||

Having three bars on the first and last columns is actually very convenient and ends up saving many bytes in the long run.

And here is where we run one giant loop. This will convert something like this:

|||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT    |||

into something like this:

 ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________ 
||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT    ||
||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________||
|/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\|

Everything between two instances of ò will run until an error happens, which will happen when we try to go up into a line that does exist yet. Since we just ran a globally substitute command, our cursor is on the last line, and we'll transform these working our way up.

ò         " Recursively:
 Ù        "   Duplicate this line
  Ó       "   Substitute all on this line:
   [^|]   "     Anything but a bar
       /  "   With:
        _ "     An underscore

This is the

|||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________|||

line.

Ù         "   Duplicate this line
 Ó        "   Subsitute all on this line:
  ׫      "     A run of *non-word characters* (that is, [^0-9A-Za-z_])
    /     "   With:
     Ü|¯  "     '\|/'

This is the

\|/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\|/

Line.

kk        "   Move up two lines (to the original text with "SHIFT")
  P       "   Paste the last line we duplicated (the one with all the underscores)
   Ó      "   Substitute:
          "     Since we don't give any regex here, it re-uses the last one 
          "     (a run of *non-word* characters)
    /     "   With:
     _ _  "     '_ _'

This is the:

_ ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________ _

Line.

k         "   Move up a line (this will throw an error, breaking the loop when we're done)
 ò        " Endwhile

Now we have the full keyboard, but each line contains either an extra bar, an extra slash (forward or backward), or an extra underscore. Super easy fix

Î             " On every line:
 x            "   Delete a character
  $           "   Move to the end of the line
   x          "   and delete another character

After all that madness, the buffer is implicitly printed.

\$\endgroup\$
9
  • 1
    \$\begingroup\$ There appear to be 4 extra underscores in the blank space off the right side of the output? \$\endgroup\$
    – ErikE
    Commented Dec 14, 2016 at 18:53
  • 7
    \$\begingroup\$ You underestimate how golfy this answer actually is lol. \$\endgroup\$ Commented Dec 16, 2016 at 17:56
  • 1
    \$\begingroup\$ @carusocomputing Haha, I guess you're right. I'm very proud of this answer and my language to be the only answer beating bubblegum. :) \$\endgroup\$
    – DJMcMayhem
    Commented Dec 16, 2016 at 17:59
  • 2
    \$\begingroup\$ @DJMcMayhem Marking you as the winner if nobody beats you by 1/3/2017 ;). \$\endgroup\$ Commented Dec 22, 2016 at 20:06
  • 7
    \$\begingroup\$ This is still by far my favorite answer on the site, by the way. I can't count how many times I've watched the GIF. \$\endgroup\$ Commented Apr 21, 2017 at 18:55
42
\$\begingroup\$

Lua 5.3, 416 394 Bytes.

k="` 1 2 3 4 5 6 7 8 9 0 - = BS|TAB Q W E R T Y U I O P [ ] \\|CAPS A S D F G H J K L ; ' ENTER|SHIFT Z X C V B N M , . / SHIFT"S={TAB=6,BS=6,ENTER=6,CAPS=7,SHIFT=9}for v in k:gmatch"[^|]+"do for i=1,4 do for s in v:gmatch"%S+"do l=S[s]or 2j=("_"):rep(l)io.write(i==1 and" _"..j.."_"or i==2 and"||"..s..(" "):rep(l-#s).."|"or i==3 and"||"..j.."|"or"|/"..j.."\\")end print(i>1 and"|"or"")end end

Ungolfed and with comments.

keys="` 1 2 3 4 5 6 7 8 9 0 - = BS|TAB Q W E R T Y U I O P [ ] \\|CAPS A S D F G H J K L ; ' ENTER|SHIFT Z X C V B N M , . / SHIFT" -- Define a keyboard. Separated with |'s, there's probably a nicer way to do this, but I'm not sure about how to yet.
special_keys={TAB=6,BS=6,ENTER=6,CAPS=7,SHIFT=9} -- Special keys get special definitions
for v in keys:gmatch"[^|]+" do -- For each row on the keyboard...
    for i=1, 4 do -- Each of the 4 rows per key...
        for s in v:gmatch"%S+" do -- Match each individual key.
            l=special_keys[s]or 2 j=("_"):rep(l) -- l is the length of the key, j is "_" repeated length times, which is used a bit.
            io.write(i==1 and -- Lua needs Switch Statements!
                     " _"..j.."_" -- The top of the key is a Space, then j with two _'s around it.
                     or
                     i==2 and
                     "||"..s..(" "):rep(l - #s).."|" -- Second row is || then the key, then the remaining whitespace, and then one more |, which chains together.
                     or
                     i==3 and
                     "||"..j.."|" -- Third row is like the second, but without the key. Instead of whitespace, uses j, which is the underlines.
                     or
                     "|/"..j.."\\") -- Last row is like the third row, but with "|/" and "\" instead of "||" and "|"
        end
        print(i>1 and"|"or"") -- First line is the only line that doresn't need a "|", everything else gets a "|" before the newline.

    end
end

Output

 ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________
||` |||1 |||2 |||3 |||4 |||5 |||6 |||7 |||8 |||9 |||0 |||- |||= |||BS    ||
||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
 ________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
||TAB   |||Q |||W |||E |||R |||T |||Y |||U |||I |||O |||P |||[ |||] |||\ ||
||______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__||
|/______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|
 _________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________
||CAPS   |||A |||S |||D |||F |||G |||H |||J |||K |||L |||; |||' |||ENTER ||
||_______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
|/_______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
 ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________
||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT    ||
||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________||
|/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\|

I'm going to get destroyed by other langauges, but I thought I'd give this a shot. Nice amount of complexity, and atleast it's shorter than the keyboard!

\$\endgroup\$
3
  • 15
    \$\begingroup\$ Screw other languages, you were the first in a rare language! Impressive, though I'm sure you definitely don't need to put pipes as delimiters on every letter. Notice how the "special" keys are only at the front and end of lines. I'm sure that hint could save you precious bytes somehow. \$\endgroup\$ Commented Dec 13, 2016 at 0:03
  • \$\begingroup\$ Which version of Lua are you using? On Lua 5.1 it gives me a syntax error: stdin:1: malformed number near '2j' \$\endgroup\$
    – brianush1
    Commented Dec 13, 2016 at 23:30
  • 5
    \$\begingroup\$ @Brianush1 Lua 5.3, It allows number constants to sit next to any letter that isn't a hexadecimal digit or 'x' in the case of 0. \$\endgroup\$
    – ATaco
    Commented Dec 14, 2016 at 0:06
29
\$\begingroup\$

Bubblegum, 191 bytes

0000000: ad d2 35 7a c6 30 10 06 e1 5e a7 50 15 66 fe 99  ..5z.0...^.P.f..
0000010: c1 8c 61 50 0e b2 87 8f 27 24 f7 eb af 78 2b e3  ..aP....'$...x+.
0000020: 3c b2 ae 99 1a 66 8d c8 a7 15 91 73 b8 80 4b b8  <....f.....s..K.
0000030: 82 6b b8 81 5b b8 83 1e 9c c1 31 8c 60 5e d9 66  .k..[.....1.`^.f
0000040: 22 46 c4 39 d1 c2 78 d6 a9 73 6f 5a d8 9b 18 ff  "F.9..x..soZ....
0000050: bb 5a e8 55 cf e6 fc ae 48 01 8f b0 82 12 6a 78  .Z.U....H.....jx
0000060: 86 7b 08 20 83 1c 5e e1 1d de e8 e5 7f 57 b4 d0  .{. ..^......W..
0000070: 8b a9 9b f9 5e 5d 9d af c5 2c af 7e 82 cd a0 82  ....^]...,.~....
0000080: 25 ac 61 03 5b 08 21 82 18 06 b0 0b ab b4 5e 95  %.a.[.!.......^.
0000090: ad 5e 5d 9d 2f d6 e9 f9 d2 c4 f2 bd aa 6d b0 ae  .^]./........m..
00000a0: ed 4f b1 17 78 82 05 3c c0 1c 52 48 e0 08 4e e0  .O..x..<..RH..N.
00000b0: 14 5a 77 fb 5e aa 58 be 97 aa 98 bf db 7c 01     .Zw.^.X......|.

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Bubblegum isn't fair. \$\endgroup\$
    – Joshua
    Commented Dec 15, 2016 at 4:09
  • 7
    \$\begingroup\$ @Joshua it's good to set a baseline for solutions. and if nothing can beat bubblegum, that's problem's problem. \$\endgroup\$ Commented Dec 15, 2016 at 13:32
21
\$\begingroup\$

Haskell, 263 chars (353 bytes UTF-8)

import Data.List
main=mapM_ putStrLn$transpose.foldr k[g]=<<
 [s"`1234567890-="%"   ←"
 ,"↹   ":s"𝑄𝑊𝐸𝑅𝑇𝑌𝑈𝐼𝑂𝑃[]\\"
 ,"⇩    ":s"𝐴𝑆𝐷𝐹𝐺𝐻𝐽𝐾𝐿;'"%"     ↵"
 ,"⇧       ":s"𝑍𝑋𝐶𝑉𝐵𝑁𝑀,./"%"       ⇧"]
r%e=r++[e]
g=" |||"
k s r=g:"_||/":['_':c:"__"|c<-s]%"_||\\"++r
s=map(:" ")

screenshot of that keyboard

As there has been a lot of discussion about the score in light of these unicode characters... here's the same program, reduced to all-ASCII:

Haskell, 263 chars (263 bytes UTF-8)

import Data.List
main=mapM_ putStrLn$transpose.foldr k[g]=<<
 [s"`1234567890-="%"BS  "
 ,"TAB ":s"QWERTYUIOP[]\\"
 ,"CAPS ":s"ASDFGHJKL;'"%"ENTER "
 ,"SHIFT   ":s"ZXCVBNM,./"%"SHIFT   "]
r%e=r++[e]
g=" |||"
k s r=g:"_||/":['_':c:"__"|c<-s]%"_||\\"++r
s=map(:" ")
\$\endgroup\$
6
  • 3
    \$\begingroup\$ Unicode keyboard? Interesting choice (nice looking math letters there), but I think it violates the competition rules. \$\endgroup\$ Commented Dec 14, 2016 at 7:58
  • \$\begingroup\$ @MarioCarneiro To be fair, it doesn't affect the length of the program at all. \$\endgroup\$
    – pydsigner
    Commented Dec 14, 2016 at 23:12
  • 1
    \$\begingroup\$ @pydsigner It does, since words like ENTER are longer than characters like ↩︎. \$\endgroup\$
    – Tuesday
    Commented Dec 15, 2016 at 9:48
  • 5
    \$\begingroup\$ But you're comparing ENTER and ↩︎ , The whitespace padding makes it the same length. \$\endgroup\$
    – CodeMonkey
    Commented Dec 15, 2016 at 14:52
  • 2
    \$\begingroup\$ Actually, I expect the unicode to make the program longer by byte count, since high unicode is more bytes in UTF8 than ASCII. \$\endgroup\$ Commented Dec 16, 2016 at 1:53
19
\$\begingroup\$

PHP, 303 bytes

Lazy but effective. :)

<?=gzinflate(base64_decode('rdO5DoJAEIDhnqegs/G+jbEAvA88wBuzPsg8vPyLZo3tOMUXmt1k/iy+ycfXYj88kacvIg1oQgva0IEu9KAPA6hDBUYQJn4+IvldxogWhrtqxmRamEw8t66afMc0CO26soczTOAAKVzhCAvYwg7u8IDs06tYVx3Oc+uqw7lef3lfUbBLimABJDCGKcxgDktYwRqGULJ143Ry+O71r/elDvb7vnSx3r2S+WKaFn+U3OACEZzs7wYxbKAMVajZvO6066WK9dNLFcuefgE'));
\$\endgroup\$
11
  • 1
    \$\begingroup\$ Nice. Annoyingly, I cannot get the same level of compression with compress/gzip/bzip2/7z, otherwise the Bash version would be trivially shorter. As it stands, it’s at 318 characters instead. \$\endgroup\$ Commented Dec 13, 2016 at 11:55
  • 14
    \$\begingroup\$ I'm pretty sure using an external compression algorithm not in your program is banned or at least frowned upon. It defeats the purpose of the question. \$\endgroup\$
    – Nobody
    Commented Dec 13, 2016 at 15:12
  • 1
    \$\begingroup\$ @KonradRudolph As I understand it, gzdeflate() uses the same compression as gzip command line but skips the file header and checksum so it will always be just a bit shorter. \$\endgroup\$ Commented Dec 13, 2016 at 15:21
  • \$\begingroup\$ 300 bytes: <?=gzinflate(base64_decode('rdO5DoJAEIDhnqegs/G+jbHA+0QEvDHrg8zDy79EMbTDFF+3m8yfXdek42phHJG3KyItaEMHutCDPgxgCCNoQg0mMI3cdETSu4wRLQx3NYxJtDCJOL9t1cnSFWNvareVE1xhASHEcIczbOAIATzhBck3V7atupuTb6vulucq43XNvCDKenkQwRyWsII1bGEHexhDxcb140X4n6us16XuVXxdulZZrmi9WcbZd5IH3GAGF/vXwIcDVKEODVs3P53nUrUq5FK1sqc/'));. Compressor: sandbox.onlinephpfunctions.com/code/… Decompressor: sandbox.onlinephpfunctions.com/code/… \$\endgroup\$ Commented Dec 14, 2016 at 10:21
  • 4
    \$\begingroup\$ @Nobody There's nothing external, gz is part of PHP's default compile and is therefore implicitly allowed. \$\endgroup\$ Commented Dec 14, 2016 at 19:14
19
\$\begingroup\$

Python 3.5+, 239 bytes

s="SHIFT   "
for k in[(*"`1234567890-=","BS   "),("TAB  ",*"QWERTYUIOP[]\\"),("CAPS  ",*"ASDFGHJKL;'","ENTER"),(s,*"ZXCVBNM,./",s)]:
 for f in"{1}__ ,|{} ||,|{1}||,/{1}\|".split(","):print(f[-1]+"".join(f.format(c,"_"*-~len(c))for c in k))
\$\endgroup\$
3
  • \$\begingroup\$ Is Python 3.5+ needed for the splat inside the tuples, or something else? \$\endgroup\$
    – mbomb007
    Commented Dec 13, 2016 at 15:07
  • 1
    \$\begingroup\$ You can save one byte if you invert the construction of each key and use "".join(...) + f[0] in the inner loop. Swapping the format argument order and the respective placeholders in the string also saves two more bytes. \$\endgroup\$
    – dfernan
    Commented Dec 13, 2016 at 22:17
  • \$\begingroup\$ ['{1}__ ','|{} ||','|{1}||','/{1}\\|'] is shorter than the use of split. \$\endgroup\$
    – Alex Hall
    Commented Dec 17, 2016 at 23:31
16
\$\begingroup\$

Batch, 465 452 bytes

@echo off
call:c _ ` 1 2 3 4 5 6 7 8 9 0 - "=" "BS   " _____
call:c _____ "TAB  " Q W E R T Y U I O P [ ] \ _
call:c ______ "CAPS  " A S D F G H J K L ";" ' ENTER _____
call:c ________ "SHIFT   " Z X C V B N M "," . / "SHIFT   " ________
exit/b
:c
set t=%1_
set s=!!%~2 !!!%3 !!
:l
set t=%t%#__
set s=%s%!%~4 !!
shift
if not "%~5"=="" goto l
set t=%t%#%4_
for %%l in (" _%t:#=_ _%_" "%s:!=|%" "||%t:#=|||%||" "|/%t:#=\|/%\|")do echo %%~l

The :c subroutine handles a line of keys. Keys containing extra spaces need to be quoted, as do the =, ;, , keys, possibly due to a bug in the shift command. The first and last parameters are strings of _s of the same length as the first and last key to aid concatenation. t then ends up as the _s common to the first, third and fourth rows, with #s marking the join, which are replaced appropriately before the leading and trailing characters are added, while s is the second row, but with |s changed to !s as they reduce the number of "s that I need. Edit: Saved 1 byte by printing all four lines in a single statement, and 12 bytes by optimising the way I assigned the s variable.

\$\endgroup\$
1
  • \$\begingroup\$ =, ; and , need to be quoted because they are in fact additional command-line argument delimiters. See stackoverflow.com/a/8145923/182705 \$\endgroup\$
    – Neil
    Commented Jan 30, 2021 at 11:37
14
\$\begingroup\$

Ruby, 226 bytes

16.times{|i|puts (([[?`,'TAB  ','CAPS  ',s='SHIFT   '][j=i/4]]+%w{1234567890-= QWERTYUIOP[] ASDFGHJKL;' ZXCVBNM,./}[j].chars+[['BS   ',?\\,'ENTER',s][j]]).map{|e|e.tr('^|'[-i%4/3,2],?_)}*3*"__ _ |||_|||_\\|/"[i%4*4,4])[72,75]}

Improvements as follows:

1.No empty string elements at the beginning and end of the array. Instead the array is triplicated making 3 side-by side keyboards. After conversion to string we have 3 keyboards with outer edges missing. This is truncated to only display the middle one, complete with edges.

2.Changed version of Ruby. Used Ideone instead of 1.9.3 installed on my machine. This means .chars.to_a can be shortened to just .chars.

Ruby, 239 bytes

There's a few more bytes to be golfed out of this. Will look tomorrow.

16.times{|i|puts ((['']+[[?`,'TAB  ','CAPS  ',s='SHIFT   '][j=i/4]]+%w{1234567890-= QWERTYUIOP[] ASDFGHJKL;' ZXCVBNM,./}[j].chars.to_a+[['BS   ',?\\,'ENTER',s][j]]+['']).map{|e|e.tr('^|'[-i%4/3,2],?_)}*"__ _ |||_|||_\\|/"[i%4*4,4])[2..-2]}

ungolfed

16.times{|i|                                                            #iterate throug 16 lines of output
  puts ((['']+[[?`,'TAB  ','CAPS  ',s='SHIFT   '][j=i/4]]+              #build row from blank element plus left special key
    %w{1234567890-= QWERTYUIOP[] ASDFGHJKL;' ZXCVBNM,./}[j].chars.to_a+ #plus regular keys
   [['BS   ',?\\,'ENTER',s][j]]+['']).map{|e|                           #plus right special key and another blank element
                                      e.tr('^|'[-i%4/3,2],?_)}*         #if i%4 != 1, replace the keytop legend with _ characters 
   "__ _ |||_|||_\\|/"[i%4*4,4])[2..-2]                                 #join the middle parts of the keys with ends. truncate spurious outer ends before printing.
}
\$\endgroup\$
13
\$\begingroup\$

C#, 357 bytes (when in one line, and incorporating most suggestions)


var s="";
foreach(var r in@"`|1|2|3|4|5|6|7|8|9|0|-|=|BS   ~TAB  |Q|W|E|R|T|Y|U|I|O|P|[|]|\~CAPS  |A|S|D|F|G|H|J|K|L|;|'|ENTER~SHIFT   |Z|X|C|V|B|N|M|,|.|/|SHIFT   ".Split('~'))
for(int i=0;i<4;s+=i>0?"|\n":"\n",i++)
foreach(var k in r.Split('|'))
{
var u=new string('_',k.Length+1);
s+=i<1?" "+u+"__"
:i<2
?"||"+k+" |"
:i<3
?"||"+u+"|"
:"|/"+u+@"\";
}
Console.Write(s);

Or, 353 with string interpolation and all other suggestions

var s="";foreach(var r in@"`|1|2|3|4|5|6|7|8|9|0|-|=|BS   ~TAB  |Q|W|E|R|T|Y|U|I|O|P|[|]|\~CAPS  |A|S|D|F|G|H|J|K|L|;|'|ENTER~SHIFT   |Z|X|C|V|B|N|M|,|.|/|SHIFT   ".Split('~'))for(int i=0;i<4;s+=i>0?"|\n":"\n",i++)foreach(var k in r.Split('|')){var u=new string('_',k.Length+1);s+=i<1?$" {u}__":i<2?$"||{k} |":i<3?$"||{u}|":$@"|/{u}\";}Console.Write(s);

Ungolfed (without string interpolation):

var solution = "";
foreach (var row in @"`|1|2|3|4|5|6|7|8|9|0|-|=|BS   ~TAB  |Q|W|E|R|T|Y|U|I|O|P|[|]|\~CAPS  |A|S|D|F|G|H|J|K|L|;|'|ENTER~SHIFT   |Z|X|C|V|B|N|M|,|.|/|SHIFT   ".Split('~'))
for (int i = 0; i < 4; solution += i > 0 ? "|\n" : "\n", i++)
foreach (var key in row.Split('|'))
{
   var underscores = new string('_', key.Length + 1);
   solution += i < 1 ? " " + underscores + "__"
                     : i < 2
                     ? "||" + key + " |"
                     : i < 3
                     ? "||" + underscores + "|"
                     : "|/" + underscores + @"\";
}
Console.Write(solution);
\$\endgroup\$
6
  • 5
    \$\begingroup\$ You can save lots of bytes formatting the golfed code as one line: foreach(var r in q){for(int i=0;i<4;i++){foreach... \$\endgroup\$
    – Mario
    Commented Dec 13, 2016 at 8:19
  • 1
    \$\begingroup\$ @Mario I just byte checked it, the given value is actually the count without newlines, so it technically has already been done \$\endgroup\$ Commented Dec 13, 2016 at 13:21
  • 1
    \$\begingroup\$ Slight golf down to 397 bytes using interpolation and replacing == with < s+=i<1?$" {u}__":i<2?$"||{k.PadRight(l)}|":i<3?$"||{u}|":$"|/{u}\\"; \$\endgroup\$ Commented Dec 13, 2016 at 13:38
  • \$\begingroup\$ Thanks @Alfie Goodacre. I replaced '==' with '<' as per your suggestion. I left interpolation out so to make it less version specific. \$\endgroup\$
    – Klinger
    Commented Dec 13, 2016 at 15:18
  • \$\begingroup\$ @Klinger I agree, the interpolation doesn't work on any online compilers either so that is a good choice! \$\endgroup\$ Commented Dec 13, 2016 at 15:19
10
\$\begingroup\$

PowerShell v2+, 465 bytes

($b=($a=' ____')*10)+$a*3+" "+($d='_'*8)
"||``@$(1..9-join'@')@0@-@=@BS    ||
||$(($f=,'__'*10-join'#'))#__#__#__#$(($g='_'*6))||
$(($c=($e='|/__\')*10))$e$e$e|/$g\|
 $d$b$a$a$a
||TAB  @Q@W@E@R@T@Y@U@I@O@P@[@]@\ ||
||$g#$f#__#__#__||
|/$g\$c$e$e$e|
 _$d$b$a $d
||CAPS  @A@S@D@F@G@H@J@K@L@;@'@ENTER ||
||_$g#$f#__#$g||
|/_$g\$c$e|/$g\|
 ___$d$b ___$d
||SHIFT   @Z@X@C@V@B@N@M@,@.@/@SHIFT    ||
||___$g#$f#___$g||
|/___$g\$c|/___$g\|"-replace'@',' #'-replace'#','|||'

I'm halfway embarrassed to be posting this answer, given how short the PHP and Python answers are, nevermind the C# answer, but I'm unable to get this method shorter. Other approaches may yield better results.

It's basically just a giant multi-line string, with variables ($a and the like) substituting for various substrings, and a couple -replaces at the end to finish it out. Script blocks $(...) are inserted where necessary to introduce new variables.

Try it online!

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

Python, 493 458 Bytes.

k=[['|']*75 for i in [0]*16]
v=' '
w='_'
y=0
def a(s,x,o):k[y+o][x:x+len(s)]=list(s)
def p(s,i,x):a(s+v*(i-len(s)),x+2,1);a(v+w*(i+2)+v,x,0);a(w*i,x+2,2);a(w*i,x+2,3);a('/',x+1,3);a('\\',x+i+2,3);return x+i+3
def q(s,x):return reduce(lambda a,b:p(b,2,a),list(s),x)
p('BS',6,q('`1234567890-=',0))
y=4
q('QWERTYUIOP[]\\',p('TAB',6,0))
y=8
p('ENTER',6,q('ASDFGHJKL;\'',p('CAPS',7,0)))
y=12
p('SHIFT',9,q('ZXCVBNM,./',p('SHIFT',9,0)))
for l in k:print''.join(l)

Functionally equivalent but somewhat more readable:

k=[['|']*75 for i in range(16)]
def a(s,x,y):k[y][x:x+len(s)]=list(s)
def p(s,i,x,y):
    a(s+' '*(i-len(s)),x+2,y+1)
    a(' '+'_'*(i+2)+' ',x,y)
    a('_'*i,x+2,y+2)
    a('_'*i,x+2,y+3)
    k[y+3][x+1]='/'
    k[y+3][x+i+2]='\\'
    return x+i+3
def q(s,x,y):return reduce(lambda a,b:p(b,2,a,y),list(s),x)
p('BS',6,q('`1234567890-=',0,0),0)
q('QWERTYUIOP[]\\',p('TAB',6,0,4),4)
p('ENTER',6,q('ASDFGHJKL;\'',p('CAPS',7,0,8),8),8)
p('SHIFT',9,q('ZXCVBNM,./',p('SHIFT',9,0,12),12),12)
for l in k:print ''.join(l)

Unfortunately it's already longer than the answer provided in Lua.

\$\endgroup\$
9
  • \$\begingroup\$ You can put the lines in the p function on one line separated by semicolons. Also, I thought that you can't make the first line k=[['|']*75]*16, do you know why? \$\endgroup\$
    – nedla2004
    Commented Dec 13, 2016 at 1:30
  • \$\begingroup\$ You can also define '_' and ' ' to a variable to save some bytes. \$\endgroup\$
    – nedla2004
    Commented Dec 13, 2016 at 1:34
  • \$\begingroup\$ Thanks for the tips! I think k=[['|']*75]*16 creates sixteen references to the same array so a change in one line affects the others as well. \$\endgroup\$
    – Cobi
    Commented Dec 13, 2016 at 1:35
  • \$\begingroup\$ Okay, then you can at least change range(16) to [0]*16. \$\endgroup\$
    – nedla2004
    Commented Dec 13, 2016 at 1:49
  • \$\begingroup\$ A small issue is that your code does not technically produce the right output, but you can fix that by changing for l in k:print ' '.join(l) to for l in k:print''.join(l). \$\endgroup\$
    – nedla2004
    Commented Dec 13, 2016 at 1:51
7
\$\begingroup\$

PHP, 316 312 bytes

foreach([($s=str_split)("`1234567890-=")+[13=>"BS   "],["TAB  "]+$s("_QWERTYUIOP[]\\"),["CAPS  "]+$s("_ASDFGHJKL;'")+[12=>ENTER],[$h="SHIFT   "]+$s("_ZXCVBNM,./")+[11=>$h]]as$r)for($y=-1;$y++<3;)foreach($r as$i=>$k)echo["\n".$a="| "[!$y]][$i],"_||/"[$y],str_pad($y-1?_:$k,strlen($k)+1,$y-1?_:" "),"_||\\"[$y],$a;

I´m pretty sure that this approach cannot be golfed any further. But if anyone finds 10 more bytes ... :D
Run with -r.

breakdown

foreach([                       // loop through rows
    ($s=str_split)("`1234567890-=")+[13=>"BS   "],
    ["TAB  "]+$s("_QWERTYUIOP[]\\"),
    ["CAPS  "]+$s("_ASDFGHJKL;'")+[12=>ENTER],
    [$h="SHIFT   "]+$s("_ZXCVBNM,./")+[11=>$h]
]as$r)
    for($y=-1;$y++<3;)          // loop through lines 0..3
        foreach($r as$i=>$k)    // loop through keys
            echo["\n".$a="| "[!$y]][$i],// first key in row: leading NL + space/pipe
                "_||/"[$y],             // key edges
                str_pad(
                    $y-1?_:$k,          // line 1: key label; else underscore
                    strlen($k)+1,       // pad to length+1
                    $y-1?_:" "),        // with spaces for label, underscores else
                "_||\\"[$y],            // more key edges
                $a                      // joining edges
            ;
\$\endgroup\$
7
\$\begingroup\$

JavaScript (ES6), 286

An anonymous function with no parameters

_=>[..."`1234567890-=~~QWERTYUIOP[]\\~ASDFGHJKL;'~~ZXCVBNM,./~"].map(x=>(o+=`/${b='_'.repeat(w=x<y?2:' 667699'[x=["BS","TAB","CAPS","ENTER"][p++]||'SHIFT',p])}\\|`,m+=y+(x+'    ').slice(0,w)+y+y,n+=y+b+y+y,l+=' __'+b)[73]&&(k.push(l,m,n,o),l='',m=n=o=y),m=n=o=y='|',p=l=k=[])&&k.join`
`

Less golfed

_=>[..."`1234567890-=~~QWERTYUIOP[]\\~ASDFGHJKL;'~~ZXCVBNM,./~"]
  .map(x=>
      (
        w = x < y // special chars are marked '~' that is > '|'
            ? 2 // normal key, width 2
            : ( // else special key, set x and width
                // p should be incremented at next step, but I need to make it numeric as it starts as []
                x = ["BS","TAB","CAPS","ENTER"][p++]||'SHIFT',
                ' 667699'[p], // value for w (note p is off by 1)
              ),
        b = '_'.repeat(w), // bottom border (and top, almost)
        o +=`/${b}\\|`, //  line 4
        n += y+b+y+y,   //  line 3
        m += y+(x+'    ').slice(0,w)+y+y, // line 2
        l += ' __'+b    // top line, the border must be longer
      )[70] && // check if at end of row (check position in l)
         (
            k.push(l, m, n, o), // add lines to list
            l = '', // reset all
            m = n = o = y
         )
    , // initial setup
    // y stays fixed to '|', lines 2,3,4 start as '|'
    m = n = o = y ='|',
    // k is the lines array, l will become as string and starts empty
    // p is the index of current special key and will become numeric
    p = l = k = [] 
  ) 
  && k.join`\n` // return lines as a single string

F=_=>[..."`1234567890-=~~QWERTYUIOP[]\\~ASDFGHJKL;'~~ZXCVBNM,./~"].map(x=>(o+=`/${b='_'.repeat(w=x<y?2:' 667699'[x=["BS","TAB","CAPS","ENTER"][p++]||'SHIFT',p])}\\|`,m+=y+(x+'    ').slice(0,w)+y+y,n+=y+b+y+y,l+=' __'+b)[73]&&(k.push(l,m,n,o),l='',m=n=o=y),m=n=o=y='|',p=l=k=[])&&k.join`
`

O.textContent=F()
<pre id=O></pre>

\$\endgroup\$
6
\$\begingroup\$

Bash (on OSX), 12 8 + 221 + 1 = 234 230 bytes

Yeah, I know, compression. But it works, no?

gunzip<f

Requires a file called "f" in the current directory with the following contents (put into base64 for PPCG-friendliness - you can decode this into the file "f" first.):

H4sIAHbPT1gAA63TuQ6CQBCA4Z6noLPxvo2xALwPPMAbsz7IPLz8i2aN7TjFFxo2mT+7vsnH12I/PJGnLyINaEIL2tCBLvSgDwOoQwVGECZ+PiL5WcaIFoazasZkWphMPLeumnzHNAjturKHM0zgAClc4QgL2MIO7vCA7NOrWFcdznPrqsO5Xn+5X1GwS4pgASQwhinMYA5LWMEahlCydeN0cvju9a/7pQ72e790sd69kvlimhYvSm5wgQhO9rlBDBsoQxVqNq/72/VSxfrppYpV9HoBoNfjQcAEAAA=
\$\endgroup\$
12
  • 4
    \$\begingroup\$ Can be made trivially shorter by writing gunzip<f. \$\endgroup\$ Commented Dec 13, 2016 at 12:00
  • \$\begingroup\$ @KonradRudolph Excellent point. Thanks. \$\endgroup\$ Commented Dec 13, 2016 at 15:20
  • \$\begingroup\$ You can save 2 bytes with zcat f, and 2 bytes by removing the two trailing null bytes (gzip complains but produces the desired output). \$\endgroup\$ Commented Dec 14, 2016 at 11:18
  • \$\begingroup\$ @Gilles Doesn't really save me bytes - I'd have to rename the file "f.Z" (on OSX at least). Removing the trailing null bytes not only makes gzip complain - it makes it error out and not print anything. \$\endgroup\$ Commented Dec 14, 2016 at 12:15
  • \$\begingroup\$ @VoteToClose Oh right, zcat<f then. On Linux, zcat without the trailing zeroes makes gzip complain (“gzip: stdin: unexpected end of file”) but only after printing the desired output. \$\endgroup\$ Commented Dec 14, 2016 at 12:57
5
\$\begingroup\$

SOGL V0.12, 131 128 127 bytes (competing?)

⅟]y‘9Δø∑"`ŗ0-=”čΚ"TAB  ”QWERTYUIOP[]\”č+"oF«▒Β²‘⁷Ο‘ASDFGHJKL;'”čΚ+"_№K³‘ZXCVBNM,./”č⁴++¹{"^쳑č;{U;"_||/”┼;{"_ŗ__”┼}"Ο  ψ¦℮³‘┼}O

SOGL does have the 2*2/ and 2/2* quirks, but those feel too much like a built-in for this challenge.
Try it Here!

...‘               push "BS   "                                            ["BS   "]
    9Δ             push an array of numbers up to 9                        ["BS   ", [1,2,3,4,5,6,7,8,9]]
      ø∑           join into a single string (without ø it results to 45)  ["BS   ", "123456789"]
        "`ŗ0-=”    push "`ŗ0-=" with ŗ replaced with the digits            ["BS   ", "`1234567890-="]
               č   chop that into an array of characters                   ["BS   ", ["`","1","2","3","4","5","6","7","8","9","0","-","="]]
                Κ  add the first "BS   " to the end of the array           [["BS   ","`","1","2","3","4","5","6","7","8","9","0","-","="]]

"TAB  ”            push "TAB  "                  [[..], "TAB  "]
       Q..P[]\”    push "QWERTYUIOP[]\"          [[..], "TAB  ", "QWERTYUIOP[]\"]
               č   chop that                     [[..], "TAB  ", ["Q","W","E","R","T","Y","U","I","O","P","[","]","\"]]
                +  prepend to the array "TAB  "  [[..], ["TAB  ","Q","W","E","R","T","Y","U","I","O","P","[","]","\"]]

"...‘             push "caps  "                       [.. , "caps  "]
     ⁷Ο‘          push "enter"                        [.. , "caps  ", "enter"]
        AL;'”     push "ASDFGHJKL;'"                  [.. , "caps  ", "enter", "ASDFGHJKL;'"]
             č    chop that                           [.. , "caps  ", "enter", ["A","S","D","F","G","H","J","K","L",";","'"]]
              Κ   append "enter" to the end of array  [.. , "caps  ", ["A","S","D","F","G","H","J","K","L",";","'","enter"]]
               +  prepend "caps  " to the array       [.. , ["caps  ","A","S","D","F","G","H","J","K","L",";","'","enter"]]

"..‘             push "shift   "                [..., "shift   "]
    ZM,./”       push "ZXCVBNM,./"              [..., "shift   ", "ZXCVBNM,./"]
          č      chop it                        [..., "shift   ", ["Z","X","C","V","B","N","M",",",".","/"]]
           ⁴     duplicate the shift            [..., "shift   ", ["Z","X","C","V","B","N","M",",",".","/"], "shift   "]
            ++   append and prepend the shifts  [..., ["shift   ","Z","X","C","V","B","N","M",",",".","/","shift   "]]
              ¹  get all the arrays into one big array
result: [[["BS   ","`","1","2","3","4","5","6","7","8","9","0","-","="], ["TAB  ","Q","W","E","R","T","Y","U","I","O","P","[","]","\"], ["caps  ","A","S","D","F","G","H","J","K","L",";","'","enter"], ["shift   ","Z","X","C","V","B","N","M",",",".","/","shift   "]]]
 - a 2D array of the keyboard characters

{                                    for each array in the array do
 "...‘                                 push " |||"
      č                                chop to chars
       ;                               get the main array ontop
        {                        }     for each string in the array
         U                               uppercase it (before lowercase was used for better compression)
          ;                              get the chopped array ontop
           "_||/”                        push "_||/"
                 ┼                       append vertically
                  ;                      get the string ontop
                   {       }             for each char in the string do
                    "_ŗ__”                 push "_ŗ__"
                          ┼                append vertically
                            "..‘         push "    _||\ |||"
                                ┼        append vertically-then horizontally
                                  O    output that in a newline
\$\endgroup\$
5
  • \$\begingroup\$ Wow, this is super impressive! No one's managed to beat me on this one yet, so good job! I might try to get mine just a little shorter, but no promises. ;) \$\endgroup\$
    – DJMcMayhem
    Commented Jun 19, 2017 at 17:07
  • \$\begingroup\$ @dzamia even though it's competing now, I accepted the answer back when this wasn't. Should I switch answers? \$\endgroup\$ Commented Mar 28, 2018 at 16:32
  • \$\begingroup\$ @MagicOctopusUrn IMO it's up to you. There's a reason it's suggested to not accept answers :p \$\endgroup\$
    – dzaima
    Commented Mar 28, 2018 at 18:19
  • \$\begingroup\$ It's suggested to not accept answers? Oh... fair enough. Then I guess I'll stop accepting answers in the future and leave stuff as-is. \$\endgroup\$ Commented Mar 28, 2018 at 19:17
  • \$\begingroup\$ @MagicOctopusUrn okay, maybe not accepting answers is a bit controversial, but still, a major positive \$\endgroup\$
    – dzaima
    Commented Mar 28, 2018 at 19:22
5
\$\begingroup\$

Swift, 777 Bytes

func b(_ c:String,_ d:Int,_ e:Int)->[String]{var f=Array(" __ |||||||||/\\|".characters),g=[String]()
for h in 0..<4{var i="";for j in e..<4{i.append(f[j+h*4])
if j==1{var k="_",l=0;if h==1{k=" ";l=c.characters.count;i += c}
for _ in l..<d{i+=k}}};g.append(i)};return g}
func c(_ d:String)->[(String,Int)]{return Array(d.characters).map{("\($0)",2)}}
func d(_ e:String,_ f:Int)->[(String,Int)]{return [(e,f)]}
var e=[c("`1234567890-=")+d("BS",6),d("TAB",6)+c("QWERTYUIOP[]\\")]
e+=[d("CAPS",7)+c("ASDFGHJKL;'")+d("ENTER",6),d("SHIFT",9)+c("ZXCVBNM,./")+d("SHIFT",9)]
var f="";for g in 0..<e.count{let h=e[g]
var i=[[String]]();for j in 0..<h.count{
let k=h[j],l=b(k.0,k.1,(j>0 ? 1:0));i.append(l)}
for k in 0..<4{if g>0||k>0{f+="\n"}
for l in i{f+=l[k]}}};print(f,separator:"")

Swift is generally not a great language of choice for golfing, so being less than double the current smallest answer (that was fast) is a good challenge here!

Ungolfed:

func createKeyboard() {
    func createKey(_ text: String, _ middleWidth: Int, _ startingColumn: Int) -> [String] {
        var keyTempalte = " __ |||||||||/\\|"
        var keyTemplateCharacters = Array(keyTempalte.characters)

        var output = [String]()

        for y in 0 ..< 4 {
            var line = ""
            for x in startingColumn ..< 4 {
                line.append(keyTemplateCharacters[x + y*4])

                if x == 1 {
                    var spacingCharacter = "_"
                    var startingOffset = 0
                    if y == 1 {
                        spacingCharacter = " "
                        startingOffset = text.characters.count
                        line += text
                    }

                    for _ in startingOffset ..< middleWidth {
                        line += spacingCharacter
                    }
                }
            }
            output.append(line)
        }

        return output
    }

    func stringToCharacterStrings(_ str: String) -> [(String, Int)] {
        return Array(str.characters).map {("\($0)",2)}
    }

    func specialKey(_ str: String, _ middleWidth: Int) -> [(String, Int)] {
        return [(str, middleWidth)]
    }

    var keys = [stringToCharacterStrings("`1234567890-=") + specialKey("BS", 6),
                specialKey("TAB", 6) + stringToCharacterStrings("QWERTYUIOP[]\\")]
    keys += [specialKey("CAPS", 7) + stringToCharacterStrings("ASDFGHJKL;'") + specialKey("ENTER", 6),
                specialKey("SHIFT", 9) + stringToCharacterStrings("ZXCVBNM,./") + specialKey("SHIFT", 9)]

    var output = ""
    for r in 0 ..< keys.count {
        let row = keys[r]
        var rowKeys = [[String]]()
        for i in 0 ..< row.count {
            let elem = row[i]
            let key = createKey(elem.0, elem.1, (i>0 ? 1 : 0))
            rowKeys.append(key)
        }

        for y in 0 ..< 4 {
            if r > 0 || y > 0 {
                output += "\n"
            }

            for key in rowKeys {
                output += key[y]
            }
        }
    }

    print(output)
}

createKeyboard()
\$\endgroup\$
2
  • 2
    \$\begingroup\$ at least it's not applescript \$\endgroup\$ Commented Dec 13, 2016 at 10:30
  • 1
    \$\begingroup\$ Now I've got to do Java don't I \$\endgroup\$
    – CAD97
    Commented Dec 13, 2016 at 15:07
4
\$\begingroup\$

Python 2, 394 388 380 bytes

k=[4]*13+[8],[8]+[4]*13,[9]+[4]*11+[8],[11]+[4]*10+[11];m='`1234567890-=*','*QWERTYUIOP[]*',"*ASDFGHJKL;'*",'*ZXCVBNM,./*';c,d,e,n,u=0,'','|','\n','_'
for a in 0,1,2,3:
 f=s=t=o='';x=0
 for y in k[a]:g=y-2;f+=' '+u*y;s+=e*2+m[a][x].replace('*','%s')+' |';t+=e*2+u*g+e;o+='|/'+u*g+'\\';x+=1
 d+=f+n+s+e+n+t+e+n+o+e+n
l='SHIFT   ';print d%('BS   ','TAB  ','\\','CAPS  ','ENTER',l,l)

Just builds a big string representing the whole keyboard, replaces * with %s for the special keys then uses string formatting to update the specials.

Edit

Now has a trailing newline at the end of the output but I don't see anywhere that's not allowed.

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ I think you should remove the output , as it does not add anything relevant. \$\endgroup\$
    – sergiol
    Commented Jun 21, 2017 at 15:13
  • 1
    \$\begingroup\$ @sergiol - good point. Wasn't aware to TIO at the time of posting. Now updated. \$\endgroup\$
    – ElPedro
    Commented Jun 21, 2017 at 15:20
3
\$\begingroup\$

C#, 376 bytes (when in one line)


var s="";foreach(var r in@"`|1|2|3|4|5|6|7|8|9|0|-|=|BS   ~TAB  |Q|W|E|R|T|Y|U|I|O|P|[|]|\~CAPS  |A|S|D|F|G|H|J|K|L|;|'|ENTER~SHIFT   |Z|X|C|V|B|N|M|,|.|/|SHIFT   ".Split('~'))for(int i=0,l;i<4;i++){foreach(var k in r.Split('|')){l=k.Length+1;var u=new string('_',l);s+=i<1?" "+u+"__":i<2?"||"+k.PadRight(l)+"|":i<3?"||"+u+"|":"|/"+u+@"\";}s+=i>0?"|\n":"\n";}Console.Write(s);

This is based entirely on Klinger's C# answer. I don't have enough rep to comment on his answer, otherwise I would.

I was able to slim down Klinger's code by 5 bytes, by modifying the initial foreach loop, and removing extraneous brackets.

var s="";
foreach(var r in@"`|1|2|3|4|5|6|7|8|9|0|-|=|BS   ~TAB  |Q|W|E|R|T|Y|U|I|O|P|[|]|\~CAPS  |A|S|D|F|G|H|J|K|L|;|'|ENTER~SHIFT   |Z|X|C|V|B|N|M|,|.|/|SHIFT   ".Split('~'))
for(int i=0,l;i<4;i++)
{
foreach(var k in r.Split('|'))
{
l=k.Length+1;
var u=new string('_',l);
s+=i<1?" "+u+"__"
:i<2
?"||"+k.PadRight(l)+"|"
:i<3
?"||"+u+"|"
:"|/"+u+@"\";
}
s+=i>0?"|\n":"\n";
}
Console.Write(s);
\$\endgroup\$
5
  • \$\begingroup\$ Good one @Bence Joful. With your suggestion I would be able to get it to 367. I have not incorporated to the current answer. \$\endgroup\$
    – Klinger
    Commented Dec 14, 2016 at 2:43
  • \$\begingroup\$ Could not resist. Your suggestion + some additional minor changes brings it to 361 (or 358 with string interpolation). \$\endgroup\$
    – Klinger
    Commented Dec 14, 2016 at 3:49
  • \$\begingroup\$ @Klinger - please do use my tweaks! I was inspired to play around with it based on your work. I learned something about initialization in the process. \$\endgroup\$ Commented Dec 14, 2016 at 7:08
  • \$\begingroup\$ Could you include the one line program? You won't exactly lose much readability over the current one \$\endgroup\$
    – Cyoce
    Commented Dec 14, 2016 at 23:50
  • \$\begingroup\$ @Cyoce, you got it, thanks for the suggestion. Though at this point, Klinger has already posted a new, smaller version incorporating these changes. \$\endgroup\$ Commented Dec 15, 2016 at 1:33
3
\$\begingroup\$

m4, 456

changequote({,})define(d,{define($@)})d(p,{patsubst($@)})d(a,{{_}p({$1},.,_)_ })d(b,{|$1||})d(c,{|p({$1},.,_)||})d(e,{/p({$1},.,_)\|})d(f,{ifelse(len({$2}),0,,{indir({$1},{$2})f({$1},shift(shift($@)))})})d(g,{ f({a},$@)
|f({b},$@)
|f({c},$@)
|f({e},$@)
})g(` ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,0 ,- ,= ,BS    )g(TAB   ,Q ,W ,E ,R ,T ,Y ,U ,I ,O ,P ,[ ,] ,\ )g(CAPS   ,A ,S ,D ,F ,G ,H ,J ,K ,L ,; ,' ,ENTER )g(SHIFT    ,Z ,X ,C ,V ,B ,N ,M ,{,} ,. ,/ ,SHIFT    )

Ungolfed:

changequote({,})dnl
define(key1, {{_}patsubst({$1}, ., _)_ })dnl _______ 
define(key2, {|$1||})dnl                     |TAB  ||
define(key3, {|patsubst({$1}, ., _)||})dnl   |_____||
define(key4, {/patsubst({$1}, ., _)\|})dnl   /_____\|
define(rkey, {dnl
ifelse(dnl
len({$2}), 0, ,dnl terminate on empty argument
{dnl
indir({$1}, {$2})dnl
rkey({$1}, shift(shift($@)))dnl
}dnl
)dnl
})dnl
define(row, {dnl
 rkey({key1}, $@)
|rkey({key2}, $@)
|rkey({key3}, $@)
|rkey({key4}, $@)dnl
})dnl
row(` ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,0 ,- ,= ,BS    )
row(TAB   ,Q ,W ,E ,R ,T ,Y ,U ,I ,O ,P ,[ ,] ,\ )
row(CAPS   ,A ,S ,D ,F ,G ,H ,J ,K ,L ,; ,' ,ENTER )
row(SHIFT    ,Z ,X ,C ,V ,B ,N ,M ,{,} ,. ,/ ,SHIFT    )

(This is actually the first time I'm both code-golfing and giving m4 a try.)

\$\endgroup\$
1
  • \$\begingroup\$ Not bad for a first answer. Welcome to the site! :) \$\endgroup\$
    – DJMcMayhem
    Commented Dec 18, 2016 at 18:18
3
\$\begingroup\$

stacked, 228 bytes

Try it here!

[,{a:a size@n(' __' '_'n 1+:@k*LF'||'a' ' '|'LF'||' '_'k*:@o'|'LF'|/'o'\')sum}"!$hcat#/!' |||'hcat out]@:p$chars@:c'`1234567890-='c'BS   'p'TAB  ' 'QWERTYUIOP[]\'c p'CAPS  ' 'ASDFGHJKL;'''c,'ENTER'p'SHIFT   ':@q'ZXCVBNM,./'c,q p

Or, slightly more readable:

{a:a size@n(' __' '_'n 1+:@k*LF'||'a' ' '|'LF'||' '_'k*'|'LF'|/' '_'k*'\')sum}"@:m
[,m$hcat#/!' |||'hcat out]@:p
'`1234567890-='chars'BS   'p
'TAB  ' 'QWERTYUIOP[]\'chars p
'CAPS  ' 'ASDFGHJKL;'''chars,'ENTER'p
'SHIFT   ':@q'ZXCVBNM,./'chars,q p

This works by defining a function p that makes a key, then hcating multiple keys.

\$\endgroup\$
2
\$\begingroup\$

Haskell, 255

import Data.List;a#b=a++[b];e=" |||";s=map(:" ");k x=[e,"_||/"]++['_':c:"__"|c<-x]#"_||\\";t="SHIFT    ";main=mapM_ putStrLn$transpose.(#e).(k=<<)=<<[s"`1234567890-="#"BS    ","TAB   ":s"QWERTYUIOP[]\\","CAPS   ":s"ASDFGHJKL;'"#"ENTER ",t:s"ZXCVBNM,./"#t]

In retrospect, similar in concept to this Haskell answer, but producing the ASCII keyboard, and with slightly different golfing.

Formatted and renamed:

import Data.List

main :: IO ()
main = mapM_ putStrLn
  $ concatMap (transpose . (`append` end) . concatMap key)
  [ split "`1234567890-=" `append` "BS    "
  , "TAB   " : split "QWERTYUIOP[]\\"
  , "CAPS   " : split "ASDFGHJKL;'" `append` "ENTER "
  , shift : split "ZXCVBNM,./" `append` shift
  ]

key :: String -> [String]
key x
  = [end, "_||/"]
  ++ ['_' : c : "__" | c <- x]
  `append` "_||\\"

append :: [a] -> a -> [a]
append a b = a ++ [b]

split :: [Char] -> [String]
split = map (: " ")

end :: String
end = " |||"

shift :: String
shift = "SHIFT    "
\$\endgroup\$
2
\$\begingroup\$

tcl, 368

As counted by http://textmechanic.com/text-tools/basic-text-tools/count-characters-words-lines/ with the "Count line breaks as spaces." set to on, it occupies 505 496 452 451 439 403 401 396 391 388 385 384 382 379 378 377 369 368

proc N x {split $x @}
proc M a\ b {string map $a $b}
regsub -all \[^@|] [set b [M [N {||||@|||@$@BS   @%@TAB  @&@CAPS @? @ENTER  @*@SHIFT   }] [regsub -all {[^@]} "`1234567890-=$@%QWERTYUIOP\[\]\\@&ASDFGHJKL;'?@*ZXCVBNM,./*" {||& ||}]]] _ f
lmap x [N [M {\\ _ / _ | \ } [set g [M {||_ |/_ _|| _\\|} [M {||| \\|/} $f]]]]] y [N $b] z [N $f] w [N $g] {puts "$x
$y
$z
$w"}

Demo: http://rextester.com/live/NTVAV88033

The ungolf:

Live cooperation on http://rextester.com/live/UDO43692

regsub -all {(\S)} "`1234567890-=←\n%QWERTYUIOP\[\]\\\n⇩ASDFGHJKL;'↵\n⇧ZXCVBNM,./⇧" {||\1 ||} b
set b [string map {|||| |||  ← "BS   " % "TAB  " ⇩ "CAPS  " ↵ "ENTER" ⇧ "SHIFT   "} $b]

regsub -all {[^\n|]} $b _ f

set g [string map {||| \\|/} $f]
set g [string map {||_ |/_  _|| _\\|} $g]
set h [string map {\\ _ / _ | " "} $g]

set H [split $h \n]
set B [split $b \n]
set F [split $f \n]
set G [split $g \n]

lmap x $H y $B z $F w $G {
puts $x
puts $y
puts $z
puts $w
}

Anyone is free and welcome to improve my version on live cooperation sites, but please: do not edit my original answer here; just say you've edited in the comments and people will visit the links.

UPDATE 1: Replaced for by foreach, because latter produces shorter code

UPDATE 2: Replaced foreach by lmap, because latter produces shorter code

UPDATE 3: Shaved one char because I Replaced " " by \

UPDATE 4: In respect to first comment, I changed all the 1st line 2 byte Unicode place holder characters to 1 byte ASCII ones

UPDATE 5: multiple puts line made into only one

UPDATE 6: use directly split commands return values on the lmap call instead of using intermediate list variables

UPDATE 7: Quotes around ENTER were not needed

UPDATE 8: string map is long enough and repeated a number of times that it is worth to encapsulate it in a proc

UPDATE 9: split $x \n is long enough and repeated a number of times that it is worth to encapsulate it in a proc

UPDATE 10: On "replacement" string can use & instead of \1, because in this case both coincide; another consequence of this is it allows to get rid of ()on the "matching" string.

UPDATE 11: Use @ instead of \nas line separator for further use on split instructions. Although the "match" string lengthens from \S to [^@] it pays off , due to number of repetitions

UPDATE 12: Replaced the first regsub "match" string {[^@|]} by\[^@|] to shave one character off. Unfortunately, could not do the same to the second regsub, because the instruction is inside a pair of [] :(

UPDATE 13: Shaved two Enter characters by concentrating the lmap body with its own heading.

UPDATE 14: Used a call to the split based procedure N instead of a direct call to the string map based procedure N which allows to shorten by 3 characters

UPDATE 15: There was an unneeded space character. Removed it to shave one char off.

UPDATE 16: set h can be embedded to get rid of $h, to shave one character off.

UPDATE 17: set h statement can really be shaved off.

UPDATE 18: puts argument changed from the ...\n...\n...\n... format to the

"...
...
...
..." 

format.

Thanks to people that helped me to shorten it, especially evilotto and aspect of the tcl IRC channel!

\$\endgroup\$
4
  • \$\begingroup\$ Nice answer, and Welcome to the site! I made a minor edit to your post so that the byte count would appear in the header, I hope you don't mind. Just so you know, I think this is actually 469 bytes since some of those characters are multiple bytes in UTF-8. I don't know very much about tcl, does it use a custom encoding where those are one byte? \$\endgroup\$
    – DJMcMayhem
    Commented Dec 18, 2016 at 18:17
  • \$\begingroup\$ @DJMcMayhem I didn't know it was based byte count instead of character count but it is a non-problem because everything that is a one byte symbol still not used can be a placeholder and I still have many available. \$\endgroup\$
    – sergiol
    Commented Dec 18, 2016 at 21:56
  • \$\begingroup\$ @DJMcMayhem after my edit, the non-problem you reported has gone! \$\endgroup\$
    – sergiol
    Commented Dec 18, 2016 at 22:12
  • \$\begingroup\$ @DJMcMayhem Why the 401 on top had a yellow background for some time? \$\endgroup\$
    – sergiol
    Commented Dec 20, 2016 at 14:57
2
\$\begingroup\$

tcl, 369

Initially based in tcl's sergiol version.
(Note that many left spaces are part of tcl's "nature")

lmap z {S R M} w {set "regsub -all" "string map"} {interp alias {} $z {} {*}$w};lmap x {"`1234567890-=¿BS   ¿" "¿TAB  ¿QWERTYUIOP\[\]\\" "¿CAPS  ¿ASDFGHJKL;'¿ENTER¿" "¿SHIFT   ¿ZXCVBNM,./¿SHIFT   ¿"} {S h [M {\\ _ / _ | \ } [S g [M {||_ |/_  _|| _\\|} [M {||| \\|/} [S f [R {[^\n|]} [S b [M {|||| |||} [R {¿(\S+\s*)¿|(.)} $x {||\1\2 ||}]]] _ ]]]]]];puts $h\n$b\n$f\n$g}
\$\endgroup\$
11
  • \$\begingroup\$ @muddyfish Edited and fixed. Thanks! \$\endgroup\$ Commented Dec 24, 2016 at 15:48
  • \$\begingroup\$ You can shorten more if you directly replace all foreach occurrences by lmap! \$\endgroup\$
    – sergiol
    Commented Dec 26, 2016 at 21:53
  • \$\begingroup\$ Tried to use your interp alias approach to shorten my version, but the shortest I could get when doing it was 398 :( rextester.com/live/NTVAV88033 \$\endgroup\$
    – sergiol
    Commented Dec 26, 2016 at 22:26
  • \$\begingroup\$ My last try I got 395: lmap z {S R M N} w {set "regsub -all" "string map" split} {interp alias {} $z {} {*}$w};lmap y [N [S b [M [N {||||@|||@$@BS @%@TAB @&@CAPS @? @ENTER @*@SHIFT } @] [R {[^@]} "`1234567890-=$@%QWERTYUIOP\[\]\\@&ASDFGHJKL;'?@*ZXCVBNM,./*" {||& ||}]]] @] z [N [S f [R {[^@|]} $b _]] @] w [N [S g [M {||_ |/_ _|| _\\|} [M {||| \\|/} $f]]] @] x [N [M {\\ _ / _ | \ } $g] @] {puts $x\n$y\n$z\n$w} \$\endgroup\$
    – sergiol
    Commented Dec 26, 2016 at 23:46
  • \$\begingroup\$ You can save one char if you removed an unneeded space like in my last update! \$\endgroup\$
    – sergiol
    Commented Dec 27, 2016 at 14:50
2
\$\begingroup\$

C (gcc), 378 342 330 327 bytes

-10 -3 bytes thanks to ceilingcat.

A first stab at it. The repeated g()'s suggests room for improvement.

Edit: There we go.

char*k[]={"eZXCVBNM,./e","cASDFGHJKL;'d","bQWERTYUIOP[]\\","`1234567890-=a","BS","TAB","CAPS","ENTER","SHIFT"},*s;f(w,i,j){for(i=16;i--;puts(""))for(s=k[i/4],j=i%4;*s;printf("%s%s%-*.*s%.2s",L" |"+(s++-k[i/4]?2:j<3),L"/||"+j,w,i&2?j^3?w>2?w:1:w+2:w,j^2?"___________":w>2?k[*s-93]:s,"\\||||| "+j*2))w=*s>96?"FFGFI"[*s-97]-64:2;}

Try it online!

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

Python 2, 672 bytes

Using a compressed zlib string:

print 'x\x9c\xad\xd3\xb9\x0e\x82@\x10\x80\xe1\x9e\xa7\xa0\xb3\xf1\xbe\x8d\xb1\x00\xbc\x0f<\xc0\x1b\xb3>\xc8<\xbc\xfc\x8bf\x8d\xed8\xc5\x17\x9a\xddd\xfe,\xbe\xc9\xc7\xd7b?<\x91\xa7/"\rhB\x0b\xda\xd0\x81.\xf4\xa0\x0f\x03\xa8C\x05F\x10&~>"\xf9]\xc6\x88\x16\x86\xbbj\xc6dZ\x98L<\xb7\xae\x9a|\xc74\x08\xed\xba\xb2\x873L\xe0\x00)\\\xe1\x08\x0b\xd8\xc2\x0e\xee\xf0\x80\xec\xd3\xabXW\x1d\xces\xeb\xaa\xc3\xb9^\x7fy_Q\xb0K\x8a`\x01$0\x86)\xcc`\x0eKX\xc1\x1a\x86P\xb2u\xe3tr\xf8\xee\xf5\xaf\xf7\xa5\x0e\xf6\xfb\xbet\xb1\xde\xbd\x92\xf9b\x9a\x16\x7f\x94\xdc\xe0\x02\x11\x9c\xec\xef\x061l\xa0\x0cU\xa8\xd9\xbc\xee\xb4\xeb\xa5\x8a\xf5\xd3K\x15\xcb\x9e~\x01r\xfc\xb9\xee'.decode('zlib')
\$\endgroup\$
3
  • 2
    \$\begingroup\$ That's 672 bytes, not 232 bytes. \$\endgroup\$
    – nneonneo
    Commented Dec 18, 2016 at 16:07
  • \$\begingroup\$ Explain further, I did not understand you. @nneonneo \$\endgroup\$
    – Whatever
    Commented Dec 21, 2016 at 16:52
  • 1
    \$\begingroup\$ If you paste your code into a file, that file will be 672 bytes long. You appear to have counted your code with len("print 'x\x9c...'") which will unescape the \xs, resulting in an incorrect byte count. You could obtain a correct count by counting with len(r"print 'x\x9c...'") but the easiest solution, as always, is to see what your text editor or filesystem says. \$\endgroup\$
    – nneonneo
    Commented Dec 21, 2016 at 17:05
1
\$\begingroup\$

Mathematica 323 bytes

Uncompress@"1:eJyt00luwjAUgGE2vUdYsWGeEeoiUGYIEKcTTWXEBXqBd3jy26CUYWe/xads8iT/sounv1gFL4VCoLNxxnyk9UZT5BiISAOa0II2dKALPejDAOpQgVcYqSAbEbtOa3GFuayraZ2mPmWyL5bnIZyxR0/CkQkhe/iECcSQwDe8wwK2sIMf+IV/IW0H56LXkJej+016E9LXlRyHO2VLhqDgDaYwgzksYQVrGELJZI+SSXxX0uOV9Jry2Y10q5iHVPPFNLGvUw7wBWP4ME8XIthAGapQM93zv29COlV8DOkrol10BmvF28U="

Boring and uncreative. The string is just the output of the built-in Compress command applied to the desired output.

\$\endgroup\$
1
  • \$\begingroup\$ @Downvoted please indicate what is wrong with my program. \$\endgroup\$
    – Ian Miller
    Commented Jun 18, 2017 at 10:14
1
\$\begingroup\$

Powershell, 249 242 bytes

"``1234567890-=Bs   
Tab  QWERTYUIOP[]\
Caps  ASDFGHJKL;'Enter
Shift   ZXCVBNM,./Shift   "-split'
'|%{($u=($r=,''+($_-csplit'(.[a-z ]*)'-ne''|% t*per)+'')-replace'.','_')-join'__ _'
$r-join' |||'
$u-join'_|||'
$u-join'_\|/'}|%{-join$_[2..76]}

Ungolfed & Explained

The middot · uses instead spaces to to clarify the source string.

"``1234567890-=Bs···
Tab··QWERTYUIOP[]\
Caps··ASDFGHJKL;'Enter
Shift···ZXCVBNM,./Shift···"-split"`n"|%{        # split the string with rows by new line
$r=,''+($_-csplit'(.[a-z ]*)'-ne''|% t*per)+''  # split each row by key labels (any char plus small letters or spaces), 't*per' is shortcut for toUpper method
$u=$r-replace'.','_'                            # replace any char to _ to take an upper 
$u-join'__ _'                                   # join labels and push 4 strings to pipe
$r-join' |||'
$u-join'_|||'
$u-join'_\|/'
}|%{
    -join$_[2..76]                              # return substring for each string
}

# $r =
# ["","`","1","2","3","4","5","6","7","8","9","0","-","=","BS   ",""]
# ["","TAB  ","Q","W","E","R","T","Y","U","I","O","P","[","]","\",""]
# ["","CAPS  ","A","S","D","F","G","H","J","K","L",";","'","ENTER",""]
# ["","SHIFT   ","Z","X","C","V","B","N","M",",",".","/","SHIFT   ",""]
# $u =
# ["","_","_","_","_","_","_","_","_","_","_","_","_","_","_____",""]
# ["","_____","_","_","_","_","_","_","_","_","_","_","_","_","_",""]
# ["","______","_","_","_","_","_","_","_","_","_","_","_","_____",""]
# ["","________","_","_","_","_","_","_","_","_","_","_","________",""]
# before substring:
# __ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________ _
#  |||` |||1 |||2 |||3 |||4 |||5 |||6 |||7 |||8 |||9 |||0 |||- |||= |||BS    |||
# _|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______|||
# _\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|/
# __ ________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ _
#  |||TAB   |||Q |||W |||E |||R |||T |||Y |||U |||I |||O |||P |||[ |||] |||\ |||
# _|||______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||
# _\|/______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/
# __ _________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________ _
#  |||CAPS   |||A |||S |||D |||F |||G |||H |||J |||K |||L |||; |||' |||ENTER |||
# _|||_______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______|||
# _\|/_______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|/
# __ ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________ _
#  |||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT    |||
# _|||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________|||
# _\|/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\|/
# final output:
#  ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________
# ||` |||1 |||2 |||3 |||4 |||5 |||6 |||7 |||8 |||9 |||0 |||- |||= |||BS    ||
# ||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
# |/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
#  ________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
# ||TAB   |||Q |||W |||E |||R |||T |||Y |||U |||I |||O |||P |||[ |||] |||\ ||
# ||______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__||
# |/______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|
#  _________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________
# ||CAPS   |||A |||S |||D |||F |||G |||H |||J |||K |||L |||; |||' |||ENTER ||
# ||_______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
# |/_______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
#  ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________
# ||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT    ||
# ||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________||
# |/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\|

Extra: keyboard with a space bar & right aligned labels, 278 bytes

I've added a couple of bytes to the regular expression to handle the space bar (old regexp (.[a-z ]*), new one ~|(.[a-z ]*)). That's one small step for the regexp, one giant leap for the solution: you can now display space bar and key labels aligned to the right (see SHIFT, CTRL and BS on the right side of the keyboard).

"``1234567890-=~   bs
Tab  QWERTYUIOP[]\
Caps  ASDFGHJKL;'Enter
Shift   ZXCVBNM,./~   shift
Ctrl  Alt ~$(' '*34)Alt ~  ctrl"-split'
'|%{($u=($r=,''+($_-csplit'~|(.[a-z ]*)'-ne''|% t*per)+'')-replace'.','_')-join'__ _'
$r-join' |||'
$u-join'_|||'
$u-join'_\|/'}|%{-join$_[2..76]}

Output:

 ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________
||` |||1 |||2 |||3 |||4 |||5 |||6 |||7 |||8 |||9 |||0 |||- |||= |||   BS ||
||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
 ________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____
||TAB   |||Q |||W |||E |||R |||T |||Y |||U |||I |||O |||P |||[ |||] |||\ ||
||______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__||
|/______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|
 _________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________
||CAPS   |||A |||S |||D |||F |||G |||H |||J |||K |||L |||; |||' |||ENTER ||
||_______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______||
|/_______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\|
 ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________
||SHIFT    |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||   SHIFT ||
||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________||
|/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\|
 _________ _______ _____________________________________ _______ _________
||CTRL   |||ALT  |||                                   |||ALT  |||  CTRL ||
||_______|||_____|||___________________________________|||_____|||_______||
|/_______\|/_____\|/___________________________________\|/_____\|/_______\|
\$\endgroup\$
0
\$\begingroup\$

///, 360 bytes

/f/!!//e/SHIFT   //d/\/\///c/ "db/ 
\|\|da/\\\|d@/#####d?/__d>/?\\\\a
c"d</aa
ad:/fffff!d&/ccccd%/ aaad#/?aaa?aaad"/??d!/?\\\\a\\\d&&&cc"b`%1%2%3%4%5%6%7%8%9%0%-%=%BS    <|@#?|||"?<\/:f">&&&cbTAB  %Q%W%E%R%T%Y%U%I%O%P%[%]%\\ <|"@#?|||?<\/":f>_&&&"bCAPS  %A%S%D%F%G%H%J%K%L%;%'%ENTER <|"_@#"?<\/"_:!">?_&&ccc"?_be%Z%X%C%V%B%N%M%,%.%\/%e <|""_|||@""_<\/"?_:""_\a

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Wolfram Language (Mathematica), 293 bytes

c=##&@@(#|2&/@Characters@#)&
r=StringRiffle
p=StringPadRight
Print/@{j=p["",#2,"_"]&@@@#;(" __"<>#&/@j)<>" ",r[p@@@#,i={l="||","|||",l}],j~r~i,j~r~{"|/","\|/","\|"}}&/@{{c@"`1234567890-=","BS"|6},{"TAB"|6,c@"QWERTYUIOP[]\\"},{"CAPS"|7,c@"ASDFGHJKL;'","ENTER"|6},{h="SHIFT"|9,c@"ZXCVBNM,./",h}}

Try it online!

Relatively straightforward: encodes rows of keys as lists of (key name)|(key width)

c=##&@@(#|2&/@Characters@#)&    (*converts a string into (key)|2 s*)
r=StringRiffle
p=StringPadRight
 Print/@
  {j=p["",#2,"_"]&@@@#;
   (" __"<>#&/@j)<>" ",         (*top of the keys*)
   r[p@@@#,i={l="||","|||",l}], (*key names*)
   j~r~i,                       (*space under key names*)
   j~r~{"|/","\|/","\|"}            (*bottom of the keys*)
  }
 &/@
{
 {c@"`1234567890-=","BS"|6},
 {"TAB"|6,c@"QWERTYUIOP[]\\"},
 {"CAPS"|7,c@"ASDFGHJKL;'","ENTER"|6},
 {h="SHIFT"|9,c@"ZXCVBNM,./",h}
}
\$\endgroup\$
0
\$\begingroup\$

Perl 5 -MList::Util=pairmap, 313 bytes

pairmap{$_=$b;s/\|{3}/|-|/g;y/-/_/c;y/-/ /;s/./ /;chop;say;$_=$b;for$r($a=~/./g){s/\| /|$r/}say;y/|/_/c;say;s,\|_,/_,g;s/_\|/_\\/g;say}"`1234567890-=",($;="||  |")x13 ."||BS    ||","QWERTYUIOP[]\\",'||TAB   |'.$;x13 .'|',"ASDFGHJKL;'","||CAPS   |".$;x11 ."||ENTER ||","ZXCVBNM,./",($s='||SHIFT    |').$;x10 ."$s|"

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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