Telegraphy Golf: Decode Baudot Code


31

sfondo

Nel 1870 Émile Baudot inventò il Baudot Code , un carattere a lunghezza fissa codificante per la telegrafia. Ha progettato il codice da inserire da una tastiera manuale con solo cinque tasti; due operavano con la mano sinistra e tre con la destra:

Tastiera Baudot a 5 tasti

L'indice destro, il medio e l'anulare azionano rispettivamente i tasti I , II e III , mentre l'indice sinistro e il medio operano IV e . (D'ora in poi userò i loro numeri in arabo occidentale, cioè da 1 a 5 ). I personaggi vengono inseriti come accordi. Per inserire la lettera "C", ad esempio, l'operatore preme 1 , 3 e 4tasti contemporaneamente, dopo di che un braccio spazzola rotante legge ogni tasto in sequenza e trasmette una corrente o, per i tasti non premuti, nessuna corrente. Il risultato è, in termini moderni, una codifica binaria a 5 bit meno significativa-prima-bit, in cui il nostro esempio "C" è codificato come 10110.

5 bit ??

Potresti pensare che 5 bit, che possono esprimere al massimo 32 simboli univoci, non sono sufficienti anche per tutte le lettere e i numeri inglesi, per non parlare di punteggiatura. Baudot aveva un asso nella manica, tuttavia: il suo set di caratteri è in realtà due set distinti: Lettere e Figure , e ha definito due codici speciali per passare da uno all'altro. Letter Shift , che passa alla modalità Lettere, viene attivato premendo il tasto 5 da solo ( 00001), e Figura Shift viene attivato con il tasto 4 ( 00010).

Sfida

La tua sfida è scrivere un programma o una funzione che decodifichi le trasmissioni del codice Baudot.

Una vera trasmissione inizierebbe con alcuni bit di inizializzazione, più un bit di inizio e di fine prima e dopo ogni carattere, ma li salteremo e ci preoccuperemo solo dei 5 bit unici per ciascun personaggio. I formati di input e output sono discussi di seguito.

Codice Baudot

Esistono due diverse versioni del codice Baudot: Continental e UK Useremo la versione UK, che non include personaggi come "É" dal francese nativo di Baudot. Tralasceremo anche tutti i simboli nella versione inglese che non sono tra i caratteri ASCII stampabili. Dovrai solo decodificare i caratteri nella tabella seguente, tutti caratteri ASCII stampabili ad eccezione dei tre caratteri di controllo finali spiegati sotto la tabella.

La colonna "Ltr" mostra i caratteri in modalità Lettera e "Fig" mostra i caratteri in modalità Figura:

        Encoding             Encoding
Ltr Fig  12345       Ltr Fig  12345
--- --- --------     --- --- --------
 A   1   10000        P   +   11111
 B   8   00110        Q   /   10111
 C   9   10110        R   -   00111
 D   0   11110        S       00101
 E   2   01000        T       10101
 F       01110        U   4   10100
 G   7   01010        V   '   11101
 H       11010        W   ?   01101
 I       01100        X       01001
 J   6   10010        Y   3   00100
 K   (   10011        Z   :   11001
 L   =   11011        -   .   10001
 M   )   01011        ER  ER  00011
 N       01111        FS  SP  00010
 O   5   11100        SP  LS  00001
 /       11000

Le ultime tre righe nella colonna di destra sono caratteri di controllo:

  • ERè la cancellazione . Le macchine telegrafiche di Baudot stamperebbero un simbolo simile ad un asterisco per questo personaggio per dire al lettore che il personaggio precedente dovrebbe essere ignorato, ma saremo ancora più carini con il lettore e in realtà ometteremo (non stamperemo) il personaggio precedente . Funziona allo stesso modo sia in modalità Lettera che Figura.

  • FSè il cambio di figura . In questo modo il set di caratteri passa da Lettere a Figure. Se il decodificatore è già in modalità Figura, FS viene trattato come uno spazio (ergo SPnella colonna "Ltr"). Quando il decodificatore è in modalità Figura, rimane in modalità Figura finché non viene ricevuto un carattere LS.

  • LSè Letter Shift . Cambia il set di caratteri da Figure a Lettere. Se il decodificatore è già in modalità Letter, LS viene trattato come uno spazio . In modalità Letter, il decodificatore rimane in modalità Letter fino a quando non viene ricevuto un carattere FS.

Il decodificatore si avvia sempre in modalità Letter.

Ecco un esempio con Figure Shift, Letter Shift e Space:

01011 10000 00100 00001 00010 10000 11100 00001 10101 11010
  M     A     Y   LS/SP FS/SP   1     5   LS/SP   T     H

Questo produce il messaggio MAY 15TH. Come puoi vedere, il primo carattere 00001(Maiusc / Spazio) funge da spazio, poiché il decodificatore è già in modalità Lettera. Il carattere successivo, 00010(Figura Maiusc / Spazio) commuta il decodificatore in modalità Figura per stampare 15. Quindi 00001appare di nuovo, ma questa volta agisce come Letter Shift per riportare il decodificatore in modalità Letter.

Per comodità, ecco i caratteri in un formato forse più facile da digerire in un editor, ordinati per codice:

A,1,10000|E,2,01000|/,,11000|Y,3,00100|U,4,10100|I,,01100|O,5,11100|FS,SP,00010|J,6,10010|G,7,01010|H,,11010|B,8,00110|C,9,10110|F,,01110|D,0,11110|SP,LS,00001|-,.,10001|X,,01001|Z,:,11001|S,,00101|T,,10101|W,?,01101|V,',11101|ER,ER,00011|K,(,10011|M,),01011|L,=,11011|R,-,00111|Q,/,10111|N,,01111|P,+,11111

Ingresso

L'input sarà una stringa, un array o un elenco di bit nell'ordine meno significativo-bit-primo. Ogni personaggio sarà rappresentato da un quintetto di 5 bit. I bit possono essere in qualsiasi formato ragionevole, ad esempio una stringa binaria, una matrice di 0s e 1s, una stringa di "0"e "1" caratteri, un singolo numero molto grande, ecc., Purché si associ direttamente ai bit della trasmissione.

Ogni trasmissione avrà almeno un quintetto stampabile e al massimo 255 quintetti (stampabili o meno), vale a dire 5–1,275 bit inclusi.

L'input può contenere solo i bit della trasmissione, con due eccezioni consentite: Qualsiasi numero di 0bit iniziali o finali e / o, per l'input di stringhe, alla riga può essere aggiunta una sola riga finale nuova. I bit o i caratteri iniziali o finali non possono essere aggiunti prima o dopo ogni quintetto, ovvero non è possibile assegnare ciascun quintetto a 8 bit (o prendere ogni quintetto come un singolo numero in un array, a meno che la propria lingua abbia un tipo intero a 5 bit) o ​​separato quintetti con eventuali bit aggiuntivi, ad es "01111\n11100".

Note e custodie per bordi

  1. La trasmissione conterrà solo i caratteri nelle colonne "Ltr" e "Fig" nella tabella sopra. Non riceverai mai ad es 01110. In modalità Figura, perché è assente dalla colonna "Fig".

  2. Si presume che il decodificatore sarà sempre in modalità Lettera all'inizio di una trasmissione. Tuttavia, il primo carattere può essere un personaggio FS per passare immediatamente alla modalità Figura.

  3. Quando il decodificatore è in modalità Letter, può ricevere un carattere LS e quando è in modalità Figure può ricevere un carattere FS. In entrambi i casi, è necessario stampare un carattere Spazio (vedere Output).

  4. Il personaggio ER non sarà mai il primo personaggio in una trasmissione, né seguirà mai immediatamente un LS, FS o un altro ER.

  5. Un personaggio di FS può immediatamente seguire un personaggio di LS e viceversa.

  6. Né il personaggio LS né quello di FS saranno gli ultimi personaggi in nessuna trasmissione.

  7. I caratteri /e -possono essere ricevuti in modalità Lettera (codici 11000e 10001, rispettivamente) o Figura ( 10111 e 00111).

Produzione

L'output può essere in qualsiasi formato ragionevole, il più ragionevole è ASCII (o UTF-8, per il quale tutti i caratteri rappresentati sono gli stessi di ASCII). Indica nella tua risposta se l'output è in un'altra codifica o formato.

Gli appunti

  • Il carattere spaziale (vedi 3. sopra) dovrebbe essere uno spazio ASCII (0x20) o l'equivalente della codifica, ovvero ciò che ottieni quando premi la barra spaziatrice.

vincente

Questo è . Vince il codice più breve in byte.

restrizioni

  • Sono vietate le scappatoie standard.

  • Sono consentiti spazi finali e / o una nuova riga finale finale. Gli spazi iniziali o altri caratteri (che non fanno parte della trasmissione) non sono consentiti.

  • Non è possibile utilizzare alcuna funzione integrata o libreria che decodifichi il codice Baudot (o uno qualsiasi dei suoi discendenti, ad esempio Codice Murray, ITA-1, ecc.).

Casi test

Input: 001101000010100111101110010101
Output: BAUDOT
Input: 11010010001001100011110111101111100
Output: HELLO
Input: 01011100000010000001000101000011100000011010111010
Output: MAY 15TH
Input: 0001000100010000001000001011101110011100101010010110101010001111100101
Output: 32 FOOTSTEPS
Input: 10110000110101011100111100001111011010000001101110
Output: GOLF
Input: 000100011000001111100000100010110111001100010110010000111111
Output: 8D =( :P
Input: 0000100001000010000100010001111011111011000011100010001
Output (4 leading spaces):     -/=/-


1
Nota: ho codificato manualmente i casi di test; se vedi qualcosa che sembra sbagliato, per favore parla.
Giordania,

1
Nella tabella dei codici e nel digest associato, il codice 00010è elencato come SPin modalità lettera e FSin modalità figura. Secondo la descrizione, se siamo in modalità lettera e riceviamo codice 00010, dovremmo passare alla modalità figura, ma i valori nella tabella sembrano essere il contrario. Inoltre, viceversa per 00001.
Ha

3
Quest'uomo era dannatamente intelligente, non ho mai saputo della compressione usata in telegrafia. Grazie per la lezione di storia, amico.
Magic Octopus Urn

4
@carusocomputing Right ?? Baudot non aveva un'educazione formale oltre alla scuola elementare, ma non solo inventò il codice Baudot, ma inventò un sistema multiplexing che permetteva a quattro operatori di usare contemporaneamente una sola linea telegrafica. Ho trovato questo opuscolo del 1919 che descrive in modo molto dettagliato le sue invenzioni in dettaglio: samhallas.co.uk/repository/telegraph/b6_baudot_multiplex.pdf
Giordania,

Risposte:


6

Pyth, 98 97 95 93 90 83 80 byte

Il codice contiene caratteri non stampabili, quindi ecco un xxdhexdump reversibile :

00000000: 753f 7133 4a69 4832 5047 2b47 3f3c 334a  u?q3JiH2PG+G?<3J
00000010: 4040 6332 2e22 275a 75ae 5751 fb4e 3cd7  @@c2."'Zu.WQ.N<.
00000020: 02ce 8719 aac1 e0e0 fe1f 09e5 85bc a767  ...............g
00000030: 8e0c 1f47 508a cad1 1acb b26f 951e e5d6  ...GP......o....
00000040: 225a 4a2a 5c20 715a 3d5a 744a 637a 356b  "ZJ*\ qZ=ZtJcz5k

Provalo online. Suite di test.

Abbastanza lungo, ma la tabella di ricerca occupa la maggior parte della metà dello spazio.

Per 117 byte, ecco la stessa cosa senza non stampabili (richiede ISO-8859-1, però):

u?q3JiH2PG+G?<3J@@c2."'Zu®WQûN<×\x02Î\x87\x19ªÁààþ\x1f\tå\x85¼§g\x8e\x0c\x1fGP\x8aÊÑ\x1a˲o\x95\x1eåÖ"ZJ*\ qZ=ZtJcz5k

Oppure, per 93 byte, senza compressione nella tabella di ricerca:

u?q3JiH2PG+G?<3J@@c2"OVDPYSBREXGMIWFNA-JKUTCQ/ZHL5'0+3;8-2;7);?;;1.6(4;9/;:;="ZJ*\ qZ=ZtJcz5k

5

JavaScript (ES6), 160 158 153 byte

let f =
    
s=>s.replace(/.{5}/g,s=>(n='0b'+s-1)<2?m-n?(m^=1,''):' ':"? !YSBREXGMIWFNA-JKUTCQ/ZHLOVDP? ?!3 8-2 7) ?  1.6(4 9/ : =5'0+"[n+m*32],m=0).replace(/.!/g,'')

console.log(f("001101000010100111101110010101"));
console.log(f("11010010001001100011110111101111100"));
console.log(f("01011100000010000001000101000011100000011010111010"));
console.log(f("0001000100010000001000001011101110011100101010010110101010001111100101"));
console.log(f("10110000110101011100111100001111011010000001101110"));
console.log(f("000100011000001111100000100010110111001100010110010000111111"));
console.log(f("0000100001000010000100010001111011111011000011100010001"));


5

Lotto, 306 304 byte

@echo off
set/pc=
set r=
set d=! !!YSBREXGMIWFNA-JKUTCQ/ZHLOVDP!! !3!8-2!7)!?!!1.6(4!9/!:!=5'0+
set s=2
:l
set/an=(s^&32)+0%c:~,2%%%6*8+0x%c:~2,3%%%14
set c=%c:~5%
if %n%==%s% set/as^^=35&goto l
call set r=%%r%%%%d:~%n%,1%%
if %r:~-1%==! set r=%r:~,-2%&goto l
if not "%c%"=="" goto l
echo %r%

Accetta input su STDIN. Dato che Batch non ha una conversione binaria, devo falsificarlo usando la conversione ottale ed esadecimale.

  • Le prime due cifre sono convertite da ottale (non posso usare il decimale perché la prima cifra potrebbe essere 0). I valori possibili sono 00, 01, 10e 11. Gli ultimi due hanno valore 8e 9ma io voglio 2o 3meno prendo il modulo rimanente 6.
  • Le ultime tre cifre vengono convertite da esadecimali. Le cifre sono 14o 252volte il loro valore desiderato, per prendere il resto modulo 14( 252=14*18).
  • c è la stringa codificata
  • r è il risultato finora
  • d è l'array di decodifica
  • s è l'indice (tenendo conto dello stato di spostamento) del carattere che cambia stato di spostamento
  • nè la decodifica binaria più il bit 5 di s, che equivale allo stato di spostamento, nel qual caso lo stato di spostamento viene attivato o indicizzato nell'array di decodifica per trovare il carattere successivo (o! per cancellare)

3

PHP, 206 byte

foreach(str_split($argv[1],5)as$s)($k="# f*YSBREXGMIWFNA-JKUTCQ/ZHLOVDP#l *3#8-2#7)#?##1.6(4#9/#:#=5'0+"[32*$f+bindec($s)])=="*"?array_pop($a):($k=="f"?$f=1:($k=="l"?$f=0:($k=="#"?:$a[]=$k)));echo join($a);

2

Chip , 1069 byte

È fantastico, ma è stato abbastanza divertente scrivere.

Prende l'input come una stringa di "1""se "0"". (Anche se in realtà guarda solo alla parte bassa.)

 AZZZZ,-o.AZZZZ  AZZZZ,o-.AZZZZ
*\\\\\]oo[\/\\\**//\\\]oo[/\\\\*
*\\\\/]oo[\/\\/**//\\/]oo[/\\\/*
*\\\//]oo[\/\//**//\//]oo[/\\//*
*\\\/\]oo[\/\/\**//\/\]oo[/\\/\*
*\\//\]oo[\///\**////\]oo[/\//\*
*\\///]oo[\////**/////]oo[/\///*
*\\/\/]oo[\//\/**///\/]oo[/\/\/*
*\\/\\]oo[\//\\**///\\]oo[/\/\\*
=
        o--------K-----o
      ,oo.   z---+~S  ,oo.
     ,LooR. !ZZZZ'   ,LooR.
    ,LLooRR.        ,LLooRR.
   ,LLLooRRR.      ,LLLooRRR.
  ,LLLLooRRRR.    ,LLLLooRRRR.
 ,LLLLLooRRRRR.  ,LLLLLooRRRRR. ,~Z
,LLLLLLooRRRRRR.,LLLLLLooRRRRRR.>m'
|||||||oo||||||||||||||oo||||||)/Rz.
xxxxxxxxxxxxxxx)xxxxxxxxxxxxxxxx\^-^S
x)x))))))))))))xx)))))))))))))xx\g
xx)xxxxxxxxxxxxxxxxxxxxxxxxxxx))\f
xxxxxx))xxxxxxxxxxxxx)))))))))xx\e
xx)x))x)xxxxx))x)))))xxxxxxx)))x\d
xx))x))xxx)))xxxxx)))xxxx)))xx)x\c
xx)xx)xx))x))x)xx)xx)xx))x))x)xx\b
x)))))))x)xx)xxxx)x)xx)x)xx)xx)x\a
x)x)x))))))x)x))x)))x)))xx))x))x/f
x)x)x))))))x)x)xxx)xxxxxxxx)x)xx/e
xxxxxxxx))xxxxxx))))x)))xxx)x))x/d
xxxxx))xxxxx)x)xxx)xxx))xx))xx)x/c
xxx)xxx)xxxx)x)xxxxxx))xxx))x))x/b
x)xxx)x)x)xx)xxxxx))x)))xx))xxxx/a

Provalo online!

Nota: la cancellazione utilizza il carattere di backspace ASCII ( \x08), il che significa che appariranno divertenti in TIO, ma sembrano a posto in, diciamo, xterm.

Struttura basilare

Nella parte superiore, sopra la =linea, si trova il decodificatore di ingresso. Trasforma l'ingresso in uno dei 32 segnali separati. Questi vengono inviati da quelli osopra =a quelli sotto.

Le montagne triangolari di L"se R" ruotano il motivo da file separate a colonne. La griglia sottostante che traduce ogni colonna nel suo carattere di output. Per segnali sconosciuti, NUL (\x00 viene prodotto ). Per i turni speciali, invece di stampare un personaggio, la piccola chiazza a destra cambia la modalità.

La funivia tra le due montagne sopprime qualsiasi stampa tra ciascun quintetto, altrimenti tenterebbe di decodificare anche tutti i quintetti sovrapposti. Prova a sostituirlo !con uno spazio per vederlo da solo. (Anche l'esecuzione in modalità dettagliata -vpuò essere interessante qui.)

Non sono sicuro di come ridurlo al momento; è già abbastanza denso per le sue dimensioni.


0

GNU sed, 334 + 1 = 335 byte

+1 byte per -rflag. Accetta input su STDIN.

Esaminando le vecchie sfide ho capito che sarebbe stato abbastanza facile con sed e buono per la pratica. Non ho provato alcuna compressione, quindi la tabella di ricerca è più della metà del codice.

s|.*|#@&;01000E211000/%00100Y310100U401100I%11100O500010f 10010J601010G711010H%00110B810110C901110F%00001 l10001-.01001X%11001Z:00101S%10101T%01101W?11101V'00011<<10011K(01011M)11011L=00111R-10111Q/01111N%11111P+10000A111110D0|
:
s/@([01]{5})(.*;.*\1)(..)/\3@\2\3/
t
s/@;.*//
s/#f /@/
s/@ l/#/
s/#(.)./\1#/
s/@.(.)/\1@/
t
s/.<|[#@]//g

Provalo online!

Spiegazione

Il codice funziona in due fasi: in primo luogo, sostituisce ogni sequenza di 5 cifre binarie con i due caratteri corrispondenti (lettera e figura) da una tabella di ricerca. La tabella di ricerca è nel formato 𝟎𝟎𝟎𝟎𝟎𝐋𝐅𝟎𝟎𝟎𝟎𝟎𝐋𝐅… dove 𝟎 è una cifra binaria e 𝐋 e 𝐅 sono rispettivamente la lettera e la figura corrispondenti. %sta per caratteri mancanti (potrebbe trattarsi di qualsiasi personaggio diverso da newline). FS/SPè rappresentato da f<space>ed SP/LSè <space>l. ERè rappresentato da<< .

Quindi passa attraverso ciascuna coppia con un "cursore" corrispondente alla modalità corrente, #per la modalità lettera, @per la modalità figura. Il #cursore rimuove il secondo carattere della coppia, quindi avanza alla coppia successiva e @rimuove la prima e avanza. In altre parole, #A1B8diventa A#B8e poi AB#, e @A1B8diventa 1@B8e poi 18@. Quando il #cursore incontra, f<space>lo elimina e si sostituisce con il @cursore e viceversa quando @incontra <space>l.

Quando non rimangono coppie, il cursore finale viene rimosso insieme a tutti i caratteri seguiti da <.

# Setup: Append a lookup table to the line.
# Also prepends "#" and "@" which we'll use as "cursors" later.
s|.*|#@&;01000E211000/%00100Y310100U401100I%11100O500010f 10010J601010G711010H%00110B810110C901110F%00001 l10001-.01001X%11001Z:00101S%10101T%01101W?11101V'00011<<10011K(01011M)11011L=00111R-10111Q/01111N%11111P+10000A111110D0|

# Phase 1
:
  # Using "@" as a "cursor", substitute for each run of 5 binary digits the
  # two corresponding characters from the lookup table.
  s/@([01]{5})(.*;.*\1)(..)/\3@\2\3/
  t   # Loop (branch to `:`) as long as substitutions are made.

s/@;.*//       # Delete the "@" and lookup table

# Phase 2
s/#f /@/       # FS (f ) in letter mode (#); delete and switch to figure mode (@ cursor).
s/@ l/#/       # LS ( l) in figure mode (@); delete and switch to letter mode (# cursor).
s/#(.)./\1#/   # Letter mode; replace pair with first of pair; advance cursor.
s/@.(.)/\1@/   # Figure mode; replace pair with second of pair; advance cursor.
t              # If any substitutions were made, branch (loop) to `:`.

# Teardown
s/.<|[#@]//g   # Delete characters followed by < (ER) and cursor.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.