Semaphore Encoder ile ilgili şikayetler


12

Amacınız , Wikipedia'da açıklanan semafor sistemine göre, verilen bir cümleyi karşılık gelen bayrak semafor karakterlerine dönüştürecek bir bayrak semafor kodlayıcı yazmaktır .

Girişin stdin (veya eşdeğeri) aracılığıyla sağlanan tek bir cümle olduğunu varsayalım. Çıktınız bir dizi semafor karakteri olmalıdır ve her satır cümlenin bir kelimesini temsil eder. Sadece alfabe (AZ) ile uğraşmanız ve diğer tüm boşluk olmayan karakterleri yok saymanız gerekir, ancak hem büyük hem de küçük harfleri işleyebilmeniz gerekir. Çıktınızın fazladan boşluk içermesine izin verilir.

Semafor karakterleri O, ortada bir ve karakterlerin temsil ettiği bayrak konumları ile 3x3 kare olarak görüntülenmelidir | - / \. Her semafor karakteri bir boşlukla bitişik karakterlerden ayrılmalı ve her satır boş bir satırla ayrılmalıdır. Ekranınız için çok uzun olabilecek sözcükleri kaydırma konusunda endişelenmeyin; satırlarınızın sonsuz uzunlukta olduğunu varsayalım.

Örnek giriş:

abcdefg hijklmn opqrstu vwxyz

Örnek çıktı:

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

Örnek giriş:

This is Code Golf.

Örnek çıktı:

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

\      
 O  -O 
/     \

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

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

Bu , en kısa çözüm kazanır.


1
kolmogorov-karmaşıklığı ? Bana öyle geliyor ki bu temel olarak bir arama tablosunu sıkıştırmakla ilgili.
Peter Taylor

@Peter Taylor Evet, muhtemelen bu etiketi eklemek iyi bir fikirdir. Teşekkürler.
migimaru

and each row must be separated by a blank line=> her kelime demek, değil mi?
kullanıcı bilinmiyor

1
Bu bulmacayı okumadan önce, yanlışlıkla programlama anlamında semaforlarla ilgili olduğunu düşündüm. ¡Jajajajajja!
Thomas Eding

@ kullanıcı bilinmiyor Semafor karakterleri sırasına başvurmak için orada satır kullanıyordum . Belki de kelime kullanmak daha iyi bir seçim olurdu.
migimaru

Yanıtlar:


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

Bazı güzelleştirici satır sonlarıyla:

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

Bu işe başlamam biraz zaman aldı (Perl cevabındaki ilk denemem). Diğer cevapların çoğuna benzer bir fikre dayanır. Her bayrak 8 konumdan birinde olabilir, iki bayrak vardır ve iki bayrak hiçbir zaman aynı konumda olamaz. Bu, her iki bayrağın konumunu bir baytta kodlayabileceğim anlamına gelir - bu da Perl y///işlevini (operatör?) Kullanarak doğrudan bir karakterden kodlamasına çevirebileceğim anlamına gelir . Yani:-

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

Bu nedenle:

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

Programın kopyalanmasını ve yapıştırılmasını kolaylaştırmak için normal kullanılan aralığın dışında kalan karakterlerden birkaçı kaçtım - ama kaçış kodlarını beni kurtarmak için karakterlerle değiştirmek için bir program yazabileceğimden eminim yaklaşık 30 karakter.


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)

Bu benim en sevdiğim hileyi kullanıyor: tek kanallı kodlama. Semafor bitlerini (sbits) etiketledim

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

hangi harf için hangi harfin oluştuğu aşağıdaki çizelgeyi elde etmek için:

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

her harf grafikte tam olarak iki kez oluşur, çünkü sinyal adamının iki kolu vardır. Daha sonra bunu, harfleri paylaşan harfler arasındaki kenarlar, paylaşılan paylaşıma göre etiketlenmiş şekilde, az harflerinde bir grafik olarak görüyorum. İdeal olarak, bu grafikte bir Hamilton yolu bulurdum, böylece sonraki kenarlar aynı etikete sahip olmaz. Böyle bir yol yok ... yani değişkenin eharfi biki kez içerdiğini göreceksiniz .

Neredeyse Hamilton yolumla, geçişinde kullanılan ebir dizi dsbit etiket oluşturuyorum e. Daha sonra, kollarını nereye koyacağınızı anlamak için, sinyal adamının sadece aşağıdaki kullanışlı grafikte istenen mektubu bulması gerekir

abhioptuwycdjmnsqxzfgvklebr
6736031025071568328578162735

kolları doğrudan mektubun altına ve altına ve sağına gider.


Değiştim kadar bu ideone çalışmasına alamadım to_lower()için lower(). Ayrıca, alfabetik olmayan girdi vermeye çalıştığımda bir hata verdi.
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"))

Ungolfed (iyi, daha az 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")
)

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

Giriş STDIN'de verilmelidir.


1

Yeni satırlar olmadan Scala 494 520 yeni satırlarla:

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

Açıklama:

Bir saat örüntüsü gözlemledim, ancak 12 saat ile değil, ama 8. Ve Starttime 0, saat 6, ve a, b, c ilk kodlar, güneyde ilk (bir) bayrakla.

Bayrak 1 ve 2 ayırt edilemez olduğu için, önce ilk bayrak için daha düşük olan tüm kombinasyonları sıralayabiliriz. Ne yazık ki, j'nin i'yi takip etmediği, ancak k, l, m ve daha sonra bir karışıklık olduğunda, başından beri iyi düzen bozulur.

Bu nedenle anahtarlarımı eşleme için yeniden düzenliyorum:

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

Her karakterden 'a' kelimesini özetlersek, sayıları (0 ila 7 + 6 + 5 + ... + 1) alırız. Bir karakter ızgarasının sayılarını eşleyebiliriz

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

İki sayı çifti iki bayrağı eşleyebilir, burada ilk sayı ilk bayrak için 0 ila 6 endeksidir ve ikinci bayrak ikinci bayrak için 1 ila 7 arasında bir sayı değil, önce ikinci bayrağa. (2,2), birinci bayrak BATI ve ikincisi oradan KUZEY'e doğru saat yönünde iki adım anlamına gelir.

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

Scala hakkında fazla bir şey bilmiyorum. Bunu ideone'de test edebilmemin bir yolu var mı? Bir object Main extends Applicationblokta sarmayı denedim , ama bu yeterli görünmüyor.
migimaru

IDEONE, Main adında bir sınıfa ihtiyaç duyar, doğru hatırlıyorsam, bir ana yöntem, App'i (Uygulama (-2.8) yerine scala-2.9 için) genişletmelidir - ve stdin'den okunuyor mu? In simplyscala bunları daha basit kod test edebilir. readLineSon satırda değiştirirseniz "readLine"çalışması gerekir (kod 2.8 uyumludur).
kullanıcı bilinmiyor

Teşekkürler! Simplyscala'yı bilmiyordum, bu işleri daha kolay hale getiriyor.
migimaru

Bağlantıya tekrar ihtiyacınız varsa: Bağlantıyı metada zaten bir yere ekledim, bu tür şeyler toplandı.
kullanıcı bilinmiyor

Bu büyük harfle başa çıkıyor mu?
Thomas Eding

1

Haskell 331 357 339 karakter

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]

Kodlama, [hour, minute]saatlerin 8 saat 8 dakika olduğu yerdir. Dakikalar saatlerden daha hızlı hareket eder. Bir saat, saat ve dakikanın eşit olacağı noktayı işaretlerse, saate 1, dakikaya 2 ekleyin (yukarıdaki ikinci kene örneğine bakın). Saatlerin artmasının tek yolu bu. Dakika, keyfi bir dakikaya ulaştığında saatler artar. Sadece dakikalar saatlere eşit olduğunda. Kurtulmamış kodda, clockharfleri semaforu temsil eden saatlere dönüştürür. Saatlerin çoğu, öncekilerden gelen işaretlere dayanarak yapılır. Geri kalanı sert kodlanmıştır. Kodda gerçekten başka bir şey yok.


1

Perl, 356 , 275 karakter

'Başka' ifadesi 'değiştirilerek' çok sayıda karakter kaydedildi? :' inşaat.

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

Kodunuz yalnızca küçük harfler için çalışıyor gibi görünüyor. Eğer kullanırsanız <>yerine $ARGV[0]girdiyi standart girdiden alıp kullanabilirsiniz size lcküçük harfe tüm karakterleri dönüştürmek. Bu size 4 karakter kazandırmanın ek bir avantajına sahiptir. Alfabe dışı karakterleri de ele almıyor, ancak tartışmalı You only need to deal with the alphabet (A-Z) and should ignore all other non-space charactersolarak onlarla ne yapılacağı konusunda çok net değil ...
Gareth

Kodu şu anda test edemiyorum, ancak kod sadece alfa olmayan karakterler için boşluklar yazdırıyor gibi görünüyor.
migimaru

@migimaru Düzeltmeye çalışacağım.
zura

@zura Alfabetik olmayan karakterler için boşluk yazdırma kabul edilebilir. Bunu düzeltmenize gerek yok.
migimaru

0

PowerShell , 198 192 191 188 bayt

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

Çevrimiçi deneyin!

Çıktıda bir kuyruk boş satır var.

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

0

Kömür , 70 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

F⪪↧S «

Küçük harfli girdiyi boşluklara bölün ve her kelimenin üzerine döngü yapın.

Fι«

Her karakterin üzerine gelin.

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

Sıkıştırılmış dizeyi fjmrwyz gnsvxz abcdefg ahiklmn bhopqrs ciotuy djkptv elquwxboşluklara ayırın ve her harf grubunun üzerinden geçirin.

P⊗№λκ

Grup geçerli harfi içeriyorsa, geçerli yönde bir çizgi çizin.

↷¹»

Saat yönünde 45 ° döndürün.

oM³→»

Merkezin çıktısını alın ove sonraki harfin konumuna gidin.

⸿M³↓

Sonraki sözcüğün başına git

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.