Флаг семафор кодировщик


12

Ваша цель - написать кодировщик семафоров флагов , который преобразует данное предложение в соответствующие символы семафоров флагов в соответствии с системой семафоров, описанной в Википедии .

Предположим, что вход представляет собой одно предложение, предоставленное через стандартный ввод (или эквивалентный). Ваш вывод должен быть последовательностью символов семафора, каждая строка представляет одно слово из предложения. Вам нужно иметь дело только с алфавитом (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
колмогоров-сложность ? Мне кажется, что в основном речь идет о сжатии таблицы поиска.
Питер Тейлор

@ Питер Тейлор Да, возможно, это хорошая идея добавить этот тег. Спасибо.
Мигимару

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

1
Перед тем, как прочесть эту загадку, я ошибочно подумал, что это связано с семафорами в смысле программирования. ¡Jajajajajja!
Томас Эдинг

@user unknown. Я использовал строку для обозначения строки символов семафора . Возможно, вместо этого было бы лучше использовать слово .
Мигимару

Ответы:


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

Я избежал изрядного числа символов, которые находятся за пределами обычного используемого диапазона, чтобы упростить копирование и вставку программы - но я вполне уверен, что мог бы написать программу, заменяющую escape-коды самими символами, спасающими меня примерно 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)

Это использует мой любимый трюк: однотрековое кодирование. Я пометил биты семафора (биты)

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

получить следующую диаграмму, какие биты встречаются для какой буквы:

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

каждая буква встречается на диаграмме ровно дважды, так как у сигнальщика есть две руки. Затем я рассматриваю это как график букв az с ребрами между буквами, разделяющими sbit, с ребрами, помеченными в соответствии с общим sbit. В идеале я бы нашел путь Гамильтона через этот граф, чтобы последующие ребра не имели одинаковую метку. Таких путей не существует ... поэтому вы заметите, что переменная eсодержит букву bдважды.

На моем почти гамильтоновом пути eя dсоздаю массив меток sbit, используемых при обходе e. Затем, чтобы выяснить, куда положить руки, связисту нужно только найти нужную букву в следующей удобной таблице.

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

откуда ее руки переходят в положение непосредственно под, а под и справа от буквы.


Я не мог заставить это работать на ideone, пока я не изменился to_lower()на lower(). Кроме того, он выдал ошибку, когда я попытался дать не алфавитный ввод.
Мигимару

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

Ungolfed (ну, меньше в гольф):

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

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

Объяснение:

Я наблюдал схему часов, но не с 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) означало бы, что первый флаг - WEST, а второй - два шага по часовой стрелке оттуда к СЕВЕРУ.

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блок, но этого оказалось недостаточно.
Мигимару

IDEONE нужен класс с именем Main, если я правильно помню, метод main должен расширять App (для scala-2.9 вместо Application (-2.8)) - и читает ли он из stdin? В simplyscala вы можете тестировать код проще. Если вы замените readLineв последней строке, "readLine"он должен работать (код совместим с 2.8).
пользователь неизвестен

Благодаря! Я не знал о simplescala, который делает вещи намного проще.
Мигимару

Если вам снова нужна ссылка: я вставил ссылку где-то в мета, где такие вещи собираются.
пользователь неизвестен

Это обрабатывает прописные буквы?
Томас Эдинг

1

Haskell 331 357 339 символов

Golfed:

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

Ungolfed:

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

Perl, 356 , 275 символов

Большое количество символов было сохранено путем замены «если еще» на «? :' строительство.

@_=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 Я постараюсь исправить это.
Зура

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