Mors kodunu ton süresine göre çevir


36

Hedef

Mors kodu genellikle ses olarak gösterilir. Sesin açık veya kapalı olduğunu gösteren bir bit akışı göz önüne alındığında, akımı harflere, sayılara ve boşluklara çevirir.

Uluslararası Mors Kodu

Ayrıntılı Bilgiler

  • Bit akımı, tekrar eden ON / OFF bitlerinin uzunluğuna göre analiz edilir.
    • 1 ON bit bir noktadır
    • 3 ON bit bir çizgidir
    • 1 OFF biti nokta ve çizgi sınırlar
    • 3 KAPALI bit karakterleri sınırlar
    • 7 OFF bit, kelimeleri sınırlandırır (boşluk)
  • Giriş bir dize veya dizi olabilir. Girişte yalnızca iki benzersiz karakter / değere seçim yapabilirsiniz. (örn. 0/1, doğru / yanlış, virgül / boşluk)
  • Çıktı bir dize döndürür veya standart çıktıya yazdırılır.

Örnek

Input:    101010100010001011101010001011101010001110111011100000001011101110001110111011100010111010001011101010001110101
Analysis: \--H--/   E   \---L---/   \---L---/   \----O----/\-- --/\---W---/   \----O----/   \--R--/   \---L---/   \--D--/
Output:   HELLO WORLD

Varsayımlar

  • Akış her zaman bir ON biti ile başlar ve biter.
  • Önde giden veya takip eden bir boşluk yok.
  • Giriş her zaman geçerlidir.
  • Tüm harfler (büyük-küçük harf duyarlı) ve rakamlar desteklenir.

Test Kılıfları

101010100010001011101010001011101010001110111011100000001011101110001110111011100010111010001011101010001110101
HELLO WORLD

10100000001011100011101110000000101110000000101011101000101000101010001010101
I AM A FISH

1010111011101110001110111011101110111000101110111011101110001110111010101
2017

101010001110111011100010101
SOS

puanlama

Bu kod golfü. Gelecek hafta bu zamana kadar en düşük bayt sayma kodu kazanır.


Çıktının sonunda boşluk var mı?
Brian J

Yanıtlar:


9

APL (Dyalog) , 65 62 60 57 bayt

-3 ngn sayesinde.

Tam önek işlevi.

CY'dfns'
morse'/|[-.]+'S'&'∘(⊃∘'/. -'¨6|'1+|(00)+'S 1)

Çevrimiçi deneyin! Üstbilgi, f←ve Altbilgi, TIO'nun bayt sayısını korurken işlevi Girdi'den çağırmaya izin vermek içindir. Normal bir APL oturumunda (TIO'nun Giriş alanına karşılık gelir), buna ihtiyaç duyulmaz .

⎕CY'dfns'c op y dfns çalışma alanı (library)

(... ) : Bu zımni fonksiyonu uygulamak
'1+|(00)+'⎕S 1 PCRE S Araması 1-çalışır ve hatta uzunlukta 0 yürütmeleri ve dönüş eşleşirken uzunlukları
6| 6 bölü bölünme kalan
⊃∘'/. -'¨ bu dize karşılık gelen karakter almak, her maç uzunluğu için
'/|[-.]+'⎕S'&'∘ PCRE S Araması kesikler ve çizgi / nokta -runs ve bunları
morse Mors alfabesinden normal metne çevirir


5
Vay, Dyalog'un mors kodu için bir yerleşimi olduğunu asla bilmiyordum.
Zacharý

@ Zacharý dfns'de çok fazla sayıda yerleşik var.
Outgolfer Erik

@ Zacharý Her zaman dfns'i kontrol edin !
09’da

Daha eski bir sürüme bağlanıyorsunuz.
Outgolfer Erik

Bir BF işlevi ...> _ <, vay.
Zacharı

8

Python 2 , 142 135 bayt

lambda s:''.join(' E-T----Z-Q---RSWU--2FH-V980NIMA--1CBYX-6--GDOK534PLJ-7'[int('0'+l.replace('111','3'),16)%57]for l in s.split('000'))

Çevrimiçi deneyin!

Açıklama:

Dizeyi üzerindeki harflere böler 000( 0böylece boşluk demektir)

Her değiştirir 111ile 3taban 16 içine ve dönüştürür.

Sonra her sayı, geçerli karakterin dizini olan 57bir aralık veren, tarafından modellenir 0..54.


Temel 3'e dönüştürülen önceki sürüm:

Python 2 , 273 252 247 bayt

lambda s:''.join(chr(dict(zip([0,242,161,134,125,122,121,202,229,238,241]+[2]*7+[5,67,70,22,1,43,25,40,4,53,23,49,8,7,26,52,77,16,13,2,14,41,17,68,71,76],[32]+range(48,91)))[int('0'+l.replace('111','2').replace('0',''),3)])for l in s.split('000'))

Çevrimiçi deneyin!

İkili dosyaya dönüştürülen önceki sürüm:

Piton 2 , 282 261 , 256 bayt

lambda s:''.join(chr(dict(zip([0,489335,96119,22391,5495,1367,341,1877,7637,30581,122333]+[2]*7+[23,469,1885,117,1,349,477,85,5,6007,471,373,119,29,1911,1501,7639,93,21,7,87,343,375,1879,7543,1909],[32]+range(48,91)))[int('0'+l,2)])for l in s.split('000'))

Çevrimiçi deneyin!


5

Ruby , 123 bayt

->s{s.split(/0000?/).map{|r|r[0]?"YE9_0IZTO_BHKU58V_GR_SFA__1_4NP_60X_____C__D_ML7WQ3__2__J"[r.to_i(2)%253%132%74]:" "}*""}

Çevrimiçi deneyin!

Karakter dizisindeki giriş dizesini böl. 3 veya 4 OFF bit kullanın, böylece boşluklar boş dizgilere dönüştürülür. Her karakterin temel 2 değerini alın ve arka arkaya 3 bölümdeki moduloyu kullanarak makul bir aralığa (60 olası değerden az) geçin.


Çok iyi yapmışsın.
Monica iamnotmaynard’a

2
Tüm durumlar için işe 0?yarayıp yaramadığını eminim, ancak Regexp'den çıkarırsanız , hala dört test vakası için de işe yarar .
Jordan

4

Python , 175 168 bayt

s=lambda t,f=''.join:f('; TEMNAIOGKDWRUS;;QZYCXBJP;L;FVH09;8;;;7;;;;;;;61;;;;;;;2;;;3;45'[int('1'+f('0'if j[1:]else j for j in i.split('0')),2)]for i in t.split('000'))

Öncelikle dizeyi 0 (çizgi) / 1 (nokta) dizgisine dönüştürün, önek ekleyin 1(baştaki sıfırları önlemek ve boşluklarla uğraşmak için), daha sonra ikiliye dönüştürün.

Her kodun uzunluğu 5'ten fazla olmadığından sonuç 0 - 63 arasındadır ve bir dizgede listelenebilir.


1
Bağımsız olarak temelde aynı çözümü elde ettim, ancak 169 bayt:lambda s:''.join("_ TEMNAIOGKDWRUS__QZYCXBJP_L_FVH09_8___7_______61_______2___3_45"[int('1'+filter(int,l).replace('2','0'),2)]for l in s.replace('111','2').split('000'))
Alex Varga

@AlexVarga Python 2'nin güzel kullanımı filter!
Colera Su


3

Visual Basic .NET (.NET Çekirdek) , 252 bayt

@Recursive sayesinde -7 bayt

Function A(i)
For Each w In i.Split({"0000000"},0)
For Each l In w.Split({"000"},0)
Dim c=0
For Each p In l.Split("0")
c=c*2+1+p.Length\2
Next
A &="!ETIANMSURWDKGOHVF!L!PJBXCYZQ!!54!3!!!2!!!!!!!16!!!!!!!7!!!8!90"(c)
Next
A+=" "
Next
End Function

Bir 1s ve 0s dizesini alan ve bir dize döndüren işlev . (Aslında, sadece bunun 0için OFFzor bir gerekliliktir. Her şeyin olmadığı OFFvarsayılmaktadır ON).

Dize değişmezi, dizi biçiminde ikili bir yığın olarak Mors kodu ayarıdır. VB.NET, dizeleri karakter dizisi olarak indekslemenizi sağlar. \İçin sol alt yığını alarak bölünme tam sayıdır 1ya doğru alt yığın 111.

!O yığın yerinde bir değer olmadığında boş olarak kullandım . Sadece endeksleri düzgün bir şekilde doldurmak için gerekli.

VB.NET, fonksiyon adına bir değer atayarak geri dönmenizi sağlar (bu durumda, A). Sadece &çıktı dizesini oluşturmak için tekrarlı olarak string birleştirme ( ) yapıyorum . İlk kez kullanmam gerekiyor &çünkü kullanışsız +bir karakter bırakıyor, fakat kullanabileceğim herhangi bir zaman dizeleriyle +aynı davranıyor &.

Çevrimiçi deneyin!


1
Kullanarak "!ETIANMSURWDKGOHVF!L!PJBXCYZQ!!5473!!8290!!!!!16"ve ardından indeksleyerek 7 bayt kaydedebilirsiniz , ardından kullanarak M(c-c\48*22)değil M, yalnızca değişmez satır içi dizgisini kullanarak başka bir 4 kaydedebilirsiniz .
özyinelemeli

@recursive 4 byte hilesini anlıyorum, yardımın için teşekkürler! Dizini değiştirme şeklinizi anlamakta sorun yaşıyorum. Dize değişmez değiştirir ve sonra kullanırsam M(c-c\48*22), 2017 durumundaki sınırlardan endeks alırım. VB'nin aynı öncelikte bölünme ve çarpma yapacağını düşünüyorum; Parantez eksik mi?
Brian J,

Öncelik konusunda haklısın. c\48*22ya 0da olacak 22. Bu , dizenin sonunu "katlayarak" kısaltmak ciçin , koşullu olarak 22'yi çıkarmanın bir yoludur M. Bu sizin için işe yaramazsa, parenleri her zaman A &=(" ")başka bir 2 bayttan kaldırabilirsiniz . :)
özyinelemeli

Sonra da değiştirebilir &=için +=ve başka bir iki boşlukları kaldırın.
özyinelemeli

@recursive Oh, ha! Çok fazla ekstra paren var. Artı olarak değiştirmekle ilgili sorun daha sonra dizgimin başında boş bir karaktere sahibim. Belki de bu önemli bir şey değil.
Brian J

3

JavaScript (ES6), 170 131 bayt

s=>s.split`000`.map(e=>'  ETIANMSURWDKGOHVF L PJBXCYZQ'[c=+`0b${1+e.replace(/0?(111|1)/g,d=>+(d>1))}`]||'473168290 5'[c%11]).join``


Nasıl çalışır:

Noktaları 0'lara, kısa çizgileri 1'lere değiştirirseniz ve 1 ile önek eklerseniz, ondalık basamağa dönüştürüldüğünde size verilen ikili sayıları alırsınız:

  1. Harfler: 2 - 18, 20 ve 22 - 29.
    Bunlar indeksleyerek doğru harfe dönüştürülebilir ' ETIANMSURWDKGOHVF L PJBXCYZQ'.
  2. Sayılar: 32, 33, 35, 39, 47, 48, 56, 60, 62 ve 63.
    Bu 11 numaralı katları alırsak, 0 - 8 ve 10 sayıları ile doğru sayılara dönüştürülebilir. içine indeksleme '473168290 5'.

Program karakterlere bölünür, ardından her bir karakteri yukarıdaki kurallara göre uygun çıktıya dönüştürülen noktalara ve çizgilere dönüştürür.


Test Durumları:


3

Python 2 , 127 bayt

lambda s:''.join("IVMB  T  K 9LZF 1HWO3 GUS4 8 7A  E QR 26   NJX    Y0P 5D  C"[(int('0'+l)^2162146)%59]for l in s.split('000'))

Çevrimiçi deneyin!

Kapalı yapı TFeld kaldırarak 'çözeltisinin yerini ve bir bit-bazında XOR maliyeti ve daha uzun bir referans dizge, 10 tabanına çalışarak.


2

PHP, 321 284 bayt

@Ovs sayesinde 37 bayt kaydedildi

$a=array_flip([242,161,134,125,122,121,202,229,238,241,5,67,70,22,1,43,25,40,4,53,23,49,8,7,26,52,77,16,13,2,14,41,17,68,71,76]);foreach(split('0000000',$argv[1])as$w){foreach(split('000',$w)as$m){echo($v=$a[base_convert(str_replace([111,0],[2,],$m),3,10)])>9?chr($v+55):$v;}echo' ';}  

Önceki sürüm (321 bytes)

$a=array_flip([22222,12222,11222,11122,11112,11111,21111,22111,22211,22221,12,2111,2121,211,1,1121,221,1111,11,1222,212,1211,22,21,222,1221,2212,121,111,2,112,1112,122,2112,2122,2211]);foreach(split('0000000',$argv[1])as$w){foreach(split('000',$w)as$m){echo($v=$a[str_replace([111,0],[2,],$m)])>9?chr($v+55):$v;}echo' ';}

Çevrimiçi deneyin!

Ungolfed versiyonu:

$a=array_flip(
// Building an array $a with every Morse letter representation (1=dot, 2=dash) and flip it
               [22222,12222,11222,11122,11112,
                // 01234
                11111,21111,22111,22211,22221,
                // 56789
                12,2111,2121,211,1,1121,221,
                // ABCDEFG
                1111,11,1222,212,1211,22,
                // HIJKLM
                21,222,1221,2212,121,111,2,
                // NOPQRST
                112,1112,122,2112,2122,2211]);
                // UVWXYZ
foreach (split('0000000', $argv[1]) as $w){
// for each word (separate with 7 consecutive zeroes)
    foreach (split('000',$w) as $m){
    // for each letter (separate with 3 consecutive zeroes)
        echo ($v = $a[str_replace([111,0],[2,],$m)]) > 9
        // Replace '111' with '2' and '0' with nothing and find $v, the corresponding entry in the array $a
            ? chr($v+55)
            // If > 9th element, then letter => echo the ASCII code equal to $v+55
            : $v;
            // Else echo $v
    }
    echo ' ';
    // Echo a space
}

2

Java (OpenJDK 8) , 370 bayt

s->{String r="";for(String t:s.split("0000000")){for(String u:t.split("000"))for(int x[]={1,7,5,21,29,23,87,93,119,85,117,341,375,343,373,471,477,349,469,1877,1367,1909,1879,1501,1911,1885,7637,5495,7543,7639,6007,30581,22391,122333,96119,489335},i=x.length;i-->0;)if(u.equals(Long.toString(x[i],2)))r+="ETISNAURMHD5WVLKGFB64ZXPOC73YQJ82910".charAt(i);r+=" ";}return r;}

Çevrimiçi deneyin!

  • @Jeutnarg sayesinde 3 bayt kurtarıldı.

1
yerine ([i], 2 x) Integer.toString arasında ([i], 2 x) Long.toString kullanarak birkaç tıraş olabilir
Jeutnarg

2

GNU sed , 261 + 1 = 262 bayt

-rBayrak için +1 bayt .

s/000/;/g
s/111/_/g
s/0//g
s/$/;:51111141111_3111__211___i1____6_11117__1118___119____10_____H1111V111_F11_1L1_11P1__1J1___B_111X_11_C_1_1Y_1__Z__11Q__1_S111U11_R1_1W1__D_11K_1_N__1G__1O___I11A1_M__E1T_/
:
s/([1_]+);(.*([^1_])\1)/\3\2/
t
y/i/1/
s/;/ /g
s/:.*//g

Çevrimiçi deneyin!

açıklama

Bu çok temel bir arama tablosu çözümüdür.

İlk üç satır girişi dönüştürür, böylece çizgiler _s ve noktalar 1s olur. İlk olarak, 000s ile değiştirilir ;, böylece karakterler ile ayrılır ;ve kelimeler ile ;;0. Sonra 111s ile değiştirilir _ve kalan 0tüm s'ler atılır, 1noktalar için s bırakılır .

s/000/;/g
s/111/_/g
s/0//g

Bir sonraki satır arama tablosunu ekler. Bu formu alan bir karakter ve dizisidir s ve onu temsil s. ile ikame edilir Belirsizliği giderme işleminin tabloda. Sed'deki normal ifadeler her zaman açgözlü olduğundan, tablo en uzundan en kısa koda sıralanır (yani, örneğin yerine eşleşir ).cmcmcm...cm_1i11_A1_i1____

s/$/;:51111141111_3111__211___i1____6_11117__1118___119____10_____H1111V111_F11_1L1_11P1__1J1___B_111X_11_C_1_1Y_1__Z__11Q__1_S111U11_R1_1W1__D_11K_1_N__1G__1O___I11A1_M__E1T_/

Daha sonra, bir döngüde, her _s ve 1s dizisi (ve ardından ;) karşılık gelen karakter ile değiştirilir:

:
s/([1_]+);(.*([^1_])\1)/\3\2/
t

Son olarak, temizleme: s'ler is ile değiştirilir 1, kalanlar ;boşluktur ve arama tablosu silinir:

y/i/1/
s/;/ /g
s/:.*//g


1

JavaScript (ES6), 104 102 101 99 bayt

s=>s.split`000`.map(n=>" _T__9VEFO0K7MX_CGS__LU1RYIJ845__Z_B_D6QP_3__AHNW2"[n*1741%8360%51]).join``

Test durumları

Nasıl?

İkili değerden ondalık bayt değerine dönüştürüldüğünden, 10 tabanında yorumlanan doğrudan ikili bloklar üzerinde çalışan bir karma işlevi kullanırız.

Örnek

dot dash dot dot = 101110101
101110101 * 1741 = 176032685841
176032685841 % 8360 = 3081
3081 % 51 = 21

--> The 21st character in the lookup table is 'L' (0-indexed).

Bu tek adımlı yaklaşımı çok seviyorum. Bu 37 çıktının yeteri kadar kısa bir fonksiyona sahip 50 beden mükemmel bir kareye sığdırmak için ne kadar büyük bir arama yaptınız?
jayprich

n*p%m0%m11p<100001<m0<100001<m1<100

1

Retina , 144 138 130 103 bayt

T`d`@#
^|@@@

 @?#
E
{T`L#@`R6_BI_Z5S1C_GD8__\L\HNF3P__7_`\w@#
T`589B-INPRSZ#@`490XYKT2\OVAMJWUQ_`\w##

Çevrimiçi deneyin! Link, test durumlarını içerir. Açıklama:

T`d`@#

İkili basamakları diğer karakterlerle değiştirin, çünkü 0 ve 1 geçerli çıkışlardır.

^|@@@
 

Her karakterden önce bir boşluk ve kelimeler arasında iki boşluk ekleyin.

 @?#
E

Tüm karakterlerin Es olduğunu varsayalım.

{T`L#@`R6_BI_Z5S1C_GD8__\L\HNF3P__7_`\w@#

Tüm harfleri bir nokta ile takip edeceklerini varsayarak tercüme edin. Örneğin, eğer bir E'miz varsa ve ikinci bir nokta görürsek (ilk önce E'yi koyduğumuzda tüketiriz) sonra bir I'e çevrilir. Varsayım ve ardından çizgi sonraki aşamada tüketilir. Diğer harfler silinir ( Lmaliyetleri bir bayt tutar).

T`589B-INPRSZ#@`490XYKT2\OVAMJWUQ_`\w##

Aslında onları takip eden bir çizgi izlerse, o zaman yanlış çevirileri düzelt. Bu aynı zamanda önceki aşamada kabul edildiğinde çizgiyi de tüketir. Her iki çeviri de tüm noktalar ve çizgiler tükenene kadar tekrar edilir.


0

Perl 5 , 241 + 1 ( -p) = 242 bayt

%k=map{(23,469,1885,117,1,349,477,85,5,6007,471,373,119,29,1911,1501,7639,93,21,7,87,343,375,1879,7543,1909,489335,96119,22391,5495,1367,341,1877,7637,30581,122333)[$i++]=>$_}A..Z,0..9;map{$\.=$k{oct"0b$_"}for split/000/;$\.=$"}split/0{7}/}{

Çevrimiçi deneyin!


0

PHP, 181 + 1 bayt

foreach(explode(_,strtr($argn. 0,[1110=>1,10=>0,"0000"=>_A,"00"=>_]))as$t)echo$t<A?~$t[-5]?(10+substr_count($t,0)*(1-2*$t[-5]))%10:__ETIANMSURWDKGOHVF_L_PJBXCYZQ[bindec("1$t")]:" ";

Pipe ile çalıştırın -nRveya çevrimiçi deneyin .


0

ES6 , 268 bayt

Mors'un bir base36 temsilinden bir dizin konumuna eşleştirmeden sonra ASCII kodlamasını kullanır. En iyi golf günüm değil ama sadece 15 dakika sürdü.

s=>s.split('00000').map(w=>String.fromCharCode.apply({},w.split('000').map(c=>"ahkn,225z,h9z,48n,11z,9h,1g5,5w5,nlh,2me5,,,,,,,,n,d1,1gd,39,1,9p,d9,2d,5,4mv,d3,ad,3b,t,1h3,15p,5w7,2l,l,7,2f,9j,af,1g7,1h1".split(',').indexOf(parseInt(c,2).toString(36))+48))).join(' ')

Okuması daha kolay (tür):

s=>
s
.split('00000')
.map(w=>
	String.fromCharCode.apply({},
		w.split('000')
			.map(c=>
				"ahkn,225z,h9z,48n,11z,9h,1g5,5w5,nlh,2me5,,,,,,,,n,d1,1gd,39,1,9p,d9,2d,5,4mv,d3,ad,3b,t,1h3,15p,5w7,2l,l,7,2f,9j,af,1g7,1h1"
				.split(',')
				.indexOf(
					parseInt(c,2).toString(36)
				)+48)
			)
	).join(' ')


0

Wolfram Dili (Mathematica) , 288 bayt

Verileri bir dosyadan ikili olarak okumakla ilgili düşündüm ama açıklaması zorlaşıyor. Taban 36, verileri verimli bir şekilde saklamak için iyi bir uzlaşma yolu gibi göründü.

Girdi olarak 0 ve 1 'lerden oluşan bir dizi alır 7 sıfır, ardından 3, sonra en uzun ikili harflerden en kısa olana kadar olan dizilerden oluşur. Değişim sırası önemlidir.

StringReplace[#,Thread@Rule[Join[{"0000000","000"},#~FromDigits~36~IntegerString~2&/@StringSplit@"ahkn 2me5 225z nlh h9z 5w7 5w5 5tj 4mv 48n 1h3 1h1 1gd 1g7 1g5 15p 11z d9 d3 d1 af ad 9p 9j 9h 3b 39 2l 2f 2d t n l 7 5 1"],Insert[Characters@" 09182Q7YJ3OZCX6P4GKBWLFV5MDRUHNASTIE","",2]]]&

Çevrimiçi deneyin!


Bekle, Mathematica'da yerleşik bir mors kodu yok mu?
Zacharý

Henüz değil! Kontrol ettim.
Kelly Lowder

0

Perl 5 , 195 bayt

İçin 194 bayt kodu + 1 -p.

%h=map{$_,(A..Z,0..9)[$i++]}unpack"S26I2S7I","\xd5]u]\xddUw\xd7uww\xdd\xd7]WWwWwuwwwwwWwWUU\xd5uw\xdd\xdd";s/0{7}/ /g;s/(\d+?)(000|\b)/$h{oct"0b$1"}/ge

Bunları sadece standart bir paketlenmiş ikili sicim ile çalıştıramadım, daha yüksek baytlık karakterlerden kaçmak zorunda kaldım, aksi halde 171'de olurdum, eğer ne kaçırdığımı bilirse ya da neden kırdığını harika olurdu !

Çevrimiçi deneyin!

açıklama

İkili dize olan packed (mors karakterleri ilgili numaraların listesi 101011101- 349için Fvs) ve bu aralıkları ile sıkıştırılmış olan A..Z,0..9ve bir arama olarak kullandı. s///İfadelerin hepsi yedi silsileleri yerini 0daha sonra boşluk ile s ve üç ile ayrılmış tüm basamakları çalışır, 0s veya sözcük sınırları \bbunlara karşılık gelen anahtarla, %hkarma.

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.