フラグセマフォエンコーダ


12

あなたの目標は、Wikiで説明されているセマフォシステムに従って、特定の文を対応するフラグセマフォ文字に変換するフラグセマフォエンコーダを作成することです。

入力は、stdin(または同等のもの)を介して提供される単一の文であると想定します。出力は一連のセマフォ文字である必要があり、各行は文の1つの単語を表します。アルファベット(AZ)のみを扱う必要があり、他のすべての非スペース文字を無視する必要がありますが、大文字と小文字の両方を処理できる必要があります。出力には余分な空白を含めることができます。

セマフォ文字は3x3の正方形で表示されO、中央にがあり、フラグの位置が文字で表されている必要があり| - / \ます。各セマフォ文字は、隣接する文字とスペースで区切る必要があり、各行は空白行で区切る必要があります。表示するには長すぎる単語の折り返しを心配しないでください-行の長さが無限であることを装います。

サンプル入力:

abcdefg hijklmn opqrstu vwxyz

サンプル出力:

        \    |    /
 O  -O   O   O   O   O-  O
/|   |   |   |   |   |   |\

    \    |   |    /
-O   O   O-  O   O   O-  O
/   /       /   /   /   / \

\    |    /         \|  \ /
-O  -O  -O  -O- -O   O   O
                  \ 

 |    /   / \ 
 O   O-  O   O-  O-
  \       \       \

サンプル入力:

This is Code Golf.

サンプル出力:

\|      \ 
 O  -O   O  -O 
    /   /     \

\      
 O  -O 
/     \

\   \    |    /
 O  -O   O   O 
 |       |   |

    \     /  
 O  -O   O   O-
 |\     /    |

これはであるため、最短のソリューションが優先されます。


1
コルモゴロフ複雑性?基本的にこれはルックアップテーブルの圧縮に関するものだと私には思えます。
ピーターテイラー

@Peter Taylorええ、おそらくそのタグを追加することをお勧めします。ありがとう。
みぎ丸

and each row must be separated by a blank line=>各単語の意味ですよね?
ユーザー不明

1
このパズルを読む前に、プログラミングの意味でセマフォに関係していると勘違いしていました。じゃじゃじゃじゃじゃ!
トーマスエディング

@user unknown セマフォ文字の行を参照するために行を使用していました。おそらく、代わりにwordを使用する方が適切な選択でした。
みぎまる

回答:


5

Perlの、282 264 251 247 245 243 241 240 236 233 229の 227 220 218 216 214文字

$_=lc<>;map{y/a-z//cd;y/a-z/`HABDP\xc0(!\x12"$0\xa0\t\n\f\30\x88\3\5\x82\24\x84\21\x90/;@a=($/)x4;map{$s=ord;$a[$_/3].=substr" \\|/-O-/|\\",$_==4||$s>>$_-($_>4)&1?$_+1:0,1for 0..8;$_.=" "for@a}split//;print@a}split

いくつかの美しい改行で:

$_=lc<>;
map{
y/a-z//cd;
y/a-z/`HABDP\xc0(!\x12"$0\xa0\t\n\f\30\x88\3\5\x82\24\x84\21\x90/;
@a=($/)x4;
map{
$s=ord;
$a[$_/3].=substr" \\|/-O-/|\\",$_==4||$s>>$_-($_>4)&1?$_+1:0,1for 0..8;
$_.=" "for@a
}split//;
print@a}split

これが機能するようになるまでに時間がかかりました(Perlでの最初の回答)。それは他の多くの答えと同様の考えに基づいています。各フラグは8つの位置のいずれかにできます。2つのフラグがあり、2つのフラグを同じ位置にすることはできません。これは、両方のフラグの位置を1バイトでエンコードできることを意味します。つまり、Perlのy///関数(演算子?)を使用して、文字からエンコードに直接変換できることも意味します。そう:-

a = 01100000 96 = `
b = 01001000 72 = H
c = 01000001 65 = A
d = 01000010 66 = B
e = 01000100 68 = D
f = 01010000 80 = P
etc...

したがって:

y/a-z/`HABDP..../;

プログラムのコピーと貼り付けを簡単にするために、通常の使用範囲外のかなりの数の文字をエスケープしましたが、エスケープコードを自分自身を保存する文字に置き換えるプログラムを書くことができると確信しています約30文字。


6

Python、244 238 233 232

e='abhioptuwycdjmnsqxzfgvklebr'
for w in raw_input().split():
 for i in 0,3,6,9:print' '.join(''.join((' '+'\|/-O-/|\ '[j])[`j`in'4'+'6736031025071568328578162735'[e.find(c):][:2]]for j in range(i,9)[:3])for c in w if c.lower()in e)

これは私のお気に入りのトリック、シングルトラックエンコーディングを使用します。セマフォビット(sbits)にラベルを付けました

\|/     012
- -  -> 3 5
/|\     678

どの文字に対してどのスビットが発生するかを示す次のチャートを取得するには:

0: ciotuy
1: djkptv
2: elquwx
3: bhopqrs
5: fjmrwyz
6: ahiklmn
7: abcdefg
8: gnsvxz

シグナルマンには2本の腕があるため、各文字はチャート内で正確に2回出現します。次に、これを文字a〜zのグラフとして表示します。文字間のエッジはsbitを共有し、エッジは共有sbitに従ってラベル付けされます。理想的には、このグラフを通るハミルトンパスを見つけて、後続のエッジに同じラベルがないようにします。そのようなパスは存在しないため、変数eに文字がb2回含まれていることに注意してください。

ほぼハミルトンのパスで、のトラバースで使用されるsbitラベルのe配列dを作成しますe。それから、彼女の腕をどこに置くかを理解するために、信号機は次の便利なチャートで目的の文字を見つけるだけです。

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

彼女の腕は、手紙の真下と真下の位置に移動します。


に変更to_lower()するまで、これをideoneで実行することはできませんでしたlower()。また、アルファベット以外の入力を試みたときにエラーが発生しました。
みぎまる

4

Scala、272文字

println(readLine.filter(c=>c.isLetter||c==' ').toLowerCase.split(" ").map{_.map(q=>("    O    "/:("^@a,6Tr?W*+5Sq9(2Pn%/-47MU"(q-'a')-27+""))((g,x)=>g.updated(x-'0',"\\|/-O-/|\\"(x-'0'))).grouped(3).toList).transpose.map(_.mkString(" ")).mkString("\n")}.mkString("\n\n"))

ゴルフをしていない(まあ、ゴルフは少ない):

println(
  readLine.filter(c => c.isLetter || c==' ').
  toLowerCase.
  split(" ").
  map{ s =>
    val lookup = "^@a,6Tr?W*+5Sq9(2Pn%/-47MU".map(c => (c-27).toString)
    s.map(q =>
      ("    O    " /: lookup(q-'a')){(g,x) => 
        g.updated(x-'0', "\\|/-O-/|\\"(x-'0'))
      }.grouped(3).toList
    ).transpose.map(_.mkString(" ")).mkString("\n")
  }.mkString("\n\n")
)

2

ルビー、287文字

gets.split.map{|w|puts (0..2).map{|l|w.chars.map{|c|(' '*576+'CAEAEADBCAF DAEBDACAAAI EAFADACAABG BAEAFEL A_ FACABADADAAG AAFBADQ AGX GAFADABAAAAF'.split.zip('\\|/-o-/|\\'.chars).map{|a,c|(a.chars.zip([' ',c]*9).map{|x,z|[z]*(x.ord-64)}.flatten)}.transpose*''*2)[c.ord*9+3*l,3]}*' '},''}

入力はSTDINで指定する必要があります。


1

改行のない Scala 494改行のある 520:

def k(i:Int,d:Int=0):(Int,Int)=if(i<(7-d))(d,i+1)else k(i-(7-d),d+1)
def t(i:Char)=(if(i=='y')i-4 else
if(i=='z')i+2 else
if(i=='j')i+14 else
if(i>='v')i+3 else
if(i>'i')i-1 else i)-'a'
def q(p:(Int,Int),i:Int,c:Char)=if(p._1==i||p._1+p._2==i)""+c else" "
def g(r:Int,c:Char)={val p=k(t(c.toLower))
print((r match{case 1=>q(p,3,'\\')+q(p,4,'|')+q(p,5,'/')
case 2=>q(p,2,'-')+"o"+q(p,6,'-')
case 3=>q(p,1,'/')+q(p,0,'|')+q(p,7,'\\')})+" ")}
for(w<-readLine.split(" ")){println;for(r<-(1 to 3)){w.map(c=>g(r,c));println}}

権利なし:

def toClock (i: Int, depth: Int=0) : (Int, Int) = {
  if (i < (7 - depth)) (depth, i+1) else toClock (i - (7-depth), depth + 1)}

def toIdx (i: Char) = {
 (if (i == 'y') i - 4  else 
  if (i == 'z') i + 2  else 
  if (i == 'j') i + 14 else 
  if (i >= 'v') i + 3 else 
  if (i > 'i') i - 1 else i ) - 'a'}

def p2c (pair: (Int, Int), i: Int, c: Char) = {
 if (pair._1 == i || pair._1 + pair._2 == i) ""+c else " "
}

def printGrid (row: Int, c: Char) = {
  val idx = toIdx (c.toLower)
  val pair = toClock (idx)
  row match {
    case 1 => { print(
      p2c (pair, 3, '\\') + 
      p2c (pair, 4, '|') + 
      p2c (pair, 5, '/') + " ")
    }
    case 2 => { print(
      p2c (pair, 2, '-') + "o" + 
      p2c (pair, 6, '-') + " ")
    }
    case 3 => { print(
      p2c (pair, 1, '/') + 
      p2c (pair, 0, '|') + 
      p2c (pair, 7, '\\') + " ")
    }
  }
}

val worte = "This is Code Golf"
(1 to 3).map (row => {worte.map (c => printGrid (row, c));println})

説明:

クロックパターンを観察しましたが、12時間ではありませんが、8です。Starttimeは0、つまり6時で、a、b、cは最初のコードで、最初の(1つの)フラグは南にあります。

フラグ1と2は区別できないため、最初のフラグの番号が小さい方の組み合わせをすべて最初にソートできます。残念ながら、jがiに続かない場合、最初からの細かい順序は乱れますが、k、l、m、およびそれ以降は混乱します。

したがって、マッピングのキーを再配置します。

val iis = is.map {i => 
  if (i == 'y') i - 4  else 
  if (i == 'z') i + 2  else 
  if (i == 'j') i + 14 else 
  if (i >= 'v') i + 3 else 
  if (i > 'i') i - 1 else i }.map (_ - 'a')

iis.zipWithIndex .sortBy (_._1) .map (p => (p._1, ('a' + p._2).toChar))

Vector((97,a), (98, b), (99, c), (100,d), (101,e), (102,f), (103,g), 
      (104,h), (105,i), (106,k), (107,l), (108,m), (109,n), 
      (110,o), (111,p), (112,q), (113,r), (114,s), 
      (115,t), (116,u), (117,y), -------
      -------  (120,j), (121,v), 
      (122,w), (123,x), 
      (124,z))

すべての文字から「a」を引くと、(0〜7 + 6 + 5 + ... + 1)の数字が得られます。文字グリッドの番号をマッピングできます

3 4 5   \ | /            |
2   6   - o -    - o   - o 
1 0 7   / | \    (2, ) (2,2)

2つの数値のペアは2つのフラグをマッピングできます。最初の数値は最初のフラグの0〜6のインデックスであり、2番目のフラグは2番目のフラグの1〜7の数値ではなく、最初から2番目のフラグ。(2,2)は、最初のフラグは西へ、2番目はそこから北へ時計回りに2ステップ進むことを意味します。

def toClock (i: Int, depth: Int=0) : (Int, Int) = {
  if (i < (7 - depth)) (depth, i+1) else toClock (i - (7-depth), depth + 1)}

Vector( (0,1), (0,2), (0,3), (0,4), (0,5), (0,6), (0,7), 
    (1,1), (1,2), (1,3), (1,4), (1,5), (1,6), 
    (2,1), (2,2), (2,3), (2,4), (2,5), 
    (3,1), (3,2), (3,3), 
           (4,2), (4,3), 
    (5,1), (5,2), 
    (6,1))

私はScalaについてあまり知りません。イデオンでこれをテストする方法はありますか?私はそれをobject Main extends Applicationブロックにラップしようとしましたが、それだけでは十分ではないようです。
みぎまる

IDEONEはMainという名前のクラスを必要とします。正しく覚えている場合、mainメソッドは多分Appを拡張する必要があります(Application(-2.8)の代わりにscala-2.9の場合)-それは標準入力から読み込みますか?でsimplyscalaあなたは、より簡単にコードをテストすることがあります。readLine最後の行を置き換えると動作"readLine"するはずです(コードは2.8互換です)。
ユーザー不明

ありがとう!単純なスカラについては知りませんでした。
みぎ丸

再度リンクが必要な場合:既にメタのどこかにリンクを挿入しました。そのようなものが収集されます。
ユーザー不明

これは大文字を処理しますか?
トーマスエディング

1

Haskellの331 357 339文字

ゴルフ済み:

import Data.Char
t[x,y]=q[x,mod(y+1)8]
q z@[x,y]|x==y=[x+1,y+2]|0<1=z
x%y=[x,y]
c 65=0%1
c 74=6%4
c 75=1%4
c 79=2%3
c 84=3%4
c 86=4%7
c 87=5%6
c 89=3%6
c 90=6%7
c x=t$c$pred x
_!9='O'
c!n|n`elem`c="|/-\\"!!mod n 4|0<1=' '
s x=do n<-[3:4%5,2:9%6,1:0%7];'\n':do c<-x;' ':map(c!)n
main=putStr.s.map(c.ord.toUpper)=<<getLine

ゴルフをしていない:

type Clock = [Int]

tick :: Clock -> Clock
tick [h, m] = tick' [h, mod (m + 1) 8]

tick' :: Clock -> Clock
tick' [h, m]
  | h == m = [h + 1, m + 2]
  | otherwise = [h, m]

clock :: Char -> Clock
clock 'a' = [0,1]
clock 'j' = [6,4]
clock 'k' = [1,4]
clock 'o' = [2,3]
clock 't' = [3,4]
clock 'v' = [4,7]
clock 'w' = [5,6]
clock 'y' = [3,6]
clock 'z' = [6,7]
clock c = tick $ clock $ pred c

arm :: Int -> Char
arm 0 = '|'
arm 1 = '/'
arm 2 = '-'
arm 3 = '\\'

drawAt :: Clock -> Int -> Char
drawAt _ 9 = 'O'
drawAt c n = if n `elem` c
  then arm $ n `mod` 4
  else ' '

-- showClock is not in golfed code. Just there for debugging.
showClock :: Clock -> String
showClock c = unlines $ map (map $ drawAt c) [
    [3,4,5]
  , [2,9,6]
  , [1,0,7]
  ]

showClocks :: [Clock] -> String
showClocks cs = unlines $ map (showClocks' cs) [[3,4,5],[2,9,6],[1,0,7]]

showClocks' :: [Clock] -> [Int] -> String
showClocks' cs ns = cs >>= \c -> ' ' : map (drawAt c)

mainx :: IO ()
mainx = putStr . showClocks . map clock =<< getLine

345    \|/                                     \                      
2 6 == -O-          -O          tick  -O   ==   O      tick   O   ==  -O
107    /|\          /                 /        /              |\      /
             [1,2] or [2,1]    tick [1,2] == [1,3]     tick [0,7] == [1,2]

エンコードは[hour, minute]、クロックが8時間8分であるところです。分は数時間よりも速く移動します。時間と分が等しい場所で時計がカチカチ音をたてる場合は、時間に1を、分に2も追加します(上記の2番目のカチカチの例を参照)。それが時間を増やす唯一の方法です。分が任意の分に達しても、時間は増加しません。分が時間に等しい場合のみ。改変されていないコードでclockは、文字をセマフォを表す時計に変換します。ほとんどの時計は、前のものからの刻みに基づいて構築されます。残りはハードコーディングされています。コードにはこれ以上何もありません。


1

Perl、356、275文字

「if else」を「?」に置き換えることで、大量の文字が保存されました。: '構築。

@_=split('', $ARGV[0]);for (@_){print eval{/[ciotuy]/ ?'\\':' '}.eval{/[djkptv]/ ?'|':' '}.eval{/[elquwx]/ ?'/':' '}."\n".eval{/[bhopqrs]/ ?'-':' '}."0".eval{/[fjmrwyz]/ ?'-':' '}."\n".eval{/[ahiklmn]/ ?'/':' '}.eval{/[abcdefg ]/ ?'|':' '}.eval{/[gnsvxz]/ ?'\\':' '."\n"};}

コードは小文字でのみ機能するようです。の<>代わりに使用する場合は$ARGV[0]、stdinから入力を取得lcし、すべての文字を小文字に変換するために使用できます。これには、4文字を節約できるという追加の利点があります。アルファベット以外の文字も処理しませんYou only need to deal with the alphabet (A-Z) and should ignore all other non-space charactersが、それらをどう処理するかについてはおそらく明確ではありません
...-Gareth

現在、コードをテストすることはできませんが、コードは非アルファ文字のスペースを印刷するだけのように見えますが、これは問題ありません。
みぎ丸

@migimaruそれを修正しようとします。
ズラ

@zuraアルファベット以外の文字の印刷スペースは許容されます。それを修正する必要はありません。
みぎ丸

0

PowerShellの198の 192 191 188バイト

-split$args|%{$s=$_
"\|/ ciotuy djkptv elquwx","-O- bho-s ^ fjmrwyz","/|\ ahik-n a-g gnsvxz"|%{$f,$p=-split$_
($s|% t*y|%{$c=$_
-join(&{$p|%{" $f"[++$i*($c-match"[$_ ]")]}})})-join' '}
''}

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

出力には、1つのテール空行が含まれます。

少ないゴルフ:

-split$args|%{
    $string=$_
    "\|/ ciotuy djkptv elquwx",
    "-O- bho-s ^ fjmrwyz",
    "/|\ ahik-n a-g gnsvxz"|%{
        $flags,$patterns=-split$_
        $row=$string|% toCharArray|%{
            $char=$_
            $semaphoreRow=&{   # call the scriptblock in a new scope to reinit $i
                $patterns|%{
                    " $flags"[++$i*($char-match"[$_ ]")]  # return a flag symbol
                }
            }
            -join($semaphoreRow)
        }
        $row-join' '
    }
    ''
}

0

、70バイト

F⪪↧S «Fι«F⪪”↶↖→∧gτ→|⮌!⧴KD✂‖5»⊞H⭆K↧ⅉ&$↥x-#↖x9|²λPe⁸” «P⊗№λκ↷¹»oM³→»⸿M³↓

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

F⪪↧S «

小文字の入力をスペースで分割し、各単語をループします。

Fι«

各文字をループします。

F⪪”↶↖→∧gτ→|⮌!⧴KD✂‖5»⊞H⭆K↧ⅉ&$↥x-#↖x9|²λPe⁸” «

圧縮された文字列fjmrwyz gnsvxz abcdefg ahiklmn bhopqrs ciotuy djkptv elquwxをスペースで分割し、各文字グループをループします。

P⊗№λκ

グループに現在の文字が含まれている場合、現在の方向に線を引きます。

↷¹»

時計回りに45°回転します。

oM³→»

中心oを出力し、次の文字の位置に移動します。

⸿M³↓

次の単語の先頭に移動します。

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