Cờ mã hóa Semaphore


12

Mục tiêu của bạn là viết một bộ mã hóa semaphore cờ , nó sẽ chuyển đổi một câu đã cho thành các ký tự semaphore cờ tương ứng, theo hệ thống semaphore được mô tả trên Wikipedia .

Giả sử rằng đầu vào là một câu duy nhất được cung cấp thông qua stdin (hoặc tương đương). Đầu ra của bạn phải là một chuỗi các ký tự semaphore, với mỗi hàng đại diện cho một từ trong câu. Bạn chỉ cần xử lý bảng chữ cái (AZ) và nên bỏ qua tất cả các ký tự không phải không gian khác, nhưng bạn phải có khả năng xử lý cả chữ hoa và chữ thường. Đầu ra của bạn được phép chứa thêm khoảng trắng.

Các ký tự semaphore phải được hiển thị dưới dạng hình vuông 3x3, với một vị trí Oở giữa và cờ được đại diện bởi các ký tự | - / \. Mỗi ký tự semaphore phải được phân cách với các ký tự liền kề bởi một khoảng trắng và mỗi hàng phải được phân tách bằng một dòng trống. Đừng lo lắng về việc gói các từ có thể quá dài cho màn hình của bạn - giả vờ rằng các dòng của bạn có độ dài vô hạn.

Đầu vào mẫu:

abcdefg hijklmn opqrstu vwxyz

Đầu ra mẫu:

        \    |    /
 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-
  \       \       \

Đầu vào mẫu:

This is Code Golf.

Đầu ra mẫu:

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

\      
 O  -O 
/     \

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

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

Vì đây là , giải pháp ngắn nhất sẽ thắng.


1
độ phức tạp kolmogorov ? Dường như với tôi về cơ bản đây là về việc nén một bảng tra cứu.
Peter Taylor

@Peter Taylor Vâng, có lẽ nên thêm thẻ đó. Cảm ơn.
Migimaru

and each row must be separated by a blank line=> mỗi từ có nghĩa là gì, phải không?
người dùng không xác định

1
Trước khi tôi đọc câu đố này, tôi đã lầm tưởng nó phải liên quan đến semaphores trong ý nghĩa lập trình. Jajajajajja!
Thomas Eding

@user unknown Tôi đã sử dụng hàng ở đó để chỉ một hàng ký tự semaphore . Có lẽ sử dụng từ thay thế sẽ là một lựa chọn tốt hơn.
Migimaru

Câu trả lời:


5

Perl, 282 264 251 247 245 243 241 240 236 233 229 227 220 218 216 214 ký tự

$_=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

Với một số ngắt dòng đẹp hơn:

$_=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

Tôi phải mất một thời gian để làm việc này (nỗ lực đầu tiên của tôi ở câu trả lời Perl). Nó dựa trên một ý tưởng tương tự như rất nhiều câu trả lời khác. Mỗi cờ có thể ở một trong 8 vị trí, có hai cờ và hai cờ không thể ở cùng một vị trí. Điều này có nghĩa là tôi có thể mã hóa vị trí của cả hai cờ trong một byte - điều đó cũng có nghĩa là tôi có thể dịch trực tiếp từ một ký tự sang mã hóa bằng y///hàm của Perl (toán tử?). Vì thế:-

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

Vì thế:

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

Tôi đã thoát được một vài ký tự nằm ngoài phạm vi được sử dụng bình thường để sao chép và dán chương trình dễ dàng - nhưng tôi khá chắc chắn rằng tôi có thể viết một chương trình để thay thế mã thoát bằng chính các ký tự cứu tôi khoảng 30 ký tự.


6

Con trăn, 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)

Điều này sử dụng một thủ thuật yêu thích của tôi: mã hóa theo dõi đơn. Tôi đã gắn nhãn các bit semaphore (sbits)

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

để có được biểu đồ sau trong đó sbits xảy ra cho chữ cái nào:

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

mỗi chữ cái xuất hiện chính xác hai lần trong biểu đồ, vì tín hiệu có hai nhánh. Sau đó, tôi xem đây là một biểu đồ trên các chữ cái az, với các cạnh giữa các chữ cái chia sẻ sbits, với các cạnh được gắn nhãn theo sbit được chia sẻ. Lý tưởng nhất là tôi tìm thấy đường dẫn Hamilton qua biểu đồ này, sao cho các cạnh tiếp theo không có cùng nhãn. Không có đường dẫn như vậy tồn tại ... vì vậy bạn sẽ lưu ý rằng biến echứa chữ cái bhai lần.

Với đường dẫn gần Hamilton của etôi, tôi xây dựng một loạt dcác nhãn sbit được sử dụng trong giao dịch của e. Sau đó, để tìm ra nơi đặt cánh tay của mình, người báo hiệu chỉ cần tìm chữ cái mong muốn trong biểu đồ tiện dụng sau đây

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

Khi cánh tay của cô ấy đi vào vị trí ngay bên dưới, và bên dưới & bên phải của bức thư.


Tôi không thể có được điều này để chạy trên ideone cho đến khi tôi đổi to_lower()thành lower(). Ngoài ra, nó đã báo lỗi khi tôi thử cung cấp cho nó đầu vào không phải là chữ cái.
Migimaru

4

Scala, 272 ký tự

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"))

Ungolfed (tốt, ít chơi gô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

Ruby, 287 ký tự

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]}*' '},''}

Đầu vào phải được đưa ra trên STDIN.


1

Scala 494 không có dòng mới 520 với dòng mới:

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

vô dụng:

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

Giải trình:

Tôi đã quan sát một mẫu đồng hồ, nhưng không phải trong 12 giờ, mà là 8. Và Thời gian bắt đầu là 0, trong đó 6 giờ và a, b, c là các mã đầu tiên, với cờ (một) đầu tiên ở phía Nam.

Vì cờ 1 và 2 không thể phân biệt được, chúng tôi có thể sắp xếp tất cả các kết hợp với số thấp hơn cho cờ đầu tiên. Thật không may, thứ tự tốt ngay từ đầu đã bị xáo trộn, khi j không theo i, nhưng k, l, m, và sau đó nó trở nên lộn xộn.

Vì vậy, tôi sắp xếp lại các khóa của mình để ánh xạ:

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

Nếu chúng ta trừ 'a' từ mỗi ký tự, chúng ta sẽ nhận được các số từ (0 đến 7 + 6 + 5 + ... + 1). Chúng ta có thể ánh xạ các số của lưới ký tự

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

Một cặp gồm hai số có thể ánh xạ hai cờ, trong đó số thứ nhất là chỉ số từ 0 đến 6 cho cờ thứ nhất và cờ thứ hai không phải là số từ 1 đến 7 cho cờ thứ hai, nhưng cho khoảng cách từ đầu tiên đến cờ thứ hai. (2,2) có nghĩa là, lá cờ đầu tiên đến TÂY, và lá thứ hai là hai bước theo chiều kim đồng hồ từ đó, đến BẮC.

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

Tôi không biết nhiều về Scala. Có cách nào tôi có thể kiểm tra điều này trên ideone không? Tôi đã thử gói nó trong một object Main extends Applicationkhối, nhưng điều đó dường như là không đủ.
Migimaru

IDEONE cần một lớp có tên Main, nếu tôi nhớ chính xác, một phương thức chính, có lẽ nên mở rộng Ứng dụng (cho scala-2.9, thay vì Ứng dụng (-2.8)) - và nó có đọc từ stdin không? Trong Simplyscala bạn có thể kiểm tra mã đơn giản hơn. Nếu bạn thay thế readLinetrong dòng cuối cùng với "readLine"nó sẽ hoạt động (mã tương thích 2.8).
người dùng không xác định

Cảm ơn! Tôi không biết về Simplyscala, điều đó làm cho mọi thứ dễ dàng hơn nhiều.
Migimaru

Nếu bạn cần liên kết lại: Tôi đã chèn liên kết ở đâu đó trong meta rồi, nơi những thứ đó được thu thập.
người dùng không xác định

Điều này có xử lý chữ hoa không?
Thomas Eding

1

Haskell 331 357 339 ký tự

Chơi gôn

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

Ung dung:

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]

Mã hóa là [hour, minute]nơi đồng hồ có 8 giờ 8 phút. Phút di chuyển nhanh hơn giờ. Nếu đồng hồ tích tắc trong đó giờ và phút sẽ bằng nhau, hãy thêm 1 vào giờ và 2 vào phút (xem ví dụ đánh dấu thứ hai ở trên). Đó là cách duy nhất tăng giờ. Giờ KHÔNG tăng khi phút đạt đến một số phút tùy ý. Chỉ khi phút sẽ bằng giờ. Trong mã không mã clockhóa , biến các chữ cái thành đồng hồ đại diện cho semaphore. Hầu hết các đồng hồ được xây dựng dựa trên đánh dấu từ những người trước đó. Phần còn lại là mã hóa cứng. Không có gì thực sự nhiều hơn cho mã.


1

Perl, 356 , 275 ký tự

Một số lượng lớn ký tự đã được lưu bằng cách thay thế 'nếu khác' thành '? :' xây dựng.

@_=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"};}

Mã của bạn dường như chỉ hoạt động cho các chữ cái viết thường. Nếu bạn sử dụng <>thay vì $ARGV[0]bạn có thể lấy đầu vào từ stdin và sử dụng lcđể chuyển đổi tất cả các ký tự thành chữ thường. Điều này có thêm lợi ích giúp bạn tiết kiệm 4 ký tự. Nó cũng không xử lý các ký tự không phải là bảng chữ cái, nhưng có thể cho rằng You only need to deal with the alphabet (A-Z) and should ignore all other non-space characterskhông rõ ràng về việc phải làm gì với chúng ...
Gareth

Tôi không thể kiểm tra mã ngay bây giờ, nhưng có vẻ như mã chỉ in các khoảng trắng cho các ký tự không phải alpha, điều này là tốt.
Migimaru

@migimaru Tôi sẽ cố gắng sửa nó.
zura

@zura In không gian cho các ký tự không phải là bảng chữ cái được chấp nhận. Bạn không cần phải sửa nó.
Migimaru

0

PowerShell , 198 192 191 188 byte

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

Hãy thử trực tuyến!

Đầu ra chứa một dòng trống đuôi.

Ít chơi gôn hơn:

-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

Than , 70 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

F⪪↧S «

Tách đầu vào cấp dưới trên khoảng trắng và lặp qua từng từ.

Fι«

Vòng qua từng nhân vật.

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

Chia chuỗi nén fjmrwyz gnsvxz abcdefg ahiklmn bhopqrs ciotuy djkptv elquwxtrên khoảng trắng và lặp qua từng nhóm chữ.

P⊗№λκ

Nếu nhóm chứa chữ cái hiện tại thì vẽ một dòng theo hướng hiện tại.

↷¹»

Xoay 45 ° theo chiều kim đồng hồ.

oM³→»

Xuất trung tâm ovà di chuyển đến vị trí của chữ cái tiếp theo.

⸿M³↓

Di chuyển đến đầu của từ tiếp theo.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.