Розбираємо посилку


24

Завдяки вашій допомозі у виклику Mark My Mail , PPCG-Post успішно відбиває всі свої посилки генерованими штрих-кодами!

Тепер прийшов час їх розшифрувати.

У цьому виклику вашій програмі буде надано штрих-код, сформований із виклику Позначити мою пошту , декодувати його та повернути закодоване ціле число.

Але пильнуйте! Штрих-код може бути догори дном ...


4-штатні штрих-коди

У випадку, якщо ви пропустили виклик кодування, вам потрібно знати, про які штрих-коди ми говоримо. Штрих-код 4 стану - це рядок рядків з чотирма можливими станами, кожен з яких представляє ціле число бази-4:

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

Надані в ASCII, штрих-коди займуть три рядки тексту, використовуючи |символ pipe ( ) для представлення частини бар, а пробіл ( ) для представлення порожнього розділу. Між кожним баром буде один пробіл. Приклад штрих-коду може виглядати так:

| | | | | | | | | |
| | | | | | | | | | | | | | | | |
    | | | | | | | |

Щоб перетворити штрих-код назад у ціле число, яке він кодує, картографуйте кожен рядок у відповідній базовій 4 цифрі, з'єднайте їх та перетворіть у десяткові.

Оскільки кожен штрих-код також буде представляти різний штрих-код, коли перевернутий ногами, ми реалізуємо послідовність запуску / зупинки, щоб орінація може бути обчислена. Для цього завдання ми будемо використовувати послідовність старту / зупинки, визначену Australia Post: кожен штрих-код починається і закінчується 1 0послідовністю.


Змагання

Ваше завдання полягає в тому, щоб, давши штрих-код ASCII 4 стану, проаналізувати його і повернути ціле число, яке воно кодує - по суті зворотній бік Позначити мою пошту .

Але, щоб приправити речі, є улов - штрих-код може бути наданий догори ногами. Як і в реальному світі, зчитувач штрих-кодів (ваша програма) буде залишений визначити правильну орієнтацію, використовуючи послідовність запуску / зупинки.

Приклад:

Дано наступний штрих-код:

    | | | |
| | | | | | | | | | |
  | | | | |

Ми чітко бачимо, що перша і остання пари цифр є 0, 2і ні 1, 0. Це означає, що штрих-код перевернуто догори ногами, тому ми повинні повернути його на 180 градусів (а не просто перевертати кожен штрих), щоб досягти правильної орієнтації:

| | | | |  
| | | | | | | | | | |
    | | | |    

Тепер ми можемо почати розшифровку. Ми відображаємо кожен рядок на відповідний базовий 4 цифри, ігноруючи послідовності запуску / зупинки, оскільки вони не кодують дані.

| | | | |  
| | | | | | | | | | |
    | | | |    

- - 2 1 0 3 0 2 3 - -

Ми з'єднуємо це з цілим числом базової-4 2103023, а потім перетворюємо його у десяткове подання 9419для остаточного результату.


Правила

  • Вхід завжди буде дійсним, 4-штатним штрих-кодом, поданим у ASCII, як зазначено вище, з описаною послідовністю початку / зупинки.
    • Ви можете попросити проміжні місця або смугасті лінії, а також зворотний новий рядок - який би формат підходив для вашого гольфу.
    • Він може бути або не мати правильну орієнтацію - ваша програма повинна визначити, чи слід її читати догори дном, використовуючи послідовність запуску / зупинки.
    • Він не буде кодувати провідні нульові цифри в цілому цілому base-4.
  • Ви можете взяти введення як список рядків або рядок з новими рядками.
  • Вихід повинен бути цілим числом у стандартній цілій базі вашої мови, що представляє дані, кодовані штрих-кодом.
  • Оскільки поштові марки невеликі і можуть вмістити на них дуже мало коду, ваш код повинен бути максимально коротким: це - так що найкоротша програма (у байтах) виграє!

Випробування

| | | | | | | | | | |
  | | |

= 4096 (перевернутий)

      | | | | | | | |
| | | | | | | | | | | | | | | |
  | | | | | | | | | |

= 7313145 (перевернутий)

    | | | |
| | | | | | | | | | |
  | | | | |

= 9419 (перевернутий)

| | | | | |   
| | | | | | | | |
    | | | |     

= 990 (не перевернуте)

| | | | |   
| | | | | | | | | | |
    | | |       

= 12345 (не перевернуте)


-1 заголовки на двох публікаціях не мають однаковий формат. ("P the P" vs "M my M", виберіть або "the", або "my": p)
Rɪᴋᴇʀ

1
Буде чи «список рядків» бути будь-який з [String], [{#Char}], [{Char}], [[Char]]?, З огляду на , що Stringеквівалентно{#Char}
Οurous

3
@Ouros Що це за позначення? Я сильно підозрюю, що відповідь "так", оскільки типи даних сильно відрізняються між мовами, тому завдання кодування зазвичай приймають "будь-який еквівалент у вашій мові", але я не знаю, які різні уявлення ви намагаєтеся представляти.
IMSoP

1
Що далі? Надіслати електронний лист? Передати телеграму? Обробити публікацію?
Санчіз

1
@Ourous так, тип даних є гнучким, як описано в IMSoP.
FlipTack

Відповіді:



5

Лушпиння , 16 байт

ḋṁẊ=hhttĊ2T§▼↔m↔

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

Введення - це список рядків (для чіткості посилання TIO використовує багаторядковий рядок). Лінії повинні мати однакову довжину, і не повинно бути зайвих пробілів.

Пояснення

ḋṁẊ=hhttĊ2T§▼↔m↔  Input is a list of strings x.
           §▼     Lexicographic minimum of
             ↔    x reversed and
              m↔  x with each line reversed.
          T       Transpose. Now we have a list of columns.
        Ċ2        Get every second column, removing the blank ones.
    hhtt          Remove first 2 and last 2 (the orientation markers).
 ṁ                Map and concatenate
  Ẋ=              equality of adjacent pairs.
                  This turns a column like "|| " into [1,0], and these pairs are concatenated.
ḋ                 Convert from binary to integer.




2

Сітківка , 71 байт

(.).
$1
sO$^`^\|.*|.

^..|..¶.*¶..|..$
¶
\|
 |
+`\| 
 ||||
.*¶$
$&$&
\|

Спробуйте в Інтернеті! Посилання включає менші тестові випадки. Потрібно, щоб перший і останній рядки мали пробіл до довжини середньої лінії. Пояснення:

(.).
$1

Видаліть зайві пробіли.

sO$^`^\|.*|.

Зворотній знак символів у коді, але якщо штрих-код починається з а |, виберіть весь код, інакше розділіть його на символи. Потім переверніть їх. Це гортає код, якщо він починається з а 0.

^..|..¶.*¶..|..$
¶

Видаліть послідовність запуску / зупинки та середній ряд (який нам не корисний).

\|
 |
+`\| 
 ||||

Перетворити пробіли та |s з бази 4 в одинакові.

.*¶$
$&$&

Подвійний останній рядок.

\|

Перетворити в десятковий.


2

Java (OpenJDK 8) , 181 160 байт

Я не надто пошарпаний для рішення Java, я впевнений, що я можу зробити оптимізації, але я вже надто довго дивився на це.

Виріжте кілька байтів, скорочуючи цикл, а не використовуючи підрядку.

Гольф

c->{String r="";Integer i,j,l=c[0].length;for(i=4;i<l-4;i+=2){j=c[0][0]>32?i:l-1-i;r+=c[0][j]%8/4*(j==i?1:2)+c[2][j]%8/4*(j==i?2:1)+"";}return l.parseInt(r,4);}

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

Безумовно

String r = "";
Integer i, j, l = c[0].length;
for(i=4; i<l-4; i+=2){
    j = c[0][0]>32 ? i : l-1-i;
    r += c[0][j]%8/4 * (j==i?1:2) + c[2][j]%8/4 * (j==i?2:1) + "";
}
return l.parseInt(r, 4);

Просто спробував свій код, але із зворотним штрих-кодом прикладу "| | |" "| | | | | | | | | | |" і дайте мені 1024, Добре, я не можу це форматувати, але той, який є на прикладі, але спробуйте той приклад, який у вас є, але не повертаючи його, можливо, я зробив поганий вклад :)
Java Gonzar

@JavaGonzalezArribas Я спробував перший приклад (не перевернутий), і, здається, він працює добре. Чи можете ви поставити один надто мало пробілів у першому рядку вводу?
Люк Стівенс

Це, мабуть, проблема, чудова відповідь :)
Java Gonzar

Запропонувати l+~iзамістьl-1-i
roofcat

2

Java 8 , 208 166 157 151 байт

Спробуючи це, мабуть, може бути і краще, зменшено 42 через непотрібні перевірки, -9 видалення змінних, -6 завдяки Люку Стівенсу

Введення - a char[][3]

(a)->{int i=2,c,s=0;c=(a[0][0]>32)?1:-1;for(;i<a.length-2;i++){s+=((a[i][1-c]>32?1:0)+(a[i][1+c]>32?2:0))*Math.pow(4,c==1?a.length-i-3:i-2);}return s;}

неозорений:

int b(char[][] a) {
    int i=2,c,s=0;                      //i for looping, c to check if it's reversed, s is the sum, n the number
    c=(a[0][0]>32)?1:-1; //Check if must be reversed

    for(;i<a.length-2;i++){         //Looping elements

            //(Checking value for 1 + Checking value for 2) * Power, if reversed increasing, else decreasing
        s+=((a[i][1-c]>32?1:0)+(a[i][1+c]>32?2:0))*Math.pow(4,c==1?a.length-i-3:i-2);   
    }
    return s;
}

1
Якщо ви використовуєте масив символів, а не Strings, ви можете перевірити | використовуючи> 32, а не == "|" що заощаджує 2 байти за кожне використання (6 усього). Ви також можете зняти дужки навколо а, коли оголосили лямбда ще два байти.
Люк Стівенс


1

Піп , 46 43 42 байт

IsQ@@gg:RV*RVgY^gR'|1(J@UW2*y@2+@y)TM2FB:4

Приймає рядки штрих-коду як три аргументи командного рядка. Перший і третій рядки повинні бути прокладені довжиною другого рядка з пробілами. Спробуйте в Інтернеті!

Пояснення

Спочатку попередня робота:

IsQ@@gg:RV*RVg Y^gR'|1

                        g is cmdline args; s is space (implicit)
IsQ                     If space equals
   @@g                  the first character of the first line, then:
           RVg           Reverse the order of the rows in g
        RV*              then reverse the characters in each row
      g:                 and assign the result back to g
                 gR'|1  In g, replace pipe character with 1
                ^       Split each row into a list of characters
               Y        Yank the result into y

Тепер зауважте, що якщо ми ігноруємо середній ряд і трактуємо |як 1 і як 0, кожен рядок - це лише 2-бітове двійкове число:

(J@UW2*y@2+@y)TM2FB:4

       y@2             Third row
     2*                Multiply by 2, turning 1 into 2 and space into 0
           @y          First row
          +            Add
   UW                  Unweave: creates a list of two lists, the first containing all
                       even-indexed elements (in our case, the actual data), the second
                       containing all odd-indexed elements (the space separators)
  @                    First item of that list
 J                     Join the list of digits into a string
(            )TM2      Trim 2 characters from the beginning and end
                 FB:4  Convert from base 4 (: makes the precedence lower than TM)
                       Autoprint

1

Лушпиння , 39 38 байт

B4ththmȯ%4+3%5f≠192Ḟz+zṀ·*cN?↔m↔(='|←←

Вводиться як список рядків: Спробуйте в Інтернеті або спробуйте тест-набір!

Пояснення

B4ththm(%4+3%5)f≠192Ḟz+zṀ·*cN?↔m↔(='|←←)
                             ?   (='|←←)  -- if the very first character == '|'
                              ↔           --   reverse the lines
                                          -- else
                               m↔         --   reverse each line
                       zṀ·*cN             -- zip the lines with [1,2,3..] under..
                        Ṁ·*c              --   convert each character to its codepoint and multiply by one of [1,2,3]
                    Ḟz+                   -- reduce the lines under zipWith(+) (this sums the columns)

               f≠192                      -- only keep elements ≠ 192 (gets rid of the separating lines)

-- for the example from the challenge we would now have:
--   [652,376,468,652,376,744,376,468,744,652,376]

      m(      )                           -- map the following function
        %4+3%5                            --   λx . ((x % 5) + 3) % 4
-- this gives us: [1,0,2,1,0,3,0,2,3,1,0]
    th                                    -- remove first & last element
  th                                      -- remove first & last element
B4                                        -- interpret as base4 number


0

Октава , 80 75 68 байт

@(b)bi2de({rot90(t=~~(b-32)([3,1],[1:2:end]),2),t}{2-t(2)}(5:end-4))

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

Цікаво, що bi2deза замовчуванням MSB праворуч, а не ліворуч, призводить до деяких головних болів, коли я це робив ... Я думаю, що я повинен мати оптимальний спосіб перевернути масив, перш ніж його індексувати, але існує надзвичайно багато способів зробити це ( або в першій індексації, або flipud, fliplr, rot90, '(транспонування), остаточна індексація ...). Бере прямокутний масив з пробілами та |s (значить, потрібні пробіли)

@(b)                    % Define anonymous function taking input b

t=                      % Inline-define t,
~~(b-32)                % which is the input, converted to 1's and 0's,
([3 1],[1:2:end])       % but only keep the relevant rows (1 and 3 flipped vertically) and columns (only odd) 

{rot90(t,2),t}          % Flip 180 degrees
{2-t(2)                 % depending on whether the second element of t is 1 or 0.}

(5:end-4)               % Flatten array, discarding control bits
bi2de( ... )            % and convert from binary to decimal,

0

JavaScript (ES6), 184 181 байт

Я не досвідчений гольфіст - я впевнений, що це можна вдосконалити, але мені сподобалось це завдання! Я завжди цікавився цими знаками.

Функція fзаймає список рядків з необхідними пробілами. Нові рядки додані до коду нижче для наочності (не включаються до кількості байтів).

f=t=>((o=[[...t[0]],[...t[2]]])[0][0]=='|'?o:(z=a=>a.reverse())(o.map(z)))
.map((a,r)=>a.filter((_,i)=>~i%2).map(e=>(1+r)*(e=='|')).slice(2,-2))
.reduce((a,b)=>a+parseInt(b.join``,4),0)

Використання

t=['                     ','| | | | | | | | | | |','  |             |   |']
console.log(f(t)) // 4096

Безгольова версія з поясненням

// take list of strings, t, as input:
f = t => ( 

  // create output variable o, discard middle row, turn other rows into lists:
  ( o = [ [...t[0]], [...t[2]] ] )

  // if top-left position isn't a pipe, rotate 180 degrees.
  // Alias [].reverse to save 3 bytes :D
  [0][0] == '|' ? o : ( z = a=> a.reverse() )( o.map(z) )

).map( (a,r) => 

  // remove even-numbered positions (non-encoding spaces):
  a.filter( (_,i) => ~i%2 )

  // convert non-pipes into zeros, and pipes into 1 or 2;
  // top row becomes the base4 1-component, bottom row is 2:
  .map( e => (1+r) * (e=='|') ).slice(2,-2)

// convert rows to base4 component strings, then decimal, then sum them:
).reduce( (a,b) => a + parseInt(b.join``,4),0)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.