Markiere meine Mail! - ASCII-Barcodes

39

4-Zustands-Barcodes

Viele Postdienste (Royal Mail UK, Canada Post, US Mail usw.) verwenden einen 4-Staaten-Barcode, um Informationen über ihre Post zu verschlüsseln. In ASCII gerendert könnte es ungefähr so ​​aussehen:

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

Ein 4-Staaten-Barcode ist eine Reihe von Balken. Jeder Balken kann nach oben, unten oder in beide Richtungen verlängert werden und bietet 4 Möglichkeiten. Dies bedeutet, dass jeder Balken im Wesentlichen eine vierstellige Basis darstellt:

            | |
Bar: | | | |
                | |

Ziffer: 0 1 2 3

Das Problem bei dieser Symbologie ist, dass es sich bei jedem Barcode um einen gültigen, anderen Barcode handelt: Die Bedeutung wird drastisch geändert, wenn die Ausrichtung falsch ist. Daher ist ein Start und Stopp werden Sequenz normalerweise implementiert , um die Scanner berechnen kann , welche Art und Weise es soll gelesen werden.

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, ein Programm oder eine Funktion zu schreiben N, die es bei einer positiven Ganzzahl in einen ASCII-4-Status-Barcode umwandelt, wobei jeder Balken (mit Ausnahme der Start- / Stopp-Sequenzen) eine Ziffer in der Base-4-Darstellung von darstellt N.

Beispiel:

Wenn die ganze Zahl gegeben ist 19623, konvertieren wir sie zuerst in ihre Basis-4-Darstellung 10302213.

Wir würden dann jede Ziffer dem entsprechenden Balken zuordnen:

1 0 3 0 2 2 1 3

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

Schließlich würden wir die Start / Stopp-Sequenzen hinzufügen:

Start Ende:
1 0 1 0

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

Der resultierende Barcode sollte die Ausgabe des Programms sein.


Regeln:

  • Die Eingabe ist eine positive Ganzzahl im Bereich der Standard-Ganzzahlgröße Ihrer Sprache.
  • Die Ausgabe:
    • Dies kann entweder eine Liste von Zeilen oder eine Zeichenfolge sein, die neue Zeilen enthält.
    • Kann führende oder nachfolgende Zeilen / Leerzeichen enthalten, solange die Form intakt bleibt.
    • Sollte den Barcode mit dem obigen Format anzeigen - es muss das Pipe-Zeichen ( |) und das Leerzeichen ( ) beim Zeichnen von Balken verwendet werden, und es sollte 1 Leerzeichen zwischen jedem senkrechten Balken sein.
  • Das ist , also gewinnt das kürzeste Programm (in Bytes)!

Testfälle

4095:

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

4096:

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

7313145:

| | | | | | | | | |  
| | | | | | | | | | | | | | | |
      | | | | | | | |      
FlipTack
quelle
Führende Leerzeichen erlaubt? ;)
Erik der Outgolfer
@FlipTack Das Problem mit dieser Symbologie - Sie haben The Boondock Saints noch nicht gesehen, oder?
Lord Farquaad
@EriktheOutgolfer Solange der eigentliche Barcode als 2D-Zeichenmatrix intakt ist, kann er vor oder nach beliebig vielen Leerzeichen stehen.
FlipTack
Weitere Herausforderungen im Zusammenhang mit Barcodes: 1 , 2 , 3
FlipTack
Kann der Ausgang führende Nullen haben?
user230118

Antworten:

9

MATL , 34 30 29 28 Bytes

TFiK_YAyhhH&\EQE+t~vB!P'|'*c

Probieren Sie es online!

Erläuterung

TF      % Push array [1 0] (start sequence)
i       % Push input
K_YA    % Convert to base 4. Gives an array of 4-ary digits
y       % Duplicate from below: pushes [1 0] again (stop sequence)
hh      % Concatenate horizontally twice. Gives array of 4-ary digits
        % including start and stop sequences
H&\     % Two-output modulo 2: pushes array with remainders and array
        % with quotients of dividing by 2
EQE     % Times 2, plus 1, times 2, element-wise. This effectively
        % multiplies each entry by 4 and adds 2
+       % Add element-wise to the array of remainders. The stack now 
        % contains an array of numbers 2, 3, 6 or 7. Each number
        % encodes, in binary form, a column of the output. The
        % previous multiplication of the quotients by 4 will have the
        % effect of shifting one row down (one binary digit upwards),
        % to make room for the central row. The addition of 2 will
        % create the central row, which is always full
t~      % Duplicate, logical negate. Gives an array of zeros of the
        % same length
v       % Concatenate vertically into a 2-row matrix
B       % Convert to binary. Gives a matrix, where each row is the
        % binary representation of one of the numbers of the input
        % matrix, read in column-major order
!P      % Transpose, flip vertically
'|'*    % Multiply by '|'. This transforms 1 into 124 (ASCII code of
        % '|') and leaves 0 as is
c       % Convert to char. Char 0 is shown as space. Implicitly display
Luis Mendo
quelle
8

Jelly , 16-15 Bytes

4;jƓb|ṃ⁾| ẎZṙ2G

Probieren Sie es online!

Wie es funktioniert

4;jƓb|ṃ⁾| ẎZṙ2G  Main link. No arguments.

4                Set the argument and the return value to 4.
 ;               Concatenate the return value with the argument, yielding [4, 4].
   Ɠ             Read an integer n from STDIN.
  j              Join, yielding [4, n, 4].
    b            Convert 4, n, and 4 to base 4. Note that 4 is [1, 0] in base 4.
     |           Perform bitwise OR of each resulting quaternary digit and 4.
                 This pads the binary representation of a digit d to three digits: 
                 [1, d:2, d%2]
      ṃ⁾|        Convert the results to base " |", i.e., binary where ' '
                 represents 0 and '|' represents 1.
          Ẏ      Concatenate the resulting arrays that correspond to 4, n, and 4.
           Z     Zip; transpose rows and columns.
            ṙ2   Rotate 2 units yo the left, correcting the order of [1, d:2, d%2]
                 to [d%2, 1, d:2].
              G  Grid; separate columns by spaces, rows by linefeeds.
Dennis
quelle
Diese Zeichenfolge ist 15 Unicode-Zeichen lang. Wie kann sie 15 Byte lang sein?
2.
2
@jmster Jelly hat eine eigene Codepage
Mr. Xcoder
@jmster Dies sind nicht die tatsächlichen Zeichen. Das Programm besteht aus 15 spezifischen Bytes, die diese Mnemonik haben. Vergleichen Sie es mit Bubblegum, es sieht meistens so aus, .......aber jeder Punkt steht für ein anderes Byte.
FrownyFrog
Warum bitweises ODER statt Hinzufügen?
FrownyFrog
@FrownyFrog Beides würde funktionieren. Da der nächste Schritt die Umwandlung in Binär ist, habe ich mich für einen bitweisen Operator entschieden.
Dennis
7

Oktave , 78 77 75 74 70 69 Bytes

@(x)' |'(dec2bin([2 6 3 7;~(1:4)](:,[2 1 dec2base(x,4)-47 2 1]))-47)'

Probieren Sie es online!

Im Gegensatz zum ursprünglichen Ansatz verwendet dieser eine einfache Nachschlagetabelle, um die Basis-4-Werte auf ihr binäres Äquivalent abzubilden. Die Nachschlagetabelle fügt auch den Abstand zwischen den einzelnen Strichen hinzu, indem zwischen den einzelnen Zahlen eine Null eingefügt wird (die einem Strich aller Leerzeichen zugeordnet wird).

Die Nachschlagetabelle ordnet Bars direkt zu als:

   base4:  0 1 2 3 -

  lookup:  2 6 3 7 0

  binary:  0 1 0 1 0
           1 1 1 1 0
           0 0 1 1 0

Die Konvertierung von binär nach |und  erfolgt nun durch Indizieren in eine Zeichenfolge aus diesen beiden Zeichen - im Grunde das gleiche Prinzip wie in der Nachschlagetabelle für die binäre Konvertierung.


* 1 Byte gespeichert, danke @LuisMendo


Original:

@(x)['' circshift(dec2bin([a=[5 4 dec2base(x,4)-44 5 4];a*0](:))'*92,1)-4384]

Probieren Sie es online!

Anonyme Funktion, die den Barcode als Zeichenfolge zurückgibt.

Dies basiert auf der Tatsache, dass wir, wenn wir 4 zu den Stellen von base4 addieren, einen Strich / Leerzeichen durch die Zahl darstellen können, die mit den vertauschten Bits 1 und 2 in eine Binärzahl umgewandelt wurde:

   base4:  0 1 2 3

    add4:  4 5 6 7

  binary:  0 1 0 1
           0 0 1 1
           1 1 1 1

swap 2/1:  0 1 0 1
           1 1 1 1
           0 0 1 1

Die knifflige Sache aus Sicht des Golfspiels ist das Hinzufügen der Abstände zwischen den Bars und das Umwandeln von 0/1in '|'/' '.

Tom Carpenter
quelle
1
@ LuisMendo clever! Vielen Dank.
Tom Carpenter
7

JavaScript (ES6), 89 87 83 Bytes

n=>`|  ${(g=(a,k=n)=>k?g(a,k>>2)+(k&a?'| ':'  '):' ')(1)}|
| |${g(~0)}| |
   `+g(2)

Testfälle

Wie?

Hinweis : In der folgenden Version wurden Vorlagenliterale durch Standardzeichenfolgen ersetzt, damit der Code ordnungsgemäß eingerückt werden kann.

n =>                        // given the input n
  '|  ' +                   // append the top leading pattern
  (g = (a,                  // g is a recursive function taking a = mask
           k = n) =>        // and using k = value, initially set to n
    k ?                     //   if k is not zero:
      g(a, k >> 2) +        //     do a recursive call for the next group of 2 bits
      (k & a ? '| ' : '  ') //     append '| ' if the bit is set or '  ' otherwise
    :                       //   else:
      ' '                   //     append an extra leading space and stop the recursion
  )(1) +                    // invoke g() with mask = 0b01
  '|\n' +                   // append the top leading pattern and a linefeed
  '| |' +                   // append the middle leading pattern
  g(~0) +                   // invoke g() with all bits set in the mask
  '| |\n' +                 // append the middle trailing pattern and a linefeed
  '   ' +                   // append the bottom leading pattern
  g(2)                      // invoke g() with mask = 0b10
Arnauld
quelle
Ich würde gerne sehen, wie diese Antwort erklärt wird, da sind einige seltsame Dinge im Gange: P
Brian H.
@BrianH. Ich habe eine Erklärung hinzugefügt.
Arnauld
4

R , 154 109 Bytes

function(n,d=c(1,0,n%/%4^floor(log(n,4):0)%%4,1,0),o=c(" ","|"))cat("",o[1+d%%2],"
",o[2+0*d],"
",o[1+(d>1)])

Probieren Sie es online!

Es wurde eine ganze Reihe von Bytes durch Indizieren und Verwenden von und nicht durch Erstellen cateiner Matrix und Verwenden writevon sowie 6 von einer geringfügig anderen Konvertierung zu Basis 4 gespeichert. Druckt mit einem führenden Leerzeichen in jeder Zeile und ohne nachfolgende Zeilenumbrüche.

Die Indizierung erfolgt unter Verwendung einer modularen Arithmetik, ähnlich wie bei einigen anderen Antworten. Da R jedoch eine auf 1 basierende Indizierung verwendet, ist die Arithmetik etwas anders.

Erläuterung:

function(n,
 d=c(1,0,                         # d contains the padding and 
   n%/%4^floor(log(n,4):0)%%4,   # the base 4 digits
   1,0),                         # 
 o=c("|"," ")                    # the vector to index into
 cat("",                         # cat separates things with spaces by default
                                 # so the empty string will print a leading space
  o[1+d%%2],"                    # odds have a | above
",                               # literal newline, a space will follow it (hence leading spaces)
 o[2+0*d],"                      # array of 2s since the middle is always |
",                               # another literal newline
 o[1+(d>1)])                     # digits greater than 1 have a | below

Giuseppe
quelle
3

Holzkohle , 50 Bytes

NθF²⊞υι¿θWθ«⊞υ﹪θ⁴≧÷⁴θ»⊞υθF²⊞υιE⟦ |¦|¦  ||⟧⪫E⮌υ§ιλω

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

Nθ

Geben Sie eine Nummer ein.

F²⊞υι

Schieben Sie die Stoppsequenz auf die vordefinierte leere Liste.

¿θ

Wenn die Zahl positiv ist,

  Wθ«⊞υ﹪θ⁴≧÷⁴θ»

Wende divmod wiederholt an, um es in die umgekehrte Basis 4 umzuwandeln.

  ⊞υθ

ansonsten einfach drauf drücken.

F²⊞υι

Schieben Sie die Startsequenz in die Liste.

E⟦ |¦|¦  ||⟧

Map über drei Saiten. Jede Zeichenfolge repräsentiert die Barcode-Übersetzung für die Ziffern 0123jeder Zeile.

⪫E⮌υ§ιλω

Ordnen Sie die Ziffern in umgekehrter Reihenfolge zu, konvertieren Sie sie mithilfe der Übersetzung in Striche oder Leerzeichen und fügen Sie die Ergebnisse zu drei Zeichenfolgen zusammen, die implizit in separaten Zeilen gedruckt werden.

Neil
quelle
3

Japt , 32 31 Bytes

A¤i2Us4)¬®n s|iS)ù2 w i|1ÃqR² y

Online testen!

Noch nicht wirklich zufrieden damit, aber es ist ein Anfang ...

Erläuterung

A¤  i2Us4)¬ ®   n s |iS)ù2 w i |1Ã qR²  y
As2 i2Us4)q mZ{Zn s'|iS)ù2 w i'|1} qRp2 y
                                           Implicit: U = input, A = 10, R = newline, S = space
As2                                        Convert 10 to a binary string.
    i2   )                                 At index 2, insert
      Us4                                    the input converted to base 4.
          q                                Split into chars.
            mZ{                  }         Map each char Z to
               Zn                            Z converted to a number,
                  s'|iS)                     converted to base " |" (binary using ' ' as 0 and '|' as 1),
                        ù2                   left-padded to length 2 with spaces,
                           w                 reversed,
                             i'|1            with another pipe inserted at index 1.
                                   q       Join the resulting list on
                                    Rp2      a newline repeated twice (adds in blank columns).
                                        y  Transpose the entire string.
                                           Implicit: output result of last expression
ETHproductions
quelle
Ihre 32 Byte macht mich ein wenig besser über dieses komplettes Chaos ! Ich sollte wirklich nicht versuchen, beim Servieren und Trinken von Pints ​​Golf zu spielen!
Shaggy
3

Haskell , 91-90 Bytes

h s=[do a<-4%s++0%0;x!!a:" "|x<-[" | |","||||","  ||"]]
_%0=[1,0]
b%n=b%div n b++[mod n b]

Probieren Sie es online! Gibt eine Liste von Zeilen zurück.


Gleiche Bytezahl-Alternative für die erste Zeile:

h s=[do a<-4%s++0%0;" | |  ||||"!!(x+a):" "|x<-[0,6,4]]
Laikoni
quelle
3

J , 57 49 47 Bytes

10 Bytes dank FrownyFrog!

[:,.2{."0[:|:' |'{~#:@2 6 3 7{~1 0,4&#.inv,1,0:

Wie es funktioniert:

1 0,4&#.inv,1,0: - wandelt die Zahl in eine Liste mit 4-stelligen Basisziffern um und fügt 1 0 am Anfang und am Ende der Liste hinzu

((#:2 6 3 7){' |') - Nachschlagetabelle für die Verschlüsselung, binäre 0 entspricht Leerzeichen, 1 bis '|'

{~ - verschlüsselt die 4-stellige Basis durch Auswahl eines Strings aus der obigen Nachschlagetabelle (Argument umgekehrt)

|: - transponiert das resultierende Array von 3 Spalten in 3 Zeilen

[: - verschließt die Gabel

,.2{."0 - fügt Leerzeichen zwischen die Balken ein

Probieren Sie es online!

Galen Ivanov
quelle
@FrownyFrog Vielen Dank!
Galen Ivanov
2

APL + WIN, 63 Bytes

(⍉5 3⍴' | ||  |||||   ')[;,⍉(2 1,(1+((⌈4⍟n)⍴4)⊤n←⎕),2 1),[.1]5]

Erläuterung:

(⍉5 3⍴' | ||  |||||   ') create a matrix where columns represent bars plus one for separator spaces

(1+((⌈4⍟n)⍴4)⊤n←⎕) prompt for screen input and convert to base 4 and add 1 to convert to index origin 1

2 1,...,2 1 concatenate start stop

,[.1]5 concatenate separator space indices

(.....)[.....] index into bar matrix to display
Graham
quelle
2

05AB1E , 19 Bytes

4BT.øS4~bT„| ‡øÁ€S»

Probieren Sie es online!

Dies ist eine halbe Portierung von Dennis 'Ansatz, der nur ein Byte kürzer ist als die Methode, die ich zuvor verwendet habe (mit der ich ziemlich zufrieden bin):

05AB1E , 20 Bytes

4BT.øS2‰í1ýøT„| ‡€S»

Probieren Sie es online!

Wie es funktioniert?

4BT.øS2 ‰ í1ýøT „| ‡ € S »| Volles Programm. Übernimmt die Eingabe von STDIN und gibt sie an STDOUT aus.

4B | In Basis 4 konvertieren.
  T | Schieben Sie eine 10 auf den Stapel.
   .ø | Surrond (stellen Sie die 10 voran und hängen Sie sie an die Basis 4-Darstellung an).
     S | In einzelne Zeichen / Ziffern aufteilen.
                      + ------------------------------------------------- --------------
                      | Dieser Teil war in der vorherigen Version ¸4.ø4в˜, die
                      | bedeutet: Surround mit 4en, konvertiere jede zu Base 4 (4 -> [1, 0])
                      | und schließlich die Liste tief zu verflachen.
                      + ------------------------------------------------- --------------
      2 ‰ | Divmod 2 ([N // 2, N% 2]).
        í | Rückwärts (elementweise).
         1ý | Addiere eine 1 in der Mitte (elementweise).
           ø | Transponieren.
            T „| ‡ | Übersetze (‡) von "10" (T) nach "|" („|).
                 € S »| Als Raster formatieren.
                 € S | Schieben Sie die Zeichen von jedem.
                   »| Fügen Sie Zeilenumbrüche hinzu, während Sie innere Listen durch Leerzeichen verbinden.

Ich habe Adnan (den Schöpfer von 05AB1E) nach dem Grid-Ding im Chat gefragt und sie haben mir geholfen, 2 Bytes zu sparen, indem sie auf eine Funktion von 05AB1E hingewiesen haben: Wenn mehrdimensionale Listen durch Zeilenumbrüche verbunden werden, werden die inneren Listen auch durch Leerzeichen verbunden ist also ðýunnötig.

Mr. Xcoder
quelle
2

APL (Dyalog Classic) , 33 Byte

' |'[≠\2/212 21 0(,,⊣)4⊥⍣¯1⊢⎕]

Probieren Sie es online!

ngn
quelle
Oh, so solltest du mit 1 0 umgeben ...
FrownyFrog
So erhalten 2⊥⍣¯1Sie eine binäre Liste?
FrownyFrog
@FrownyFrog Es gibt keinen wirklichen Weg, um zu umgeben. Ja, 2⊥⍣¯1ist die Umkehrung ("obverse"?) Von "two-decode". Es wird mit so vielen Bits wie nötig in eine Binärdatei codiert.
7.
2

J , 42 40 39 Bytes

' |'{~[:#:4#.2|.0|:4#:@+1 0(,,[)4#.inv]

2 Bytes rasiert dank Dennis. 1 Byte danke an ngn.

Probieren Sie es online!

Wie es funktioniert

                                4#.inv]      to base 4
                        1 0(,,[)             append (1 0) on both sides
                   4#:@+                     add 4 to each digit and convert to binary
                0|:                          transpose
             2|.                             rotate the rows
      [:#:4#.             from base 4 to base 2, it's supposed to separate the columns
' |'{~                                       to characters
FrownyFrog
quelle
2

JavaScript (ES6) 79 Byte

Verwendet .toString, um die Zahl in Basis 4 umzuwandeln, und arbeitet dann mit jeder Zeile und bitweisem ODER, um die Ausgabe zeilenweise zu erstellen. Gibt eine Liste von Zeilen aus.

n=>[2,3,1].map(d=>[...'10'+n.toString(4)+'10'].map(q=>(q|d)>2?"|":" ").join` `)

f = n=>[2,3,1].map(d=>[...'10'+n.toString(4)+'10'].map(q=>(q|d)>2?"|":" ").join` `)

console.log(f(19623))
console.log(f(4095))
console.log(f(4096))
console.log(f(7313145))

Kuilin Li
quelle
1
Cooler Ansatz mit Karte und bitweisem ODER! Sie können ein ganzes Byte speichern, indem Sie `10${n.toString(4)}10`:)
Chris M
2

Bash + Coreutils, 71 67 Bytes

dc -e4ddon?np|sed 's/./& /g;h;y/01/23/;G;y/12/21/;H;x;y/0123/ | |/'

Probieren Sie es online!

Erläuterung

Das dcBit wird in die Basis 4 konvertiert, wobei ein vorangestellt und angehängt wird 4(wird in 10die Ausgabe umgewandelt) und verwendet wird n, um alles in einer Zeile zu halten.

Der Rest passiert in sed:

s/./& /g;     Add a space after each digit
h;            Make a copy in hold space
y/01/23/;     Prepare up the second row (2/3 will turn to pipes)
G;y/12/21/;   Append what will be the third row and prep it (1/3 will turn to pipes)
H;x;          Prepend hold space
y/0123/ | |/  Make 1 and 3 pipes, 0 and 2 spaces
Sophia Lechner
quelle
1
Die Umwandlung des Teils nach dc ganz sed spart ein paar Bytes, tio.run/##S0oszvj/PyVZQTfVJCUlP88@r6CmODVFQb1YX09fTUE/...
Kritixi Lithos
Sehr schön! Ich habe so etwas ausprobiert, aber ich habe immer wieder andere Methoden ausprobiert, xum die Halte- / Musterbereiche zu ändern und dann salles auf einmal zu erledigen , und nichts wurde kürzer.
Sophia Lechner
@Cowsquack Ich habe es sogar geschafft, basierend auf Ihrer Idee zwei weitere Bytes nach unten zu bringen!
Sophia Lechner
Schöne Idee, die Transliterationen zu kombinieren, +1
Kritixi Lithos
1

Retina , 83 Bytes

.+
$*
+`(1+)\1{3}
${1};
^
1;;
$
;1;;
1*;
$.&
.+
$&¶$&¶$&
T`13` `^.+
T`12` `.+$
\d
|

Probieren Sie es online! Link enthält die schnelleren Testfälle. Erläuterung:

.+
$*

In Unary konvertieren.

+`(1+)\1{3}
${1};

Konvertiere zu Basis 4 als durch ;s getrennte unäre Zahlen .

^
1;;

Stellen Sie die Startsequenz voran.

$
;1;;

Fügen Sie ein an ;und verwandeln Sie es in einen Ziffernabschluss und nicht in ein Trennzeichen. Geben Sie dann die Stoppsequenz an.

1*;
$.&

In Dezimalzahl umwandeln, aber jeder Ziffer 1 hinzufügen.

.+
$&¶$&¶$&

Verdreifache es.

T`13` `^.+

In der ersten Zeile werden 1s und 3s (für 0s und 2s) zu Leerzeichen.

T`12` `.+$

In der letzten Zeile werden 1s und 2s (für 0s und 1s) zu Leerzeichen.

\d
|

Alle anderen Ziffern werden zu Balken.

Neil
quelle
1

Pip , 33 31 29 27 26 Bytes

25 Byte Code, +1 für -SFlag.

Y^aTB4WRt" |"@[y%2oMyy/2]

Probieren Sie es online!

Erläuterung

Wir beobachten ein Muster in den vier Balkentypen:

  • Die erste Zeile ist ein Leerzeichen, wenn die Ziffer gerade ist, und eine Pipe, wenn sie ungerade ist.
  • Die zweite Reihe ist immer eine Pfeife.
  • Die dritte Zeile ist ein Leerzeichen, wenn die Ziffer 0 oder 1 ist, Pipe, wenn 2 oder 3.

Damit:

                           a is cmdline arg; o is 1; t is 10 (implicit)
  aTB4                     Convert a to base 4
      WRt                  Wrap it before and after with 10
 ^                         Split into a list of digits
Y                          and yank into y
              [         ]  List of:
               y%2          0 if even, 1 if odd for each item in y
                  oMy       1 mapped to y, i.e. constant 1 for each item in y
                     y/2    Each item in y divided by 2 (0, 0.5, 1, or 1.5)
         " |"@             Use the elements of that list as indices into this string
                           Note that indices are truncated to integers!
                           Autoprint, separating rows with newline and elements of
                           each row with space (-S flag)
DLosc
quelle
1

C (gcc) , 176 Bytes

#include<stdio.h>
int n,m;f(n,r){if(n)f(n>>2);printf("%c%c",n?32:10,(n&r||!r)&&n?'|':32);}main(){scanf("%d",&n);m=(n+(4<<(32-__builtin_clz(n)/2*2)))*16+4;f(m,1);f(m,0);f(m,2);}

Probieren Sie es online!

Etwas weniger schrecklich formatiert (weniger Golf):

#include<stdio.h>
int n,m;
f(n,r) {
    if(n)
        f(n>>2);
    printf("%c%c",n?32:10,(n&r||!r)&&n?'|':32);
}

main() {
    scanf("%d",&n);
    m=(n+(4<<2*(16-__builtin_clz(n)/2)))*16+4;
    f(m,1);
    f(m,0);
    f(m,2);
}

Erläuterung

Betrachten Sie zunächst den folgenden Code, um eine Ganzzahl zu lesen und die Basis 4-Version auszugeben:

#include <stdio.h>
int n;
f(n) {if(n)printf("%d\n",n&3,f(n>>2));}
main(){scanf("%d",&n);f(n);}

Dies verwendet die Schwanzrekursion, um die Reihenfolge der Ausgabe umzukehren. Jeder rekursive Schritt verschiebt sich um 2 Bits (springt von den letzten 2 Bits ab und dividiert durch 4). Es gibt das mit 3 (0b11) maskierte Ergebnis aus, das nur die letzten beiden Bits anzeigt, also die letzte Ziffernbasis 4.

Der Funktionsaufruf ist in dem printfArgument als nachstehendes Argument enthalten (es wird nicht gedruckt, aber ausgewertet), um zu vermeiden, dass {} (+2 Byte) zum Gruppieren printfdes Funktionsaufrufs und des Funktionsaufrufs verwendet werden muss.

Die Lösung hier erweitert diesen Base-4-Code. Zunächst wird m als n definiert, aber so, dass in Basis 4 10 vorangestellt und angehängt wird. Wir drucken dann m.

In der regulären Druckbasis 4 haben wir eine Bitmaske von 3 verwendet, um die Ziffer zu erhalten. Im Postcode ist die oberste Zeile das niederwertige Bit dieser Ziffer (eine Bitmaske von 1) und die unterste Zeile das höherwertige Bit (eine Bitmaske von 2). Dementsprechend ist die rin f(n,r)dem Bitmask - unsere Funktionsaufrufe f(m,1)für die erste Zeile und f(m,2)für die letzte Zeile.

Damit die mittlere Zeile funktioniert (immer "|" drucken), addieren wir ||!rdie Bedingung - wenn r 0 ist, wird immer true ausgewertet und ein "|" ausgegeben. Dann rufen wir f(m,0)nach der Mittellinie.

Schließlich möchten wir, dass sich Zeilenumbrüche verhalten. Das Einfügen eines zusätzlichen printfCodes ist in Bezug auf den Quellcode sehr teuer. Stattdessen fügen wir dem vorhandenen einen weiteren% c-Bezeichner hinzu printf. n?32:10Gibt eine neue Zeile aus, wenn n 0 (falsch) ist, andernfalls ein Leerzeichen. 32 und 10 werden anstelle von '\ n' und '' verwendet, um Bytes zu speichern.

Billy Graydon
quelle
1
Sie können es auf 146 bringen, wenn Sie keine Warnungen dagegen haben:f(n,r){n&&f(n>>2);printf("%c%c",n?32:10,(n&r|!r)&&n?'|':32);}main(n){scanf("%d",&n);f(n=(n+(4<<(32-__builtin_clz(n)/2*2)))*16+4,1);f(n,0);f(n,2);}
Gastropner
1

Common Lisp, 191 Bytes

(lambda(n &aux(k`(1 0,@((lambda(n &aux r f)(do()((= n 0)f)(setf(values n r)(floor n 4))(push r f)))n)1 0)))(format t"~3{~{~:[  ~;| ~]~}~%~}"`(,(mapcar'oddp k),k,(mapcar(lambda(c)(> c 1))k))))

Probieren Sie es online!

Renzo
quelle
1

PHP, 99 + 1 Bytes

for($n=10 .base_convert($argn,10,4). 104;(~$c=$n[$i++])||3>$y+=$i=1;)echo" | ||  |||||

"[$c*3+$y];

erfordert PHP> = 5.5 für die Indexierung von Literalstrings und <7.1 für die Indexierung, um keine Warnung zu erhalten.

Laufen Sie als Pipe mit -nRoder versuchen Sie es online .

Fügen Sie eine weitere neue Zeile ein, um eine nachfolgende zu erhalten.

Titus
quelle
Warnung: Ein nicht numerischer Wert, der in [...] Zeile 7
RedClover,
@ Soaku PHP-Version muss von 5.5 bis 7.0 sein
Titus
1

Python 2, 142 126 Bytes

B=lambda n:n<4and`n`or B(n/4)+`n%4`
def F(i):
 for r in 0,1,2:print' '.join(" |"[(int(x)%2,1,x>'1')[r]]for x in'10'+B(i)+'10') 

Ein großes Dankeschön an ovs!

Ich habe versucht, die Methoden der anderen Antworten nicht zu kopieren und ... igitt.

Daniel
quelle
128 Bytes
Ovs
1

C # (.NET Core) , 160 Byte

i=>{string s=$"10{B(i)}10",a="";for(int y=0;y<3;y++,a+="\n")foreach(var t in s)a+=t<51&y!=1&t-(y>>1)!=49?"  ":"| ";return a;string B(int n)=>n>0?B(n/4)+n%4:"";}

Probieren Sie es online!

Ich bin sicher, ich habe einige Verbesserungen verpasst.

DeGolfed

i=>{
    string s = $"10{B(i)}10", // prepend and append 10 to the base 4 number
           a="";

    for (int y=0; y<3; y++, a+="\n") // go through each row
        foreach (var t in s)         // go through each char digit
            a += t<51 & y != 1 & t-(y>>1) != 49 ? "  " : "| "; // check if bar or space occurs

    return a;

    string B(int n) => n>0? B(n/4) + n%4 : ""; // convert int to base 4
}

t<51 & y != 1 & t-(y>>1) != 49 überprüft, ob das Zeichen nicht '3' ist, nicht die zweite Zeile, und dann etwas Binärzauber, um festzustellen, ob die erste oder dritte Zeile das Leerzeichen enthalten soll.

Ayb4btu
quelle
1

Zsh , 156 154 151 133 Bytes

y(){for i (${(s//)$(echo 10$(([##4]x))10)});printf "$a[(i+1)] ";echo};a=(' ' '|' ' ' '|');y;a[1]='|';a[3]='|';y;a=(' ' ' ' '|' '|');y

Probieren Sie es online!

Nimmt Basis-10-Eingabe von der var $x

Noskcaj
quelle
0

Japt , 42 Bytes

s4 +A iA)d1"|| "0" | "2" ||"3'|³ ò3 miR ·y

Probieren Sie es online!

Oliver
quelle
Es sollte 1 Leerzeichen zwischen jeder aufrechten Stange sein
Erik the Outgolfer
0

C, 120 Bytes

Funktioniert leider nur unter Windows, da dies itoazu praktisch ist, um Standard zu sein.

char*p,s[21]="10";g(a){for(p=s;*p;)printf(!a|*p++&a?" |":"  ");puts(p);}f(n){strcat(itoa(n,s+2,4),"10");g(1);g(0);g(2);}
Gastropner
quelle