レトロなディスプレイを読む


22

盗まれたアート数字のサイズは?


7セグメントの数字は、文字を使用してASCIIで表すことができます_|。数字は0-9次のとおりです。

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|

あなたの仕事は、アートを通常の数値に解析することです。

数字に関する注意

  • 各桁の幅は異なります。
    • 1 幅が 1
    • 3そして、7ある2広いです
    • 245689そして0、すべて3広いです

また、各桁の間には1文字のパディングがあります。完全な文字セットは次のとおりです。

 // <-1つのスペースである必要がありますが、SEの書式設定は台無しにします
|
|
-------------
 _ 
 _ |
| _ 
-------------
_ 
_ |
_ |
-------------

| _ |
  |
-------------
 _ 
| _ 
 _ |
-------------
 _ 
| _ 
| _ |
-------------
_ 
 |
 |
-------------
 _ 
| _ |
| _ |
-------------
 _ 
| _ |
 _ |
-------------
 _ 
| |
| _ |

入力

入力は、コンソールから、または関数への文字列引数として行うことができます。

出力

出力はコンソールに出力されるか、関数から返されます。

例:

  _  _   _ 
|  |  | |_ 
|  |  | |_|
1776

 _   _     _ 
 _| | | | |_ 
|_  |_| | |_|
2016

   _       _ 
| |_| |_| |_ 
|  _|   |  _|
1945

   _   _   _   _   _   _ 
| | | | | | | | | | | | |
| |_| |_| |_| |_| |_| |_|
1000000

 _     _  _       _   _  _   _   _ 
| | |  _| _| |_| |_  |_   | |_| |_|
|_| | |_  _|   |  _| |_|  | |_|  _|
0123456789

これはコードゴルフなので、最短バイト数が勝ちです!



私はこの種の問題を解決するための最良のアルゴリズムについて学ぶことに興味があり、ここの答えから学ぶのは困難です(それらは良い、非常に簡潔です)。もっと長い説明を見るために、できれば写真で紹介してくれる場所はありますか?

まあ、私の働き方はかなり簡単です。これは、転置リストをし、それをループします。次に、空の行で分割します。各番号は、各番号の指紋表と照合されます。他の人は、指紋テーブルの代わりに基本的に使用するハッシュテーブルを除いて、私のものと少し似ています。
Jアトキン

この種のコンピューターサイエンスの問題にもっと一般的な名前はありますか?

私には
わから

回答:


4

Pyth、33 30バイト

sm@."/9Àøw"%%Csd409hTcC.z*3d

アイデアは次のとおりです。入力を転置し、数字に分割したら、個々の数字文字列をハッシュして値に割り当てることができます。

sm@."/9Àøw"%%Csd409hTcC.z*3d     Implicit: z=input
                      C.z        Transpose input.
                     c   *3d     Split that on "   ", a space between digits.
 m@."/9Àøw"%%Csd409hT            Map the following lambda d over that. d is a digit string.
             Csd                   Flatten the digit string, and convert from base 256.
            %   409                Modulo that by 409
           %       hT              and then by 11. All digits go to a distinct num mod 11.
   ."/9Àøw"                        The compressed string "03924785/61".
  @                                Index into that string.
s                                Flatten and implicitly output.

ここで試してみてください


クールで、基本的に私のアプローチのように見えますが、はるかに短いです!
リン

@Lynnそれについてすみません。基本的に、Pythでこれを行う最短の方法が1つあります。
リルトシアスト

4

ルビー、184バイト

a=0
l=$<.map{|x|x.bytes.map{|y|y==32?0:1}+[0]*2}
(0..l[0].count-1).map{|i|l[0][i]+2*l[1][i]+4*l[2][i]}.each{|x|
x>0?(a=x+2*a):(p Hash[[40,6,32,20,18,26,42,8,44,64].zip(0..9)][a];a=0)}

説明

  • stdinから入力を取得します
  • 文字列をバイナリシーケンス、セグメントオン/オフの1/0に変換します
  • 列を3ビットの2進数にエンコードします
  • 3ビット数のシーケンスを9ビット数にエンコードし、ストップシンボルとして「0」列を使用します
  • ルックアップテーブルを使用して、9ビットの数値を数字に変換します

これは私の最初のコードゴルフです。お楽しみいただきありがとうございます!


2
PPCGへようこそ!最初の投稿でとてもいい仕事をしました!
Jアトキン


2

Japt、119バイト

Ur"[|_]"1 z r" +
"R x1 qR² £"11
1 1
1151151
111
 15111
115 1
 1
115 1
111
1511
111
15  1
11511
111
115 1
111
11"q5 bXÃq

Try it here!

ああ、これは本当に長い。ゴルフを終えたとは思わない。

説明

準備

入力を受け取り、any |_をに変換し1ます。次に、転置し、終了スペースを取り除き、二重改行に沿って分割します。

翻訳

結果の配列をマッピングし、参照配列でフォームが表示されるインデックスを見つけます。役立つ図を次に示します。

MAPITEM
  11
  1 1 --> This same form appears at index 0 in the reference array
  11                            |
                                |
                                V
                        change the mapitem to 0!

その後、数値の配列と出力を結合します!

:なぜ各アートキャラクターを一連の1に変更する必要があるのか​​疑問に思われるかもしれません。これは、のような文字を保存できないバグ(またはそのようなもの)があるように見えるため|_です。


_バグに気付きましたが、原因はわかりません。
ETHproductions

OK、"\n\n"と交換することができる、と"\\||_"して"%||_"。私はあなたにもできたベース4(する4つのdisinctive文字のそれぞれを変更するには、長い文字列を符号化することにより、いくつかのバイトの保存を考える012、または3、4の倍数の長さにパディングが、その後、実行しているr"...."_n4 d}その上)が、いくつかの理由、まだ動作するようになっていない。
ETHproductions

2

Python2、299の 261 244バイト

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
p=lambda l:['95572431508448853268'.find(`sum(ord(c)**i for i,c in enumerate("".join(n)))%108`)/2for n in s(l.split('\n'))]

私はこの挑戦が本当に好きでした、良い仕事です!

説明

この関数sは3行を入力として受け取り、数字の区切りを見つけようとします(すべての文字はスペースです)。このような分離が見つかるsと、残りの3行で呼び出し、呼び出しによって返された値を数字を構成する3行に追加します。分離がない場合は、1桁しかないことを意味します。

この関数pはエントリポイントなので、数字を表す文字列を受け取ります。数字は、sum(ord(c)**i for i,c in enumerate("".join(n)))%108スペースを節約するために計算された「ハッシュ」として保存されます(他の回答のおかげです!)。

digits="""
 _     _ 
| | |  _|
|_| | |_ """[1:]  # remove the '\n' at the beginning

p(digits)  # [0, 1, 2]

他のバージョン

261バイト(py3):

s=lambda a,i=0:[a]if i==len(a[0])else[[j[:i]for j in a]]+s([j[i+1:]for j in a])if all(j[i]==' 'for j in a)else s(a,i=i+1)
def p(l):[print([91,21,84,31,58,76,88,41,80,68].index(sum(ord(c)**i%20 for i,c in enumerate("".join(n)))),end="")for n in s(l.split('\n'))]

249バイト、これは行を転置します(py2):

f="".join
s=lambda a,i=0:[a]if i==len(a)else[a[:i]]+s(a[i+1:])if all(c==' 'for c in a[i])else s(a,i=i+1)
h=lambda s:ord(s[0])**len(s)+h(s[1:])if s else 0
p=lambda l:["10220907112527153129".index(`h(f(map(f,n)))%34`)/2for n in s(zip(*l.split('\n')))]

2

JavaScript(ES6)、169バイト

a=>[...(a=a.split`
`)[0]].map((b,c)=>(d={' ':0,'|':1,'_':2})[b]+d[a[1][c]]*2+d[a[2][c]]).join``.split(0).map(b=>[343,3,182,83,243,281,381,23,383,283].indexOf(+b)).join``

3行に分割し、各列を値に再マッピングし、それらの値から各列に一意のIDを構築することから始めます。次に0(列間のスペースのID)で分割し、最後に各IDをその数値にマップし、連結して出力​​します。


非常に素晴らしい!Pythonにリスト分割機能があればいいのに…
Jアトキン

@JAtkin join分割できるように、文字列に編集しました。Pythonでも同様にできると思いますか?
Mwr247

0

Python 3、281 254バイト

編集

他のpython回答のコードを見たところ、多くのコードが似ていることに気付きました。これは独自に到達しました。

(「読みやすさ」のために追加された改行)

def p(i):
 n=[[]]
 for l in zip(*i.split('\n')):
  if all(i==" "for i in l):n+=[[]]
  else:n[-1]+=l
 return''.join(map(lambda l:str([''.join(l[2:])==x for x in
             "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"
                     .split(',')].index(1)),n))

ゴルフをしていない:

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]
    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst
    return ''.join(map(digit, numbers))

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(num[2:]) == y for y in fingerprint].index(True))

テスト:

assert (parse("   _   _   _   _   _   _ \n| | | | | | | | | | | | |\n| |_| |_| |_| |_| |_| |_|") == '1000000')
assert (parse("   _       _ \n| |_| |_| |_ \n|  _|   |  _|") == '1945')
assert (parse(" _   _     _ \n _| | | | |_ \n|_  |_| | |_|") == '2016')
assert (parse(" _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|") == '0123456789')
assert (parse("  _  _   _ \n|  |  | |_ \n|  |  | |_|") == '1776')

使い方

(注:ここでは、digit関数がラムダにインライン化されていることを除いて、より読みやすく、まったく同じコードを持っているので、ungolfedプログラムを説明しています)

def parse(input):
    lines = list(input.split('\n'))
    numbers = [[]]

主な機能はparseです。最初に入力を行に分割し、numbers配列を作成します。

    for lst in zip(*lines):
        if all(i==" " for i in lst):
            numbers += [[]]
        else:
            numbers[-1] += lst

これは私のお気に入りの部分です(把握するのに時間がかかったため)。ここでzipラインを使用して、基本的に入力を垂直方向にトラバースできるようにします。行に文字が含まれている場合、numbers配列の最後の数字に追加します。文字が含まれていない場合は、新しい数値を配列に追加します。

    return ''.join(map(digit, numbers))

本当にシンプルnumbersで、digit関数でマップされ、文字列に変換されます。

def digit(num):
    fingerprint = 
        "|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||".split(',')
    return str([''.join(x[2:]) == y for x, y in zip([num]*10, fingerprint)].index(True))

これは(かなり)簡単です。fingerprint上で作成された数字から最初の2文字を引いた文字列表現です(これは私が見つけることができる最小の指紋でした)。最初の一致のインデックスを返します。


0

Haskell、270 207バイト

難しすぎないでください、これは私の初めてのハスケルプログラムです;)これをさらにゴルフにかけることができると確信していますが、言語の私の限られた知識をどのように与えたかわかりません。

import Data.Lists
b n=map c$splitOn["   "]$transpose$lines n
c n|e<-drop 2$concat n,Just r<-elemIndex True[e==f|f<-splitOn",""|_ _ ||,|,|___ | ,_ ||,  _  ||, ___  |,|___  |,  ||,|___ ||, ___ ||"]=(show r)!!0

ゴルフをしていない:

module Main where
import Data.Lists

main :: IO ()
main = print $ parse " _     _  _       _   _  _   _   _ \n| | |  _| _| |_| |_  |_   | |_| |_|\n|_| | |_  _|   |  _| |_|  | |_|  _|"

parse :: String -> String
parse n = let lst = transpose $ lines n
              numbers = splitOn ["   "] lst --"   " lst
              number = map digit numbers
          in number

digit :: [String] -> Char
digit n | e <- drop 2 $ intercalate "" n
        , fingerprint <- ["|_ _ ||","|","|___ | ","_ ||","  _  ||"," ___  |","|___  |","  ||","|___ ||"," ___ ||"]
        , Just res <- elemIndex True [e == finger | finger <- fingerprint]
        = head $ show res

ヒントについては@nimiに感謝します!


まず悪いニュース:import Data.Listバイトカウントに含める必要があると思います。朗報:a)Data.Listsインストール済みの場合は、代わりにインポートしasplitOn...map c$splitOn[" "]$transpose...およびに置き換えることができます...f<-splitOn",""|_...。b)のintercalate "" nですconcat nid=<<n。c)res1文字の名前に置き換えます。d)の使用パターンは、ガードの代わりにlet ... inc n|e<-drop 2$id=<<n,Just r<-elemIndex ... ]=(show r)!!0
nimi

へへへ、おっと!コピー/貼り付けでインポートが失われました;)すべてのヒントをありがとう!
Jアトキン

@nimi迷惑をかけてすみませんが、何をするのか説明して=<<もいいですか?hoogle docsもtype signatureも私にとって非常に役に立ちません。
Jアトキン

=<<リストコンテキストではですconcatMap。つまり、指定された関数をリストにマッピングし、結果を単一のリストに結合します。>>=同じことをしますが、引数を反転します。id =<< n(またはn >>= id)識別関数を(リストの)リストにマッピングします。つまり、サブリストで何もせず、それらを連結します。ですから、と同じconcatです。
-nimi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.