Golf Telegrafi: Dekode Kode Baudot

31

Latar Belakang

Pada tahun 1870, Emile Baudot menemukan Baudot Code , sebuah pengkodean karakter dengan panjang tetap untuk telegrafi. Dia merancang kode yang akan dimasukkan dari keyboard manual hanya dengan lima tombol; dua dioperasikan dengan tangan kiri dan tiga dengan tangan kanan:

Keyboard 5 tombol Baudot

Jari telunjuk kanan, tengah dan jari manis mengoperasikan kunci I , II , dan III , masing-masing, dan jari telunjuk kiri dan jari tengah mengoperasikan IV dan . (Selanjutnya saya akan menggunakan angka Arab Barat mereka, yaitu 1 , sampai 5. ) Karakter dimasukkan sebagai akord. Untuk memasukkan huruf "C," misalnya, operator menekan 1 , 3 , dan 4secara bersamaan, dimana lengan sikat berputar membaca setiap tombol secara berurutan dan mentransmisikan arus atau, untuk kunci yang tidak ditekan, tidak ada arus. Hasilnya adalah, dalam istilah modern, pengkodean biner 5-bit-paling-signifikan-bit-pertama, di mana contoh kita, "C," dikodekan sebagai 10110.

5 bit ??

Anda mungkin berpikir bahwa 5 bit, yang dapat mengekspresikan paling banyak 32 simbol unik, tidak cukup bahkan untuk semua huruf dan angka bahasa Inggris, untuk tidak mengatakan tanda baca. Namun, Baudot punya trik di lengan bajunya: Perangkat karakternya sebenarnya adalah dua perangkat yang berbeda: Surat dan Angka , dan dia mendefinisikan dua kode khusus untuk beralih di antara mereka. Letter Shift , yang beralih ke mode Letters, diaktifkan dengan menekan tombol 5 saja ( 00001), dan Gambar Shift diaktifkan dengan tombol 4 ( 00010).

Tantangan

Tantangan Anda adalah menulis program atau fungsi yang menerjemahkan transmisi Kode Baudot.

Transmisi yang sebenarnya akan dimulai dengan beberapa bit inisialisasi, ditambah bit mulai dan berhenti sebelum dan sesudah setiap karakter, tetapi kita akan melewatkan itu dan hanya khawatir tentang 5 bit unik untuk setiap karakter. Format input dan output dibahas di bawah ini.

Kode Baudot

Ada dua versi berbeda dari Kode Baudot: Continental dan Inggris. Kita akan menggunakan versi Inggris, yang tidak termasuk karakter seperti "É" dari bahasa Prancis asli Baudot. Kami juga akan mengabaikan semua simbol dalam versi Inggris yang tidak termasuk dalam karakter ASCII yang dapat dicetak. Anda hanya perlu mendekode karakter dalam tabel di bawah ini, yang semuanya merupakan karakter ASCII yang dapat dicetak kecuali tiga karakter kontrol terakhir yang dijelaskan di bawah tabel.

Kolom "Ltr" menunjukkan karakter dalam mode Letter dan "Fig" menunjukkan karakter mode Gambar:

        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

Tiga baris terakhir di kolom kanan adalah karakter kontrol:

  • ERadalah Penghapusan . Mesin telegraf Baudot akan mencetak simbol seperti tanda bintang untuk karakter ini untuk memberi tahu pembaca bahwa karakter sebelumnya harus diabaikan, tetapi kita akan lebih baik kepada pembaca dan benar - benar menghilangkan (tidak mencetak) karakter sebelumnya . Kerjanya sama dalam mode Letter dan Figure.

  • FSadalah Gambar Shift . Ini mengalihkan set karakter dari Letters ke Angka. Jika decoder sudah dalam mode Gambar, FS diperlakukan sebagai Spasi (ergo SPdi kolom "Ltr"). Ketika decoder berada dalam mode Gambar, ia tetap dalam mode Gambar sampai karakter LS diterima.

  • LSadalah Letter Shift . Ini beralih set karakter dari Angka ke Surat. Jika decoder sudah dalam mode Letter, LS diperlakukan sebagai Spasi . Ketika dalam mode Letter, decoder tetap dalam mode Letter sampai karakter FS diterima.

Dekoder selalu dimulai dalam mode Letter.

Berikut ini contoh dengan Gambar Shift, Letter Shift, dan Spasi:

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

Ini menghasilkan pesan MAY 15TH. Seperti yang Anda lihat, karakter pertama 00001(Letter Shift / Spasi) bertindak sebagai spasi, karena decoder sudah dalam mode Letter. Karakter berikutnya, 00010(Pergeseran Gambar / Spasi) mengalihkan dekoder ke mode Gambar untuk dicetak 15. Kemudian 00001muncul lagi, tapi kali ini berfungsi sebagai Letter Shift untuk mengembalikan decoder ke mode Letter.

Untuk kenyamanan Anda, berikut adalah karakter dalam format yang mungkin lebih mudah dicerna di editor, diurutkan berdasarkan kode:

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

Memasukkan

Input akan berupa string, array, atau daftar bit dengan urutan paling tidak signifikan-bit-pertama. Setiap karakter akan diwakili oleh kuintet 5 bit. Bit dapat dalam format apa pun yang masuk akal, misalnya string biner, array 0s dan 1s, string "0"dan "1" karakter, angka tunggal yang sangat besar, dll., Selama ia memetakan langsung ke bit transmisi.

Setiap transmisi akan memiliki setidaknya satu kwetet yang dapat dicetak dan paling banyak 255 kwintet (dapat dicetak atau sebaliknya), yaitu 5–1.275 bit inklusif.

Input hanya dapat berisi bit-bit transmisi, dengan dua pengecualian yang diizinkan: Sejumlah 0bit leading atau trailing dan / atau, untuk input string, baris baru trailing tunggal dapat ditambahkan ke transmisi. Leading atau trailing bits atau karakter tidak dapat ditambahkan sebelum atau setelah setiap quintet, yaitu Anda tidak dapat menambahkan setiap quintet ke 8 bit (atau mengambil setiap quintet sebagai angka tunggal dalam sebuah array — kecuali bahasa Anda memiliki tipe integer 5-bit) atau terpisah kwintet dengan bit tambahan, mis "01111\n11100".

Catatan & tepi kasus

  1. Transmisi hanya akan berisi karakter di kolom "Ltr" dan "Fig" pada tabel di atas. Anda tidak akan pernah menerima mis 01110dalam mode Gambar, karena tidak ada di kolom "Gambar".

  2. Diasumsikan bahwa decoder akan selalu dalam mode Letter di awal transmisi. Namun, karakter pertama mungkin merupakan karakter FS untuk segera beralih ke mode Gambar.

  3. Ketika decoder dalam mode Letter, itu mungkin menerima karakter LS, dan ketika itu dalam mode Gambar itu mungkin menerima karakter FS. Dalam kedua kejadian tersebut karakter Space harus dicetak (lihat Output).

  4. Karakter ER tidak akan pernah menjadi karakter pertama dalam suatu transmisi, juga tidak akan pernah segera mengikuti LS, FS, atau ER lainnya.

  5. Karakter FS dapat segera mengikuti karakter LS dan sebaliknya.

  6. Baik karakter LS maupun FS tidak akan menjadi karakter terakhir dalam transmisi apa pun.

  7. The /dan -karakter dapat diterima baik dalam modus Surat (kode 11000dan 10001, masing-masing) atau mode Gambar ( 10111 dan 00111).

Keluaran

Output mungkin dalam format yang masuk akal, yang paling masuk akal adalah ASCII (atau UTF-8, yang semua karakter yang diwakilkan sama dengan ASCII). Harap cantumkan dalam jawaban Anda jika output Anda dalam format atau penyandian lain.

Catatan

  • Karakter spasi (lihat 3. di atas) harus berupa spasi ASCII (0x20) atau yang setara dengan pengkodean Anda, yaitu apa yang Anda dapatkan saat menekan bilah spasi.

Kemenangan

Ini adalah . Kode terpendek dalam byte menang.

Batasan

  • Celah standar dilarang.

  • Spasi trailing dan / atau satu trailing newline diperbolehkan. Spasi terdepan atau karakter lain (yang bukan bagian dari transmisi) tidak diizinkan.

  • Anda tidak boleh menggunakan fungsi perpustakaan atau built-in apa saja yang menerjemahkan kode Baudot (atau keturunannya, misalnya Kode Murray, ITA-1, dll.).

Uji Kasus

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):     -/=/-
Jordan
sumber
Terkait
Jordan
1
Catatan: Saya menyandikan kotak uji dengan tangan; jika Anda melihat sesuatu yang keliru, silakan bicara.
Jordan
1
Dalam tabel kode dan intisari yang menyertainya, kode 00010terdaftar sebagai SPdalam mode huruf, dan FSdalam mode angka. Menurut deskripsi, jika kita dalam mode huruf dan kita menerima kode 00010, kita harus beralih ke mode angka, tetapi nilai-nilai dalam tabel tampaknya sebaliknya. Demikian juga sebaliknya untuk 00001.
Sok
3
Pria ini sangat pintar, saya tidak pernah tahu tentang kompresi yang digunakan dalam telegrafi. Terima kasih atas pelajaran sejarahnya.
Magic Octopus Guci
4
@computer Benar ?? Baudot tidak memiliki pendidikan formal di luar sekolah dasar, tetapi tidak hanya ia menciptakan Kode Baudot, ia menciptakan sistem multiplexing yang memungkinkan empat operator untuk menggunakan saluran telegraf tunggal secara bersamaan. Saya menemukan pamflet 1919 ini yang menggambarkan penemuannya dalam beberapa detail yang sangat menarik: samhallas.co.uk/repository/telegraph/b6_baudot_multiplex.pdf
Jordan

Jawaban:

6

Pyth, 98 97 95 93 90 83 80 byte

Kode ini berisi karakter yang tidak patut xxddicetak , jadi ini adalah hexdump yang dapat dibalik:

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

Cobalah online. Suite uji.

Cukup lama, tetapi tabel pencarian memakan sebagian besar ruang.

Untuk 117 byte, inilah hal yang sama tanpa unsintables (membutuhkan ISO-8859-1, meskipun):

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

Atau, untuk 93 byte, tanpa kompresi di tabel pencarian:

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

Arnauld
sumber
5

Batch, 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%

Mengambil input pada STDIN. Karena Batch tidak memiliki konversi biner, saya harus memalsunya menggunakan konversi oktal dan hex.

  • Dua digit pertama dikonversi dari oktal (saya tidak dapat menggunakan desimal karena digit pertama mungkin 0). Nilai yang mungkin adalah 00, 01, 10dan 11. Dua yang terakhir memiliki nilai 8dan 9tetapi saya ingin 2atau 3jadi saya mengambil modulo sisanya 6.
  • Tiga digit terakhir dikonversi dari heksadesimal. Digit adalah nilai kali 14atau yang 252diinginkan, untuk saya ambil modulo sisanya 14( 252=14*18).
  • c adalah string kode
  • r sejauh ini hasilnya
  • d adalah array decoding
  • s adalah indeks (dengan mempertimbangkan status shift) dari karakter yang mengganti status shift
  • nadalah decode biner plus bit 5 dari s, yang sama dengan keadaan shift, dalam hal ini keadaan shift diaktifkan, atau indeks ke dalam array decoding untuk menemukan karakter berikutnya (atau! untuk menghapus)
Neil
sumber
3

PHP, 206 Bytes

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);
Jörg Hülsermann
sumber
2

Chip , 1069 byte

Itu besar, tapi cukup menyenangkan untuk menulis.

Mengambil input sebagai string "1"'s dan "0"' s. (Meskipun itu hanya terlihat pada bit rendah.)

 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

Cobalah online!

Catatan: Erasure menggunakan karakter backspace ASCII ( \x08), yang berarti mereka akan terlihat lucu di TIO, tetapi mereka terlihat baik-baik saja, katakanlah, xterm.

Struktur dasar

Di atas, di atas =garis, adalah dekoder input. Ini mengubah input menjadi salah satu dari 32 sinyal terpisah. Ini dikirim dari o's di atas =ke yang di bawah ini.

Pegunungan segitiga L's dan R' s hanya memutar pola dari baris terpisah ke kolom. Kotak di bawah ini yang menerjemahkan setiap kolom ke karakter keluarannya. Untuk sinyal yang tidak dikenal, NUL ( \x00) diproduksi. Untuk shift khusus, alih-alih mencetak karakter, gumpalan kecil ke kanan mengubah mode.

Mobil kabel seperti di antara dua gunung menekan setiap percetakan di antara masing-masing kuintet, jika tidak, ini juga akan mencoba untuk memecahkan kode semua quintet yang tumpang tindih juga. Coba ganti !dengan spasi untuk melihatnya sendiri. (Berjalan dalam mode verbose -vmungkin juga menarik di sini.)

Saya tidak yakin bagaimana membuat ini lebih kecil saat ini; sudah cukup padat untuk ukurannya.

Phlarx
sumber
0

GNU sed, 334 + 1 = 335 byte

+1 byte untuk -rbendera. Mengambil input pada STDIN.

Melihat tantangan lama saya menyadari ini akan sangat mudah dengan sed, dan bagus untuk latihan. Saya belum mencoba kompresi apa pun, jadi tabel pencarian lebih dari setengah kode.

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

Cobalah online!

Penjelasan

Kode ini berfungsi dalam dua fase: Pertama, ia menggantikan setiap proses 5 digit biner dengan dua karakter yang sesuai (huruf dan gambar) dari tabel pencarian. Tabel pencarian dalam format 𝟎𝟎𝟎𝟎𝟎𝐋𝐅𝟎𝟎𝟎𝟎𝟎𝐋𝐅 ... di mana 𝟎 adalah digit biner dan 𝐋 dan 𝐅 masing-masing adalah huruf dan gambar yang sesuai. %mendukung karakter yang hilang (ini bisa berupa karakter apa pun selain baris baru). FS/SPdiwakili oleh f<space>dan SP/LSadalah <space>l. ERdiwakili oleh <<.

Kemudian ia melangkah melalui setiap pasangan dengan "kursor" yang sesuai dengan #mode saat ini— untuk mode huruf, @untuk mode gambar. The #kursor menghilangkan karakter kedua dari pasangan dan kemudian maju ke pasangan berikutnya, dan @menghilangkan pertama dan kemajuan. Dengan kata lain, #A1B8menjadi A#B8lalu AB#, dan @A1B8menjadi 1@B8lalu 18@. Ketika #kursor bertemu f<space>itu menghapusnya dan menggantikannya dengan @kursor, dan sebaliknya ketika @bertemu <space>l.

Ketika tidak ada pasangan yang tersisa, kursor terakhir akan dihapus bersama dengan karakter apa pun yang diikuti oleh <.

# 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.
Jordan
sumber