14
\$\begingroup\$

Write the shortest program that waits for every key of a Standard 101 key US Keyboard* to be pressed and then exits writing OK!

Every time a key is pressed the program displays on a new line the remaining number of unpressed unique keys that need to be pressed until all key are pressed at least once. The program should be able to test a 101 keyboard and see if every key works. So pressing twice a key or enter is to be allowed as long as this is specified to the user.

Pressing same key twice or more should not disrupt the code nor change the displayed number of remaining unpressed keys.

All keys (Left Shift, Right Shift, Right Control, Esc, Enter, etc.) should be included.

The actual keyboard keys are important in this challenge so from the perspective of the program (A and a, are the same and so are 6 and ^).

Combined keys will not be registered as a combined command and only the individual keys will be registered if Ctrl + Alt + Del is pressed that will count for all the individual keys in the combination being pressed. So no need to press also the capital letters if you pressed already the lowercase and vice-versa.

Numeric keys on the numeric keypad are different from the perspective of the program, so they are still needed to be pressed for the program to finish, if you have a laptop or any other keyboard that doesn't have the US Standard 101 keyboard layout you cannot fulfill the challenge unless you plugin a compatible keyboard.

*Keyboards having Fn key and laptop key will not be supported to keep this challenge doable

This is the list of keys for a US Standard 101 keyboard layout:

backspace
tab
enter
right shift
right ctrl
right alt
left shift
left ctrl
left alt
print screen
pause/break
caps lock
escape
page up
page down
end
home
left arrow
up arrow
right arrow
down arrow
insert
delete
0
1
2
3
4
5
6
7
8
9
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
numpad 0
numpad 1
numpad 2
numpad 3
numpad 4
numpad 5
numpad 6
numpad 7
numpad 8
numpad 9
multiply
add
subtract
decimal point
numpad enter
divide
f1
f2
f3
f4
f5
f6
f7
f8
f9
f10
f11
f12
num lock
scroll lock
semi-colon
equal sign
comma
dash
period
forward slash
grave accent
open bracket
back slash
close braket
single quote
space
\$\endgroup\$
  • 1
    \$\begingroup\$ Is it okay to require the Enter/Return key to be pressed after every keypress? If not, this is impossible in many languages. \$\endgroup\$ – Doorknob Aug 23 '15 at 13:03
  • 5
    \$\begingroup\$ List of keys please! \$\endgroup\$ – feersum Aug 23 '15 at 13:05
  • 2
    \$\begingroup\$ Also, does the program have to support non-printable-ASCII? (ex. Escape, Tab, Ctrl, Shift, Alt, Insert, the arrow keys, Caps Lock, Home, End, Page Up/Down, Backspace, Del, the F keys, etc.)? Do a character and its shifted version both have to be pressed? What about Ctrl + a character? Do numpad keys count differently than regular ones? \$\endgroup\$ – Doorknob Aug 23 '15 at 13:08
  • 1
    \$\begingroup\$ @Doorknob You cannot fulfill the challenge using a laptop's keyboard unless it has all 101 keys needed by the US Standard 101 keys layout \$\endgroup\$ – Eduard Florinescu Aug 23 '15 at 13:28
  • 1
    \$\begingroup\$ @beta-decay Most of the people that closed this question never asked what they don't understand from it so is hard for me to guess. \$\endgroup\$ – Eduard Florinescu Aug 24 '15 at 7:25
7
\$\begingroup\$

Javascript, 524 bytes

Hi, this is my first ever post here, so excuse me if I'm still ignorant on some stuff, I think I stayed within the rules though.

k=[8,9,"130","133","161","162","171","172","181","182",19,20,27,44,45,46,48,49,50,51,52,53,54,55,56,57,144,145,186,187,188,189,190,191,192,219,220,221,222];for(i=32;i<124;i+=1){i<41?k.push(i):i>64?i<91?k.push(i):i>95?i!=108?k.push(i):0:0:0}d=[13,16,17,18];m=document.addEventListener;c=console.log;m("keydown",e=>{e.preventDefault()});m("keyup",e=>{c(e.code);if(d.includes(e.which)){l=e.which+""+e.location;if(k.includes(l)){k.splice(k.indexOf(l),1)}}else if(k.includes(e.which)){k.splice(k.indexOf(e.which),1)}c(k.length)})

It seems buggy if I don't use Chrome, but you can try it out here. (be sure to open the console before you focus on the example window, as the default functionality of F12 is prevented)

Overview

The program makes an array of all the 101 "keycodes". Some are written explicitly, some sequences are added with a for loop and some are stored as strings. I have a seperate array for the "double" keycodes, since left and right control for instance give the same keycode. They also give a location, however, so I combine the keycodes with the locations as strings in the array. From there it's just an eventlistener that prevents default keydown functionality (don't wanna refresh with F5 in this case) and a seperate eventlistener for keyup, because every single key can be detected on keydown, EXCEPT FOR PRINTSCREEN.

After every keyup event the remaining keys (aka the length of the array) gets logged, as well as the name of the keycode (so there is the distinction between left and right shift, etc). I wasn't sure if that was a requirement, if not you can subtract another 10 bytes from the score.

Limitations

  • It only seems to work well in Chrome

I hope this answer is appreciated and please let me know if I've done anything wrong.

\$\endgroup\$
  • 5
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – FantaC Jan 23 '18 at 22:04
  • \$\begingroup\$ Can you change some or all of the semicolons to newlines? It won’t help your byte count but it would be much easier to read. \$\endgroup\$ – Jordan Jan 23 '18 at 22:24
  • \$\begingroup\$ here's a version that's much easier to read pastebin.com/PE4anSFw \$\endgroup\$ – M4Y Jan 23 '18 at 22:27
4
\$\begingroup\$

Java 8, 607 + 64 = 671 bytes

This is a lambda taking an unused parameter and throwing InterruptedException. It launches a window which, when in focus, intercepts presses of the 101 standard keys. Byte count includes lambda and required imports.

import java.awt.event.*;import javax.swing.*;import java.util.*;

v->{Set<Integer>s=new HashSet();long[]l={0x2bfff1ff081f0300l,0x8fffefff3ffffffel,3075<<16,4<<28|1};JFrame f=new JFrame();f.addKeyListener(new KeyAdapter(){public void keyReleased(KeyEvent e){int c=e.getKeyCode(),o=e.getKeyLocation(),n;c=(c==10|c>15&c<19)&o<3?-c:c==225?98:c==226?100:c==65386?101:c==227?102:c==224?104:o>3?c==33?105:c==34?99:c==35?97:c==36?103:c==127?110:c==155?96:c:(l[c/64]>>>c&1)<1?0:c;if(c!=0)s.add(c);System.out.println(n=101-s.size());if(n<1)synchronized(f){f.notify();}}});f.setFocusTraversalKeysEnabled(0<1);f.show();synchronized(f){f.wait();}System.out.print("OK!");System.exit(0);}

You can find a test class with an ungolfed version here.

Overview

As keys are pressed, values uniquely identifying them (in most cases the key code) are stored in a set. The first few levels of the ternary assignment to c handle cases where the key code is ambiguous (e.g. the "Home" key, which could come from the main portion of the keyboard or the number pad) and cases where the same key can map to multiple key codes (e.g. number pad behavior with Num Lock on or off). The final branch handles the "normal" keys whose key code can simply be used in the set. The key code indexes into the bitmap l which indicates whether the key is one of the standard 101.

Limitations

  • The program should be able to test a 101 keyboard and see if every key works.

    If any key other than the standard 101 is pressed, a stack trace may be printed to standard error, or unexpected behavior may occur.

  • The program uses the numeric values of key code constants directly, and Oracle's KeyEvent documentation indicates that these values may change over time.

Acknowledgments

  • -10 bytes thanks to Kevin Cruijssen
\$\endgroup\$
4
\$\begingroup\$

JavaScript, 98 90 75 bytes

So ... I suspect I may be underthinking things here but this should work. Let me know if I have overlooked anything. Only tested in Chrome.

s=new Set()
f=onkeydown=e=>!(onkeyup=e=>f(e,alert(101-s.add(e.code).size)))

Try it

alert overridden for your sanity and order reversed to save scrolling.

alert=x=>o.prepend(document.createTextNode(x+`\n`))
s=new Set()
f=onkeydown=e=>!(onkeyup=e=>f(e,alert(101-s.add(e.code).size)))
p{font-family:sans-serif;font-size:14px;}pre{margin:0 10px;}
<p>Focus here and start typing ...</p><pre id=o></pre>

\$\endgroup\$
  • \$\begingroup\$ One thing you overlooked is that it also counts down when you press keys that are not on the 101-key keyboard, like the windows keys. \$\endgroup\$ – M4Y Jan 24 '18 at 10:46
  • 1
    \$\begingroup\$ @M4Y, my interpretation of the challenge was that we assume that the specified keyboard is what's being used, especially given this line: "if you have a laptop or any other keyboard that doesn't have the US Standard 101 keyboard layout you cannot fulfill the challenge unless you plugin a compatible keyboard." \$\endgroup\$ – Shaggy Jan 24 '18 at 10:49
  • \$\begingroup\$ that's fair enough I suppose, clever solution! \$\endgroup\$ – M4Y Jan 24 '18 at 10:54

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.