Kod 39 barkod kodlayıcı


16

Bir dizeyi Kod 39 biçimindeki bir barkoda kodlayan bir işlev veya program yazın ; burada her karakter dört boşlukla ayrılmış beş çubuk olarak kodlanır. Çubukların ikisi ve boşluklardan biri geniş ve diğerleri dar (10 * 4 kod) veya boşlukların üçü geniş ve çubukların hiçbiri (4 kod) değil. Bu, kodlanmış dizenin başlangıcını ve sonunu belirtmek için kullanılan ayrılmış bir kod olan 44 farklı kod verir.

Meydan okuma

Giriş, yalnızca kümedeki karakterleri içeren bir dizedir

1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-. +/$%

Çıktı, barkod dizesi olarak kodlanan dizedir. Dar boşluk ve karakter arası boşluklar tek boşluktur ve geniş boşluk üç boşluktur. Dar çubuk Unicode "Tam blok", █ için UTF-8 bayt dizisidir, yani 0xE2 0x96 0x88geniş çubuk üç bayt dizisi / karakteridir ( ███). Kodların tam listesi:

      Spaces
      0100 0010 0001 1000 1011 1101 1110 0111
Bars
00000                       +    /    $   %
10001   1    A    K    U
01001   2    B    L    V
11000   3    C    M    W
00101   4    D    N    X
10100   5    E    O    Y
01100   6    F    P    Z
00011   7    G    Q    -
10010   8    H    R    .
01010   9    I    S  space          1=wide
00110   0    J    T  start/end      0=narrow

Çubuklar ve boşluklar, bir çubuktan başlayarak araya eklenir, örneğin Q,

bar   0 0 0  1     1 
code  █ █ █ ███   ███
space  0 0 0    1

Tüm karakterleri kodladıktan sonra, dize her iki uçta ile sınırlandırılır █ █ ███ ███ █. Karakterler arası boşluk, tek bir boşluk, her harf arasına eklenir. Çözümünüz, sondaki boşlukları ve sondaki yeni satırı (bu sırayla) çıktılayabilir.

Örnekler

""     → "█   █ ███ ███ █ █   █ ███ ███ █"

"A"    → "█   █ ███ ███ █ ███ █ █   █ ███ █   █ ███ ███ █"

"C++"  → "█   █ ███ ███ █ ███ ███ █   █ █ █   █ █   █   █ █   █ █   █   █ █   █ ███ ███ █"

"GOLF" → "█   █ ███ ███ █ █ █ █   ███ ███ ███ █ ███ █   █ █ ███ █ █   ███ █ ███ ███   █ █ █   █ ███ ███ █"

Standart giriş / çıkış biçimlerine izin verilir ve standart boşluklara izin verilmez. Bu , bu yüzden bayt cinsinden ölçülen en kısa kod kazanır!


1
İnstead yerine yazdırılabilir bir ASCII karakteri kullanabilir miyiz (hangisine izin verileceğini seçebilirsiniz)?
Outgolfer Erik

BrainFuck gibi bir dil için "tek kullanım" ne anlama gelir?
l4m2

1
@Angs Ben kod üzerinde değil, temelde çıktı demekti. #Örneğin, "#"bir dilde kullanılabilmesinin tek nedeni , karakterin kullanımlarına ceza vermek çok adil değil.
Outgolfer Erik

@EriktheOutgolfer Demek istediğim dize değişmezleri ve benzerlerinde idi, ancak l4m2'nin noktası göz önüne alındığında buna izin vermemek en iyisi olabilir. Sonuçta, üç bayt veremeyen dil var mı?
Angs

Yanıtlar:


7

JavaScript (ES6), 225 212 bayt

@ L4m2 sayesinde 4 bayt kaydedildi

s=>`#${s}#`.replace(/./g,c=>'0202020202'.replace(/./g,(j,k)=>[C='█',C+C+C,' ','   '][(i="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT".indexOf(c),[170,257,260,5,272,17,20,320,65,68,80][i>>2]^2<<i%4*2)>>k&1|j]))

Çevrimiçi deneyin!

Nasıl?

Tablo, karakterin 9 bitlik ikili maskesi, aşağıdaki formül kullanılarak satırından ve sütunundan hızlı bir şekilde çıkarılacak şekilde yeniden düzenlenebilir:

n = m XOR (2 << k)

ile:

  m  | k: 0   2   4   6
-----+------------------      Examples:
 170 |    %   +   /   $
 257 |    U   1   A   K         'G' = 320 XOR (2 << 4) = 320 XOR 32 = 352
 260 |    V   2   B   L
   5 |    W   3   C   M         '+' = 170 XOR (2 << 2) = 170 XOR 8  = 162
 272 |    X   4   D   N
  17 |    Y   5   E   O
  20 |    Z   6   F   P
 320 |    -   7   G   Q
  65 |    .   8   H   R
  68 |   spc  9   I   S
  80 |    #   0   J   T

s=>`#${s}#`.replace(/./g,c=>'0202020202'.replace(/./g,(j,k)=>[C='#',C+C+C,' ',' '][(i="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT".indexOf(c),[,257,260,5,272,17,20,320,65,68,80][i>>2]|(2<<i%4*2^(i<4)*170))>>k&1|j]))(221)
l4m2

@ l4m2 Bu geçerli görünmüyor. Ancak, 221 bayt için bir düzeltme bulmayı başardım .
Outgolfer Erik

@EriktheOutgolfer Bence l4m2 '#' yerine tam blok ile gönderilen şey bu. Yoksa bir şey mi kaçırıyorum?
Arnauld

@Arnauld Orijinalleri gerektiği gibi boşluk bırakmıyor.
Outgolfer Erik

3

Kırmızı , 452 445 bayt

func[s][q: func[x y z][append/dup x y z]append insert s"*""*"b:
func[n][v: copy[]until[append v n % 2 * 2 + 1
1 > n: n / 2]q v 1 5 - length? v
reverse v]a: q":1234567890:ABCDEFGHIJ:KLMNOPQRST:UVWXYZ-. *"" "44
a/45: #"+"a/56: #"/"a/67: #"$"a/78: #"%"foreach t s[i: index? find a t
k: b pick[0 17 9 24 5 20 12 3 18 10 6]either 0 = j: i % 11[11][j]m:
b pick[8 4 2 16 22 26 28 14]i - 1 / 11 + 1 z: copy""repeat n 5[q z"█"k/(n)
q z" "m/(n)]prin z]]

Çevrimiçi deneyin!

Daha fazla golf yapmaya çalışacağım, ama bu naif çözümden fazla beklemiyorum.


2

Java 10, 455 bayt

s->{String r="",R=r;for(var c:("~"+s+"~").split(""))r+=r.format("%9s",Long.toString(new int[]{148,289,97,352,49,304,112,37,292,100,52,265,73,328,25,280,88,13,268,76,28,259,67,322,19,274,82,7,262,70,22,385,193,448,145,400,208,133,388,196,138,162,168,42}["~1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-. +/$%".indexOf(c)],2)).replace(' ','0');for(int l=r.length(),i=0,c;i<l;R+=""+(i%9%2<1?c<49?"█":"███":c<49?" ":"   ")+(i%9>7&++i<l?" ":""))c=r.charAt(i);return R;}

Çevrimiçi deneyin.

Açıklama:

s->{                     // Method with String as both parameter and return-type
  String r="",           //  Temp-String, staring empty
         R=r;            //  Result-String, starting empty as well
  for(var c:("~"+s+"~")  //  Prepend and append "~" to the input
            .split(""))  //  And loop over each character
    r+=r.format("%9s",Long.toString( 
                         //   Convert the following integer to a 9-bit binary String:
       new int[]{148,289,97,352,49,304,112,37,292,100,52,
                 265,73,328,25,280,88,13,268,76,28,259,67,322,
                 19,274,82,7,262,70,22,385,193,448,145,400,208,
                 133,388,196,138,162,168,42}
                         //    Array containing all decimal values of the binary Strings
       ["~1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-. +/$%".indexOf(c)]
                         //    with the index based on the current character
   ,2)).replace(' ','0');
                         //   (also part of the integer to 9-bit binary String conversion)
  for(int l=r.length(),i=0,c;i<l;
                         //  Loop `i` over the temp-String
      R+=                //    After every iteration: append the following to the result:
         ""+(i%9%2<1?    //     If `i` modulo-9 modulo-2 is 0:
              c<49?      //      And `c` is '0':
               "█"       //       Append a single block
              :          //      Else:
               "███"     //       Append three blocks
             :c<49?      //     Else-if `c` is '0':
              " "        //      Append a single space
             :           //     Else:
              "   ")     //      Append three spaces
         +(i%9>7         //     If `i` modulo-9 is 8,
           &++i<l?       //     and this is not the very last character
            " "          //      Append a space delimiter
           :             //     Else:
            ""))         //      Append nothing more
    c=r.charAt(i);       //   Set `c` to the current character in `r`
  return R;}             //  Return the result

2

C (gcc) , 311 , 303 bayt

(*P)()=printf;i;j;w;m[]={170,257,260,5,272,17,20,320,65,68,80};char*b=" \0\xE2\x96\x88",*t="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT",*c;p(x){j=256;w=2;while(j){P(b+w);if(x&1){P(b+w);P(b+w);}x/=2;j>>=1;w=2*!w;}P(" ");}f(char*_){p(82);for(c=_;*c;c++){i=strchr(t,*c)-t;p(m[i>>2]^(2<<(i&3)*2));}p(82);}

Çevrimiçi deneyin!

-8 ceilingcat sayesinde

Arnauld'un cevabından kodlama stratejisini kullanır. TIO bağlantısı, -wuyarıları kaldırmak için anahtar ve kazan plakası içerir , bunlar gereksizdir ve dolayısıyla skora dahil değildir.

Arnauld tarafından açıklanan kodlama şemasının yanı sıra, buradaki diğer hile w değişkeni 2 ve 0 ( w=2*!w) arasında geçiş yapmaktır . Bu, içindeki ilk ve ikinci dizeler arasında seçim yapmamı sağlıyor b. Birincisi boşluk, ikincisi dolu dikdörtgendir.


zekice, onu göndermelisin :)
LambdaBeta

2

C (gcc) , 241239227221 bayt

#define P printf(i%2?" ":"█")
i;p(x){for(i=9;i--;x/=2)P,x&1&&P+P;P;}f(char*_){p(82);for(char*t="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT";*_;p(L"ªāĄ\5Đ\21\24ŀADP"[i/4]^2<<i%4*2))i=index(t,*_++)-t;p(82);}

Çevrimiçi deneyin!

Dayalı LambdaBeta uygulamasına @ .

Biraz daha az golf:

#define P printf(i%2?" ":"█")
i;
p(x){
 for(i=9;i--;x/=2)
  P,
  x&1&&
   P+
   P;
 P;
}
f(char*_){
 p(82);
 for(char*t="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT";*_;p(L"ªāĄ\5Đ\21\24ŀADP"[i/4]^2<<i%4*2))
  i=index(t,*_++)-t;
 p(82);
}

1

Kömür , 90 bayt

⪫EE⪫**S⌕⁺⁺⭆…αχ﹪⊕μχα-. *+/$%ι⪫E⁵⁺⎇μ× ∨⁼›ι³⁹⁼²﹪⁻÷ι∨›ι³⁹χμ⁴¦³ω×█∨›ι³⁹∨§↨℅§.6':+3<-59ι²⊕μ³ω 

Çevrimiçi deneyin! Not: Sondaki boşluk. Bağlantı, kodun ayrıntılı versiyonudur. Açıklama:

⪫EE⪫**S...⪫E⁵⁺...ω 

Giriş dizesini *s içine sarın ve ardından iki kez eşleyin ve sonuçta boşluklarla birleştirin. İkinci harita için, 0..4iki alt dizenin birleştirildiği kapalı aralık üzerinde ek bir harita olur ve bu sonuçlar daha sonra önceden tanımlanmış boş dize sabiti ile birleştirilir.

⌕⁺⁺⭆…αχ﹪⊕μχα-. *+/$%ι

İlk iç harita için, artan basamakları, büyük harfli alfabeyi ve sembolleri alarak oluşturulan bir dize oluşturun -. *+/$%ve eşlenen giriş karakterinin konumuna bakın. Örneğin, ile C++eşleşir [12, 40, 40].

⎇μ× ∨⁼›ι³⁹⁼²﹪⁻÷ι∨›ι³⁹χμ⁴¦³ω

İlk alt dize, çubuklardan önceki boşlukları temsil eder. İlk çubuktan önce hiçbir şey yoktur, ancak diğer çubuklar eşlenen giriş karakterinin konumuna bağlıdır: 39'dan büyükse, sadece bir yerin tek bir alanı vardır, 40'ın altındaysa, sadece bir yerin üçü vardır boşluklar ve konum da 10'a bölünerek bir sütuna dönüştürülür. Sütun ve döngü indeksi 2 (modulo 4) farklıysa, o zaman garip bir yer olur.

×█∨›ι³⁹∨§↨℅§.6':+3<-59ι²⊕μ³

İkinci alt dize çubukları temsil eder. Konum 39'un üzerindeyse, her zaman bir çubuk vardır, aksi takdirde konum karakterlerle eşlenen bir bit dizisinde aranır. Örneğin, konum 12 'ise 100111, ikili olarak karaktere dairesel olarak endekslenir ve sütun 1 ve 2'deki geniş çubukları gösterir. ( 1Satır aralığı yoksayılır, yalnızca tutarlı bir bit sayımı sağlar.)


1

Perl 5 , 244 bayt

$l="{ ,   ,...,.........}"x9;@h{$",qw($ % + - . /),0..9,'',A..Z}=(<"$l">)[q{..=9...Z.>>...J=9..j.%r1...=).[.>=-..Ux?V.^=8.>.6o+ax_.=(..B=,..Yx6..b=(..#r'p.^...G.<=,..Sx5B.\=(.V.It..z:..-z.=<6.}=~s/./ord$&/gre=~/.{6}/g];s/^|./$h{$&} /g;$\=$h{''}

Çevrimiçi deneyin!

Birçok yazdırılamaz ve yüksek baytlık karakter içerir, TIO bağlantısı bir xxdgösterim sağlar. Bunun daha küçük olmasını umuyordum ve verileri daha verimli bir şekilde paketleyebileceğimi umuyorum, bu yüzden nasıl gittiğimi göreceğim. Bu, tüm permütasyonları oluşturur " "," ","█","███"ve ardından listenin göstergelerini karşılık gelen karakterlerle eşleştirir.


1

Haskell , 275 270 bayt

z=0:z
x!0=[]
x!n=mod n x:x!div n x
e c|Just a<-lookup c.zip"W3YZ56C$EF. 89*HM/ORU1QGNTDJ7%40LSBIP2-+XVKA".((++)<*>(reverse<$>))$take 9.(++z).(2!)<$>scanl(+)7(67!0x117CDBC49F9EEEF11C3A659CACB31236)=zipWith(\l c->c<$[1..2*l+1])(a++[0])(cycle"█ ")>>=id
f s='*':s++"*">>=e

Çevrimiçi deneyin!

x!nN'nin x-baz basamaklarını hesaplayan operatör , kodları açmak için iki kez kullanılır. Kodlar ilk olarak renge bakılmaksızın geniş = 1 ve dar = 0 olan ikili dizeler olarak sıkıştırılır;R↔10000110↔262 . Bu sayılar daha sonra sıralanır ve ikili rakam algoritmasının tersi ile sıkıştırılan [3,66] aralığındaki sayıları elde etmek için farklılaşır 0x117CDBC49F9EEEF11C3A659CACB31236. Bu kodların sadece yarısını içerir, geri kalanı bunların tersidir.

Ungolfed:

z=0:z                       -- infinite zeroes for padding
x!0=[]                      -- digits of n in base x, recursion base case
x!n=mod n x:x!div n x       -- digits of n in base x
e c | Just a                -- read upwards from (*)
  <-lookup c                -- lookup code, given letter
  . zip"W3YZ56C$EF. 89*HM/ORU1QGNTDJ7%40LSBIP2-+XVKA" 
                            -- combine codes with correct letters
  . ((++)<*>(reverse<$>))   -- concatenate list and list with reverse codes
  $ take 9                  -- take nine
  . (++z)                   -- pad with infinite zeroes on right
  . (2!)                    -- convert to binary digits – [[1,1,1],[1,0,1,1]…]
  <$> scanl (+) 7           -- cumulative sum starting from 7 – [7,13,19,22,25…]
        (67!0x117CDBC49F9EEEF11C3A659CACB31236)       
                            -- (*) digits in base 67 – [6,6,3,3,3,9,5,7…]
  = zipWith
      (\l c->c<$[1..2*l+1]) -- combine width and color, length is 2*l+1
      (a++[0])              -- list of widths as 0/1, 0 added for interchar gap
      (cycle"█ ")           -- infinite list of bar colors, leftovers are unused
  >>=id                     -- concatenate
f s='*':s++"*">>=e          -- surround string with delimiters, map e and concat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.