Tandai Semaphore Encoder

12

Tujuan Anda adalah untuk menulis encoder semaphore bendera , yang akan mengubah kalimat yang diberikan menjadi karakter semaphore bendera yang sesuai, sesuai dengan sistem semaphore yang dijelaskan di Wikipedia .

Asumsikan bahwa input adalah satu kalimat yang diberikan melalui stdin (atau setara). Keluaran Anda harus berupa serangkaian karakter semafor, dengan setiap baris mewakili satu kata dari kalimat. Anda hanya perlu berurusan dengan alfabet (AZ) dan harus mengabaikan semua karakter non-spasi lainnya, tetapi Anda harus dapat menangani huruf besar dan kecil. Output Anda diizinkan mengandung spasi putih tambahan.

Karakter semafor harus ditampilkan sebagai kotak 3x3, dengan posisi Odi tengah dan bendera diwakili oleh karakter | - / \. Setiap karakter semafor harus dipisahkan dari karakter yang berdekatan dengan spasi, dan setiap baris harus dipisahkan oleh garis kosong. Jangan khawatir tentang membungkus kata-kata yang mungkin terlalu panjang untuk tampilan Anda - berpura-pura bahwa garis Anda memiliki panjang yang tak terbatas.

Input sampel:

abcdefg hijklmn opqrstu vwxyz

Output sampel:

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

Input sampel:

This is Code Golf.

Output sampel:

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

\      
 O  -O 
/     \

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

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

Karena ini adalah , solusi terpendek menang.

migimaru
sumber
1
kolmogorov-kompleksitas ? Sepertinya saya bahwa pada dasarnya ini adalah tentang mengompresi tabel pencarian.
Peter Taylor
@ Peter Taylor Ya, mungkin ide yang baik untuk menambahkan tag itu. Terima kasih.
migimaru
and each row must be separated by a blank line=> setiap kata dimaksudkan, bukan?
pengguna tidak diketahui
1
Sebelum saya membaca puzzle ini, saya secara keliru mengira itu ada hubungannya dengan semaphore dalam pengertian pemrograman. ¡Jajajajajja!
Thomas Eding
@ pengguna tidak diketahui Saya menggunakan baris di sana untuk merujuk ke deretan karakter semafor . Mungkin menggunakan kata saja akan menjadi pilihan yang lebih baik.
migimaru

Jawaban:

5

Perl, 282 264 251 247 245 243 241 240 236 233 229 227 220 218 216 214 karakter

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

Dengan beberapa jeda garis prettifying:

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

Butuh beberapa saat untuk menyelesaikannya (upaya pertamaku pada jawaban Perl). Ini didasarkan pada ide yang mirip dengan banyak jawaban lain. Setiap bendera dapat berada di salah satu dari 8 posisi, ada dua bendera, dan kedua bendera tersebut tidak dapat berada di posisi yang sama. Ini berarti saya dapat mengkodekan posisi kedua flag dalam satu byte - yang juga berarti saya dapat menerjemahkan langsung dari karakter ke pengkodeannya menggunakan y///fungsi Perl (operator?). Begitu:-

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

Karena itu:

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

Saya telah lolos dari beberapa karakter yang berada di luar rentang yang biasa digunakan untuk mempermudah penyalinan dan menempelkan program - tetapi saya cukup yakin saya bisa menulis program untuk mengganti kode pelarian dengan karakter itu sendiri menyelamatkan saya kira-kira 30 karakter.

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

Ini menggunakan trik favorit saya: pengodean single-track. Saya telah memberi label bit semaphore (sbits)

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

untuk mendapatkan bagan berikut yang sbits terjadi untuk surat yang mana:

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

setiap huruf muncul tepat dua kali dalam bagan, karena pemberi sinyal memiliki dua tangan. Kemudian, saya melihat ini sebagai grafik pada huruf az, dengan tepi antara huruf berbagi sbits, dengan tepi berlabel sesuai dengan sbit bersama. Idealnya, saya akan menemukan jalur Hamilton melalui grafik ini, sehingga tepi berikutnya tidak memiliki label yang sama. Tidak ada jalur seperti itu ... jadi Anda akan perhatikan bahwa variabel eberisi surat itu bdua kali.

Dengan jalur hampir-Hamilton esaya, saya membangun sebuah array dlabel sbit yang digunakan dalam traversal e. Kemudian, untuk mencari tahu di mana harus meletakkan lengannya, pemberi sinyal hanya perlu menemukan huruf yang diinginkan dalam bagan praktis berikut

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

dari mana tangannya berada pada posisi tepat di bawah, dan di bawah & kanan surat itu.

stan
sumber
Aku tidak bisa mendapatkan ini untuk berjalan di ideone sampai aku berubah to_lower()ke lower(). Juga, itu memberikan kesalahan ketika saya mencoba memberikan input non-alfabet.
migimaru
4

Scala, 272 karakter

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

Tidak diseret (well, kurang golf):

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")
)
Rex Kerr
sumber
2

Ruby, 287 karakter

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

Masukan harus diberikan pada STDIN.

Howard
sumber
1

Scala 494 tanpa baris baru 520 dengan baris baru:

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

ungolfed:

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

Penjelasan:

Saya mengamati pola-jam, tetapi tidak dengan 12 jam, tetapi 8. Dan Starttime adalah 0 adalah, di mana jam 6 adalah, dan a, b, c adalah kode pertama, dengan bendera (satu) pertama di Selatan.

Karena flag 1 dan 2 tidak dapat dibedakan, kami dapat mengurutkan semua kombinasi dengan angka yang lebih rendah untuk flag pertama terlebih dahulu. Sayangnya, urutan yang baik dari awal terganggu, ketika j tidak mengikuti saya, tetapi k, l, m, dan kemudian menjadi berantakan.

Karenanya saya mengatur ulang kunci saya untuk pemetaan:

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

Jika kita mengurangi 'a' dari setiap karakter, kita mendapatkan angka dari (0 hingga 7 + 6 + 5 + ... + 1). Kami dapat memetakan angka dari kotak karakter

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

Sepasang dua angka dapat memetakan dua bendera, di mana angka pertama adalah indeks dari 0 hingga 6 untuk bendera pertama, dan bendera kedua bukanlah angka dari 1 hingga 7 untuk bendera kedua, tetapi untuk jarak dari pertama ke bendera kedua. (2,2) berarti, bendera pertama adalah BARAT, dan yang kedua adalah dua langkah searah jarum jam dari sana, ke UTARA.

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))
Pengguna tidak diketahui
sumber
Saya tidak tahu banyak tentang Scala. Apakah ada cara saya bisa menguji ini pada ideone? Saya mencoba membungkusnya dalam satu object Main extends Applicationblok, tetapi itu tampaknya tidak cukup.
migimaru
IDEONE membutuhkan kelas bernama Main, jika saya ingat dengan benar, metode utama, mungkin perlu memperpanjang App (untuk scala-2.9, bukan Aplikasi (-2.8)) - dan apakah itu dibaca dari stdin? Di simplyscala Anda dapat menguji kode lebih sederhana. Jika Anda mengganti readLinepada baris terakhir dengan "readLine"itu harus berfungsi (kode 2,8 kompatibel).
pengguna tidak diketahui
Terima kasih! Saya tidak tahu tentang SimplyCala, yang membuat segalanya lebih mudah.
migimaru
Jika Anda memerlukan tautan lagi: Saya sudah memasukkan tautan di suatu tempat di meta, tempat hal-hal seperti itu dikumpulkan.
pengguna tidak diketahui
Apakah ini menangani huruf besar?
Thomas Eding
1

Haskell 331 357 339 karakter

Golf:

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

Tidak Disatukan:

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]

Pengkodean adalah di [hour, minute]mana jam memiliki 8 jam dan 8 menit. Menit bergerak lebih cepat daripada jam. Jika jam berdetik di mana jam dan menit akan sama, tambahkan 1 ke jam dan 2 juga sebagai menit (lihat contoh centang kedua di atas). Itulah satu-satunya cara peningkatan jam. Jam TIDAK bertambah ketika menit mencapai beberapa menit sewenang-wenang. Hanya ketika menit akan sama dengan jam. Dalam kode yang tidak diubah, clockmengubah huruf menjadi jam yang mewakili semafor. Sebagian besar jam dibangun berdasarkan detakan dari yang sebelumnya. Sisanya kode keras. Tidak ada yang lebih dari kode.

Thomas Eding
sumber
1

Perl, 356 , 275 karakter

Sejumlah besar karakter disimpan dengan mengganti 'jika lain' menjadi '? : 'konstruksi.

@_=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"};}
zura
sumber
Kode Anda sepertinya hanya berfungsi untuk huruf kecil. Jika Anda menggunakan <>alih-alih, $ARGV[0]Anda dapat mengambil input dari stdin dan menggunakan lcuntuk mengubah semua karakter menjadi huruf kecil. Ini memiliki manfaat tambahan untuk menghemat 4 karakter. Itu tidak menangani karakter non-alfabet juga, tetapi bisa dibilang You only need to deal with the alphabet (A-Z) and should ignore all other non-space characterstidak terlalu jelas tentang apa yang harus dilakukan dengan mereka ...
Gareth
Saya tidak dapat menguji kode sekarang, tetapi sepertinya kode hanya mencetak spasi untuk karakter non-alpha, yang baik-baik saja.
migimaru
@migimaru Saya akan mencoba memperbaikinya.
zura
@zura Ruang cetak untuk karakter non-alfabet dapat diterima. Anda tidak perlu memperbaikinya.
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' '}
''}

Cobalah online!

Output berisi satu baris baris kosong.

Kurang golf:

-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' '
    }
    ''
}
mazzy
sumber
0

Arang , 70 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

F⪪↧S «

Pisahkan input dengan huruf kecil pada spasi dan lewati setiap kata.

Fι«

Ulangi setiap karakter.

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

Pisahkan string yang dikompresi fjmrwyz gnsvxz abcdefg ahiklmn bhopqrs ciotuy djkptv elquwxpada spasi dan loop di atas setiap grup huruf.

P⊗№λκ

Jika grup berisi huruf saat ini maka buat garis ke arah saat ini.

↷¹»

Putar 45 ° searah jarum jam.

oM³→»

Keluarkan pusat odan pindah ke posisi huruf berikutnya.

⸿M³↓

Pindah ke awal kata berikutnya.

Neil
sumber