Analysieren und verarbeiten Sie die Eingabe in der Schlüsselsprache

9

Lassen Sie uns die Schlüsselsprache analysieren und verarbeiten! Schreiben Sie bei Eingabe einer Folge von Tastaturtastendrücken und / oder Sondertasten ein Programm, eine Funktion usw., die das Produkt ausgibt, wenn alle Aktionen auf der folgenden Tastatur ausgeführt werden:

+-------------------------------------------------------+
| ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | - | + |   |
| ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | _ | = |Del|
+-------------------------------------------------------+
|TAB| q | w | e | r | t | y | u | i | o | p | [ | ] | \ |
|   | Q | W | E | R | T | Y | U | I | O | P | { | } | | |
+-------------------------------------------------------+
|CAPS | a | s | d | f | g | h | j | k | l | ; | ' | RET |
|     | A | S | D | F | G | H | J | K | L | : | " |     |
+-------------------------------------------------------+
| SHIFT | z | x | c | v | b | n | m | , | . | / | SHIFT |
|       | Z | X | C | V | B | N | M | < | > | ? |       |
+-------------------------------------------------------+
|                                                       |
|                      SPACEBAR                         |
+-------------------------------------------------------+                         

Die Schlüssel, die tatsächliche Zeichen ausgeben, die nicht aus Leerzeichen bestehen und von anderen Schlüsseln geändert werden können, werden als "Zeichentasten" bezeichnet, und diejenigen, die die Ausgabe anderer Schlüssel oder Ausgabe-Leerzeichen ändern, werden als "Sonderschlüssel" bezeichnet. Die Alphabet-Zeichentasten, die in der Eingabe mit Großbuchstaben angezeigt werden, können entweder mit Shiftoder Caps Lockin Großbuchstaben geändert werden , und die übrigen Zeichentasten können nur mit geändert werden Shift, um ihre alternativen Zeichen zu erzeugen. Daher entspricht Ain der Eingabe die a AZeichentaste, deren normale Ausgabe ist aund deren modifizierte Ausgabe, die entweder mit der Taste Shiftoder erhältlich ist Caps Lock, ist A. Auf der anderen Seite,/, die der / ?Zeichentaste entspricht , hat eine normale Ausgabe von /und eine modifizierte Ausgabe von ?, die nur mit Shiftdieser Zeit erhältlich ist.

Regeln

  • Die Eingabe ist immer eine Zeichenfolge, die aus einer Folge von Zeichentasten und Sondertasten besteht. Der vollständige Spezialschlüssel für die Zeichenfolgenzuordnung für die Eingabe (dh das Format, in dem sie garantiert in der Eingabe enthalten sind) und die entsprechenden Aktionen / Ausgaben lauten wie folgt:

    • <DEL> -> Delete the previous character (including whitespace). If called when string is empty, nothing happens. If called 2 or more times in a row, 2 consecutive deletes happen. For instance, "RE<DEL><DEL>" should return an empty string ("") and also "R<RET><DEL><DEL>E" should return just "E".
    • <CAPS> -> Enable Caps Lock until <CAPS> appears again, upon which it is disabled, although it is not guaranteed to be disabled by the end of the input. Enabling this only modifies the upcoming alphabet keys resulting in them outputting only uppercase letters. For instance, "<CAPS>RE<CAPS>" results in the output "RE", but <CAPS>.<CAPS> would still result in a ".".
    • <RET> -> Add a new line.
    • <SPC> -> Add a single blank space.
    • <TAB> -> Add 4 spaces.
    • <SHFT> -> Shift is held down resulting in the alternate character of the upcoming keypress to be output, after which the key is released. For instance, "<SHFT>A" results in the output "A", "<SHFT>1" results in the output "!", and "<SHFT>1234" results in the output "!234" as only the first upcoming keypress is modified and nothing else. It is guaranteed that a character key will succeed a <SHFT>. Therefore, <SHFT><SPC> is not a possible input.
  • Als Eingabe ist auch eine leere Zeichenfolge möglich, für die die Ausgabe nichts sein sollte.

  • Die Verwendung von jedem eingebauten dass löst dieses Problem direkt nicht zulässig ist.
  • Die Verwendung von Standardlücken ist nicht zulässig.

Testfälle

Präsentiert im Format, Actual String Input -> Actual String Outputgefolgt von einer Erklärung für einige.

  1. 1<SHFT>2<TAB><CAPS>R.KAP.<SPC><SHFT>123 -> 1@ R.KAP. !23

    Ausgabe, 1wenn die 1Taste ohne Umschalten gedrückt wird, dann die Umschalttaste 2gedrückt gehalten wird und die Taste gedrückt wird, was zur @Ausgabe führt. Dann wird die Umschalttaste losgelassen und die Tabulatortaste gedrückt, was zu einer Einrückung mit 4 Abständen führt. Nach oben wird die Caps - Lock - Taste gedrückt, wonach das R, ., K, A, P, und .Tasten gedrückt werden , in der Ausgabe führt R.KAP.. Schließlich wird ein Leerzeichen gefolgt von Ausgabeverschiebung führt in !23ausgegeben wird, wenn das 1, 2, und 3Tasten am Ende gedrückt werden.

  2. <SHFT>ABCDEFG<SHFT>HIJK<SHFT>1<SHFT>2<SHFT>3<SHFT>4567890 -> AbcdefgHijk!@#$567890

    Die Umschalttaste wird gedrückt gehalten, gefolgt von der ATaste. Dies führt zur Ausgabe, Agefolgt von der Ausgabe, bcdefgwenn die B-GTasten gedrückt werden. Dann wird die Umschalttaste erneut gedrückt , gefolgt von der HTaste, woraufhin die Ausgabe erfolgt H, gefolgt vom Drücken ijkder I-KTasten. Schließlich 1-4werden alle Tasten geändert, wenn die Umschalttaste vor jedem Tastendruck gedrückt wird, was dazu führt, dass die Ausgabe !@#$beendet wird, 567890wenn die 5-0Tasten erneut gedrückt werden.

  3. <CAPS>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>CAPS<CAPS><SPC>NOW<SPC>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>LOWERCASE -> THIS IS IN ALL CAPS now this is in all lowercase

  4. <TAB><SPC><TAB><SHFT>1 -> !
  5. <CAPS>WWW<CAPS>.CODEGOLF.STACKEXCHANGE<SHFT>.COM -> WWW.codegolf.stackexchange>com
  6. PROGRAMMING<CAPS><SPC>IS<SPC><CAPS>AWESOME -> programming IS awesome
  7. <DEL><RET><DEL><RET><DEL> -> "" (Empty String)

    Die Löschtaste wird am Anfang gedrückt, danach passiert nichts mehr. Dann wird die Eingabetaste gedrückt, was zu einer neuen Zeile führt, die gelöscht wird, nachdem die Rücktaste erneut gedrückt wurde. Schließlich wird dieselbe Sequenz (neue Zeile gefolgt von Rücktaste) wiederholt. Nach all dem ist die Ausgabe eine leere Zeichenfolge.

  8. <SHFT>HI<SPC>HOW<SPC>ARE<SPC>YOU<SHFT>/<RET><SHFT>I<SPC><SHFT>AM<SPC>O<DEL><SHFT>GOOD<SHFT>1 -> Hi how are you?\nI Am Good!

  9. <SHFT>,<CAPS>RET<CAPS><SHFT>. -> <RET>

    Die Zeichenfolge <RET>sollte die tatsächliche Zeichenfolgenausgabe sein. Daher sollte dies keine neue Zeile ausgeben.

  10. <CAPS>67890,.;'[]<CAPS> -> 67890,.;'[]

  11. <CAPS><SHFT>A -> A
  12. RE<DEL><DEL> -> "" (Empty String)
  13. U<RET><DEL><DEL>I -> i
  14. <DEL><DEL><DEL>5<DEL> -> "" (Empty string)
  15. "" (Empty String) -> "" (Empty String)

Dies ist also gewinnt der kürzeste Code in Bytes!

R. Kap
quelle
5
Das ist eine seltsame Löschtaste, die Sie dort haben ...
Dennis
1
@Dennis Nun, ich beschreibe Tasten basierend auf der Tastatur meines MacBook Pro, wobei die Löschtaste das vorherige Zeichen löscht. Ich stimme dir trotzdem zu. Es ist ein ziemlich seltsames Layout.
R. Kap
Ah, das erklärt es. Es heißt Backspace auf buchstäblich jeder Tastatur, die ich jemals besessen habe. murmelt etwas über normale Tastaturtasten
Dennis
1
Sollte in Test 2 die Ausgabe sein AbcdefgHijk!@#$567890? Auch in Test Nr. 8 <SHFT>befindet sich am Ende der Zeichenfolge, aber die Regeln besagen: "Es ist garantiert, dass ein Zeichenschlüssel eine <SHFT> erfolgreich ist."
Atlasologe
@atlasologist Ja, du hast recht und schöner Fang! Ich habe vergessen, diese zu aktualisieren.
R. Kap

Antworten:

6

16-Bit-x86-Maschinencode, 140 139 Byte

1 Byte durch Ersetzen von DL durch DX im vorletzten Opcode gespeichert. Außerdem wurden die Sprungversätze bei der Demontage korrigiert, um sie an den Hex-Dump anzupassen.

Da die Art der Aufgabe einige vorinitialisierte Daten erfordert und die Antwort kein vollständiges Programm, sondern eine Funktion ist, gehe ich davon aus, dass das Programm einen Datenabschnitt enthält und der Linker die Adresse der Daten umgehend aktualisiert. Der Adressplatzhalter wird mit '????' bezeichnet.

Dies ist eine hexadezimale Darstellung des Codes. Die Parameter sind Zeiger auf Eingabezeichenfolge in SI und Zeiger auf den Ausgabepuffer in DI. Es wird angenommen, dass Zeichenfolgen NULL-terminiert sind.

8D1E????89F931D231C0FCAC84C07419D0EA72173C3C74263C41720A3C5A770684F675020C20AAEBE2AAC33C41720B3C5A76F324170402D7EBEC2C27EBF94646AC46240F74154848741748741948741A4848741A39F973B34FEBB04680F601EBAAB020AAAAAAB020EBBCB00AEBB84642EB99

Inhalt der Zuordnungstabelle (25 Bytes):

"   =<_>?)!@#$%^&*( :{}|`

Die Byteanzahl berücksichtigt sowohl Code als auch Daten.

Demontage:

8d 1e ?? ??        lea    bx,ds:???? ;Load address of mapping table to BX
89 f9              mov    cx,di      ;Save pointer to output buffer in CX
31 d2              xor    dx,dx      ;DX is the status register, bit 0 - shift status
31 c0              xor    ax,ax      ;bit 8 - caps lock status
fc                 cld               ;Clear DF

_loop:
ac                 lodsb             ;Fetch next char
84 c0              test   al,al      ;If end of string found
74 19              je     _end       ;break
d0 ea              shr    dl,1       ;Copy shift flag to CF and clear it
72 17              jc     _shift     ;Branch to input procssing with shift set
3c 3c              cmp    al,0x3c    ;If AL == '<'
74 26              je     _special   ;branch to special character processing
3c 41              cmp    al,0x41    ;At this point anything
72 0a              jb     _out       ;not in 'A'..'Z' range
3c 5a              cmp    al,0x5a    ;should be printed unmodified
77 06              ja     _out
84 f6              test   dh,dh      ;If caps lock status flag is set
75 02              jne    _out       ;go to printing right away
0c 20              or     al,0x20    ;otherwise convert to lower case
_out:
aa                 stosb             ;Store AL into output buffer
eb e2              jmp    _loop      ;Continue
_end:
aa                 stosb             ;NULL-terminate the output string
c3                 ret               ;and return

_shift:
3c 41              cmp    al,0x41    ;AL in the range [0x27..0x3b] with
72 0b              jb     _xlat0     ;a couple of holes in it

3c 5a              cmp    al,0x5a    ;AL in the range 'A'..'Z'
76 f3              jbe    _out       ;Since shift is active, go print it

24 17              and    al,0x17    ;AL is 0x5b, 0x5c, 0x5d or 0x7e,
04 02              add    al,0x2     ;convert to the [0x15..0x18] range
_xlat:
d7                 xlatb             ;Lookup mapping table (AL=[BX+AL])
eb ec              jmp    _out
_xlat0:
2c 27              sub    al,0x27    ;Convert AL to be a zero-based index
eb f9              jmp    _xlat      ;Reuse lookup code

_special:                            ;The next 4 or 5 chars are special character opcode
46                 inc    si         ;Since correct input format is guaranteed
46                 inc    si         ;don't bother reading & checking all of them,
ac                 lodsb             ;just load the third one and skip the rest
46                 inc    si         ;The lower 4 bits of the 3rd char
24 0f              and    al,0xf     ;allow to differentiate opcodes

74 15              jz     _sc_caps   ;0x0
48                 dec    ax
48                 dec    ax
74 17              jz     _sc_tab    ;0x2
48                 dec    ax
74 19              jz     _sc_spc    ;0x3
48                 dec    ax
74 1a              jz     _sc_ret    ;0x4
48                 dec    ax
48                 dec    ax
74 1a              jz     _sc_shft   ;0x6

_sc_del:                             ;0xC, <DEL> opcode
39 f9              cmp    cx,di      ;Check the length of the current output
73 b3              jae    _loop      ;DI <= CX ==> NOOP
4f                 dec    di         ;Remove the last char
eb b0              jmp    _loop
_sc_caps:                            ;<CAPS> opcode
46                 inc    si         ;Consume leftover '>' from the input
80 f6 01           xor    dh,0x1     ;Flip caps lock status bit
eb aa              jmp    _loop
_sc_tab:                             ;<TAB> opcode
b0 20              mov    al,0x20    ;Space char
aa                 stosb             ;Print it three times
aa                 stosb             ;and let the <SPC> handler
aa                 stosb             ;do the last one
_sc_spc:                             ;<SPC> opcode
b0 20              mov    al,0x20    ;Space char
eb bc              jmp    _out       ;Go print it
_sc_ret:                             ;<RET> opcode
b0 0a              mov    al,0xa     ;Newline char
eb b8              jmp    _out       ;Go print it
_sc_shft:                            ;<SHFT> opcode
46                 inc    si         ;Consume leftover '>' from the input
42                 inc    dx         ;Set shift status bit (DL is guaranteed to be zero)
eb 99              jmp    _loop

Für 32-Bit-Befehlssätze ist der Code absolut identisch, mit Ausnahme des ersten Befehls, der aufgrund der 32-Bit-Adressierung 2 Byte länger ist (8d1d ???????? lea ebx, ds: ??????? ?)

meden
quelle
Gute Arbeit! :) Wenn es nicht zu viel Mühe gibt, können Sie bitte überprüfen, ob Ihr Programm ifür den Testfall U<RET><DEL><DEL>Iund eine leere Zeichenfolge für die Eingabe zurückgibt und ausgibt RE<DEL><DEL>? Ich habe die Regeln bezüglich des Löschschlüssels ein wenig präzisiert. Wenn diese beiden Testfälle nicht funktionieren, können Sie bitte auch Ihren Code aktualisieren, damit er die richtige Ausgabe für diese Testfälle liefert. Vielen Dank!
R. Kap
Alle Testfälle waren erfolgreich. Warum sollte <DEL> falsch funktionieren? Es ist nur eine Registerdekrementierung mit
Grenzprüfung
Gut. Ich wollte nur sicherstellen, dass Ihr Programm so funktioniert, wie es sollte. Gute Antwort.
R. Kap
Wir brauchen mehr Sonderfälle. Es wäre interessanter, wenn <DEL> das <RET> nicht löschen könnte. Ich kann es in nur 3 Bytes implementieren.
meden
1
Wenn Sie die Befehlszeile einer Shell eingeben, ist dies absolut sinnvoll. Aber wohlgemerkt, ich bitte nicht um die Regeländerung. Danke für die Herausforderung.
meden
4

Netzhaut, 136 Bytes

Kann wahrscheinlich weiter Golf gespielt werden.

<SHFT>
§ §
<SPC>

<TAB>

<CAPS>
¶
<RET>
þ
<DEL>
÷
T`L`l` (? <= ^ (. * ¶. * ¶) *). +
T` - =; '[] / \\, w` \ _ +: "{}? | <> _)! @ # $% ^ & * (IL`§.
§ | ¶

i (`þ
¶
[^ §]? ÷

Überprüfen Sie alle Testfälle. (Leicht modifiziert, um alle Testfälle gleichzeitig auszuführen.)

Undichte Nonne
quelle
Großbuchstaben + Umschalt + A = a auf meiner Tastatur.
Neil
@Neil Nun, für die Zwecke dieser Herausforderung (und gemäß der Tastatur meines Macbook Pro) Caps+Shift+A = A. Mann, meine Tastatur ist komisch ...
R. Kap
CAPS + SHIFT + A = A. Warum um alles in der Welt würden Kappen die Verschiebung umkehren?
Katze
1
@cat in Millionen auf Windows-System CAPS Invert Shift, egal wie viele Fragezeichen Sie schreiben. Weil es bequem ist und Benutzer daran
gewöhnt
1
Aaaand, zwei 110-Byte-Lösungen: retina.tryitonline.net/… , retina.tryitonline.net/… ... Ich denke, ich bin jetzt fertig. ;)
Martin Ender
4

JavaScript (ES6), 207

Aktualisiert, um den Fehler durch wiederholtes Löschen zu beheben, auch wenn einige Bytes kürzer sind.

s=>s.replace(/<\w+>|./g,x=>(k=x[3])=='L'?o=o.slice(0,-1):k=='P'?l=!l:k=='F'?s=0:o+=k?k<'C'?'    ':k<'D'?' ':`
`:s?l?x.toLowerCase():x:s=")!@#$%^&*("[x]||'_={}|:"<>?'["-+[]\\;',./".indexOf(x)]||x,l=s,o='')&&o

weniger Golf gespielt

s=>s.replace( /<\w+>|./g, x =>
  (k=x[3]) == 'L' ? o = o.slice(0,-1)
  : k == 'P' ? l = !l
  : k == 'F' ? s = 0
  : o+= k ? k < 'C' ? '    ' : k < 'D' ? ' ' : '\n'
  : s ? l ? x.toLowerCase() : x
  : s = ")!@#$%^&*("[x] || '_={}|:"<>?' ["-+[]\\;',./".indexOf(x)] || x,
  l = s, o = ''
) && o

Prüfung

F=
s=>s.replace(/<\w+>|./g,x=>(k=x[3])=='L'?o=o.slice(0,-1):k=='P'?l=!l:k=='F'?s=0:o+=k?k<'C'?'    ':k<'D'?' ':`
`:s?l?x.toLowerCase():x:s=")!@#$%^&*("[x]||'_={}|:"<>?'["-+[]\\;',./".indexOf(x)]||x,l=s,o='')&&o

console.log=(...x)=>O.textContent+=x.join` `+'\n'

;[["1<SHFT>2<TAB><CAPS>R.KAP.<SPC><SHFT>123", "1@    R.KAP. !23"]
,["<SHFT>ABCDEFG<SHFT>HIJK<SHFT>1<SHFT>2<SHFT>3<SHFT>4567890", "AbcdefgHijk!@#$567890"]
,["<CAPS>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>CAPS<CAPS><SPC>NOW<SPC>THIS<SPC>IS<SPC>IN<SPC>ALL<SPC>LOWERCASE", "THIS IS IN ALL CAPS now this is in all lowercase"]
,["<TAB><SPC><TAB><SHFT>1", "         !"]
,["<CAPS>WWW<CAPS>.CODEGOLF.STACKEXCHANGE<SHFT>.COM", "WWW.codegolf.stackexchange>com"]
,["PROGRAMMING<CAPS><SPC>IS<SPC><CAPS>AWESOME", "programming IS awesome"]
,["<DEL><RET><DEL><RET><DEL>", ""]
,["<SHFT>HI<SPC>HOW<SPC>ARE<SPC>YOU<SHFT>/<RET><SHFT>I<SPC><SHFT>AM<SPC>O<DEL><SHFT>GOOD<SHFT>1", "Hi how are you?\nI Am Good!"]
,["<SHFT>,<CAPS>RET<CAPS><SHFT>.", "<RET>"]
,["<CAPS>67890,.;'[]<CAPS>", "67890,.;'[]"]
,["<CAPS><SHFT>A", "A"]
,["U<RET><DEL><DEL>I", "i"]
,["RE<DEL><DEL>", ""]
,["", ""]].forEach(t=>{
  var i=t[0],k=t[1],r=F(i)
  console.log(
    k==r?'OK':'KO',i,'\n->',r,k==r?'\n':'(should be ->'+k+')\n'
  )
})
<pre id=O></pre>

edc65
quelle
Gute Arbeit! :) Wenn es nicht zu viel Mühe gibt, können Sie bitte überprüfen, ob Ihr Programm Ifür den Testfall U<RET><DEL><DEL>Iund eine leere Zeichenfolge für die Eingabe zurückgibt und ausgibt RE<DEL><DEL>? Ich habe die Regeln bezüglich des Löschschlüssels ein wenig präzisiert. Wenn diese beiden Testfälle nicht funktionieren, können Sie bitte auch Ihren Code aktualisieren, damit er die richtige Ausgabe für diese Testfälle liefert. Vielen Dank!
R. Kap
Falsch für diese Testfälle. Ich muss einen anderen Ansatz wählen. In der Zwischenzeit U<RET><DEL>IiI
nehme
Ja, da hast du recht. Aktualisiert.
R. Kap