Analiza el paquete


24

¡Gracias a su ayuda en el desafío Mark My Mail , PPCG-Post ha estampado con éxito todos sus paquetes con los códigos de barras generados!

Ahora es tiempo de decodificarlos.

En este desafío, su programa, dado un código de barras generado por el desafío Mark My Mail , lo decodificará y devolverá el entero codificado.

Pero ten cuidado! El código de barras podría estar al revés ...


Códigos de barras de 4 estados

En caso de que se haya perdido el desafío de codificación, necesitará saber de qué tipo de códigos de barras estamos hablando. Un código de barras de 4 estados es una fila de barras con cuatro estados posibles, cada uno de los cuales representa un entero de base 4:

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

Representados en ASCII, los códigos de barras ocuparán tres líneas de texto, utilizando el |carácter de barra vertical ( ) para representar parte de una barra y un espacio ( ) para representar una sección vacía. Habrá un solo espacio entre cada barra. Un ejemplo de código de barras puede verse así:

El | El | El | El | El | El | El | El | El | El |
El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El |
    El | El | El | El | El | El | El | El |

Para volver a convertir un código de barras al número entero que codifica, asigne cada barra a su correspondiente dígito de base 4, concatene estos y conviértalo a decimal.

Como cada código de barras también representará un código de barras diferente cuando esté al revés, implementamos una secuencia de inicio / parada para que se pueda calcular la orientación. Para el propósito de este desafío, utilizaremos la secuencia de inicio / parada especificada por Australia Post: cada código de barras comienza y termina con una 1 0secuencia.


El reto

Su tarea es, dado un código de barras ASCII de 4 estados, analizarlo y devolver el número entero que codifica, esencialmente el reverso de Mark My Mail .

Pero para animar las cosas, hay un problema: el código de barras puede darse al revés. Como en el mundo real, se dejará al lector de código de barras (su programa) determinar la orientación correcta usando la secuencia de inicio / parada.

Ejemplo:

Dado el siguiente código de barras:

    El | El | El | El |
El | El | El | El | El | El | El | El | El | El | El |
  El | El | El | El | El |

Podemos ver claramente que el primer y el último par de dígitos son 0, 2y no 1, 0. Esto significa que el código de barras está al revés, por lo que debemos rotarlo 180 grados (no solo voltear cada barra) para lograr la orientación correcta:

El | El | El | El | El |  
El | El | El | El | El | El | El | El | El | El | El |
    El | El | El | El |    

Ahora, podemos comenzar la decodificación. Asignamos cada barra a su correspondiente dígito de base 4, ignorando las secuencias de inicio / parada, ya que no codifican los datos.

El | El | El | El | El |  
El | El | El | El | El | El | El | El | El | El | El |
    El | El | El | El |    

- - 2 1 0 3 0 2 3 - -

Concatenamos esto al entero base 4 2103023, luego lo convertimos a su representación decimal 9419para el resultado final.


Reglas

  • La entrada siempre será un código de barras válido de 4 estados, representado en ASCII como se establece anteriormente, con la secuencia de inicio / parada descrita.
    • Puede solicitar espacios finales, o líneas despojadas, así como una nueva línea final, cualquiera que sea el formato que se adapte a su juego de golf.
    • Puede o no estar en la orientación correcta: su programa debe determinar si leerlo al revés, utilizando la secuencia de inicio / parada.
    • No codificará los dígitos cero iniciales en el entero de base 4.
  • Puede tomar la entrada como una lista de líneas o una cadena con nuevas líneas.
  • El resultado debe ser un entero en la base de enteros estándar de su idioma, que represente los datos codificados por el código de barras.
  • Como los sellos postales son pequeños y pueden contener muy poco código, su código deberá ser lo más corto posible: este es un , ¡por lo que gana el programa más corto (en bytes)!

Casos de prueba

El | El | El | El | El | El | El | El | El | El | El |
  El | El | El |

= 4096 (volteado)

      El | El | El | El | El | El | El | El |
El | El | El | El | El | El | El | El | El | El | El | El | El | El | El | El |
  El | El | El | El | El | El | El | El | El | El |

= 7313145 (volteado)

    El | El | El | El |
El | El | El | El | El | El | El | El | El | El | El |
  El | El | El | El | El |

= 9419 (volteado)

El | El | El | El | El | El |   
El | El | El | El | El | El | El | El | El |
    El | El | El | El |     

= 990 (no invertido)

El | El | El | El | El |   
El | El | El | El | El | El | El | El | El | El | El |
    El | El | El |       

= 12345 (no invertido)


-1 los títulos en las dos publicaciones no tienen el mismo formato. ("P the P" vs "M my M", elige 'the' o 'my': p)
Rɪᴋᴇʀ

1
Sería "lista de líneas" ser cualquiera de [String], [{#Char}], [{Char}], [[Char]]?, Teniendo en cuenta que Stringes equivalente a{#Char}
Οurous

3
@Ouros ¿Qué notación es esa? Sospecho firmemente que la respuesta es "sí", porque los tipos de datos son muy diferentes entre los idiomas, por lo que los desafíos de codificación generalmente aceptan "cualquiera que sea el equivalente en su idioma", pero no tengo idea de las diferentes representaciones que está tratando de representar.
IMSoP

1
¿Que sigue? Emitir el correo electrónico? Transmitir el telegrama? ¿Procesar la publicación?
Sanchises

1
@Ourous sí, el tipo de datos es flexible, como se describe en IMSoP.
FlipTack

Respuestas:



5

Casco , 16 bytes

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

Pruébalo en línea!

La entrada es una lista de líneas (el enlace TIO utiliza una cadena de varias líneas para mayor claridad). Las líneas deben tener la misma longitud y no debe haber espacios finales adicionales.

Explicación

ḋṁẊ=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

Retina , 71 bytes

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

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

Pruébalo en línea! El enlace incluye casos de prueba más pequeños. Requiere que la primera y la última línea se rellenen con espacio a lo largo de la línea media. Explicación:

(.).
$1

Eliminar los espacios innecesarios.

sO$^`^\|.*|.

Invierta los caracteres en el código, pero si el código de barras comienza con a |, seleccione el código completo, de lo contrario, divídalo en caracteres. Luego, inviértelas. Esto voltea el código si comienza con a 0.

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

Elimine la secuencia de inicio / parada y la fila central (que no nos sirve).

\|
 |
+`\| 
 ||||

Convierta los espacios |ys de la base 4 a unario.

.*¶$
$&$&

Dobla la última línea.

\|

Convierte a decimal.


2

Java (OpenJDK 8) , 181 160 bytes

No está nada mal para una solución de Java, estoy seguro de que hay optimizaciones que puedo hacer, pero ya he estado mirando esto durante demasiado tiempo.

Reduzca algunos bytes acortando el bucle en lugar de usar la subcadena.

Golfed

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

Pruébalo en línea!

Sin golf

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

Acabo de probar su código pero con el código de barras invertido del ejemplo "| | |" "| | | | | | | | | | |" y dame 1024, Ok, no puedo formatear esto, pero el del ejemplo pero, prueba el ejemplo que tienes pero sin revertirlo, tal vez hice una entrada incorrecta :)
Java Gonzar

@JavaGonzalezArribas Probé el primer ejemplo (sin voltear) y parece funcionar bien. ¿Podría ser que pones uno muy pocos espacios en la primera línea de la entrada?
Luke Stevens

Ese es probablemente el problema, gran respuesta :)
Java Gonzar

Sugerir en l+~ilugar del-1-i
ceilingcat

2

Java 8 , 208 166 157 151 bytes

Probando, probablemente puede ser mejor, reducido 42 debido a controles innecesarios, -9 eliminando variables, -6 gracias a Luke Stevens

La entrada es un 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;}

sin golf:

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
Si utiliza una matriz de caracteres en lugar de cadenas, puede verificar si hay | usando> 32 en lugar de == "|" que ahorra 2 bytes para cada uso (6 en general). También puede eliminar los corchetes alrededor de a al declarar el lambda para otros dos bytes.
Luke Stevens

2

Limpio , 191 ... 161 144 bytes

import StdEnv
?' '=0;?_=1
r=reverse
$a b|hd a<'|'= $(r b)(r a)=[?(b!!n)*2+ ?(a!!n)\\n<-[4,6..length b-4]]
@[a,_,b]=sum[d*4^p\\d<- $a b&p<-[0..]]

Pruébalo en línea!


1

Pip , 46 43 42 bytes

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

Toma las líneas del código de barras como tres argumentos de línea de comandos. Las líneas primera y tercera deben rellenarse a la longitud de la segunda línea con espacios. Pruébalo en línea!

Explicación

Primero algunos preparativos:

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

Ahora observe que si ignoramos la fila del medio y tratamos |como 1 y como 0, cada barra es solo un número binario de 2 bits:

(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

Casco , 39 38 bytes

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

Toma datos como una lista de cadenas: ¡ Pruébelo en línea o pruebe el conjunto de pruebas!

Explicación

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

1

Perl 5 , 152 + 2 ( -F) bytes

push@a,[@F]}{for$i(0..$#{$a[1]}){$_.=($a[0][$i]eq'|')+2*($a[2][$i]eq'|')}$_=reverse y/12/21/r if/^0/;s/^0*1000|10*$//g;s/.\K0//g;$\=$_+$\*4for/./g;say$\

Pruébalo en línea!


0

Octava , 80 75 68 bytes

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

Pruébalo en línea!

Curiosamente, bi2dees por defecto MSB a la derecha en vez de la izquierda, lo que lleva a algunos dolores de cabeza, mientras que hice esto ... creo que debería tener la forma óptima en el lanzamiento de la matriz antes de la indexación, pero hay muy muchas maneras de hacerlo ( ya sea en la primera indexación, o con flipud, fliplr, rot90, '(transposición), la indexación última ...). Toma una matriz rectangular con espacios |ys (por lo tanto, se requieren espacios finales)

@(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 bytes

No soy un golfista experimentado, estoy seguro de que esto se puede mejorar, ¡pero me encantó este desafío! Siempre me he preguntado acerca de esas marcas.

La función ftoma una lista de cadenas con los espacios finales necesarios. Se agregaron nuevas líneas al código siguiente para mayor claridad (no incluido en el recuento de bytes).

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)

Uso

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

Versión sin golf con explicación

// 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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.