45
9
We all know that programmers tend to be lazy. In order to maximize your free time, you decide to write a program that outputs a minimal number of keystrokes for text fed into it.
Input: Text that has to be converted into keystrokes. You may decide on how to input the text (STDIN / reading from a file provided in the arguments)
Output: The necessary actions in the following format:
- They must be numbered
H
it: Pressing a key and immediately releasing itP
ress: Pressing a key and not releasing it (this will never be optimal when the key isR
eleased as the next keystroke)R
elease: Releasing aP
ressed key
Example:
Input:
Hello!
Output:
A naive solution would be:
1 P Shift
2 H h
3 R Shift
4 H e
5 H l
6 H l
7 H o
8 P Shift
9 H 1
10 R Shift
This would be more efficient:
1 P Shift
2 H h
3 H 1
4 R Shift
5 H Left
6 H e
7 H l
8 H l
9 H o
Environment:
- The editor uses a monospaced font
- Text is soft wrapped at 80 characters
- Arrow up and Arrow down preserve the column, even if there are shorter lines in between
- The clipboard is assumed to be empty
- Num lock is assumed to be enabled
- Caps lock is assumed to be disabled
- Caps lock only works for the letters (i.e. no Shift Lock)
Hotkeys / Shortcuts:
- Home: Jump to the beginning of the current line
- End: Jump to the end of the current line
- Ctrl+A: Mark everything
- Ctrl+C: Copy
- Ctrl+X: Cut
- Ctrl+V: Paste
- Shift+Cursor moving: Marking
- Ctrl+F: Opens a search dialog.
- Stupid text matching, no Regular Expressions
- Case sensitive
- Searches wrap around
- Single line text input for the search
- The input is prefilled with the current selection, unless there is a newline in between, the complete input is selected
- Copying / Pasting works as usual
- Pressing Enter performs the search, selecting the first match after the current cursor position
- F3: Repeat last search
- Ctrl+H: Opens a replace dialog
- Stupid text matching, no Regular Expressions
- Case sensitive
- Replace All, with wrap around
- Single line text inputs
- The search input is prefilled with the current selection, unless there is a newline in between, the complete input is selected
- The replace input is empty
- Copying / Pasting works as usual
- Tab jumps to the replace input
- Pressing Enter performs the replace all. The cursor is placed after the last replacement
Rules:
- Solutions must be a complete program that compiles / parses and executes without any further modification
- The keyboard displayed above is the keyboard to use
- It is not required to handle characters that cannot be typed with it
- Every key must be released at the end
- The cursor does not need to be at the end of file at the end
Scoring:
Your score is sum the amount of actions needed to type the following texts. The winner is the solution with the lowest score. Using my naive solution I get 1371 + 833 + 2006 = 4210
. Beat it! I will pick a winner in two weeks.
1 My naive solution
number = 1
H = (char) -> console.log "#{number++} H #{char}"
P = (char) -> console.log "#{number++} P #{char}"
R = (char) -> console.log "#{number++} R #{char}"
strokes = (text) ->
shiftActive = no
for char in text
if /^[a-z]$/.test char
if shiftActive
R "Shift"
shiftActive = no
H char
else if /^[A-Z]$/.test char
unless shiftActive
P "Shift"
shiftActive = yes
H char.toLowerCase()
else
table =
'~': '`'
'!': 1
'@': 2
'#': 3
'$': 4
'%': 5
'^': 6
'&': 7
'*': 8
'(': 9
')': 0
'_': '-'
'+': '='
'|': '\\'
'<': ','
'>': '.'
'?': '/'
':': ';'
'"': "'"
'{': '['
'}': ']'
if table[char]?
unless shiftActive
P "Shift"
shiftActive = yes
H table[char]
else
H switch char
when " " then "Space"
when "\n" then "Enter"
when "\t" then "Tab"
else
if shiftActive
R "Shift"
shiftActive = no
char
R "Shift" if shiftActive
input = ""
process.stdin.on 'data', (chunk) -> input += chunk
process.stdin.on 'end', -> strokes input
2 Easy repetition
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
3 More complex repetition
We're no strangers to love
You know the rules and so do I
A full commitment's what I'm thinking of
You wouldn't get this from any other guy
I just wanna tell you how I'm feeling
Gotta make you understand
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
We've known each other for so long
Your heart's been aching but
You're too shy to say it
Inside we both know what's been going on
We know the game and we're gonna play it
And if you ask me how I'm feeling
Don't tell me you're too blind to see
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
(Ooh, give you up)
(Ooh, give you up)
(Ooh)
Never gonna give, never gonna give
(Give you up)
(Ooh)
Never gonna give, never gonna give
(Give you up)
We've know each other for so long
Your heart's been aching but
You're too shy to say it
Inside we both know what's been going on
We know the game and we're gonna play it
I just wanna tell you how I'm feeling
Gotta make you understand
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
You can use the replay program written by me to test your solutions (Note: It does not support Searching / Replacing yet, everything else should work).
6I would love to see a program like this for vim. – Braden Best – 2014-03-06T04:01:40.343
4Normally I use the mouse for part of those things. – Victor Stafusa – 2014-03-06T06:42:17.343
1Very interesting. I'll have a go in the morning ;3 – cjfaure – 2014-03-10T22:01:26.730
Is Ctrl+Shift+left/right allowed for selecting entire words? – user80551 – 2014-03-11T10:51:32.763
@user80551 Unfortunatly the question has gone out 5 days before, it would be unfair to others to change it. So: No, it is not. – TimWolla – 2014-03-11T11:49:21.887
2You didn't really have to Rick Roll us, did you? :) – Filip Haglund – 2014-03-11T12:04:50.233
@FilipHaglund I did not have to, but I remembered it from another question I answered as containing repetition :) – TimWolla – 2014-03-11T13:27:20.700
Hmm interesting! No shift-end/shift-home? – intx13 – 2014-03-11T16:09:37.380
@intx13 Unfortunatly I did not consider them when writing the question, see my answer to user80551 above. – TimWolla – 2014-03-11T16:12:05.763
For simplicity, can we list the key to be pressed as either its shifted or unshifted version? Or must we convert to unshifted? Meaning: "P Shift H ^ R Shift" versus "P Shift H 6 R Shift" – intx13 – 2014-03-11T16:24:36.393
@intx13 Please use the unshifted one. This is not Code Golf anyway. – TimWolla – 2014-03-11T16:27:21.567
@TimWolla is there a "replay" program we can use to test out solutions? – intx13 – 2014-03-11T16:39:37.890
@intx13 Not yet, I'll try to provide one! – TimWolla – 2014-03-11T16:42:41.453
@intx13 A replay program (currently w/o Search & Replace) is now available: http://jsfiddle.net/TimWolla/M4VNM/
– TimWolla – 2014-03-11T17:56:41.630@TimWolla I've got a bit of a problem. My solution always gives the best solution possible but it's really, really slow. At best, it'll take ~4.0676^9111 years to complete your scoring. – cjfaure – 2014-03-13T10:53:00.703
@Trimsty I'd say: Go ahead anyway to show off your work. I am interested in your solution (and currently you are the only one). – TimWolla – 2014-03-13T12:20:25.963
@Trimsty, I'm guessing you iterate all possible key-presses , replay and compare against the target text, and keep the shortest? – intx13 – 2014-03-13T15:16:48.237
@intx13 Bingo. ;3 – cjfaure – 2014-03-13T15:24:03.527
1I'm kinda with @B1KMusic. To me this would be more interesting to generate solutions to vimgolf. (Which is the equivalent of what you are trying to do here just using vim commands.) This however while sounds like a fun idea reducing keystrokes is very hard (or at least I think it is) as precise movement for selection is difficult. This makes copying and pasting is a really hard task and takes almost as many keystrokes as the thing you were trying to copy. (Or at least this is how I'm reading how copy and paste works). And I don't see many other ways to reduce key strokes. – FDinoff – 2014-03-13T20:35:39.423
There's several bugs in the replay program. It maintains the selection as an optional pair of positions, but selections are normally just one optional position plus the cursor. This leads to bugs that the selection doesn't update on Home, End, Up, Down; also that Ctrl-A doesn't move the cursor to the end as it should. Ctrl-C, Ctrl-X do not handle 'no selection'. Cursor motion without shift should turn off selection. (It won't come as a surprise to know this means I'm writing an answer) – bazzargh – 2014-03-15T10:53:03.800
@bazzargh looks like I'm modifying my code before I enter s'more. – cjfaure – 2014-03-15T12:41:03.637
@bazzargh I think I got all those issues fixed now. Thanks! – TimWolla – 2014-03-15T14:16:10.937
@intx13 Shift+End / Shift+Home is now possible (due to the fixes in the selection program. Have fun! – TimWolla – 2014-03-15T14:16:52.400
@TimWolla it's still buggy. Home only works on the first line. You have
start = 0 if start is -1
, but this should just bestart++
. I'm not using arrow keys in my stuff, but I can see obvious bugs there too - Up won't let you stay in column 0, and Left/Right can step outside the document. – bazzargh – 2014-03-15T17:16:32.880@bazzargh Those bugs are corrected as well, thanks again. – TimWolla – 2014-03-15T17:59:26.223
Isn't this equivalent to finding Kolmogorov complexity?
– Display Name – 2014-03-15T18:51:19.850Question: If I have to type "AAAAAAAAAAAAAAAAAAAAAAAAAA", can I convert that to
<press A> <release A>
? It will end up generating the proper amount ofA
s if the timing is done just right. This is optimizing keystrokes after all non? – Claudiu – 2014-03-16T16:49:12.207@Claudiu It is not allowed in the question, so: No, that would be too easy (a simple regex). – TimWolla – 2014-03-16T17:28:17.427
May I suggest this stylistic update to your replay program?
– Braden Best – 2014-03-16T22:02:00.723