세마포어 인코더 플래그


12

당신의 목표는 Wikipedia에 설명 된 세마포어 시스템에 따라 주어진 문장을 해당 플래그 세마포어 문자로 변환 하는 플래그 세마포어 인코더 를 작성하는 것 입니다.

입력이 stdin (또는 동등한)을 통해 제공되는 단일 문장이라고 가정하십시오. 출력은 일련의 세마포 문자 여야하며 각 행은 문장의 한 단어를 나타냅니다. 알파벳 (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
kolmogorov- 복잡성 ? 기본적으로 이것은 조회 테이블 압축에 관한 것 같습니다.
피터 테일러

@ 피터 테일러 그래, 아마 그 태그를 추가하는 것이 좋습니다. 감사.
migimaru

and each row must be separated by a blank line=> 각 단어 는 의미가 아닌가?
사용자가 알 수 없음

1
이 퍼즐을 읽기 전에 프로그래밍 의미에서 세마포어와 관련이 있다고 생각했습니다. ¡ 자 자자 자자!
Thomas Eding

@user unknown 나는 행을 사용하여 세마포어 문자 행을 참조하고있었습니다 . 아마도 단어를 대신 사용 하는 것이 더 나은 선택이었을 것입니다.
migimaru

답변:


5

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 개의 위치 중 하나에있을 수 있으며 두 개의 플래그가 있으며 두 플래그는 같은 위치에있을 수 없습니다. 이것은 두 플래그의 위치를 ​​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

파이썬 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

신호 원이 두 개의 팔을 가지고 있기 때문에 각 문자는 차트에서 정확히 두 번 나타납니다. 그런 다음이 문자를 공유 비트에 따라 레이블이 지정된 문자와 비트를 공유하는 문자 사이의 가장자리가있는 문자 az에서 그래프로 봅니다. 이상적 으로이 그래프를 통해 해밀턴 경로를 찾으면 후속 가장자리의 레이블이 동일하지 않습니다. 그러한 경로가 존재하지 않으므로 변수 e에 문자가 b두 번 포함되어 있습니다 .

거의 해밀턴 경로를 사용하여의 순회에 사용되는 e일련 d의 sbit 레이블을 구성합니다 e. 그런 다음 팔을 어디에 넣을지를 결정하기 위해 신호 원은 다음 편리한 차트에서 원하는 문자 만 찾으면됩니다.

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

그녀의 팔은 편지의 바로 아래와 아래의 위치에있을 때.


로 변경 to_lower()하기 전까지는 이데온에서 실행할 수 없었 습니다 lower(). 또한 알파벳이 아닌 입력을 시도했을 때 오류가 발생했습니다.
migimaru

4

스칼라, 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 시간이었습니다. 그리고 시작 시간은 0입니다.

플래그 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)

두 숫자 쌍은 두 플래그를 맵핑 할 수 있습니다. 첫 번째 숫자는 첫 번째 플래그의 경우 0에서 6까지의 색인이고 두 번째 플래그는 두 번째 플래그의 경우 1에서 7 사이의 숫자가 아니라 두 플래그의 거리입니다. 먼저 두 번째 플래그. (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))

스칼라에 대해 잘 몰라요. 이데온에서 이것을 테스트 할 수있는 방법이 있습니까? 나는 그것을 object Main extends Application블록으로 감싸려고했지만 충분하지 않은 것 같습니다.
migimaru

IDEONE은 Main이라는 클래스가 필요합니다. 정확히 기억한다면 주된 방법은 응용 프로그램 (-2.8 대신 scala-2.9)을 확장해야하며 stdin에서 읽습니까? 간단히 스칼라 에서는 코드를 더 간단하게 테스트 할 수 있습니다. 당신이 교체하는 경우 readLine와 마지막 줄에 "readLine"작동한다 (코드 호환 2.8)입니다.
사용자가 알 수 없음

감사! 나는 간단하게 scala에 대해 몰랐습니다.
migimaru

링크가 다시 필요한 경우 : 메타가있는 곳에 어딘가에 링크를 삽입했습니다.
사용자가 알 수 없음

대문자를 처리합니까?
Thomas Eding

1

하스켈 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도 분에 추가하십시오 (위의 두 번째 틱 예제 참조). 그것이 시간이 증가하는 유일한 방법입니다. 분이 임의의 분에 도달하면 시간이 증가하지 않습니다. 분이 시간과 같은 경우에만. ungolfed 코드에서 clock문자를 세마포어를 나타내는 시계로 바꿉니다 . 대부분의 시계는 이전 시계의 틱을 기반으로 빌드됩니다. 나머지는 하드 코딩되어 있습니다. 코드에는 더 이상 아무것도 없습니다.


1

펄, 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

@migimaru 나는 ​​그것을 고치려고 노력할 것이다.
zura

@zura 알파벳 이외의 문자를위한 인쇄 공간이 허용됩니다. 고칠 필요는 없습니다.
migimaru

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' '}
''}

온라인으로 사용해보십시오!

출력에는 꼬리 빈 줄이 하나 있습니다.

덜 골프 :

-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.