이중 문자 스테 가노 그래피


19

스테 가노 그래피는 특정 메시지를 지정된 캐리어 안에 숨겨 의심스러운 패키지를 만듭니다. 이 문제를 해결하려면 ASCII 메시지와 ASCII 캐리어를 입력으로 사용하는 프로그램을 작성하고 메시지에 해당하는 문자가 두 배로 표시되는 것을 제외하고는 캐리어와 동일한 패키지를 반환하거나 인쇄합니다. 메시지.

규칙 :

  1. 반송파에 이미 동일한 문자 시퀀스가 ​​두 번 이상 포함되어 있고 메시지 문자를 인코딩하는 데 사용되지 않는 경우 프로그램은 단일 문자로 줄입니다.
  2. 반송파에 메시지 문자가 올바른 순서로 포함되어 있지 않으면 프로그램이 반송파 자체 또는 오류를 반환하지 않을 수 있습니다.
  3. 메시지와 캐리어가 비어 있지 않은 ASCII 문자열이라고 가정 할 수 있습니다.
  4. 대문자 사용 문제 : A는 a와 동등하지 않습니다.
  5. 둘 이상의 패키지가 유효하면 프로그램이 일부 또는 전부를 출력 할 수 있습니다.
  6. 스페이스는 다른 캐릭터와 마찬가지로 캐릭터입니다.

테스트 사례 :

메시지 캐리어 패키지
"안녕하세요" "도착 했습니까?" "iit가 도착 했습니까?" 또는 "이것이 해결 되었습니까?"
"sir" "도착 했습니까?" "iit가 도착 했습니까?"
"foo" "도착 했습니까?" ""또는 "도착 했습니까?" 또는 오류.
"자동차" "고양이는 시원하다." "CCaats arre col."
"자동차" "고양이는 시원하다." ""또는 "고양이는 시원합니다." 또는 오류.
"카우치" "카우치" "CCoouucchh"
"oo" "oooooooooo" "oooo"
"o o" "oooo oooa" "oo ooa"

이것은 코드 골프이므로 가장 적은 바이트가 이깁니다.


5
전혀 의심하지 않는 ... : P
Quintec

"oooo oa"최종 테스트 케이스에 대한 올바른 출력 (2 공백)?
Arnauld

3
패키지의 두 배 문자 순서가 메시지의 문자 순서와 일치해야하므로 올바른 출력이 아닙니다. 메시지에는 'o', '', 'o'가 있지만 패키지는 o 다음에 공백이 있습니다.
jkpate

아 그렇습니다.
Arnauld

1
아니요.이 규칙을 뒷받침하는 이유는 해결책이없는 경우 프로그램의 출력이 해결책이 없어야한다는 것입니다. 허용되는 세 가지 출력은 분명하지만 중복 제거 된 경우에는보다 광범위한 검사가 필요합니다.
jkpate

답변:


5

젤리 , 28 바이트

ẹⱮŒp<ƝẠ$ƇṪ
nƝ+çṬ¥a⁸ḟ0Ḥç¦ð¹ç?

전체 프로그램 촬영 carrier하고 message그 결과를 출력 명령 라인 인수로
(비 팩커 블 들어 message인쇄 불변 carrier).

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오.

어떻게?

ẹⱮŒp<ƝẠ$ƇṪ - Link 1, helper function to find the indices to double: carrier, message
           -                               e.g. "programming", "rom"
 Ɱ         - map across message with:
ẹ          -   indices of                       [[2,5], [3], [7,8]]
  Œp       - Cartesian product                  [[2,3,7],[2,3,8],[5,3,7],[5,3,8]]
        Ƈ  - filter keep if:
       $   -   last two links as a monad:
     Ɲ     -     for neighbours:
    <      -       less than?                    [1,1]   [1,1]   [0,1]   [0,1]
      Ạ    -     all truthy?                     1       1       0       0
           -                                    [[2,3,7],[2,3,8]]
         Ṫ - tail (if empty yields 0)                    [2,3,8]

nƝ+çṬ¥a⁸ḟ0Ḥç¦ð¹ç? - Main Link: carrier, message
                ? - if...
               ç  - ...condition: last Link (the helper function) as a dyad
             ð    - ...then: perform the dyadic chain to the left (described below)
              ¹   - ...else: do nothing (yields carrier)
                  - (the then clause:)
 Ɲ                - for neighbours in the carrier
n                 - not equal?
     ¥            - last two links as a dyad:
   ç              -   call last Link (the helper function) as a dyad
    Ṭ             -   untruth (e.g. [2,5] -> [0,1,0,0,1])
  +               - add (vectorises)
      a⁸          - logical AND with carrier
        ḟ0        - filter out zeros
            ¦     - sparse application...
           ç      - ...to indices: call last Link (the helper function) as a dyad
          Ḥ       - ...do: double (e.g. 'x' -> 'xx')

3

자바 스크립트 (ES6), 71 바이트

로 입력을 (message)(carrier)받습니다.

s=>g=([c,...C],p)=>c?(c==s[0]?(s=s.slice(1),c)+c:p==c?'':c)+g(C,c):s&&X

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


대체 버전, 66 바이트

메시지를 문자 배열로 사용할 수 있다면 :

s=>g=([c,...C],p)=>c?(c==s[0]?s.shift()+c:p==c?'':c)+g(C,c):s+s&&X

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


편집 : 비 재귀 버전에서 재귀 버전으로 전환 할 때 일부 코드를 제거하는 것을 잊어 버린 @tsh에게 감사드립니다.


p=p가 매개 변수에 의해 전달되므로 제거 할 수 있습니다.
tsh December

@tsh 죄송합니다. 내가 잊어 버린 이전의 비 재귀 버전의 일부 잔여 코드입니다. 감사합니다!
Arnauld

2

하스켈 124 121 107 101 97 95 90 바이트

(#).(++"ü")
"ü"#[]=[]
p@(m:n)#e@(c:d)|m/=c=c:p#snd(span(==c)d)|m==n!!0=m:m:n#d|1<2=m:n#e

이동 통신사에 메시지가 포함되어 있지 않은 경우 "완전하지 않은 패턴"예외가 발생합니다.

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

편집 : @Laikoni 덕분에 -5 바이트.


나는 경우를 전환하여 제거 할 수 있습니다 생각 m==c: 온라인으로보십시오!
Laikoni

1

레티 나 0.8.2 , 67 바이트

+`(.)(\1*)\1*(.*¶)(?(\1)(\1(\2)))(.*)$(?!¶)
$1$4$5¶$3$6
M!s`.*¶$
¶

온라인으로 사용해보십시오! 첫 번째 줄에서 이동 통신사를 가져오고 두 번째 줄에서 메시지를받습니다. 설명:

+`(.)(\1*)\1*(.*¶)(?(\1)(\1(\2)))(.*)$(?!¶)
$1$4$5¶$3$6

캐리어의 1 개 이상의 동일한 문자로 프로세스를 실행합니다. 메시지에 동일한 문자 중 하나 이상의 런이있는 경우 두 런 중 더 짧은 런을 출력에 추가하고 그렇지 않으면 캐리어의 단일 문자를 출력에 추가하십시오. 각 출력 문자는 입력과 구별하기 위해 개행으로 종료됩니다. (?!¶)캐리어 생각에서 최종 방지의 정규식 메시지가 소진되면, 같은 일반적으로 메시지입니다 $어디에 일치하도록 허용 ¶$일치합니다.

M!s`.*¶$

메시지가 완전히 인코딩되지 않은 경우 모든 것을 삭제하십시오.

출력에서 개행을 제거하십시오.


나는 그것이 마지막 테스트 케이스를 통과하지 못한다고 생각합니다 (공평하게 말하면 초기 게시물에는 없었습니다).
jkpate

@jkpate 지적 해 주셔서 감사합니다. 내 접근 방식을 약간 다시 작성해야했습니다.
Neil

0

클린 , 118 바이트

import StdEnv,StdLib
$[][]=[]
$[u:v]b#(_,w)=span((==)u)v
|b%(0,0)==[u]=[u,u: $if(v%(0,0)<>b%(1,1))w v(tl b)]=[u: $w b]

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

이동 통신사를 먼저 가져온 다음 메시지를받습니다.

Run time error, rule '$;2' in module 'main' does not match메시지가 맞지 않는 경우 오류가 발생합니다.


0

루비 , 73 바이트

f=->m,c,b=p{x,*c=c;x ?(x==m[0]?x+m.shift: x==b ?'':x)+f[m,c,x]:m[0]?x:''}

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

재귀 함수는 문자 배열로 입력을받습니다.

한 번은 squeeze동일한 문자의 연속 실행을 단일 인스턴스로 계약하는 Ruby의 내장 메소드를 사용하기를 희망했습니다 . 그러나 불행히도, 아니, 마지막 두 가지 테스트 사례는 모든 것을 심하게 망쳐 놓았 기 때문에 완전히 다른 접근법에 의존해야했으며, 이것은 기본적으로 Arnauld의 대답의 포트였습니다 .


0

파워 쉘, 134 바이트

param($m,$c)$c-csplit"([$m])"|%{$i+=$o=$_-ceq$m[+$i]
if($o-or$_-cne"`0$h"[-1]){$h+=($_-replace'(.)(?=\1)')*($o+1)}}
$h*!($i-$m.Length)

스크립트는 empty string 캐리어에 메시지 문자가 올바른 순서로 포함되어 있지 않은 경우를 .

덜 골프 테스트 스크립트 :

$f = {

param($message,$carrier)
$carrier-csplit"([$message])"|%{                # split by chars of the message, chars itself included ([])
    $offset=$_-ceq$message[+$i]                 # 0 or 1 if current substring is a current message char (case-sensitive equality)
    $i+=$offset                                 # move to next message char if need it
    if($offset-or$_-cne"`0$h"[-1]){             # condition to remove redundant doubles after message char: arrrived -> arrived, ooo -> oo, etc
                                                # `0 to avoid exception error if $h is empty
        $h+=($_-replace'(.)(?=\1)')*($offset+1) # accumulate a double message char or a single substring without inner doubles: arried -> arived, anna -> ana, etc
    }
}
$h*!($i-$message.Length)                        # repeat 0 or 1 times to return '' if the carrier does not contain the message characters in the right order

}

@(
    ,('hi'         ,'has it arrived?'    ,'hhas iit arived?', 'hhas it ariived?')
    ,('hi?'        ,'has it arrived?'    ,'hhas iit arived??', 'hhas it ariived??')
    ,('sir'        ,'has it arrived?'    ,'hass iit arrived?')
    ,('foo'        ,'has it arrived?'    ,'')
    ,('Car'        ,'Cats are cool.'     ,'CCaats arre col.')
    ,('car'        ,'Cats are cool.'     ,'')
    ,('Couch'      ,'Couch'              ,'CCoouucchh')
    ,('oo'         ,'oooooooooo'         ,'oooo')
    ,('o o'        ,'oooo oooa'          ,'oo  ooa')
    ,('er'         ,'error'              ,'eerorr', 'eerror')
    ,('a+b'        ,'anna+bob'           ,'aana++bbob')
) | % {
    $message,$carrier,$expected = $_
    $result = &$f $message $carrier
    "$($result-in$expected): $result"
}

산출:

True: hhas iit arived?
True: hhas iit arived??
True: hass iit arrived?
True:
True: CCaats arre col.
True:
True: CCoouucchh
True: oooo
True: oo  ooa
True: eerror
True: aana++bbob

0

C (gcc) , 69 + 12 = 81 바이트

g(char*m,char*_){for(;*_;++_)*m-*_?_[-1]-*_&&p*_):p p*m++));*m&&0/0;}

(12 바이트)로 컴파일

-Dp=putchar(

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

g(char*m,char*_){
    for(;*_;++_)        //step through _
        *m-*_?          //check if character should be encoded
            _[-1]-*_&&  //no? skip duplicates
                p*_)    //    print non-duplicates
        :p p*m++));     //print encoded character twice
    *m&&0/0;            //if m is not fully encoded, exit via Floating point exception
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.