Flag Semaphore Encoder

12

Ihr Ziel ist es, einen Flag-Semaphor-Encoder zu schreiben , der einen bestimmten Satz gemäß dem in Wikipedia beschriebenen Semaphor-System in die entsprechenden Flag-Semaphor-Zeichen umwandelt .

Angenommen, die Eingabe ist ein einzelner Satz, der durch stdin (oder einen gleichwertigen Satz) bereitgestellt wird. Ihre Ausgabe sollte eine Reihe von Semaphorzeichen sein, wobei jede Zeile ein Wort aus dem Satz darstellt. Sie müssen sich nur mit dem Alphabet (AZ) befassen und sollten alle anderen Nicht-Leerzeichen ignorieren, müssen jedoch in der Lage sein, sowohl Groß- als auch Kleinbuchstaben zu verarbeiten. Ihre Ausgabe darf zusätzliche Leerzeichen enthalten.

Semaphorzeichen müssen als 3x3-Quadrat angezeigt werden, wobei eine Oin der Mitte und die Flaggenpositionen durch die Zeichen dargestellt werden | - / \. Jedes Semaphorzeichen muss durch ein Leerzeichen von benachbarten Zeichen getrennt sein, und jede Zeile muss durch eine Leerzeile getrennt sein. Machen Sie sich keine Sorgen um das Umbrechen von Wörtern, die für Ihre Anzeige möglicherweise zu lang sind - tun Sie so, als hätten Ihre Zeilen eine unendliche Länge.

Beispieleingabe:

abcdefg hijklmn opqrstu vwxyz

Beispielausgabe:

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

Beispieleingabe:

This is Code Golf.

Beispielausgabe:

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

\      
 O  -O 
/     \

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

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

Da dies , gewinnt die kürzeste Lösung.

Migimaru
quelle
1
Kolmogorov-Komplexität ? Es scheint mir, dass es im Grunde darum geht, eine Nachschlagetabelle zu komprimieren.
Peter Taylor
@ Peter Taylor Ja, es ist wahrscheinlich eine gute Idee, dieses Tag hinzuzufügen. Vielen Dank.
Migimaru
and each row must be separated by a blank line=> Jedes Wort ist gemeint, nicht wahr?
Benutzer unbekannt
1
Bevor ich dieses Puzzle las, dachte ich fälschlicherweise, es habe mit Semaphoren im Sinne der Programmierung zu tun. Jajajajajja!
Thomas Eding
@user unbekannt Ich habe dort eine Zeile verwendet, um auf eine Zeile mit Semaphorzeichen zu verweisen . Vielleicht wäre es besser gewesen, stattdessen ein Wort zu verwenden.
Migimaru

Antworten:

5

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

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

Mit einigen schönen Zeilenumbrüchen:

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

Ich habe eine Weile gebraucht, um das zum Laufen zu bringen (mein erster Versuch einer Perl-Antwort). Es basiert auf einer ähnlichen Idee wie viele andere Antworten. Jedes Flag kann sich an einer von 8 Positionen befinden, es gibt zwei Flags und die beiden Flags können sich niemals an derselben Position befinden. Dies bedeutet, dass ich die Position beider Flags in einem Byte codieren kann - was auch bedeutet, dass ich mit der Perl- y///Funktion (Operator?) Direkt von einem Zeichen in seine Codierung übersetzen kann . So:-

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

Deshalb:

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

Ich bin einigen Zeichen entkommen, die außerhalb des normalen Bereichs liegen, um das Kopieren und Einfügen des Programms zu vereinfachen. Ich bin mir jedoch ziemlich sicher, dass ich ein Programm schreiben kann, um die Escape-Codes durch die Zeichen selbst zu ersetzen, die mich retten ungefähr 30 Zeichen.

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

Dies verwendet einen meiner Lieblingstricks: die einspurige Codierung. Ich habe die Semaphorbits (sbits) beschriftet.

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

um die folgende Tabelle zu erhalten, welche sbits für welchen Buchstaben vorkommen:

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

Jeder Buchstabe kommt in der Tabelle genau zweimal vor, da der Signalgeber zwei Arme hat. Dann betrachte ich dies als eine Grafik auf den Buchstaben az, mit Kanten zwischen Buchstaben, die sbits teilen, wobei die Kanten entsprechend dem gemeinsam genutzten sbit beschriftet sind. Im Idealfall würde ich einen Hamilton-Pfad durch dieses Diagramm finden, sodass nachfolgende Kanten nicht dieselbe Beschriftung haben. Es gibt keine solchen Pfade. Sie werden also feststellen, dass die Variable eden Buchstaben bzweimal enthält .

Mit meinem Fast-Hamilton-Pfad ekonstruiere ich ein Array dvon sbit-Labels, die beim Durchlaufen von verwendet werden e. Um herauszufinden, wo sie ihre Arme hinlegen soll, muss der Signalgeber nur den gewünschten Buchstaben in der folgenden handlichen Tabelle finden

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

woher gehen ihre Arme in die Position direkt unter und unter und rechts vom Brief.

Standby
quelle
Ich konnte nicht bekommen diese auf ideone laufen , bis ich geändert to_lower()zu lower(). Außerdem gab es einen Fehler, als ich versuchte, eine nicht alphabetische Eingabe zu machen.
Migimaru
4

Scala, 272 Zeichen

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 (gut, weniger 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
quelle
2

Ruby, 287 Zeichen

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

Die Eingabe muss über STDIN erfolgen.

Howard
quelle
1

Scala 494 ohne Zeilenumbrüche 520 mit Zeilenumbrüchen:

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

Erläuterung:

Ich habe ein Uhrmuster beobachtet, aber nicht mit 12 Stunden, sondern mit 8. Und Startzeit ist 0, wobei 6 Uhr ist, und a, b, c sind die ersten Codes, mit der ersten (einen) Flagge im Süden.

Da Flag 1 und 2 nicht zu unterscheiden sind, können wir alle Kombinationen mit der niedrigeren Nummer für das erste Flag zuerst sortieren. Leider ist die Ordnung von Anfang an gestört, wenn j nicht i folgt, sondern k, l, m, und später wird es ein Chaos.

Deshalb ordne ich meine Schlüssel für das Mapping neu:

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

Wenn wir von jedem Zeichen 'a' subtrahieren, erhalten wir die Zahlen von (0 bis 7 + 6 + 5 + ... + 1). Wir können die Nummern eines Zeichenrasters abbilden

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

Ein Paar von zwei Zahlen kann zwei Flags zuordnen, wobei die erste Zahl der Index von 0 bis 6 für das erste Flag ist und das zweite Flag keine Zahl von 1 bis 7 für das zweite Flag ist, sondern für die Entfernung von der erste bis zur zweiten Flagge. (2,2) würde bedeuten, dass das erste Flag nach WEST und das zweite zwei Schritte im Uhrzeigersinn von dort nach NORTH ist.

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))
Benutzer unbekannt
quelle
Ich weiß nicht viel über Scala. Gibt es eine Möglichkeit, dies auf ideone zu testen? Ich habe versucht, es in einen object Main extends ApplicationBlock zu wickeln , aber das scheint nicht genug zu sein.
Migimaru
IDEONE benötigt eine Klasse namens Main. Wenn ich mich richtig erinnere, sollte eine Hauptmethode möglicherweise die App erweitern (für Scala-2.9 anstelle von Application (-2.8)) - und liest sie von stdin? In simplyscala können Sie Code einfacher testen. Wenn Sie readLinein der letzten Zeile ersetzen "readLine", sollte es funktionieren (der Code ist 2.8-kompatibel).
Benutzer unbekannt
Vielen Dank! Ich wusste nichts über simplyscala, das macht die Sache viel einfacher.
Migimaru
Wenn Sie den Link erneut benötigen: Ich habe den Link bereits irgendwo in das Meta eingefügt, wo solche Dinge gesammelt werden.
Benutzer unbekannt
Behandelt dies Großbuchstaben?
Thomas Eding
1

Haskell 331 357 339 Zeichen

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

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]

Bei der Codierung [hour, minute]haben Uhren 8 Stunden und 8 Minuten. Minuten bewegen sich schneller als Stunden. Wenn eine Uhr dort tickt, wo Stunde und Minute gleich sind, addieren Sie 1 zur Stunde und 2 zur Minute (siehe Beispiel für das zweite Häkchen oben). Nur so können sich die Stunden erhöhen. Die Stunden erhöhen sich NICHT, wenn die Minute eine beliebige Minute erreicht. Nur wenn Minuten Stunden entsprechen würden. Verwandelt im ungolfed Code clockBuchstaben in Uhren, die das Semaphor darstellen. Die meisten Uhren basieren auf dem Ticken der vorherigen Uhren. Der Rest ist fest codiert. Der Code enthält nichts wirklich mehr.

Thomas Eding
quelle
1

Perl, 356 , 275 Zeichen

Eine große Anzahl von Zeichen wurde gespeichert, indem 'if else' durch 'ersetzt wurde. :' Konstruktion.

@_=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
quelle
Ihr Code scheint nur für Kleinbuchstaben zu funktionieren. Wenn Sie <>stattdessen verwenden $ARGV[0], können Sie Eingaben von stdin übernehmen und lcalle Zeichen in Kleinbuchstaben konvertieren. Dies hat den zusätzlichen Vorteil, dass Sie 4 Zeichen sparen. Es behandelt auch keine Nicht-Alphabet-Zeichen, aber es ist wohl You only need to deal with the alphabet (A-Z) and should ignore all other non-space charactersnicht ganz klar, was man damit machen soll ...
Gareth
Ich kann den Code derzeit nicht testen, aber es sieht so aus, als würde der Code nur Leerzeichen für Nicht-Alpha-Zeichen drucken, was in Ordnung ist.
Migimaru
@ Migimaru Ich werde versuchen, es zu korrigieren.
Zura
@zura Das Drucken von Leerzeichen für Nicht-Alphabet-Zeichen ist zulässig. Sie müssen das nicht beheben.
Migimaru
0

PowerShell , 198 192 191 188 Bytes

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

Probieren Sie es online aus!

Die Ausgabe enthält eine leere Leerzeile.

Weniger 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
quelle
0

Holzkohle , 70 Bytes

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

Probieren Sie es online aus! Der Link führt zur ausführlichen Version des Codes. Erläuterung:

F⪪↧S «

Teilen Sie die Eingabe in Kleinbuchstaben auf Leerzeichen und durchlaufen Sie jedes Wort.

Fι«

Schleife über jedes Zeichen.

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

Teilen Sie die komprimierte Zeichenfolge fjmrwyz gnsvxz abcdefg ahiklmn bhopqrs ciotuy djkptv elquwxauf Leerzeichen und durchlaufen Sie jede Buchstabengruppe.

P⊗№λκ

Wenn die Gruppe den aktuellen Buchstaben enthält, ziehen Sie eine Linie in die aktuelle Richtung.

↷¹»

45 ° im Uhrzeigersinn drehen.

oM³→»

Geben Sie die Mitte aus ound gehen Sie zur Position des nächsten Buchstabens.

⸿M³↓

Gehen Sie zum Anfang des nächsten Wortes.

Neil
quelle