Oznacz moją pocztę! - Kody kreskowe ASCII

39

4-stanowe kody kreskowe

Wiele usług pocztowych (Royal Mail UK, Canada Post, US Mail itp.) Używa 4-stanowego kodu kreskowego do kodowania informacji o swojej poczcie. Renderowane w ASCII może wyglądać mniej więcej tak:

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

4-stanowy kod kreskowy to rząd pasków. Każdy słupek może być przedłużony w górę, w dół lub oba, co daje 4 możliwości. Oznacza to, że każdy słupek zasadniczo reprezentuje podstawową 4 cyfrę:

            | |
Bar: | | | |
                | |

Cyfra: 0 1 2 3

Problem z tą symboliką polega na tym, że każdy kod kreskowy jest prawidłowym, innym kodem kreskowym do góry nogami: drastycznie zmienia znaczenie, jeśli orientacja jest nieprawidłowa. Dlatego rozruch i zatrzymanie sekwencji są zwykle realizowane tak, że skaner można obliczyć, w jaki sposób jest on powinien być odczytany.

Do celów tego wyzwania wykorzystamy sekwencję start / stop określoną przez Australia Post: każdy kod kreskowy zaczyna się i kończy 1 0sekwencją.


Wyzwanie

Twoim zadaniem jest napisanie programu lub funkcji, która przy dodatniej liczbie całkowitej Nprzekształci go w 4-stanowy kod kreskowy ASCII, w którym każdy słupek (z wyjątkiem sekwencji start / stop) reprezentuje cyfrę w reprezentacji base-4 N.

Przykład:

Biorąc pod uwagę całkowitą 19623, chcielibyśmy najpierw przekonwertować go do swojej bazy-4 reprezentacji 10302213.

Następnie zamapowalibyśmy każdą cyfrę na odpowiednim pasku:

1 0 3 0 2 2 1 3

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

Na koniec dodamy sekwencje start / stop:

Początek Koniec:
1 0 1 0

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

Wynikowy kod kreskowy powinien stanowić wynik programu.


Zasady:

  • Dane wejściowe będą dodatnią liczbą całkowitą w zakresie standardowej wielkości całkowitej twojego języka.
  • Wyjście:
    • Może być albo listą linii, albo łańcuchem zawierającym nowe linie.
    • Może zawierać wiodące lub końcowe znaki nowej linii / spacje, o ile kształt pozostaje nienaruszony.
    • Powinien wyświetlać kod kreskowy o powyższym formacie - musi używać znaku kreski ( |) i znaku spacji ( ) podczas rysowania pasków, a między każdym pionowym paskiem powinna znajdować się 1 spacja.
  • To jest , więc wygrywa najkrótszy program (w bajtach)!

Przypadki testowe

4095:

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

4096:

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

7313145:

| | | | | | | | | |  
| | | | | | | | | | | | | | | |
      | | | | | | | |      
FlipTack
źródło
Dopuszczalne miejsca wiodące ? ;)
Erik the Outgolfer,
@FlipTack Problem z tą symboliką - nie widziałeś Świętych z Boondock, prawda?
Lord Farquaad
@EriktheOutgolfer Dopóki rzeczywisty kod kreskowy, jako matryca 2D znaków, jest nienaruszony, może zawierać tyle spacji przed nim lub po nim, ile potrzeba.
FlipTack,
Inne wyzwania związane z kodem kreskowym: 1 , 2 , 3
FlipTack
Czy dane wyjściowe mogą mieć zera na początku?
user230118,

Odpowiedzi:

9

MATL , 34 30 29 28 bajtów

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

Wypróbuj online!

Wyjaśnienie

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
źródło
8

Galaretka , 16 15 bajtów

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

Wypróbuj online!

Jak to działa

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
źródło
Ten ciąg ma 15 znaków Unicode, jak może mieć 15 bajtów?
jmster,
2
@jmster Jelly ma własną stronę kodową
Mr. Xcoder
@jmster To nie są rzeczywiste postacie. Program ma 15 specyficznych bajtów, które mają te mnemoniki. Porównaj to z Bubblegum, wygląda to najczęściej, .......ale każda kropka oznacza inny bajt.
FrownyFrog,
Dlaczego bitowe LUB zamiast dodawać?
FrownyFrog,
@FrownyFrog Oba działałyby. Ponieważ następnym krokiem jest konwersja na binarną, poszedłem z operatorem bitowym.
Dennis,
7

Oktawa , 78 77 75 74 70 69 bajtów

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

Wypróbuj online!

W przeciwieństwie do pierwotnego podejścia, ta wykorzystuje prostą tablicę przeglądową do mapowania wartości base-4 na ich binarny odpowiednik. Tabela odnośników dodaje również odstępy między poszczególnymi słupkami, dodając zero między każdą liczbą (która odwzorowuje na słup wszystkich pól).

Tabela odnośników bezpośrednio odwzorowuje na paski:

   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

Konwersja z  pliku binarnego na |i jest teraz wykonywana przez indeksowanie w ciąg tych dwóch znaków - w zasadzie ta sama zasada, co tabela odnośników do konwersji binarnej.


* Zapisano 1 bajt, dzięki @LuisMendo


Oryginał:

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

Wypróbuj online!

Anonimowa funkcja, która zwraca kod kreskowy jako ciąg znaków.

Jest to oparte na tym, że jeśli dodamy 4 do base4 cyfr, wówczas możemy przedstawić słupek / spację przez liczbę przekonwertowaną na binarną z zamienionymi bitami 1 i 2:

   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

Trudne z golfa jest dodanie odstępów między taktami i konwersja z 0/1na '|'/' '.

Tom Carpenter
źródło
1
@LuisMendo sprytne! Dzięki.
Tom Carpenter,
7

JavaScript (ES6), 89 87 83 bajtów

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

Przypadki testowe

W jaki sposób?

Uwaga : W poniższej wersji literały szablonów zostały zastąpione standardowymi łańcuchami, aby kod mógł być odpowiednio wcięty.

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
źródło
Chciałbym zobaczyć wyjaśnienie tej odpowiedzi, dzieje się kilka dziwnych rzeczy: P
Brian H.
@BrianH. Dodałem wyjaśnienie.
Arnauld,
4

R , 154 109 bajtów

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

Wypróbuj online!

Zaoszczędzono całą masę bajtów, indeksując i wykorzystując catzamiast konstruować macierz i używając write, a także 6 z nieco innej konwersji na bazę 4. Drukuje z wiodącą spacją w każdym rzędzie i bez końcowych znaków nowej linii.

Indeksowanie odbywa się za pomocą pewnej modularnej arytmetyki, podobnie jak inne odpowiedzi, ale ponieważ R używa indeksowania opartego na 1, arytmetyka jest nieco inna.

Wyjaśnienie:

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
źródło
3

Węgiel drzewny , 50 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

Nθ

Wpisz liczbę.

F²⊞υι

Wciśnij sekwencję zatrzymania do wstępnie zdefiniowanej pustej listy.

¿θ

Jeśli liczba jest dodatnia,

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

wielokrotnie stosuj divmod, aby przekonwertować go na odwróconą bazę 4,

  ⊞υθ

w przeciwnym razie po prostu go popchnij.

F²⊞υι

Wciśnij sekwencję początkową do listy.

E⟦ |¦|¦  ||⟧

Mapa nad trzema ciągami. Każdy ciąg reprezentuje tłumaczenie kodu kreskowego dla cyfr 0123dla każdego wiersza.

⪫E⮌υ§ιλω

Odwzoruj cyfry (odwrócone z powrotem do zwykłej kolejności), przekonwertuj je na słupki lub spacje za pomocą tłumaczenia, a następnie połącz wyniki w trzy ciągi, które zostaną domyślnie wydrukowane w osobnych wierszach.

Neil
źródło
3

Japt , 32 31 bajtów

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

Przetestuj online!

Nie jestem jeszcze z tego zadowolony, ale to dopiero początek ...

Wyjaśnienie

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
ETHprodukcje
źródło
Twoje 32 bajty sprawiają, że czuję się trochę lepiej z tym kompletnym bałaganem ! Naprawdę nie powinienem próbować grać w golfa podczas serwowania i picia kufli!
Kudłaty
3

Haskell , 91 90 bajtów

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

Wypróbuj online! Zwraca listę wierszy.


Ta sama liczba bajtów alternatywa dla pierwszego wiersza:

h s=[do a<-4%s++0%0;" | |  ||||"!!(x+a):" "|x<-[0,6,4]]
Laikoni
źródło
3

J , 57 49 47 bajtów

10 bajtów dzięki FrownyFrog!

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

Jak to działa:

1 0,4&#.inv,1,0: - konwertuje liczbę na listę 4 podstawowych cyfr, dodaje 1 0 na początku i na końcu listy

((#:2 6 3 7){' |') - tablica przeglądowa szyfrowania, binarne 0 odpowiada spacji, 1 do „|”

{~ - szyfruje podstawową 4 cyfrę, wybierając ciąg z powyższej tabeli odnośników (argument odwrócony)

|: - transponuje wynikową tablicę z 3 kolumn do 3 wierszy

[: - zakrywa widelec

,.2{."0 - umieszcza spacje między słupkami

Wypróbuj online!

Galen Iwanow
źródło
@FrownyFrog Dziękujemy!
Galen Iwanow,
2

APL + WIN, 63 bajty

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

Wyjaśnienie:

(⍉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
źródło
2

05AB1E , 19 bajtów

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

Wypróbuj online!

Jest to połowa podejścia Dennisa, który jest tylko o jeden bajt krótszy niż metoda, którą stosowałem wcześniej (z czego jestem całkiem zadowolony):

05AB1E , 20 bajtów

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

Wypróbuj online!

Jak to działa?

4BT.øS2 ‰ í1ýøT „| ‡ € S »| Pełny program Pobiera dane wejściowe ze STDIN, dane wyjściowe do STDOUT.

4B | Konwertuj na bazę 4.
  T | Wciśnij 10 na stos.
   .ø | Surrond (dołącz i dodaj 10 do podstawowej reprezentacji 4).
     S | Podziel na poszczególne znaki / cyfry.
                      + ------------------------------------------------- --------------
                      | Ta część była poprzednio „4.4” w poprzedniej wersji, która
                      | oznacza: otaczaj 4-ami, konwertuj każdy na podstawę 4 (4 -> [1, 0])
                      | i na koniec dokładnie spłaszcz listę.
                      + ------------------------------------------------- --------------
      2 ‰ | Divmod 2 ([N // 2, N% 2]).
        í | Odwrotny (pod względem elementu).
         1ý | Dodaj 1 na środku (pod względem elementu).
           ø | Transponować.
            T „| ‡ | Przetłumacz (‡) z „10” (T) na „|” („|).
                 € S »| Sformatuj jako siatkę.
                 € S | Wciśnij znaki każdego z nich.
                   »| Dołącz przez nowe linie, jednocześnie łącząc wewnętrzne listy spacjami.

Zapytałem Adnana (twórcę 05AB1E) o siatkę na czacie , a oni pomogli mi zaoszczędzić 2 bajty, wskazując funkcję 05AB1E: podczas łączenia list wielowymiarowych nowymi liniami, wewnętrzne listy są również łączone za pomocą spacji , więc ðýjest niepotrzebne.

Pan Xcoder
źródło
2

APL (Dyalog Classic) , 33 bajty

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

Wypróbuj online!

ngn
źródło
Och, właśnie tak powinieneś otoczyć 1 0 ...
FrownyFrog,
Więc 2⊥⍣¯1jak uzyskasz listę binarną?
FrownyFrog,
@FrownyFrog Nie ma jednego prawdziwego sposobu na otoczenie. Tak, czy 2⊥⍣¯1jest odwrotność („awers”?) „Dwu-dekodowania”. Koduje na binarny z tyloma bitami, ile potrzeba.
ngn
2

J , 42 40 39 bajtów

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

Ogolono 2 bajty dzięki Dennisowi. 1 bajt dzięki ngn.

Wypróbuj online!

Jak to działa

                                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
źródło
2

JavaScript (ES6) 79 bajtów

Używa .toString do konwersji liczby na podstawę 4, a następnie rozróżnia poszczególne linie i bitowe LUB do budowania linii wyjściowej linia po linii. Wyświetla listę linii.

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
źródło
1
Fajne podejście z mapą i bitowe OR! Możesz zapisać cały bajt, używając `10${n.toString(4)}10`:)
Chris M
2

Bash + coreutils, 71 67 bajtów

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

Wypróbuj online!

Wyjaśnienie

W dcbitowe nawróceni do podstawy 4, poprzedzenie i dołączając z 4(odwraca się 10do wyjścia) i stosując nsię utrzymać wszystko w jednym wierszu.

Reszta dzieje się w 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
źródło
1
Konwersja części po dc całkowicie na sed pozwala zaoszczędzić kilka bajtów, tio.run
##
Bardzo dobrze! Próbowałem czegoś takiego, ale próbowałem różnych sposobów bycia sprytnym, wprowadzając xprzestrzenie Hold / Pattern, aby je zmodyfikować, a następnie zrobić swszystko naraz, i nic nie było krótsze.
Sophia Lechner
@ Cowsquack Udało mi się nawet zmniejszyć kolejne dwa bajty w oparciu o Twój pomysł!
Sophia Lechner,
Fajny pomysł na połączenie transliteracji, +1
Kritixi Lithos
1

Siatkówka , 83 bajty

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

Wypróbuj online! Link zawiera szybsze przypadki testowe. Wyjaśnienie:

.+
$*

Konwertuj na unary.

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

Konwertuj na bazę 4 jako liczby jednostkowe oddzielone ;s.

^
1;;

Przygotuj sekwencję początkową.

$
;1;;

Dodaj a ;, zamieniając go w terminator cyfrowy zamiast separatora, i sekwencję zatrzymania.

1*;
$.&

Konwertuj na dziesiętne, ale dodając 1 do każdej cyfry.

.+
$&¶$&¶$&

Potrój to.

T`13` `^.+

W pierwszym rzędzie 1s i 3s (reprezentujące 0s i 2s) stają się spacjami.

T`12` `.+$

W ostatnim wierszu, 1S i 2s (reprezentujący 0S i 1S) się przestrzenie.

\d
|

Wszystkie pozostałe cyfry stają się słupkami.

Neil
źródło
1

Pip , 33 31 29 27 26 bajtów

25 bajtów kodu, +1 dla -Sflagi.

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

Wypróbuj online!

Wyjaśnienie

Obserwujemy wzór w czterech typach słupków:

  • Pierwszy rząd to spacja, jeśli cyfra jest parzysta, a jeśli nieparzysty, potok.
  • Drugi rząd to zawsze rura.
  • Trzeci wiersz to spacja, jeśli cyfra to 0 lub 1, a potok, jeśli 2 lub 3.

Więc:

                           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
źródło
1

C (gcc) , 176 bajtów

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

Wypróbuj online!

Nieco mniej strasznie sformatowane (mniej golfa):

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

Wyjaśnienie

Najpierw rozważ następujący kod, aby odczytać liczbę całkowitą i wyprowadzić wersję podstawową 4:

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

Wykorzystuje rekurencję ogona do odwrócenia kolejności danych wyjściowych. Każdy cykl rekurencyjny przesuwa się o 2 (odciąga ostatnie 2 bity i dzieli przez 4). Wyprowadza wynikową maskę bitów za pomocą 3 (0b11), która pokazuje tylko dwa ostatnie bity, czyli ostatnią cyfrę 4.

Wywołanie funkcji jest uwzględnione w printfargumencie końcowym (nie jest drukowane, ale jest oceniane), aby uniknąć konieczności używania {} (+2 bajty) do grupowania printfwywołania funkcji i.

Rozwiązanie tutaj rozszerza ten kod base-4. Po pierwsze, m jest zdefiniowane jako n, ale w taki sposób, że w bazie 4 będzie miał 10 dodanych i dołączonych do niego. Następnie drukujemy m.

Podczas drukowania bazy 4 regularnie używaliśmy maski bitowej 3, aby uzyskać cyfrę. W kodzie pocztowym górny wiersz to bit niskiego rzędu tej cyfry (maska ​​bitowa 1), a dolny wiersz to bit wysokiego rzędu (maska ​​bitowa 2). W związku z tym rin f(n,r)jest maską bitów - nasza główna funkcja wywołuje f(m,1)pierwszą linię i f(m,2)ostatnią linię.

Aby linia środkowa działała (zawsze wypisuje „|”), dodajemy ||!rdo warunkowego - jeśli r wynosi 0, zawsze będzie oceniać jako prawda i wypisze „|”. Następnie wzywamy f(m,0)do środkowej linii.

Wreszcie chcemy, aby zachowywały się nowe linie. Dołączenie dodatkowego printfjest kosztowne, jeśli chodzi o bajty kodu źródłowego, dlatego zamiast tego dodajemy kolejny specyfikator% c do istniejącego printf. n?32:10wypisuje znak nowej linii, jeśli n wynosi 0 (fałsz), a spacja w przeciwnym razie. 32 i 10 są używane zamiast „\ n” i „” do zapisywania bajtów.

Billy Graydon
źródło
1
Możesz sprowadzić go do 146, jeśli nie masz nic przeciwko ostrzeżeniom: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 bajtów

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

Wypróbuj online!

Renzo
źródło
1

PHP, 99 + 1 bajtów

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

"[$c*3+$y];

wymaga PHP> = 5,5 dla dosłownego indeksowania ciągów i <7,1 dla indeksowania, aby nie wyświetlać ostrzeżenia.

Uruchom jako potok z -nRlub spróbuj online .

Wstaw jeszcze jedną nową linię, aby uzyskać końcową.

Tytus
źródło
Ostrzeżenie: Nienumeryczna wartość napotkana w [...] [...] w linii 7
RedClover
@Soaku Wersja PHP musi mieć od 5.5 do 7.0
Titus
1

Python 2, 142 126 bajtów

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

Wielkie dzięki dla ovs!

Próbowałem nie kopiować metod innych odpowiedzi i ... fuj.

Daniel
źródło
1

C # (.NET Core) , 160 bajtów

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:"";}

Wypróbuj online!

Jestem pewien, że przegapiłem kilka ulepszeń.

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 sprawdza, czy znak nie jest „3”, a nie drugi rząd, a następnie trochę magii binarnej, aby sprawdzić, czy pierwszy lub trzeci rząd powinien zawierać spację.

Ayb4btu
źródło
1

Zsh , 156 154 151 133 bajtów

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

Wypróbuj online!

Pobiera dane wejściowe base-10 z var $x

Noskcaj
źródło
0

C, 120 bajtów

Niestety działa tylko w systemie Windows, ponieważ itoajest to zbyt duża wygoda, aby być standardem.

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
źródło