톤 지속 시간을 기준으로 모스 코드 번역


36

모스 부호 는 종종 소리로 표현됩니다. 사운드가 켜져 있는지 꺼져 있는지를 나타내는 비트 스트림이 있으면 스트림을 문자와 숫자 및 공백으로 변환하십시오.

국제 모스 부호

사양

  • 비트 스트림은 반복되는 ON / OFF 비트의 길이에 따라 분석됩니다.
    • 1 ON 비트는 점입니다
    • 3 ON 비트는 대시입니다
    • 1 OFF 비트는 점과 대시를 구분합니다
    • 3 개의 OFF 비트는 문자를 구분합니다
    • 7 개의 OFF 비트는 단어를 구분합니다 (공백).
  • 입력은 문자열 또는 배열 일 수 있습니다. 입력에는 두 개의 고유 한 문자 / 값만 허용됩니다. (예 : 0/1, true / false, 쉼표 / ​​공백)
  • 출력은 문자열을 반환하거나 표준 출력으로 인쇄됩니다.

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

가정

  • 스트림은 항상 ON 비트로 시작하고 끝납니다.
  • 선행 또는 후행 공백이 없습니다.
  • 입력은 항상 유효합니다.
  • 모든 문자 (대소 문자 구분)와 숫자가 지원됩니다.

테스트 사례

101010100010001011101010001011101010001110111011100000001011101110001110111011100010111010001011101010001110101
HELLO WORLD

10100000001011100011101110000000101110000000101011101000101000101010001010101
I AM A FISH

1010111011101110001110111011101110111000101110111011101110001110111010101
2017

101010001110111011100010101
SOS

채점

이것은 코드 골프입니다. 다음 주이 시간까지 가장 낮은 바이트 수 코드가 이깁니다.


출력에 후행 공백이있을 수 있습니까?
브라이언 J

답변:


9

APL (Dyalog) , 65 62 60 57 바이트

ngn 덕분에 -3입니다.

암묵적 접두사 기능.

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

온라인으로 사용해보십시오! Header, f←및 Footer는 TIO의 바이트 수를 유지하면서 Input에서 함수를 호출하는 것을 허용합니다. 일반 APL 세션 (TIO의 입력 필드에 해당)에서는 필요하지 않습니다 .

⎕CY'dfns'C의 OP Y dfns이 작업 공갂 (라이브러리)

(... ) 이 암묵적 기능을 적용
'1+|(00)+'⎕S 1 PCRE S earch 1-실행, 심지어 길이 0 실행과 리턴 매치 '길이의
6| 6으로 나눈 분할 나머지
⊃∘'/. -'¨ 문자열에서 해당 문자를 선택, 각 일치 길이
'/|[-.]+'⎕S'&'∘ PCRE S earch 슬래시와 대시 / 점
morse 모스 코드에서 일반 텍스트로 번역 된 것들을 돌려 보냅니다


5
와우, Dyalog에 모스 부호가 내장되어 있다는 것을 결코 알지 못했습니다.
Zacharý

@ Zacharý dfns에는 많은 내장이 있습니다.
Outgolfer Erik

@ Zacharý 항상 dfns를 확인 하십시오 !
Adám

이전 버전으로 연결 중입니다.
Outgolfer Erik

BF 기능 ...> _ <, 와우.
Zacharý

8

파이썬 2 , 142135 바이트

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

온라인으로 사용해보십시오!

설명:

문자열을 문자로 분할합니다 000( 0따라서 공백을 의미합니다)

각각 1113로 바꾸고 밑 16로 변환합니다.

그런 다음 각 숫자는에 의해 수정되며 57, 0..54현재 문자의 색인 인 범위를 제공합니다 .


기본 3으로 변환 된 이전 버전 :

파이썬 2 , 273 252 247 바이트

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

온라인으로 사용해보십시오!

이진으로 변환 된 이전 버전 :

파이썬 2 , 282 261 256 바이트

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

온라인으로 사용해보십시오!


5

루비 , 123 바이트

->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]:" "}*""}

온라인으로 사용해보십시오!

입력 문자열을 문자 제한으로 분할하십시오. 공백이 빈 문자열로 변환되도록 3 또는 4 개의 OFF 비트를 사용하십시오. 모든 캐릭터의 기본 2 값을 취하고 3 개의 연속 나누기에서 모듈로를 사용하여 합리적인 범위 (가능한 60 값 미만)로 가져옵니다.


아주 잘 했어요
복원 Monica Monica iamnotmaynard

2
모든 경우에 작동하는지 확실하지만 0?Regexp에서 제거 하면 여전히 네 가지 테스트 경우에 작동합니다.
Jordan

4

파이썬 , 175168 바이트

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

먼저 문자열을 0 (대시) / 1 (점) 문자열 목록으로 변환하고 접두사를 추가하여 1(앞의 0을 방지하고 공백을 처리) 바이너리로 변환하십시오.

모든 코드의 길이는 5를 넘지 않기 때문에 결과의 범위는 0-63이며 문자열로 나열 될 수 있습니다.


1
나는 독립적으로 기본적으로 동일한 솔루션을 얻었지만 169 바이트 :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의 멋진 사용법 filter!
Colera Su


3

Visual Basic .NET (.NET 코어) , 252 바이트

@recursive 덕분에 -7 바이트

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

1s와 0s의 문자열을 가져 와서 문자열을 반환하는 함수입니다 . (실제로, 0for 만이 OFF어려운 요구 사항입니다. 아닌 OFF것으로 가정 ON).

문자열 리터럴은 배열 형식의 이진 힙으로 모스 코드 설정입니다. VB.NET을 사용하면 문자열을 문자 배열로 색인 할 수 있습니다. 는 \왼쪽, 서브 힙 복용 분할 정수인 1또는 오른쪽 서브 힙을111 .

!그 힙 지점에 값이 없을 때 공백으로 사용 했습니다. 인덱스를 올바르게 채우면됩니다.

VB.NET을 사용하면 함수 이름 (이 경우 A) 에 값을 할당하여 돌아갈 수 있습니다 . 반복적으로 문자열 연결 ( &)을 수행하여 출력 문자열을 작성합니다. 난생 처음 내가 사용에 필요한 &사용하기 때문에 +잎 선도적 인 널 문자를하지만, 다른 시간 나는 사용할 수 있습니다 +동일하게 동작하는 &문자열.

온라인으로 사용해보십시오!


1
을 사용하여 7 바이트를 저장 "!ETIANMSURWDKGOHVF!L!PJBXCYZQ!!5473!!8290!!!!!16"한 다음을 사용하여 색인을 생성 M(c-c\48*22)한 다음을 사용하지 않고 M문자열 리터럴 인라인을 사용 하여 다른 4 개를 저장할 수 있습니다 .
재귀

@ recursive 4 바이트 트릭을 이해합니다. 도움을 주셔서 감사합니다! 색인 변경 방법을 이해하는 데 문제가 있습니다. 문자열 리터럴을 바꾸고를 사용 M(c-c\48*22)하면 2017 경우에 범위를 벗어난 인덱스를 얻습니다. 나는 VB가 같은 우선 순위에서 나누기와 곱셈을 할 것이라고 생각한다. 괄호가 없습니까?
브라이언 J

당신은 우선권에 대해 옳습니다. c\48*22수 중 것이다 022. 이 조건에서 22을 뺀의 방법입니다 c수 있도록, M문자열의 "접이식"말에 짧은합니다. 그래도 문제가 해결되지 않으면 A &=(" ")다른 2 바이트 동안 항상 파 렌스를 제거 할 수 있습니다 . :)
재귀

그리고 당신은 변경할 수 있습니다 &=+=, 또 다른 두 개의 공백을 제거합니다.
재귀

@ 재귀 아, 어! 여분의 파슨이 너무 많습니다. 더하기로 변경하는 문제는 문자열 시작 부분에 선행 null 문자가 있다는 것입니다. 그래도 큰 문제는 아닙니다.
브라이언 J

3

자바 스크립트 (ES6) 170 131 바이트

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


작동 방식 :

점을 0으로 바꾸고 대시를 1로 바꾸고 접두사를 1로 붙이면 이진수를 얻습니다. 이진수는 십진수로 변환하면 다음과 같이 나타납니다.

  1. 문자 : 2-18, 20 및 22-29.
    로 색인하여 올바른 문자로 변환 할 수 있습니다 ' ETIANMSURWDKGOHVF L PJBXCYZQ'.
  2. 숫자 : 32, 33, 35, 39, 47, 48, 56, 60, 62 및 63.
    이 숫자 계수 11을 취하면 0-8 및 10의 숫자를 얻습니다. 에 색인을 생성합니다 '473168290 5'.

이 프로그램은 문자를 분할 한 다음 각 문자를 점과 대시로 변환하며 위의 규칙에 따라 적절한 출력으로 변환됩니다.


테스트 사례 :


3

파이썬 2 , 127 바이트

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

온라인으로 사용해보십시오!

비트 xor 및 더 긴 참조 문자열 을 대가로 replace 를 제거 하고 base 10에서 작업 하여 TFeld 의 솔루션을 구축 합니다.


2

PHP, 321 284 바이트

@ovs 덕분에 37 바이트 절약

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

이전 버전 (321 바이트)

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

온라인으로 사용해보십시오!

언 골프 버전 :

$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

자바 (OpenJDK 8) 370 바이트

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

온라인으로 사용해보십시오!

  • @Jeutnarg 덕분에 3 바이트가 절약되었습니다.

1
Integer.toString (x [i], 2) 대신 Long.toString (x [i], 2)를 사용하여 몇 가지를 줄일 수 있습니다.
Jeutnarg

2

GNU sed , 261 + 1 = 262 바이트

-r플래그의 경우 +1 바이트

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

온라인으로 사용해보십시오!

설명

이것은 매우 기본적인 조회 테이블 솔루션입니다.

처음 세 줄은 입력을 변환하여 대시는 _이고 도트는 1s입니다. 먼저 000s는로 바뀌 ;므로 문자는로 구분되고 ;단어 는로 구분 됩니다 ;;0. 그런 다음 111s로 바뀌고 _나머지 0s는 모두 버리고 1점은 s로 남겨 둡니다 .

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

다음 줄은 조회 테이블을 추가합니다. 문자는 형식 cmcmcm...이며 c문자를 나타내는 s와 s m의 순서입니다 . 명확성을 위해 표에서 대체된다 . sed의 정규 표현식은 항상 탐욕 스러우므로 테이블은 가장 긴 코드에서 가장 짧은 코드로 정렬됩니다 (예 : 대신에 일치 )._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_/

다음으로 루프에서 _s 및 1s 의 각 시퀀스 (및 후속 ;)가 해당 문자로 바뀝니다.

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

마지막으로 정리 : is는 s로 바뀌고 1나머지 ;s는 공백이며 찾아보기 테이블은 삭제됩니다.

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


1

자바 스크립트 (ES6) 104 102 101 99 바이트

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

테스트 사례

어떻게?

바이너리에서 10 진수로 바이트로 변환하기 때문에 10 진법으로 해석 된 바이너리 블록에서 직접 작동하는 해시 함수를 사용합니다.

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

나는이 원스텝 접근 방식을 매우 좋아합니다. 이 37 개의 출력을 충분히 짧은 기능으로 크기 50의 완벽한 해시에 맞추기 위해 얼마나 큰 검색을 수행 했습니까?
jayprich

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

1

망막 , 144 138 130 103 바이트

T`d`@#
^|@@@

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

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

T`d`@#

0과 1은 유효한 출력이므로 이진수를 다른 문자로 변경하십시오.

^|@@@
 

모든 문자 앞에 공백과 단어 사이에 공백을 삽입하십시오.

 @?#
E

모든 문자가 Es라고 가정하십시오.

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

뒤에 점이 있다고 가정하여 모든 문자를 번역하십시오. 예를 들어, E가 있고 두 번째 점이 보이면 (E를 삽입 할 때 첫 번째 점을 소비 한 경우) I로 변환됩니다. 합법적으로 뒤에 올 수있는 문자는 대시로 변환됩니다. 다음 단계에서 대시가 소비됩니다. 다른 문자는 삭제됩니다 ( L비용은 1 바이트 유지 ).

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

그것이 실제로 대시 뒤에 있음을 나타내면 오역을 수정하십시오. 또한 이전 단계에서 가정했을 때 대시를 사용합니다. 모든 점과 대시가 모두 소비 될 때까지 두 변환이 반복됩니다.


0

Perl 5 , 241 + 1 ( -p) = 242 바이트

%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}/}{

온라인으로 사용해보십시오!


0

PHP, 181 + 1 바이트

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")]:" ";

파이프로 실행 -nR하거나 온라인으로 사용해보십시오 .


0

ES6 , 268 바이트

모스의 base36 표현에서 색인 위치로 맵핑 한 후 ASCII 인코딩을 사용합니다. 최고의 골프 ​​데이는 아니지만 15 분 정도 밖에 걸리지 않았습니다.

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

더 읽기 쉽다 (kinda) :

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 Language (Mathematica) 288 바이트

파일에서 데이터를 바이너리로 읽는 것에 대해 생각했지만 설명하기가 어렵습니다. Base 36은 데이터를 어휘 적으로 효율적으로 저장하는 데있어 타협 방법처럼 보였습니다.

입력으로 0과 1의 문자열을받습니다. 7 개의 런으로 시작하여 3의 런으로 시작하여 가장 긴 이진 문자를 가장 짧은 문자로 시작하는 일련의 대체 작업을 수행합니다. 교체 순서가 중요합니다.

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]]]&

온라인으로 사용해보십시오!


잠깐, Mathematica에는 모스 부호가 내장되어 있지 않습니까?
Zacharý

아직! 나는 확인했다.
켈리 로우더

0

펄 5 , 195 바이트

194 바이트 코드 + 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

표준 압축 이진 문자열 로이 작업을 수행 할 수 없었습니다. 높은 바이트 문자를 피해야했습니다. 그렇지 않으면 누군가 내가 놓친 것을 알고 있거나 그것이 깨지는 이유를 알고 있다면 171에있을 것입니다. !

온라인으로 사용해보십시오!

설명

이진 스트링은 인 pack에드 (모스 문자와 관련된 숫자 목록 101011101- 349위한 F등)이 범위로 압축된다 A..Z,0..9및 조회 쓰인다. 이 s///표현식은 7 0s의 모든 런을 공백으로 바꾼 다음 3 0s 또는 단어 경계로 구분 된 모든 자릿수를 해시 \b의 해당 키로 %h바꿉니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.