電信ゴルフ:Baudotコードのデコード


31

バックグラウンド

1870年、エミールバウドットは電報用の固定長文字エンコーディングであるバウドットコードを発明しました。彼は、5つのキーを備えた手動キーボードからコードが入力されるように設計しました。2つは左手で、3つは右手で操作しました。

Baudot 5キーキーボード

右のインデックスは、ミドルと薬指が動作III、および IIIそれぞれのキーを、左人差し指と中指が動作 IVⅤを。(以降、西アラビア数字、つまり 1から5を使用します。)文字は和音として入力されます。例えば、文字「C」を入力するには、操作者が押圧13、及び4キーを同時に押すと、回転するブラシアームが各キーを順番に読み取り、電流を送信します。押されていないキーの場合は電流を送信しません。結果は、最新の用語では、5ビットの最下位ビット優先のバイナリエンコードになります。この例では、「C」がとしてエンコードされ10110ます。

5ビット??

最大32個の一意の記号を表現できる5ビットでは、句読点は言うまでもなく、すべての英語の文字や数字でも十分ではないと考えているかもしれません。しかし、Baudotはスリーブを巧みに操っていました。彼のキャラクターセットは、実際にはLettersFiguresという2つの異なるセットであり、それらを切り替える2つの特別なコードを定義しました。 レターモードに切り替わるレターシフトは、5キーのみを押すとアクティブになり()、図シフト4キーでアクティブになり ます()。0000100010

チャレンジ

あなたの課題は、Baudotコード送信をデコードするプログラムまたは関数を書くことです。

実際の送信は、いくつかの初期化ビットに加えて、各文字の前後に開始ビットと停止ビットが追加されますが、それらをスキップし、各文字の5つの一意のビットのみを心配します。入力および出力形式については以下で説明します。

バウドットのコード

Baudotコードには2つの異なるバージョンがあります。ContinentalとUK Baudotのネイティブフランス語の「É」などの文字を含まない UKバージョンを使用します。また、印刷可能なASCII文字に含まれない英国版のすべてのシンボルを除外します。下の表の文字をデコードするだけでよく、表の下に説明されている最後の3つの制御文字を除き、すべて印刷可能なASCII文字です。

「Ltr」列はレターモードの文字を示し、「図」は図モードの文字を示します。

        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

右の列の最後の3行は制御文字です。

  • ERある消去は。Baudotの電信機は、この文字にアスタリスクのような記号を印刷して、先行する文字を無視することを読者に伝えますが、読者にさらに優しくして、実際に先行する文字を省略します(印刷しない)。文字モードと図モードの両方で同じように機能します。

  • FSである。図シフト。これにより、文字セットが文字から数字に切り替わります。デコーダーが既に Figureモードにある場合、FSはスペースSP「Ltr」列のエルゴ)として扱われます。デコーダーが図モードの場合、LS文字が受信されるまで図モードのままになります。

  • LSある手紙シフト。文字セットを数字から文字に切り替えます。デコーダーが既にレターモードになっている場合、LSはSpaceとして扱われます。レターモードの場合、FS文字が受信されるまでデコーダはレターモードのままです。

デコーダーは常にレターモードで起動します。

以下に、Figure Shift、Letter Shift、およびSpaceの例を示します。

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

これはメッセージをもたらしますMAY 15TH。ご覧のとおり00001、デコーダーは既にレターモードになっているため、最初の(文字シフト/スペース)文字はスペースとして機能します。次の文字00010(Figure Shift / Space)は、デコーダーをFigureモードに切り替えて印刷します15。その後00001、再び表示されますが、今回はレターシフトとして機能し、デコーダをレターモードに戻します。

便宜上、エディターでダイジェストしやすい形式の文字をコード別にソートして示します。

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

入力

入力は、文字列、配列、または最下位ビット優先順のビットのリストになります。各文字は5ビットのクインテットで表されます。ビットは、任意の合理的な形式、例えば、Aバイナリ文字列の配列であってもよく、0Sおよび1S、列"0""1" であれば送信のビットに直接マッピングするように、文字等、単一の非常に大きな数、。

すべての送信には、少なくとも1つの印刷可能なクインテットと最大で255のクインテット(印刷可能またはそれ以外)、つまり5〜1,275ビットが含まれます。

入力には、送信のビットのみを含めることができますが、許可される例外は2つあります。任意の数の先頭または末尾0ビット、および/または文字列入力の場合、単一の末尾改行を送信に追加できます。各クインテットの前後に、先頭または末尾のビットまたは文字追加することはできません。つまり、各クインテットを8ビットにパディングすることはできません(または、各クインテットを配列内の単一の数字として取ることができます(言語が5ビット整数型でない限り)追加ビットのあるクインテット"01111\n11100"

メモとエッジケース

  1. 送信には、上の表の「Ltr」列と「Fig」列の文字のみが含まれます。01110「Fig」列には存在しないため、例えばFigureモードでは受信しません 。

  2. デコーダーは、送信の開始時に常にレターモードになっていると想定されます。ただし、最初の文字、フィギュアモードにすぐに切り替えるためのFS 文字である場合があります。

  3. デコーダーがレターモードの場合、LS文字を受け取ることがあり、フィギュアモードの場合、FS文字を受け取ることがあります。いずれの場合も、スペース文字を印刷する必要があります(出力を参照)。

  4. ERキャラクターは、伝送の最初のキャラクターになることはなく、LS、FS、または別のERの直後に続くこともありません。

  5. FSキャラクターはLSキャラクターの直後に続く場合があります。

  6. LS文字もFS文字も、送信の最後の文字にはなりません。

  7. /そして-文字がいずれかの文字モード(コードで受信することができる1100010001、それぞれ)または図モード(1011100111)。

出力

出力は、ASCII(またはUTF-8、表現されたすべての文字がASCIIと同じ)が最も妥当な形式であれば、どのような形式でもかまいません。出力が別のエンコードまたは形式であるかどうかを回答で示してください。

ノート

  • スペース文字(上記3.を参照)は、ASCIIスペース(0x20)またはエンコードに相当するもの、つまりスペースバーを押したときに得られるものでなければなりません。

勝ち

これはです。バイト単位の最短コードが優先されます。

制限事項

  • 標準的な抜け穴は禁止されています。

  • 末尾のスペースおよび/または単一の末尾の改行が許可されます。先行スペースまたはその他の文字(送信の一部ではない)は許可されません。

  • Baudotコード(またはMurrayコード、ITA-1などの子孫)をデコードする組み込み関数またはライブラリ関数を使用することはできません。

テストケース

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
注:テストケースは手動でエンコードしました。間違っていると思われるものがあれば、声を上げてください。
ヨルダン

1
コード表および付随するダイジェストで00010は、コードはSP文字モードおよびFS図モードでリストされています。説明によると、文字モードでコードを受け取った場合00010、数字モードに移行する必要がありますが、表の値は逆になっているようです。また、逆も同様です00001
ソク

3
この男はかなり頭が良く、電信で使用される圧縮については知りませんでした。歴史のレッスンマンをありがとう。
魔法のタコ

4
@carusocomputing右?? Baudotは小学校以外に正式な教育を受けていませんでしたが、Baudot Codeを発明しただけでなく、4人のオペレーターが1本の電信回線を同時に使用できる多重化システムを発明しました。:私はいくつかの詳細に彼の発明は、超面白い記述し、この1919パンフレットたsamhallas.co.uk/repository/telegraph/b6_baudot_multiplex.pdf
ヨルダン

回答:


6

Pyth、98 97 95 93 90 83 80バイト

コードには印刷できない文字が含まれているため、ここに可逆の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

オンラインでお試しください。 テストスイート。

かなり長いですが、ルックアップテーブルはほとんどのスペースを占有します。

117バイトの場合、印刷できないものがない同じものがあります(ただし、ISO-8859-1が必要です)。

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

または、93バイトで、ルックアップテーブルを圧縮しない場合:

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バイト

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

バッチ、306 304バイト

@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で入力を受け取ります。Batchにはバイナリ変換がないため、8進および16進変換を使用してバッチを偽造する必要があります。

  • 最初の2桁は8進数から変換されます(最初の2桁がである可能性があるため、10進数は使用できません0)。可能な値は00011011。後者の二つは値を持っている89私はしたい2か、3私は残りの剰余を取ります6
  • 最後の3桁は16進数から変換されます。数字のいずれかである14か、252私は残りのモジュロを取るために、倍の所望の値14252=14*18)。
  • c コード化された文字列です
  • r これまでの結果です
  • d デコード配列です
  • s シフト状態を切り替える文字のインデックス(シフト状態を考慮に入れる)です
  • nは、バイナリデコードにビット5を加えたものでs、シフト状態に等しくなります。この場合、シフト状態が切り替えられます。または、デコード配列にインデックスを付けて次の文字を見つけます(または!を消去します)。

3

PHP、206バイト

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

チップ、1069バイト

これは大したことではありませんが、書くのはとても楽しかったです。

入力を"1"'と"0"'の文字列として受け取ります。(実際には低ビットのみを調べます。)

 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

オンラインでお試しください!

注:ErasureはASCIIバックスペース文字(\x08)を使用します。つまり、TIOではおかしく見えますが、xtermなどではうまく見えます。

基本構造

一番上の=行の上には、入力デコーダーがあります。入力を32の個別の信号のいずれかに変換します。これらは、o上の=から下に送信されます。

三角形の山LさんとRのちょうど列に別の行からパターンを回転させます。その下のグリッドは、各列を出力文字に変換します。未知の信号の場合、NUL(\x00)が生成されます。特別なシフトでは、キャラクターを印刷する代わりに、右側の小さなブロブがモードを変更します。

2つの山の間のケーブルカーのようなものは、各クインテット間の印刷を抑制します。そうしないと、重複するクインテットもすべてデコードしようとします。を!スペースで置き換えて、これを自分で確認してください。(冗長モードで実行する-vこともここで興味深いかもしれません。)

現時点でこれを小さくする方法はわかりません。そのサイズはすでにかなり密集しています。


0

GNU sed、334 + 1 = 335バイト

-rフラグ用に+1バイト。STDINで入力を受け取ります。

古い課題に目を通すと、これはsedを使えば非常に簡単で、練習に向いていることがわかりました。圧縮は試みていないので、ルックアップテーブルはコードの半分以上です。

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

オンラインでお試しください!

説明

コードは2つのフェーズで機能します。最初に、5つの2進数の各実行を、ルックアップテーブルの対応する2文字(文字と数字)で置き換えます。ルックアップテーブルの形式は𝟎𝟎𝟎𝟎𝟎𝐋𝐅𝟎𝟎𝟎𝟎𝟎𝐋𝐅…です。ここで、𝟎は2進数で、𝐋と𝐅はそれぞれ対応する文字と数字です。%欠落している文字を表します(これは、改行以外の任意の文字である可能性があります)。FS/SPはで表されf<space>SP/LSです<space>lERはで表され<<ます。

次に、現在のモードに対応する「カーソル」で各ペアをステップスルーします—#@ます。文字モード、図形モードの場合。#カーソルは、対の2番目の文字を削除し、その後、次のペアに進み、@第一及び進歩を除去します。つまり、に#A1B8なりA#B8、になりAB#、に@A1B8なり1@B8、になり18@ます。場合#カーソル遭遇f<space>それを削除し、で自身を置き換える@カーソル、およびその逆のときに@遭遇<space>l

ペアが残っていない場合、最後のカーソルは、その後に続く文字とともに削除され<ます。

# 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.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.