Analysieren Sie das Paket

24

Dank Ihrer Hilfe bei der Mark My Mail Challenge hat PPCG-Post alle Pakete erfolgreich mit den generierten Barcodes versehen!

Jetzt ist es Zeit, sie zu entschlüsseln.

Bei dieser Abfrage decodiert Ihr Programm anhand eines Barcodes, der aus der Abfrage " Mark My Mail" generiert wurde, diesen und gibt die codierte Ganzzahl zurück.

Aber achten Sie auf! Der Barcode ist möglicherweise verkehrt herum angebracht ...


4-Staaten-Barcodes

Falls Sie die Codierungsaufforderung verpasst haben, müssen Sie wissen, um welche Art von Barcodes es sich handelt. Ein 4-Zustands-Barcode ist eine Reihe von Balken mit vier möglichen Zuständen, die jeweils eine Ganzzahl zur Basis 4 darstellen:

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

In ASCII gerendert, belegen die Barcodes drei Textzeilen, wobei das Pipe ( |) -Zeichen einen Teil eines Strichs und ein Leerzeichen ( ) einen leeren Abschnitt darstellt. Zwischen den einzelnen Balken befindet sich jeweils ein Leerzeichen. Ein Beispiel-Barcode könnte folgendermaßen aussehen:

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

Um einen Barcode wieder in die von ihm codierte Ganzzahl umzuwandeln, ordnen Sie jeden Barcode der entsprechenden 4-stelligen Basis zu, verknüpfen Sie diese und konvertieren Sie ihn in eine Dezimalzahl.

Da jeder Barcode verkehrt herum auch einen anderen Barcode darstellt, implementieren wir eine Start- / Stopp-Sequenz, damit die Ausrichtung berechnet werden kann. Für diese Herausforderung verwenden wir die von Australia Post festgelegte Start- / Stopp-Sequenz: Jeder Barcode beginnt und endet mit einer 1 0Sequenz.


Die Herausforderung

Ihre Aufgabe ist es, einen ASCII-4-Status-Barcode zu analysieren und die codierte Ganzzahl zurückzugeben - im Wesentlichen die Umkehrung von Mark My Mail .

Aber um die Dinge aufzupeppen, gibt es einen Haken: Der Barcode kann verkehrt herum ausgegeben werden. Wie in der Realität wird es dem Barcode-Leser (Ihrem Programm) überlassen, die richtige Ausrichtung mithilfe der Start- / Stopp-Sequenz zu bestimmen .

Beispiel:

Mit folgendem Barcode:

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

Wir können deutlich sehen, dass das erste und das letzte Ziffernpaar gleich sind 0, 2und nicht 1, 0. Dies bedeutet, dass der Barcode auf dem Kopf steht. Wir müssen ihn also um 180 Grad drehen (nicht nur jeden Balken umdrehen), um die richtige Ausrichtung zu erzielen:

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

Jetzt können wir mit der Dekodierung beginnen. Wir ordnen jeden Balken der entsprechenden Basis-4-Ziffer zu und ignorieren dabei die Start- / Stopp-Sequenzen, da sie die Daten nicht codieren.

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

- - 2 1 0 3 0 2 3 - -

Wir verketten dies mit der Ganzzahl zur Basis 4 2103023und konvertieren es dann in seine Dezimaldarstellung 9419für das Endergebnis.


Regeln

  • Die Eingabe ist immer ein gültiger 4-Status-Barcode, der wie oben beschrieben in ASCII mit der beschriebenen Start- / Stopp-Sequenz gerendert wird.
    • Sie können ein Leerzeichen oder eine gestrippte Linie sowie eine nachgestellte Linie anfordern - je nachdem, welches Format für Ihr Golfspiel geeignet ist.
    • Es kann in der richtigen Ausrichtung sein oder nicht - Ihr Programm muss mithilfe der Start- / Stopp-Sequenz bestimmen, ob es verkehrt herum gelesen werden soll.
    • Führende Nullstellen in der Ganzzahl zur Basis 4 werden nicht codiert.
  • Sie können die Eingabe als Liste von Zeilen oder als Zeichenfolge mit Zeilenumbrüchen verwenden.
  • Die Ausgabe sollte eine Ganzzahl in der Standard-Ganzzahlbasis Ihrer Sprache sein, die die vom Barcode codierten Daten darstellt.
  • Da Briefmarken klein sind und nur sehr wenig Code enthalten, muss Ihr Code so kurz wie möglich sein: Dies ist ein - also gewinnt das kürzeste Programm (in Bytes)!

Testfälle

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

= 4096 (gespiegelt)

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

= 7313145 ( gespiegelt )

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

= 9419 ( gespiegelt )

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

= 990 (nicht gespiegelt)

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

= 12345 (nicht gespiegelt)

FlipTack
quelle
-1 Die Titel der beiden Posts haben nicht dasselbe Format. ("P the P" vs "M my M", wählen Sie entweder "the" oder "my": p)
Rɪᴋᴇʀ
1
Würde „Liste der Linien“ werden alle [String], [{#Char}], [{Char}], [[Char]]?, Da Stringentspricht{#Char}
Οurous
3
@Ouros Was für eine Schreibweise ist das? Ich vermute sehr, dass die Antwort "Ja" lautet, da die Datentypen zwischen den Sprachen sehr unterschiedlich sind. Daher akzeptieren Codierungsprobleme im Allgemeinen "was auch immer in Ihrer Sprache gleichwertig ist", aber ich habe keine Ahnung, welche unterschiedlichen Darstellungen Sie darstellen möchten.
IMSoP
1
Was kommt als nächstes? E-Mail senden? Senden Sie das Telegramm? Post bearbeiten?
Sanchises
1
@Unser ja, der Datentyp ist flexibel, wie IMSoP beschrieben hat.
FlipTack

Antworten:

5

Schale , 16 Bytes

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

Probieren Sie es online!

Die Eingabe ist eine Liste von Zeilen (die TIO-Verknüpfung verwendet zur Verdeutlichung eine mehrzeilige Zeichenfolge). Die Zeilen müssen gleich lang sein und dürfen keine zusätzlichen Leerzeichen enthalten.

Erläuterung

ḋṁẊ=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.
Zgarb
quelle
3

Python 2 , 113 105 Bytes

lambda x:int(''.join([`2*(c>'#')+(a>'#')`for a,b,c in zip(*x[::1-2*(x[-1]>'#')].split('\n'))][4:-4:2]),4)

Probieren Sie es online!

Stange
quelle
2

Retina , 71 Bytes

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

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

Probieren Sie es online! Link enthält kleinere Testfälle. Erfordert, dass die erste und die letzte Zeile bis zur Länge der mittleren Zeile mit Leerzeichen aufgefüllt werden. Erläuterung:

(.).
$1

Löschen Sie die unnötigen Leerzeichen.

sO$^`^\|.*|.

Kehren Sie die Zeichen im Code um. Beginnt der Barcode jedoch mit einem |, wählen Sie den gesamten Code aus, andernfalls teilen Sie ihn in Zeichen auf. Dann kehren Sie sie um. Dadurch wird der Code umgedreht, wenn er mit einem beginnt 0.

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

Löschen Sie die Start- / Stopp-Sequenz und die mittlere Zeile (was für uns nicht von Nutzen ist).

\|
 |
+`\| 
 ||||

Konvertieren Sie die Leerzeichen und |s von Basis 4 nach unär.

.*¶$
$&$&

Verdopple die letzte Zeile.

\|

In Dezimalzahl konvertieren.

Neil
quelle
2

Java (OpenJDK 8) , 181 160 Bytes

Für eine Java-Lösung nicht allzu schäbig, ich bin mir sicher, dass ich Optimierungen vornehmen kann, aber ich habe das schon zu lange angestarrt.

Reduzieren Sie einige Bytes, indem Sie die Schleife kürzen, anstatt Teilzeichenfolgen zu verwenden.

Golf gespielt

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

Probieren Sie es online!

Ungolfed

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);
Luke Stevens
quelle
Habe gerade deinen Code ausprobiert, aber mit dem umgekehrten Barcode des Beispiels "| | |" "| | | | | | | | | | |" und gib mir 1024, ok ich kann das nicht formatieren, aber die auf dem Beispiel, aber versuchen Sie das Beispiel, das Sie haben, aber ohne es umzukehren, vielleicht habe ich eine schlechte Eingabe :)
Java Gonzar
@JavaGonzalezArribas Ich habe das erste Beispiel ausprobiert (nicht gespiegelt) und es scheint gut zu funktionieren. Könnte es sein, dass Sie zu wenig Leerzeichen in die erste Zeile der Eingabe setzen?
Luke Stevens
Das ist wahrscheinlich das Problem, tolle Antwort :)
Java Gonzar
Schlagen Sie l+~istattdessen vorl-1-i
ceilingcat
2

Java 8 , 208 166 157 151 Bytes

Der Versuch kann wahrscheinlich besser sein, reduziert 42 aufgrund unnötiger Überprüfungen, -9 Entfernen von Variablen, -6 dank Luke Stevens

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

ungolfed:

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;
}
Java Gonzar
quelle
1
Wenn Sie anstelle von Strings ein Array von Zeichen verwenden, können Sie nach | suchen mit> 32 anstatt == "|" Das spart 2 Bytes für jede Verwendung (6 insgesamt). Sie können auch die Klammern um a entfernen, wenn Sie das Lambda für weitere zwei Bytes deklarieren.
Luke Stevens
2

Sauber , 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..]]

Probieren Sie es online!

Οurous
quelle
1

Pip , 46 43 42 Bytes

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

Nimmt die Zeilen des Barcodes als drei Befehlszeilenargumente. Die erste und dritte Zeile müssen mit Leerzeichen auf die Länge der zweiten Zeile aufgefüllt werden. Probieren Sie es online!

Erläuterung

Zuerst ein paar Vorarbeiten:

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

Beachten Sie nun, dass, wenn wir die mittlere Zeile ignorieren und |als 1 und als 0 behandeln, jeder Balken nur eine 2-Bit-Binärzahl ist:

(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
DLosc
quelle
1

Schale , 39 38 Bytes

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

Nimmt Eingaben als Liste von Zeichenfolgen: Probieren Sie es online aus oder probieren Sie die Testsuite aus!

Erläuterung

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
ბიმო
quelle
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$\

Probieren Sie es online!

Xcali
quelle
0

Oktave , 80 75 68 Bytes

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

Probieren Sie es online!

Merkwürdigerweise bi2deist standardmäßig MSB auf der rechten anstatt der linken Seite, was zu einigen Kopfschmerzen , während ich dies gemacht ... Ich denke , ich sollte den optimalen Weg von Spiegeln das Array haben , bevor es die Indizierung, aber es gibt sehr viele Möglichkeiten , es zu tun ( entweder in den ersten Indexierungs oder mit flipud, fliplr, rot90, '(transponieren), die endgültigen Indexierungs ...). Nimmt ein rechteckiges Array mit Leerzeichen und |s an (daher sind nachgestellte Leerzeichen erforderlich)

@(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,
Sanchises
quelle
0

JavaScript (ES6), 184 181 Bytes

Ich bin kein erfahrener Golfer - ich bin sicher, dass dies verbessert werden kann, aber ich habe diese Herausforderung geliebt! Ich habe mich immer über diese Zeichen gewundert.

Function erstellt feine Liste von Zeichenfolgen mit erforderlichen Leerzeichen. Zeilenumbrüche wurden der Übersichtlichkeit halber in den Code unten eingefügt (nicht in der Byte-Anzahl enthalten).

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)

Verwendung

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

Ungolfed Version mit Erklärung

// 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)
Chris M
quelle