Прапор Семафорний Енкодер


12

Ваша мета - написати кодер семафорного прапора , який перетворить задане речення у відповідні символи семафору прапора, згідно з семафорною системою, описаною у Вікіпедії .

Припустимо, що вхід - це одне речення, яке надається через stdin (або еквівалент). У вашому висновку має бути ряд семафорних символів, кожен рядок представляє одне слово з речення. Потрібно мати справу лише з алфавітом (AZ) і слід ігнорувати всі інші символи, що не містять пробілів, але ви повинні мати можливість обробляти як великі, так і малі літери. Ваш вихід може містити додатковий пробіл.

Символи семафору повинні відображатися у вигляді квадрата 3х3, з 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 Так, напевно, це гарна ідея, щоб додати цей тег. Дякую.
migimaru

and each row must be separated by a blank line=> мається на увазі кожне слово , чи не так?
користувач невідомий

1
Перш ніж прочитати цю головоломку, я помилково подумав, що це стосується семафорів у сенсі програмування. ¡Jajajajajja!
Томас Едінг

@user unknown Я використовував рядок там для позначення рядів семафору . Можливо, використання слова замість цього було б кращим вибором.
migimaru

Відповіді:


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 положень, два прапори, і два прапори ніколи не можуть бути в одному положенні. Це означає, що я можу кодувати положення обох прапорів в одному байті - це також означає, що я можу перевести безпосередньо з символу в його кодування за допомогою y///функції Perl (оператора?). Тому:-

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, з краями між ділянками обміну літерами, з краями, позначеними відповідно до загального sbit. В ідеалі я знайшов би шлях Гамільтона через цей графік, щоб наступні краї не мали однакової мітки. Таких шляхів не існує ... тож ви зауважите, що змінна eмістить літеру bдвічі.

Своїм майже гамільтоновим контуром eя dбудую масив sbit міток, які використовуються для обходу e. Потім, щоб розібратися, куди покласти руки, сигналісту потрібно лише знайти потрібну букву в наступній зручній схемі

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

звідки її руки йдуть у положення прямо внизу, а внизу та праворуч від листа.


Я не міг змусити це працювати на ideone , поки я не змінив 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, де 6 годин, а a, b, c - перші коди, з першим (одним) прапором на Південь.

Оскільки прапор 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))

Я мало знаю про Скалу. Чи є спосіб я перевірити це на ideone? Я спробував загорнути його в object Main extends Applicationблок, але цього, здається, недостатньо.
migimaru

IDEONE потребує класу з іменем Main, якщо я правильно пам’ятаю, основний метод, можливо, повинен поширити додаток (для scala-2.9, замість програми (-2.8)) - і читання це з stdin? У простому масштабі ви можете перевірити код простіше. Якщо ви заміните readLineв останньому рядку, "readLine"він повинен працювати (код сумісний із 2.8).
користувач невідомий

Дякую! Я не знав про просто шкалу, що значно полегшує справи.
migimaru

Якщо вам знову потрібне посилання: я вставив посилання десь у мета, де вже збираються такі речі.
користувач невідомий

Це обробляє великі регістри?
Томас Едінг

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 - хвилину (див. Приклад другого галочки вище). Це єдиний спосіб збільшення годин. Години НЕ збільшуються, коли хвилина досягає якоїсь довільної хвилини. Тільки тоді, коли хвилини дорівнювали б годинам. У ненаголошеному коді 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, не дуже зрозуміло, що з ними робити ...
Гарет

Я зараз не в змозі перевірити код, але схоже, що код просто друкує пробіли для символів, які не містять альфа, що добре.
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³↓

Перейдіть до початку наступного слова.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.