Telegraphy Golf: Kod Çözme Baudot Kodu


31

Arka fon

1870 yılında Émile Baudot , telgrafiyi kodlayan sabit uzunlukta bir karakter olan Baudot Kodunu icat etti . Manuel klavyeden girilecek kodu yalnızca beş tuş ile tasarladı; iki tanesi sol el ile ve üç tanesi sağ el ile kumanda edilir:

Baudot 5 tuşlu klavye

Sağ işaret, orta ve zil parmakları sırasıyla I , II ve III tuşlarını, sol işaret ve orta parmakları IV ve tuşlarını kullanır . (Bundan böyle, onların Batılı, Arap rakamları kullanacağız yani 1 yoluyla 5 .) Karakterler akor olarak girilir. Örneğin "C" harfini girmek için, operatör 1 , 3 ve 4 tuşlarına basar.tuşlar aynı anda, döner bir fırça kolu her tuşa sırayla okur ve bir akım iletir ya da, basılmamış tuşlar için akım olmaz. Sonuç, modern terimlerle, "C" örneğimizin olduğu gibi kodlandığı, 5 bitlik en az anlamlı olan ilk bitlik ikili kodlamadır 10110.

5 bit ??

En fazla 32 benzersiz sembolü ifade edebilecek 5 bitin, tüm İngilizce harfleri ve sayıları için bile, noktalama işareti söylememesi için yeterli olmadığını düşünüyor olabilirsiniz. Ancak Baudot, kılıfını kandırdı: Karakter karakteri aslında iki ayrı setti: Harfler ve Rakamlar ve aralarında geçiş yapmak için iki özel kod tanımladı. Harfler moduna geçen Letter Shift , sadece 5 tuşuna ( 00001) basılarak ve Şekil Shift , 4 tuşu ( 00010) ile etkinleştirilir .

Meydan okuma

Buradaki zorluk, Baudot Kodu iletimlerinin kodunu çözen bir program veya işlev yazmaktır.

Gerçek bir iletim bazı başlatma bitleriyle başlar, artı her karakterden önce ve sonra bir başlangıç ​​ve durma biti ile başlar, ancak bunları atlayacağız ve her karakter için sadece 5 benzersiz bit için endişeleneceğiz. Giriş ve çıkış formatları aşağıda tartışılmaktadır.

Baudot Kodu

Baudot Kodunun iki farklı sürümü vardır: Kıta ve İngiltere Baudot'un ana dilindeki Fransızca'dan "É" gibi karakterler içermeyen İngiltere sürümünü kullanacağız . Ayrıca, Birleşik Krallık versiyonunda, yazdırılabilir ASCII karakterleri arasında olmayan tüm sembolleri dışarıda bırakacağız. Aşağıdaki tabloda, sadece tablonun altında açıklanan son üç kontrol karakteri dışında yazdırılabilir ASCII karakterleri olan karakterlerin kodunu çözmeniz gerekecektir.

"Ltr" sütunu, Harf modundaki karakterleri gösterir ve "Şekil", Şekil modu karakterlerini gösterir:

        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

Sağ sütundaki son üç satır kontrol karakterleridir:

  • ERolduğunu Silme . Baudot'un telgraf makineleri, okuyucuya önceki karakterin göz ardı edilmesi gerektiğini söylemesi için bu karaktere yıldız işareti benzeri bir simge basar, ancak okuyucuya daha iyi davranırız ve aslında önceki karakteri atlar (basmaz) . Hem Letter hem de Şekil modunda aynı şekilde hareket eder.

  • FSolan Şekil Kaydırma . Bu, karakter kümesini Harflerden Rakamlara değiştirir. Kod çözücü zaten Şekil modundaysa, FS Boşluk olarak değerlendirilir ( SP"Ltr" sütununda ergo ). Kod çözücü Şekil modundayken, bir LS karakteri alınana kadar Şekil modunda kalır.

  • LSolduğunu Harf Shift . Karakter kümesini Şekillerden Harflere değiştirir. Kod çözücü zaten Letter modundaysa, LS Boşluk olarak değerlendirilir . Letter modundayken kod çözücü, bir FS karakteri alınana kadar Letter modunda kalır.

Kod çözücü her zaman Harf modunda başlar.

İşte Şekil Değiştirme, Harf Değiştirme ve Boşluğa bir örnek:

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

Bu mesaj verir MAY 15TH. Gördüğünüz gibi, ilk 00001(Harf Kaydırma / Boşluk) karakteri boşluk olarak işlev görür, çünkü kod çözücü zaten Harf modundadır. Bir sonraki karakter, 00010(Figure Shift / Space), dekoderi yazdırmak için Şekil moduna getirir 15. Sonra 00001tekrar belirir, ancak bu sefer dekoderi Letter moduna geri döndürmek için Letter Shift işlevi görür.

Size kolaylık sağlamak için, burada bir düzenleyicide sindirilmesi daha kolay, biçimine göre sıralanmış, kodlara göre sıralanmış karakterler:

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

Giriş

Girdi, en az anlamlı bit ilk sırada bir dize, dizi veya bitlerin listesi olacaktır. Her karakter 5 bitlik bir quintet ile temsil edilecektir. Bitler, doğrudan iletim bitlerine eşlendiği sürece herhangi bir makul formatta, örneğin bir ikili dize, bir 0s ve 1s dizisi , bir dize "0"ve "1"karakter, tek bir çok büyük sayı vb. Olabilir.

Her iletimin en az bir adet yazdırılabilir beşlisi ve en çok 255 adet beşlisi (yazdırılabilir veya başka türlü), yani 5–1,275 bit olacaktır.

Girdi, izin verilen iki istisna dışında yalnızca iletimin bitlerini içerebilir : Herhangi bir sayıda 0satır veya iz bit ve / veya dizge girişi için iletime tek bir izleyen satır eklenebilir. Liderlik veya takip bitleri veya karakterleri , her beşlikten önce veya sonra eklenemez; yani, her beşlisi 8 bite (ya da her beşlisi bir dizide tek bir sayı olarak kabul edemezsiniz - diliniz 5 bitlik bir tamsayı tipinde değilse) veya ayrı Herhangi bir ek bit ile quintets, ör "01111\n11100".

Notlar ve kenar kılıfları

  1. İletim yalnızca yukarıdaki tabloda "Ltr" ve "Fig" sütunlarındaki karakterleri içerecektir. 01110"Şekil" sütununda bulunmadığından, örneğin Şekil modundayken asla almazsınız .

  2. Kod çözücünün bir iletimin başlangıcında her zaman Harf modunda olacağı varsayılmaktadır. Bununla birlikte, ilk karakter hemen Şekil moduna geçmek için bir FS karakteri olabilir .

  3. Kod çözücü Letter modundayken, bir LS karakteri alabilir ve Şekil modundayken bir FS karakteri alabilir. Her iki durumda da bir Boşluk karakteri yazdırılmalıdır (Çıktıya bakın).

  4. ER karakteri hiçbir zaman bir iletimdeki ilk karakter olmayacak ve bir LS, FS veya başka bir ER'yi de hemen izleyemeyecektir.

  5. Bir FS karakteri hemen bir LS karakterini takip edebilir ve tam tersi de olabilir.

  6. Ne LS ne de FS karakter hiçbir iletideki son karakter olmayacak.

  7. /Ve -karakterler ya mektup modunda (kodları içine alınabilir 11000ve 10001, sırası ile) ya da Şekil modu ( 10111 ve 00111).

Çıktı

Çıktı, en makul olan ASCII (veya temsil edilen karakterlerin hepsinin ASCII ile aynı olduğu UTF-8) olan herhangi bir makul formatta olabilir. Lütfen çıktınızın başka bir kodlama veya formatta olup olmadığını cevabınızda belirtiniz.

notlar

  • Boşluk karakteri (yukarıya bakın 3.) bir ASCII boşluğu (0x20) veya kodlamanın eşdeğeri olmalıdır, yani boşluk çubuğuna bastığınızda ne elde edersiniz.

Kazanan

Bu . Bayt cinsinden en kısa kod kazanır.

Kısıtlamalar

  • Standart boşluklar yasaktır.

  • Sondaki boşluklara ve / veya sondaki tek bir yeni satıra izin verilir. Önde gelen boşluklara veya diğer karakterlere (iletimin parçası olmayan) izin verilmez.

  • Baudot Kodunu (veya onun torunlarından herhangi birini, örneğin Murray Code, ITA-1 vb.) Deşifre eden herhangi bir yerleşik veya kütüphane işlevini kullanamazsınız.

Test Kılıfları

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
Not: Test durumlarını elle kodladım; yanlış görünen bir şey görürseniz lütfen konuşun.
Ürdün

1
Kod tablosunda ve eşlik eden özette, kod harf modunda ve şekil modunda 00010olduğu gibi listelenir . Açıklamaya göre, harf modundaysak ve kod alırsak, şekil moduna geçmeliyiz, ama tablodaki değerler tersi gibi görünüyor. Ayrıca, bunun tersi de geçerlidir . SPFS0001000001
Sok

3
Bu adam çok akıllıydı, telgrafta kullanılan sıkıştırmayı hiç bilmiyordum. Tarih dersi için teşekkürler.
Magic Octopus Urn

4
@carusocomputing Sağ ?? Baudot'un ilkokul dışında resmi bir eğitimi yoktu, ama sadece Baudot Kodunu icat etmekle kalmadı, aynı zamanda dört operatörün aynı anda tek bir telgraf hattını kullanmasına izin veren çoklama sistemini icat etti. Buluşlarını açıklayan ve çok ilginç bir şekilde açıklayan bu 1919 broşürünü çok ilginç buldum
Ürdün

Yanıtlar:


6

Pyth, 98 97 95 93 90 83 80 bayt

Kod yazdırılamayan karakterler içeriyor, bu yüzden geri dönüşümlü bir xxdhexdump:

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

Çevrimiçi deneyin. Test odası.

Oldukça uzun, ancak arama tablosu çoğu zaman alıyor alanının yarısını.

117 bayt için, işte yazdırılamayan aynı şey (ISO-8859-1'e ihtiyacı var):

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

Veya, arama tablosunda sıkıştırma olmadan 93 bayt için:

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 bayt

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

Toplu İş, 306 304 bayt

@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%

STDIN'de girişi ele alır. Batch ikili dönüşüm olmadığından sekizli ve onaltılık dönüşüm kullanarak sahte yapmak zorundayım.

  • İlk iki hane sekizlikten dönüştürülür (ilk hane olabileceği için ondalık kullanamam 0). Olası değerler 00, 01, 10ve 11. Son iki değere sahip 8ve 9fakat istediğim2 ya da 3öylesine ben kalanı modulo alıyorum6 .
  • Son üç hane onaltılıktan dönüştürülür. Kalan modüloyu almak için rakamlar, istenen değerlerinin ya 14da 252zamanlarının değeridir 14(252=14*18 ) ' .
  • c kodlu dize
  • r sonuç şu ana kadar
  • d kod çözme dizisi
  • s vardiya durumunu değiştiren karakterin indeksi (vardiya durumunu dikkate alan)
  • nİkili kod çözme artı biti 5'tir s; bu, kayma durumuna eşittir, bu durumda kayma durumu değiştirilir veya bir sonraki karakteri bulmak için kod çözme dizisine indekslenir (veya!

3

PHP, 206 Bayt

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

Çip , 1069 bayt

Bu büyük bir neydi ama yazmak oldukça eğlenceliydi.

Girdiyi "1"'ve "0"' lerin dizgesi olarak alır . (Gerçekten de sadece düşük bite bakarsa da)

 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

Çevrimiçi deneyin!

Not: Silme, ASCII backspace karakterini ( \x08) kullanır; bu, TIO'da komik görünecekleri anlamına gelir, ancak xterm olarak iyi görünürler.

Basit yapı

Üstte, =satırın üstünde giriş kod çözücüsü bulunur. Girişi 32 ayrı sinyalden birine dönüştürür. Bunlar, oyukarıdakilerden =aşağıdakine gönderilir.

L'Nın ve R' nin üçgen dağları , deseni yalnızca ayrı satırlardan sütunlara döndürür. Her bir sütunu çıktı karakterine çeviren aşağıdaki ızgara. Bilinmeyen sinyaller için, NUL ( \x00) üretilir. Özel vardiyalarda, karakter basmak yerine, sağdaki küçük damla modu değiştirir.

İki dağ arasındaki teleferik benzeri şey, her quintet arasındaki herhangi bir baskıyı bastırır, aksi takdirde bu, üst üste gelen tüm quintet'leri deşifre etmeye çalışır. Bunu !kendiniz görmek için bir boşlukla değiştirmeyi deneyin . (Ayrıntılı modda çalışmak -vda ilgi çekici olabilir.)

Şu an bunun nasıl daha küçük hale getirileceğinden emin değilim; Zaten onun boyutu için oldukça yoğun.


0

GNU sed, 334 + 1 = 335 bayt

-rBayrak için +1 bayt . STDIN'de girişi ele alır.

Eski zorluklara bakmakla, bunun sed ile oldukça kolay ve pratikte iyi olacağını fark ettim. Sıkıştırma girişiminde bulunmadım, bu yüzden arama tablosu kodun yarısından fazla.

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

Çevrimiçi deneyin!

açıklama

Kod iki aşamada çalışır: Birincisi, arama tablosundaki 5 karakterin her basamağını karşılık gelen iki karakterle (harf ve şekil) değiştirir. Arama tablosu 𝟎𝟎𝟎𝟎𝟎𝐋𝐅𝟎𝟎𝟎𝟎𝟎𝐋𝐅… biçimindedir, burada 𝟎 bir ikili rakamdır ve 𝐋 ve 𝐅 sırasıyla karşılık gelen harf ve rakamdır. %eksik karakterleri temsil eder (bu, yeni satır dışında herhangi bir karakter olabilir). FS/SPile temsil edilir f<space>ve SP/LSbir <space>l. ERile temsil edilir <<.

Daha sonra, her bir çift boyunca o anki #moda tekabül eden imleç ile ilerler - harf modu @için, şekil modu için. #İmleç çiftinin ikinci karakterini kaldırır ve daha sonra bir sonraki çifte ilerler ve @birinci ve gelişmeleri kaldırır. Başka bir deyişle, #A1B8olur A#B8ve sonra AB#ve @A1B8olur 1@B8sonra ve 18@. Zaman #imleç karşılaşır f<space>bunu siler ve kendini yerine @imleç ve ters zaman tam tersi @karşılaşır <space>l.

Hiçbir çift kalmadığında, son imleç, ardından gelen karakterlerle birlikte kaldırılır <.

# 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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.