7セグメントディスプレイを使用して単語を表示する


13

初めてのプログラミングパズルとコードゴルフは、Seven-Slash Displayです。これも、7セグメントディスプレイに基づく私の最初のチャレンジです。

数字以外に、単純な7セグメントディスプレイを使用してどのような文字を表示できるかをよく考えます。多くの文字が表示できることが判明しました。実際、K、M、V、W、Xの文字以外はすべて、単一の7セグメントディスプレイを使用して表示できます。これは、文字の小文字または大文字を表示できるためです。例えば

「abcdef」は次のように表示できます

 _     _     _  _
!_!!_ !   _!!_ !_ 
! !!_!!_ !_!!_ !  

各文字は、とで構成され、3×3行列であることに注意してください!_

もちろん、7セグメントディスプレイを使用して数字と記号を表示できます。

 _     _  _  _           _  _     _    
  ! _ !_ !_ !      _!  !!_ !_!!  !_!!_!
  !    _!!_ !_!   !_!  ! _!!  !_ ! ! _!

一部の文字には、大文字と小文字の両方を使用できます。

 _                 _          
!   _ !_!!_   !   ! ! _ ! !   
!_ !_ ! !! !  !  !!_!!_!!_!!_!

完全な文字セットは次のとおりです。

 _     _  _     _  _  _  _  _                       _
! !  ! _! _!!_!!_ !_   !!_!!_!    _ !_     _     _  _!
!_!  !!_  _!  ! _!!_!  !!_! _!   !_ ! !  !!_!!_!   !  

 _     _     _  _  _                 _  _  _     _           _ 
!_!!_ !   _!!_ !_ !  !_!  !  !!   _ ! !!_!!_! _ !_ !_ ! !!_! _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_! _!!_ 

空白()、ダッシュ(-)、疑問符(?)があることに注意してください。文字IOおよびZは、それぞれ数字10およびと同じ2です。

この課題では、上記の7セグメント表示形式を使用して文字列を表示するプログラムまたは関数を作成します。

ルール

  1. プログラムまたは関数を書くことができます

  2. これはコードゴルフです。バイト単位の最短コードが勝ちます

  3. プログラムまたは関数は、STDINからまたはパラメーターとして入力を受け取る必要があります。文字列をSTDOUTに出力するか、先頭行スペースなしで改行で終了する3行の文字列として出力します。大文字/小文字をCHIOU適切に扱ってください。

  4. オプションで末尾の空白を印刷できます

  5. 上記の形式に従う必要があります。アンダースコア_と感嘆符を使用!して、7セグメントディスプレイを形成します。

  6. あなたはホワイトスペース(サポートしている必要があります)、ダッシュ(-()と疑問符?

  7. 文字列にサポートされていない文字(k、m、v、w、x)が含まれる場合、単一のエラー文字(3水平線、例を参照)が表示されます。サポートされていない5文字に加えて、入力がサポートされている文字セットのみで構成されていると想定できます。

  8. l混乱のため、小文字のL()の文字を持たないことを選択しましたが、そのように傾いている1場合は、右または左のように表示できます。

$./a.out Start
 _     _    
!_ !_ !_! _ !_
 _!!_ ! !!  !_
$./a.out "7-seg dIsplay"
 _     _  _  _           _  _     _ 
  ! _ !_ !_ !      _!  !!_ !_!!  !_!!_!
  !    _!!_ !_!   !_!  ! _!!  !_ ! ! _!
$./a.out "0123456789 chiou-?"
 _     _  _     _  _  _  _  _                       _
! !  ! _! _!!_!!_ !_   !!_!!_!    _ !_     _     _  _!
!_!  !!_  _!  ! _!!_!  !!_! _!   !_ ! !  !!_!!_!   !
$./a.out "ABCDEFGHIJLNOPQRSTUZ"
 _     _     _  _  _                 _  _  _     _        _
!_!!_ !   _!!_ !_ !  !_!  !  !!   _ ! !!_!!_! _ !_ !_ ! ! _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_!!_
$./a.out "abcdefghijlnopqrstuz"
 _           _  _  _                    _  _     _        _
!_!!_  _  _!!_ !_ !  !_      !!   _  _ !_!!_! _ !_ !_     _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_!!_
$./a.out "Bad Form"
 _
 _
 _
$./a.out "Hello"
    _       
!_!!_ !  !   _
! !!_ !_ !_ !_!
$./a.out "World"
 _
 _
 _

はい、サポートされていないシンボルはないと想定できます。私の意図は、含む文字列k, m, v, w, xが表示されないようにすることです。
一部のユーザー


キャリッジリターン(CR、\r)とラインフィード(LF、\n)を混同したと思います。* nixはLFを使用し、WindowsはCRLFを使用します。特定のレガシーシステムのみがCRを単独で使用します。詳細はこちら:en.wikipedia.org/wiki/Newline
ウィニー

あなたの「8」キャラクターにはバー「|」があるようです 感嘆符「!」の代わりに。それは意図されていますか?
コアダンプ

1
@Winny、あなたはもちろん正しいです。私はそれを書いたときにそれを調べるのが面倒でした。
一部のユーザー

回答:


7

CJam、123の 114 112 110バイト

Qq_eu";=KMVWX":T&"@"@?" -chiou"Tereu{i"^A^W^G;^Þ¯     ^Þ^Û9³·^É¿»
^@
^P
^Ü^Ò½7¦^_¶´§=   ^O^V&5^U¯¼¹^T³6/"=i2b9Ue[3/"!_!"f.{S?}.+}/N*

コードには印刷できない文字が含まれているため、上記ではキャレット表記を使用しています。それらの1つはヌルバイト(^@)です。つまり、このコードはコマンドラインからのみ実行できます。

あと2バイト(合計112バイト)のコストで、これを修正できます。

Qq_eu";=KMVWX":T&"@"@?" -chiou"Tereu{i"AWG{ÞïIÞÛyó÷Éÿû
@
P
ÜÒýwæ_öôç}IOVfuUïüùTóvo"=i448+2b1>3/"!_!"f.{S?}.+}/N*

今回は、すべての文字が印刷可能です。CJamインタプリタでオンラインで試してください。

実行例

$ LANG=en_US
$ xxd -ps -r > 7seg.cjam <<< 51715f6575223b3d4b4d565758223a5426224022403f22202d6368696f752254657265757b69220117073b9eaf099e9b39b3b789bfbb0a000a100a9c92bd37a61fb6b4a73d090f16263515afbcb914b3362f223d6932623955655b332f22215f2122662e7b533f7d2e2b7d2f4e2a
$ wc -c 7seg.cjam 
110 7seg.cjam
$ echo -n '0123456789 chiou-?' | cjam 7seg.cjam; echo
 _     _  _     _  _  _  _  _                       _ 
! !  ! _! _!!_!!_ !_   !!_!!_!    _ !_     _     _  _!
!_!  !!_  _!  ! _!!_!  !!_! _!   !_ ! !  !!_!!_!   !  
$ echo -n 'ABCDEFGHIJLNOPQRSTUYZ' | cjam 7seg.cjam; echo
 _     _     _  _  _                 _  _  _     _           _ 
!_!!_ !   _!!_ !_ !  !_!  !  !!   _ ! !!_!!_! _ !_ !_ ! !!_! _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_! _!!_ 
$ echo -n 'World' | cjam 7seg.cjam; echo
 _ 
 _ 
 _

アイデア(印刷可能なバージョン)

各文字は9セグメントディスプレイに表示できます

!_!
!_!
!_!

その文字の一部をスペースに置き換えます。

特定の文字を整数に変換するには、表示されている各セグメントを自然な読み取り順序で1に置き換え、それぞれの表示されていないセグメントを0に置き換え、結果の2進数を考慮します。

最初と3番目のセグメントは表示されないため、範囲[0,64)および[128,192)の整数が生成されます。

これらの各整数を1バイトとしてエンコードできますが、それらの半分は印刷できない文字になります。したがって、文字にキャストする前に各整数に64を追加し、コードポイントが[64,128)および[192,256)の範囲にあることを確認します。

これらの2つの範囲で印刷できない文字はDEL(コードポイント127)のみで、これは次の未使用のディスプレイ構成に対応します。

!_!
!_!

各コードポイントに448 == 512-64を追加し、ベース2に変換して最初の2進数を削除することで、上記のエンコードを逆にすることができます。

これらのエンコードされたsegmenetsを対応するASCII文字に関連付ける効率的な方法を見つけるために残されたすべて。

我々は文字マップする場合" -chiou"の文字を";=KMVWX"大文字に全体の入力および変換、我々は、単にの間の全ての文字をコード格納することができる0(コード・ポイント48)とZ、(コード・ポイント90)43の範囲を与えます。

配列のインデックスは、その場合、CJamにモジュール化されA、長さ43の文字列でありA86=A43=そしてA0=全て同じ結果をもたらします。コードポイント86の文字はですVので、V-Zおよび0-Uのエンコードされたセグメントを順番に保存するだけです。

実際のコードでは、アットマークを「不正な形式」文字として選択し"@"、禁止文字が含まれている場合は入力全体を文字列で置き換え、上記の手順を逆にします。

コード(印刷可能バージョン)

Q            e# Push an empty array for posterior concatenation.
q            e# Read from STDIN.
_eu          e# Copy the input and convert is to uppercase.
";=KMVWX":T& e# Intersect the result with with T := ";=KMVWX".
"@"@?        e# Select "@" if truthy and the input if falsy.
" -chiou"Ter e# Perform transliteration.
eu           e# Convert everything to uppercase.
{            e# For each character in the modified input:
  i          e#   Push its code point.
  "…"=       e#   Select the corresponding character from the string.
  i448+      e#   Push that character's code point and add 448.
  2b1>       e#   Convert to base 2 and discard the first digit.
  3/         e#   Group into triplets of digits (rows).
  "!_!"      e#   Push that string.
  f.{        e#   For each group of digits:
    S?       e#     Select the corresponding char of "!_!" for 1 and " " for 0.
  }          e#
  .+         e#   Concatenate along the rows with the previous results.
}/           e#
N*           e# Join, separating by linefeeds.

2

Perlの、475の 469 424 390 280 272バイト

$_=<>;die" -
"x3if/[kmvwx]/i;y/chiou/kmvwx/;$_=lc;while(/(.)/g){$z=ord($1=~y/a-z0-9\-\? /{v\x17nWS7z(.F\x16rb?[yBuV> f&|O?(Omxuw)\x7f}@K\0/r);$i.=$z&1?' _ ':$"x3;$m.=($z&16?'!':$").($z&64?'_':$").($z&8?'!':$");$p.=substr("  !  _!_",$z&6,2).($z&32?'!':$")}print"$i
$m
$p
"

コメント付きの複数行:

$_=<>;   # accept input
die" -   # check for invalid chars
"x3if/[kmvwx]/i;
y/chiou/kmvwx/;$_=lc;   # substitute invalid chars, convert to lowercase
while(/(.)/g)   # loop over each character
    # lookup character from string using transliteration and convert to
    # number using ord() for bit checking:
    {$z=ord($1=~y/a-z0-9\-\? /{v\x17nWS7z(.F\x16rb?[yBuV> f&|O?(Omxuw)\x7f}@K\0/r);
    $i.=$z&1?' _ ':$"x3;    # first row
    $m.=($z&16?'!':$").($z&64?'_':$").($z&8?'!':$");   # second row
    $p.=substr("  !  _!_",$z&6,2).($z&32?'!':$")}    # third row
# print result:
print"$i
$m
$p
"

セグメントをエンコードするビットパターンは文字列(スペースを使用\xして使用する3つの印刷できない文字をエスケープする)に格納され\0、Perl音訳演算子を使用して入力文字にマップされます。

7つのセグメントのうち5つについては、ビット単位のandを三項演算子とともに使用して、スペースまたはセグメント文字を出力します。左下の2つのセグメント(ビットセットの2と4でエンコード)については、8文字の文字列へのサブストリングルックアップを使用して2バイトを節約します。

Perlゴルフのヒントを提供してくれたDom Hastingsに感謝します。

古いバージョン(パターンのエンコードに正規表現を使用)、390バイト:

$_=<>;if(/[kmvwx]/i){print" -\n"x3;exit}y/chiou/kmvwx/;$_=lc;while(/(.)/g){$z=$1;$i.=($z=~/[acefgopqsz\?0235-9]/?' _ ':'   ');$m.=($z=~/[abce-hlmopqstuy045689]/?'!':' ').($z=~/[abdefhkmnp-twyz\-\?2-689]/?'_':' ').($z=~/[adhijopquyz\?0-4789]/?'!':' ');$p.=($z=~/[a-hj-prtuwxz\?0268]/?'!':' ').($z=~/[b-egjklostuw-z0235689]/?'_':' ').($z=~/[abdg-jmnoqsu-y013-9]/?'!':' ')}print"$i\n$m\n$p\n"

コメント付きの複数行:

$_=<>;   # accept input
if(/[kmvwx]/i){print" -\n"x3;exit}   # check for invalid chars
y/chiou/kmvwx/;$_=lc;   # substitute invalid chars, convert to lowercase
while(/(.)/g)
{$z=$1;$i.=($z=~/[acefgopqsz\?0235-9]/?' _ ':'   '); # first row
$m.=($z=~/[abce-hlmopqstuy045689]/?'!':' ').
($z=~/[abdefhkmnp-twyz\-\?2-689]/?'_':' ').
($z=~/[adhijopquyz\?0-4789]/?'!':' '); # second row
$p.=($z=~/[a-hj-prtuwxz\?0268]/?'!':' ').
($z=~/[b-egjklostuw-z0235689]/?'_':' ').
($z=~/[abdg-jmnoqsu-y013-9]/?'!':' ')} # third row
print"$i\n$m\n$p\n" # print result

文字列が読み込まれ、正規表現を使用して無効な文字がチェックされ、見つかった場合は終了します。次に、許可された小文字の文字が無効な文字に置き換えられ、文字列全体が小文字に変換されます。

行は一度に1つずつ生成され、最初の行では文字ごとに1セグメント、他の2行では3セグメントになります。行ごとに、文字列は一度に1文字ずつ処理され、文字は各セグメントの正規表現と照合され、!または_が表示されます。正規表現を使用すると、セグメントが設定されていない文字では、設定するかどうかをエンコードするために文字ごとのセグメントごとにゼロビットがかかり、正規表現文字の範囲は中古。したがって、セット内の文字あたりのセグメントあたり約3または4ビット、または文字あたり約21〜24ビットになります。

行の折り返しは処理しません。


1
@samgakさん、Perlの愛をもっと楽しみにしています!いくつかのバイトを削るのに役立ついくつかのことに気づき、それらを共有したいと思いました!Perlのマジック変数のいくつかを使用して、これを減らすことができます。' '交換することができる$"' 'することができ$"x3、いくつかのオフをトリミングされ、あなた\nのは少数のより多くを取り除くためにリテラル改行することができます。あなたの早期終了は、金型を用いて、あまりにも短絡することができますので、それはif(/[kmvwx]/i){print" -\n"x3;exit}なりdie" - "x3if(/[kmvwx]/i)。同様にもう少し工夫すれば、括弧を避けるためにループを再配置することができ$z、さらにいくつかを保存する必要はありません!
ドムヘイスティングス

1
あなたが気分を害さないことを願っていますが、gist.github.com / dom111 / e651b5de8c7e7fc9a6cfをさらに減らすことを検討しました。323まで!
ドムヘイスティングス

@DomHastingsはまったく違反していません。素晴らしいゴルフのヒントをありがとう!編集した回答でできるだけ多く使用しましたが、セグメントパターンに正規表現の代わりにビット単位のエンコードを使用するように変更しました。残念ながら$ zが復活しました。それを取り除く方法がわかりません。また、$_=lc<>その後、コードは、上部とCHIOU小文字を区別できないので、仕事をしない
samgak

1

Common Lisp、 488 416

(lambda(z)(dotimes(r 3)(map()(lambda(c)(do((i 0(+ 17 i))n)((or(and(> i 901)(setf n 146))(=(char-code c)(ldb(byte 8 9)(setf n(ldb(byte 17 i)#36RIL884OIVFXJY4DCQ0O8DPH8MOMR2DSLPP3O4ESYHS234A9HEQYSV8IBDBZI6Z3C3MCVR77OYD3QN5G6CX2UQWGL4UY5R9PKYI1JQ5Y6DC27MQQGUZSCGI8Q9JCYP9N1L4YYKRWM1ZNMSVTSB4792UUWV6Z3906VSP981WCCBMDNJ02)))))(loop for v from(* 3 r)for d across"!_!"do(format t"~:[ ~;~A~]"(logbitp v n)d)))))z)(terpri)))

"abcdefg'hijklnopqrstuz"、印刷:

 _           _  _  _  _           _           _  _     _        _ 
!_!!_  _  _!!_ !_ !   _ !_   !  ! _ !   _  _ !_!!_! _ !_ !_     _!
! !!_!!_ !_!!_ !  !_! _ ! !  !!_! _ !_ ! !!_!!    !!   _!!_ !_!!_ 

備考

文字とその表現は、ベース36のこの番号にエンコードされます。

IL884OIVFXJY4DCQ0O8DPH8MOMR2DSLPP3O4ESYHS234A9HEQYSV8IBDBZI6Z3C3MCVR77OYD3QN5G6CX2UQWGL4UY5R9PKYI1JQ5Y6DC27MQQGUZSCGI8Q9JCYP9N1L4YYKRWM1ZNMSVTSB4792UUWV6Z3906VSP981WCCBMDNJ02

この数字のバイナリ表現は、17ビットのグループに分割されます。

たとえば、17ビットの最後のグループは110000111101010であり、ここでは2つの部分に分解されます。

  1. 110000、文字の文字コード 0
  2. 111101010、図面のエンコーディング。次のように表現するのが最適です。

    010 (bits 0-2)         _ 
    101 (bits 3-5)   =>   ! !
    111 (bits 6-8)        !_!
    

    最初と最後の「列」のビットは!文字用で、中央の列の_文字は文字用です。必要に応じて、大文字と小文字の両方の文字が保存されます。

この関数は、出力の各行に1つずつ、入力文字列に対して3回反復し、テーブル内の一致する文字を検索し(またはデフォルトは146、別名3本のバー)、現在の行に表現を出力します。


チャレンジにご参加いただきありがとうございます。出力で「K」が「L」として表示されていることに気付きました。サポートされていない文字を他の有効な文字と一緒に印刷できないという要件を誤解している可能性があります。また、'キャラクターを追加したことがわかりました。ただし、7セグメントディスプレイで可能な範囲外に表示されます。!1行下に移動すると、完璧になります。
一部のユーザー

'文字を更新し、質問を編集します。K実際、K入力文字列の間違った場所に入力しているため( "... jlKn ...");-)トリプルバー(エラー)が表示されるだけです。 L.に気づいてくれてありがとう。
コアダンプ

1

JavaScript(ES6)、380 352 324バイト

注:コードは、それはいくつかの印刷できない文字が含まれているとして、元のコードを取得するには、キャレット表記を使用します。ここでは、生データを選択していない、。hCJamプログラムではありません;)

d=s=>{a=' ',u=n=>r>>n&1?'!':a,v=n=>r>>n&1?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK^0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(0)+a,y+=u(4)+v(1)+u(3),z+=u(6)+v(2)+u(5)){q=g.indexOf(s[i++]);if(q<0)return d`ÿ`;r=h.charCodeAt(q)}return x+`
${y}
`+z}

と呼ばれる、d("7-seg display")または同様。Firefox 40で動作しますが、他のブラウザでは動作しない場合があります。何らかの理由で、HTML / JSスニペットは非印刷物を保存しませんが、ここから生データをコピーして貼り付けることができます。

ゴルフをしていない:

注: gh一致するようにスペースが埋め込まれた8-ÿおよびspaceそれらの対応するユニコード値を有します。)

d = function (s) {
  t = function (n) { return Math.floor(n) % 2; };
  g = 'ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz012345679? 8      -      ÿ      space ';
  h = '{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)?K \u007f \u0002 \u0007 \u0000';
  x = y = z = '';
  for(var i = 0; i < s.length; i++) {
    q = g.indexOf(s.charAt(i));
    if (q < 0)          // if g does not contain the character
      return d('ÿ');    // ÿ is equivalent to the error character, '\u0007'
    r = h.charCodeAt(q);
    x += ' ' + (r % 2 === 1 ? '_' : ' ') + ' ';
    y += (t(r / 16) === 1 ? '!' : ' ') + (t(r / 2) === 1 ? '_' : ' ') + (t(r / 8) === 1 ? '!' : ' ');
    z += (t(r / 64) === 1 ? '!' : ' ') + (t(r / 4) === 1 ? '_' : ' ') + (t(r / 32) === 1 ? '!' : ' ');
  }
  return x + '\n' + y + '\n' + z;
}

説明:

0/ 1ビットに変換された7つのセグメントは、最初の128個のUnicode文字にうまく合うことにすぐに気付きました。このアイデアの問題は、これらの文字の1/4が印刷不可能な制御文字であるということです。私のコードでそれらを使用すると、信じられないほど乱雑に見えます(または信じられないほどインテリジェントです;私はどちらを決定していません)。残りのコードをシンプルに保ちながらこれを解決するために、私はこのアイデアを思いつきました:

-space、およびerrorを除き、両方の下部垂直セグメントに文字が欠落していませんでした。したがって、すべてのこれらの文字の間滞在していることを確認する0020007f、私は単純にマッピングされ、6432のように、これらのセグメントにビットをそう:

     1
    ---
16 |   | 8
  2 ---
64 |   | 32
    ---
     4

他の5つのセグメントの番号はそれほど重要ではありません。他の方法で配置することもできますが、すべての文字が「インバウンド」のままです。

例として、Aのエンコードされたバージョンを次に示します。

     1
    ---
16 |   | 8
  2 ---
64 |   | 32

Dec: 64 + 32 + 16 + 8 + 2 + 1 = 123
Hex: 40 + 20 + 10 + 8 + 2 + 1 = 7B = u+007B = {

次に、各7セグメント文字のエンコードされたバージョンをに詰めましたh。ただし、8結果は007f削除制御コード。セグメントの配置方法に関係なく定数)、スペース0000ヌルコード、定数も)、-結果は0002エラーはとなりました0007。Iは、コピー貼り付け生のバイトを正しい位置に8-及びエラースペースはで簡単に実現しました\0

このすべてのエンコードの後、文字列をデコードして7セグメントで読み取り可能な形式で出力するために使用する必要がありました。私は使用のために(ループと三つの変数xyおよびz文字列内の各文字を通過し、出力にその7セグ同等を追加するために、各出力線に対応します)。私の知る限り、エラーキャラクターを選んだのÿは、キーボードにはなく、範囲内の最後のキャラクターだからです。たぶん私は機知に富んでいて、代わりに選ばれたかもしれません(ギリシャ文字xi)....;)u+0000-u+00ffΞ

編集1:保存されたかどうかを判断するためにミニの関数を作成することによって、スペースの束!_または必要とされています。

編集2:最後にこの投稿を訪れてから学んだトリックを使用して、より多くのスペースを節約しました。

いつものように、提案は大歓迎です!

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