Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

My Problem

At my current place of employment, I single-handedly (ok dual-handedly because I'm missing no limbs) maintain approximately 700 laptops. Due to the nature and frequency of their use, I often find they are returned with a bit of damage. For this problem, my primary concern is when a laptop is returned with a broken or defunct keyboard. When the hardware repairman fixes these broken keyboards, it becomes necessary to test them. The test involves using each...and...every...single...key. What a drag right? The problem is, sometimes I lose track of if I typed a key or not.

A solution?

Write a program/script that:

  1. Takes user input
  2. Upon submission (in whatever way you deem fit), determines whether each key was pressed.
  3. Outputs yes or no or any way to indicate that either I was successful in pressing all the keys or not. (Indicate in your answer the two possible outputs if it's not something obvious).

Assumptions:

  1. Uppercase, lowercase, both? Whichever way you deem fit. As long as it's [A-Z], [a-z] or [A-Za-z]. Same goes with numbers and other symbols. (So if = was typed in, + doesn't matter). Your choice if you want to include shifted characters or not.
  2. You needn't worry about tabs or spaces
  3. No needs for function keys, CTRL, ALT, Esc or any other keys that don't output something on the screen
  4. This assumes an EN-US keyboard and the laptops do not include a numpad.
  5. OS agnostic, whatever language you prefer
  6. It doesn't matter if the key has been pressed multiple times (for when the tester just gets lazy and starts button smashing like it's Mortal Kombat)

Here's a potential input set that would return true (or yes, or "You did it!")

`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./

Winner is determined by the least number of characters.

share|improve this question
    
Do we need to check that each keystroke appears at least once or exactly once? –  xnor Jun 7 at 14:04
    
@xnor, If it appears multiple times, it's ok. I updated the question. –  ChristopherW Jun 7 at 14:10
1  
Okay then, that isn't worth it. –  nyuszika7h Jun 7 at 15:34
1  
@ChristopherW If this is an ongoing issue for you, you should have a look at this website keyboardtester.com. –  gxtaillon Jun 7 at 15:39
2  
@MomemtumMori, that hand doing the Pennsylvania Dutch keyboarding technique over in the side bar? Totally mine. –  ChristopherW Jun 7 at 15:44

9 Answers 9

up vote 1 down vote accepted

GolfScript, 6 bytes

.&,94=

If all ASCII characters with codes between 33 and 127 are present, it prints 1. Otherwise, it prints 0.

This approach will fail if the input contains other characters (including a final newline), which has been allowed by the OP and is also true for the existing GolfScript solution.

Usage

$ echo -n '!"#$%&'"'"'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~' |
> golfscript <(echo '.&,94=')
1

How it works

.&  # Compute the intersection of the input string with itself. This removes duplicates.
,   # Compute the length of the resulting string.
94= # Push 1 if the length is 94, otherwise push 0.
share|improve this answer
    
The comment you linked doesn't say the input won't contain a newline (or other characters outside of 33-126), it just says it will only contain valid characters. Is newline an invalid character? –  aditsu Jun 10 at 11:29
    
By valid I meant in the range we're testing against, but I guess I should have expressed myself more clearly when asking the OP... –  Dennis Jun 10 at 13:49

GolfScript, 11

Printable ASCII isn’t that interesting…

127,32,-^,!

Ruby, 68

With flag -rset for 4 characters.

p Set.new(?`..?z)+(?,..?9)+%w{[ ] \\ ; '}==Set.new(gets.split'')

and

Python 3, 76

print(set("`1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./")==set(input()))
share|improve this answer
1  
I'd suggest posting these in two separate answers. –  nyuszika7h Jun 7 at 15:42

JavaScript - 62 70

alert(!(47-prompt().match(/([',-\/\d;=a-z\[-\]`]?)(?!.*\1)/g).length))

And a bit shorter:

alert(!!prompt().match(/([',-\/\d;=a-z\[-\]`])(?!.*\1)/g)[46])
share|improve this answer

CJam - 9

',33>q-!

It checks for the "shifted" characters too (including uppercase letters).
Try it at http://cjam.aditsu.net/

Note: there is an invisible character (with code 127) after the apostrophe.

share|improve this answer
    
“It checks for the "shifted" characters too (including uppercase letters).” I’d say that’s incorrect behaviour. –  minitech Jun 7 at 15:48
    
@minitech "Your choice if you want to include shifted characters or not." –  aditsu Jun 7 at 15:49
    
But right before that, it says “Uppercase OR lowercase” (that’s exclusive, right?) –  minitech Jun 7 at 15:51
    
@minitech, I updated the question. Sorry. That OR is misleading. –  ChristopherW Jun 7 at 15:54
    
@ChristopherW My program will print 0 on your example input, but if you also press all those characters while holding shift, it will print 1. Is that ok? –  aditsu Jun 7 at 15:59

PHP

    foreach (str_split("`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./") as $v) {
        if (strpos($_GET['i'],$v)!==false)die(NO);
    }

$_GET['i'] is the input

share|improve this answer
1  
Use $_GET to save 1 char if it's acceptable. –  tomsmeding Jun 8 at 22:53
    
@tomsmeding, yeah I did :) –  Alireza Fallah Jun 9 at 4:35
    
You can add a padding character (é or something) to the front of your string and remove the !==false to save 8 characters, then the braces for 4 more. register_globals makes this "é$i". die(NO) is also possible. –  minitech Jun 10 at 3:24
    
@minitech - I dont know what you say, padding character ? feel free to edit my answer instead –  Alireza Fallah Jun 10 at 4:46

Python 72:

f=lambda x:set(x)==set("`1234567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./")
share|improve this answer
3  
The OP asked for a program that takes user input. –  nyuszika7h Jun 7 at 15:43

Perl, 70 characters

say[sort grep!$s{$_}++,<>=~/\S/g]~~[sort"',-./;=[\]`"=~/./g,0..9,a..z]

Usage:

echo `134223423567890-=qwertyuiop[]\asdfghjkl;'zxcvbnm,./ | perl -E 'say[sort grep!$s{$_}++,pop=~/\S/g]~~[sort"',-./;=[\]`"=~/./g,0..9,a..z]'

Prints 1 if all keystrokes present, else prints nothing.

share|improve this answer
    
Requires Perl 5.10+ –  Zaid Jun 8 at 18:25
    
In most shells, your example will fail since some of the characters in the echoed string require escaping. –  Dennis Jun 9 at 21:27

Haskell, 41 (two solutions)

interact(\y->show$all(`elem`y)[' '..'`'])

or (point-free style)

interact$show.(`all`[' '..'`']).flip elem

Need to input at least these characters:

 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`

in any order, any number of times. Extra characters are allowed. Run in an interpreter. Must hit Enter when you are done, but if you hit Enter before you are done, you can keep entering characters, and press Enter again. Will print True if you have hit every character, otherwise it won't print anything.

share|improve this answer

C, 97 characters

main(long a,char**u){a=0xfb0000000750003d;for(u++;**u;a|=2L<<*(*u)++-39);a=48+!~a;write(1,&a,1);}

Need to call the program with argument containing at least the letters:

`1234567890-=AZERTYUIOPQSDFGHJKLMWXCVBN[]\;',./

and get answer 1 (true). The charset can be changed by changing the initialization value of a.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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