Parsel Ayrıştırma


24

Mark My Mail yarışmasındaki yardımınız sayesinde , PPCG-Post tüm parsellerini oluşturulan barkodlarla damgaladı!

Şimdi, onları çözmenin zamanı geldi.

Bu meydan okumada, programınız, My My Mark (Mücadeleyi İşaretle) mücadelesinden oluşturulan bir barkod verildiğinde kodunu çözer ve şifreli tamsayıyı döndürür.

Ama dikkat et! Barkod baş aşağı olabilir ...


4 durumlu barkodlar

Kodlama zorluğunu kaçırmanız durumunda, ne tür bir barkoddan bahsettiğimizi bilmeniz gerekir. 4 durumlu bir barkod, her biri bir temel 4 tamsayısını temsil eden, dört olası durumu olan bir çubuk satırıdır:

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

ASCII'de oluşturulan barkodlar, |çubuğun bir bölümünü temsil etmek için pipe ( ) karakterini ve boş bir bölümü temsil etmek için bir boşluk ( ) kullanarak üç satır metin alacaktır . Her çubuk arasında tek bir boşluk olacaktır. Örnek bir barkod şöyle görünebilir:

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

Bir barkodu tekrar kodladığı tamsayıya dönüştürmek için, her bir çubuğu ilgili baz-4 rakamıyla eşleştirin, bunları birleştirin ve ondalık değerine dönüştürün.

Her barkod, ters çevrildiğinde farklı bir barkodu da göstereceğinden, oryantasyonun hesaplanabilmesi için bir start / stop dizisi uygularız. Bu zorluğun amacı için, Avustralya Post tarafından belirtilen start / stop dizisini kullanacağız: her barkod bir 1 0diziyle başlar ve biter .


Meydan okuma

Göreviniz, bir ASCII 4 durumlu barkod verildiğinde, onu ayrıştırmak ve kodladığı tamsayıyı geri döndürmek - esasen Mark My Mail'in tersidir .

Ama bir şeyleri canlandırmak için bir av var - barkod baş aşağı verilebilir. Gerçek dünyada olduğu gibi , başlat / durdur dizisini kullanarak doğru yönlendirmeyi belirlemek için barkod okuyucusuna (programınız) bırakılacaktır .

Örnek:

Aşağıdaki barkod verildi:

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

Biz açıkça basamak ilk ve son çiftleri olduğunu görebilirsiniz 0, 2değil 1, 0. Bu, barkodun baş aşağı olduğu anlamına gelir; bu nedenle doğru yönlendirmeyi elde etmek için 180 derece döndürmemiz gerekir (her bir çubuğu çevirmek değil):

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

Şimdi kod çözmeye başlayabiliriz. Her çubuğu, verileri kodlamadıkları için start / stop sekanslarını görmezden gelen karşılık gelen base-4 rakamıyla eşleriz.

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

- - 2 1 0 3 0 2 3 - -

Bunu base-4 tamsayısına birleştirip 2103023, daha sonra 9419nihai sonucu elde etmek için ondalık temsiline dönüştürürüz .


kurallar

  • Girdi her zaman, yukarıda belirtilen ASCII'de açıklanan, başlatılmış / durdurulan dizilimde geçerli olan 4-durumlu bir barkod olacaktır.
    • Hangi formatı golf oynamaya uygun olursa olsun, sondaki boşlukları veya soyulmuş çizgileri ve sondaki yeni hattı isteyebilirsiniz.
    • Doğru yönde olabilir veya olmayabilir - programınız başlat / durdur dizisini kullanarak baş aşağı okunup okunmayacağını belirlemelidir.
    • Temel 4 tamsayısında baştaki sıfır basamakları kodlamaz.
  • Girdiyi bir satır listesi veya yeni satırlı bir dize olarak alabilirsiniz.
  • Çıktı, dilinizin standart tamsayı tabanında, barkod tarafından kodlanan verileri temsil eden bir tam sayı olmalıdır.
  • Posta pulları küçük olduğundan ve bunlara çok az kod sığabileceğinden, kodunuzun mümkün olduğu kadar kısa olması gerekir: bu bir - yani en kısa program (bayt cinsinden) kazanır!

Test Kılıfları

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

= 4096 (çevrilmiş)

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

= 7313145 (çevrilmiş)

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

= 9419 (çevrilmiş)

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

= 990 (çevrilmemiş)

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

= 12345 (çevrilmemiş)


-1 İki yazıdaki başlıklar aynı formatta değil. ("P the P" - "M my M", "ya" ya da "a"
yı seçin

1
"Çizgilerin listesi" herhangi olurdu [String], [{#Char}], [{Char}], [[Char]]?, Verilen bu Stringeşdeğerdir{#Char}
Οurous

3
@Ouros Bu gösterim nedir? Cevabın "evet" olduğundan şüpheliyim, çünkü veri türleri diller arasında çok farklıdır, bu nedenle kodlama zorlukları genellikle "dilinizdeki denk ne olursa olsun" dır, ancak hangi farklı sunumları temsil etmeye çalıştığınızı bilmiyorum.
IMSoP

1
Sıradaki ne? E-postayı yayınla? Telgrafı İletmek? Gönderiyi İşle?
Sanchises

1
@Evet, evet, IMSoP açıklandığı gibi veri tipi esnektir.
FlipTack

Yanıtlar:



5

Kabuğu , 16 bayt

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

Çevrimiçi deneyin!

Giriş, satırların bir listesidir (TIO bağlantısı netlik için çok satırlı bir dize kullanır). Satırlar eşit uzunluklarda olmalı ve fazladan boşluk bırakılmamalıdır.

açıklama

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

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

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

Çevrimiçi deneyin! Link, daha küçük test senaryoları içerir. İlk ve son çizgilerin orta çizginin uzunluğuna boşlukla doldurulmasını gerektirir. Açıklama:

(.).
$1

Gereksiz boşlukları silin.

sO$^`^\|.*|.

Koddaki karakterleri ters çevirin, ancak barkod a ile başlıyorsa |, kodun tamamını seçin, aksi halde karakterlere bölün. Sonra onları ters çevirin. Bu bir ile başlarsa kodu çevirir 0.

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

Başlatma / durdurma sırasını ve orta sırayı (bizim için faydasız olan) silin.

\|
 |
+`\| 
 ||||

Boşlukları ve |sleri taban 4'ten unary'a dönüştürün.

.*¶$
$&$&

Son çizgiyi ikiye katla.

\|

Ondalık dönüştür.


2

Java (OpenJDK 8) , 181 160 bayt

Bir java çözümü için pek perişan değil, yapabileceğim optimizasyonlar olduğundan eminim, ama ben zaten çok uzun zamandır buna bakıyorum.

Subring kullanmak yerine döngüyü kısaltarak birkaç byte'ı azaltın.

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

Çevrimiçi deneyin!

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

Kodunuzu henüz denedim, ancak "| | |" örneğinin tersine çevrilmiş barkoduyla "| | | | | | | | | | |" ve bana 1024 ver, Tamam Bunu formatlayamıyorum, ama örnekteki olanı denedim, ama sahip olduğun örneği dene ama tersine çevirmeden, belki kötü bir giriş yaptım :)
Java Gonzar

@ JavaGonzalezArribas İlk örneği denedim (saygısız) ve iyi çalışıyor gibi görünüyor. Girişin ilk satırına çok az boşluk bırakabilir miydiniz?
Luke Stevens

Muhtemelen sorun budur, büyük cevap :)
Java Gonzar

Öner l+~iyerinel-1-i
ceilingcat

2

Java 8 , 208 166 157 151 bayt

Denemek, muhtemelen daha iyi olabilir, gereksiz kontroller nedeniyle 42 azaltılabilir, -9 değişkenleri kaldırarak, -6 Luke Stevens sayesinde

Giriş bir 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;
}

1
Dizeler yerine bir karakter dizisi kullanıyorsanız, | == "|" yerine> 32 kullanarak her kullanım için 2 bayt kaydeder (6 genel). Ayrıca lambdayı başka bir iki bayt için bildirirken, braketleri bir etrafından da çıkarabilirsiniz.
Luke Stevens

2

Clean , 191 ... 161 144 bayt

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

Çevrimiçi deneyin!


1

Pip , 46 43 42 bayt

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

Barkodun satırlarını üç komut satırı argümanı olarak alır. Birinci ve üçüncü çizgiler, boşluk içeren ikinci çizginin uzunluğuna kadar doldurulmalıdır. Çevrimiçi deneyin!

açıklama

İlk önce bazı hazırlıklar:

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

Şimdi, ortadaki satırı görmezden gelirsek ve |1 ile 0 olarak kabul edersek , her bir çubuğun sadece 2 bitlik bir ikili sayı olduğunu gözlemleyin :

(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

Kabuğu , 39 38 bayt

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

Dizelerin bir listesi olarak girdi alır: Çevrimiçi deneyin ya da test paketini deneyin!

açıklama

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

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$\

Çevrimiçi deneyin!


0

Octave , 80 75 68 bayt

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

Çevrimiçi deneyin!

İlginçtir ki, bi2devarsayılan MSB sağ ziyade solda Bunu yapan ise bazı baş ağrısı yol açan ... ben bunu indeksleme önce diziyi saygısız optimal bir yol olmalı düşünüyorum, ama orada son derece bunu yapmak için birçok yol ( ya birinci indeksleme ya ile flipud, fliplr, rot90, '(devrik), nihai indeksleme ...). Boşluk ve |s ile dikdörtgen bir dizi alır (bu nedenle, sondaki boşluklar gerekir)

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

Tecrübeli bir golfçü değilim - bunun geliştirilebileceğinden eminim, ama bu mücadeleyi çok sevdim! Bu izleri hep merak etmişimdir.

İşlev f, gerekli izleyen boşlukları olan dizelerin bir listesini alır. Netlik için aşağıdaki koda eklenen yeni satırlar (bayt sayısına dahil değil).

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)

kullanım

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

Açıklama ile Ungolfed versiyonu

// 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)
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.