Стенографія з подвійною літерою


19

Стеганографія приховує задане повідомлення всередині даного оператора, створюючи пакет, який не виглядає підозрілим. Для цього завдання ви напишете програму, яка приймає повідомлення ASCII та носій ASCII як вхідний файл, а поверніть або роздрукуєте пакет, ідентичний носії, за винятком того, що символи, відповідні повідомлення, подвоюються в тому ж порядку, у якому вони відображаються в повідомлення.

Правила:

  1. Якщо носій вже містить послідовності одного і того ж символу не один раз, і вони не використовуються для кодування символу повідомлення, програма зменшить їх до одного символу.
  2. Якщо оператор не містить символів повідомлення в потрібному порядку, програма може нічого не повернути, сам оператор або помилка.
  3. Ви можете припустити, що повідомлення та носій є не порожніми рядками ASCII.
  4. Капіталізація має значення: A не еквівалентно a.
  5. Якщо дійсний більш ніж один пакет, ваша програма може виводити будь-який або всі з них.
  6. Простір - це характер, як і будь-який інший персонаж.

Тестові приклади:

Пакет перевізника повідомлень
"привіт" "це прибуло?" "що, я прилетів?" АБО "так це аріоні?"
"сер" "це прибуло?" "hass iit прибув?"
"foo" "це прибуло?" "" АБО "це прибуло?" АБО помилка
"Автомобіль" "Кішки класні". "CCaats arre col."
"машина" "Кішки класні". "" АБО "Кішки класні". АБО помилка
"Диван" "Диван" "CCoouucchh"
"oo" "oooooooooo" "oooo"
"o o" "oooo oooa" "oo ooa"

Це кодовий гольф, тому виграє найменше байтів.


5
Зовсім не підозріло ...: P
Квінтек

Чи "oooo oa"(з двома пробілами) є дійсним висновок для останнього тестового випадку?
Арнольд

3
Це невірний вихід, тому що порядок подвоєних символів у пакеті повинен відповідати порядку символів у повідомленні. У повідомленні у нас є "o", потім "", потім "o", але ваш пакет має пробіл після o
jkpate

Ага так, це має сенс.
Арнольд

1
Ні. Моє міркування цього правила полягає в тому, що вихід програми в разі відсутності рішення повинен бути однозначним, що рішення неможливо. Три дозволені виходи однозначні, але для дедупльованого випадку потрібна більш широка перевірка.
jkpate

Відповіді:


5

Желе , 28 байт

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

Повна програма взяття carrierі в messageякості аргументів командного рядка , яка виводить результат
(для НЕ Packable 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

JavaScript (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=оскільки р передається параметром.
tsh

@tsh На жаль Я забув видалити залишковий код з попередніх, нерекурсивних версій. Дякую!
Арнольд

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

Підвищує виняток "Невичерпні шаблони", якщо перевізник не містить повідомлення.

Спробуйте в Інтернеті!

Редагувати: -5 байт завдяки @Laikoni


Я думаю, що перемикання справ дозволяє вам відмовитися m==c: Спробуйте це в Інтернеті!
Лайконі

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 або більше однакових символів носія. Якщо в повідомленні також є пробіг з 1 або більше одних і тих же символів, тоді додайте коротший з двох прогонів до виводу у двох примірниках, інакше додайте до виводу один символ носія. Кожен запуск символів виводу закінчується новим рядком, щоб відрізнити його від вхідного. (?!¶)На кінцях запобігають регулярний вираз від мислення носія є повідомлення , коли повідомлення буде вичерпано, як це зазвичай $допускається , щоб відповідати де ¶$буде відповідати.

M!s`.*¶$

Видаліть усе, якщо повідомлення було не закодовано повністю.

Видаліть нові рядки з виводу.


Я думаю, що це не проходить другий за останній тестовий випадок (чого, чесно кажучи, я не мав на початковій посаді).
jkpate

@jkpate Дякую, що вказав на це; Мені довелося трохи переписати свій підхід.
Ніл

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, який передає послідовні запуски одного і того ж символу в один екземпляр. Але, на жаль, ні - останні два тестові справи все настільки сильно перекрутили, що мені довелося вдатися до зовсім іншого підходу, і це в основному було портом відповіді Арнальда .


0

Powershell, 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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.