แยกวิเคราะห์พัสดุ


24

ด้วยความช่วยเหลือของคุณในการทำเครื่องหมายท้าทายอีเมลของฉัน PPCG-Post ได้ทำการประทับตราพัสดุทั้งหมดด้วยบาร์โค้ดที่สร้างเสร็จเรียบร้อยแล้ว!

ตอนนี้ถึงเวลาถอดรหัสพวกมันแล้ว

ในการท้าทายนี้โปรแกรมของคุณจะได้รับบาร์โค้ดที่สร้างจากMark My Mailความท้าทาย , ถอดรหัสและคืนค่าจำนวนเต็มที่เข้ารหัส

แต่ระวัง! บาร์โค้ดอาจคว่ำลง ...


บาร์โค้ด 4 สถานะ

ในกรณีที่คุณพลาดการท้าทายการเข้ารหัสคุณจะต้องรู้ว่าบาร์โค้ดประเภทใดที่เรากำลังพูดถึง บาร์โค้ด 4 สถานะคือแถวของแท่งที่มีสี่สถานะที่เป็นไปได้แต่ละอันแสดงจำนวนเต็มฐาน 4:

            |       |
Bar:    |   |   |   |
                |   |

Digit:  0   1   2   3

แสดงผลใน ASCII บาร์โค้ดจะใช้ข้อความสามบรรทัดโดยใช้|อักขระpipe ( ) เพื่อแสดงส่วนหนึ่งของบาร์และเว้นวรรค ( ) เพื่อแสดงส่วนที่ว่างเปล่า จะมีช่องว่างเดียวในแต่ละแถบ บาร์โค้ดตัวอย่างอาจมีลักษณะเช่นนี้:

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

หากต้องการแปลงบาร์โค้ดกลับไปเป็นจำนวนเต็มจะเข้ารหัสแผนที่แต่ละแท่งให้ตรงกับตัวเลขฐาน 4 ที่สอดคล้องกันต่อกันและแปลงเป็นทศนิยม

เนื่องจากบาร์โค้ดแต่ละอันจะแสดงบาร์โค้ดที่แตกต่างกันเมื่อคว่ำเราใช้ลำดับการเริ่ม / หยุดเพื่อให้สามารถคำนวณค่าความเบี่ยงเบนได้ สำหรับจุดประสงค์ของการท้าทายนี้เราจะใช้ลำดับเริ่มต้น / หยุดที่ระบุโดย Australia Post: บาร์โค้ดแต่ละอันจะเริ่มต้นและสิ้นสุดด้วย1 0ลำดับ


ความท้าทาย

งานของคุณคือเพื่อรับ ASCII 4 รัฐบาร์โค้ดแยกมันและกลับจำนวนเต็มมัน encodes - หลักหลังของมาร์คจดหมายของฉัน

แต่เพื่อทำให้สิ่งมีชีวิตชีวามีสิ่งที่จับได้ - บาร์โค้ดอาจถูกคว่ำ ในโลกแห่งความเป็นจริงมันจะถูกทิ้งไว้ที่เครื่องอ่านบาร์โค้ด (โปรแกรมของคุณ) เพื่อกำหนดทิศทางที่ถูกต้องโดยใช้ลำดับการเริ่ม / หยุด

ตัวอย่าง:

รับบาร์โค้ดต่อไปนี้:

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

เราสามารถเห็นได้ชัดเจนว่าคู่แรกและครั้งสุดท้ายของตัวเลขที่เป็นและไม่ได้0, 2 1, 0ซึ่งหมายความว่าบาร์โค้ดกลับหัว - เราต้องหมุนมัน 180 องศา (ไม่ใช่แค่พลิกแต่ละแท่ง) เพื่อให้ได้แนวที่ถูกต้อง:

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

ตอนนี้เราสามารถเริ่มถอดรหัสได้ เราแมปแต่ละแถบกับตัวเลขฐาน 4 ที่สอดคล้องกันโดยไม่สนใจลำดับการเริ่ม / หยุดเนื่องจากไม่เข้ารหัสข้อมูล

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

- - 2 1 0 3 0 2 3 - -

เราต่อสิ่งนี้เข้ากับจำนวนเต็มฐาน 4 2103023จากนั้นแปลงเป็นทศนิยมแทน9419ผลลัพธ์สุดท้าย


กฎระเบียบ

  • อินพุตจะเป็นบาร์โค้ด 4 สถานะที่ถูกต้องแสดงผลใน ASCII ตามที่กำหนดไว้ด้านบนพร้อมลำดับเริ่มต้น / หยุดที่อธิบายไว้
    • คุณอาจร้องขอช่องว่างที่ลากหรือถอดสายรวมถึงการขึ้นบรรทัดใหม่ - รูปแบบใดที่เหมาะกับการเล่นกอล์ฟของคุณ
    • อาจหรือไม่อยู่ในทิศทางที่ถูกต้อง - โปรแกรมของคุณต้องพิจารณาว่าจะอ่านกลับหัวโดยใช้ลำดับการเริ่ม / หยุด
    • มันจะไม่เข้ารหัสเลขศูนย์นำหน้าในจำนวนเต็มฐาน 4
  • คุณอาจรับอินพุตเป็นรายการของบรรทัดหรือสตริงที่มีบรรทัดใหม่
  • ผลลัพธ์ควรเป็นจำนวนเต็มในฐานจำนวนเต็มมาตรฐานของภาษาของคุณซึ่งเป็นข้อมูลที่เข้ารหัสด้วยบาร์โค้ด
  • เนื่องจากแสตมป์มีขนาดเล็กและสามารถใส่รหัสได้น้อยมากรหัสของคุณจะต้องสั้นที่สุดเท่าที่จะเป็นไปได้: นี่คือ - ดังนั้นโปรแกรมที่สั้นที่สุด (เป็นไบต์) ชนะ!

กรณีทดสอบ

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

= 4096 (พลิก)

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

= 7313145 (พลิก)

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

= 9419 (พลิก)

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

= 990 (ไม่พลิก)

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

= 12345 (ไม่พลิก)


-1 ชื่อเรื่องของทั้งสองโพสต์นั้นไม่เหมือนกัน ("P the P" กับ "M my M" เลือก 'the' หรือ 'my': p)
Rɪᴋᴇʀ

1
จะ "รายการของสาย" ใด ๆ ของ[String], [{#Char}], [{Char}], [[Char]]ที่ระบุว่า? Stringจะเทียบเท่ากับ{#Char}
Οurous

3
@Ouro สัญกรณ์คืออะไร? ฉันสงสัยอย่างยิ่งว่าคำตอบคือ "ใช่" เนื่องจากชนิดข้อมูลแตกต่างกันมากระหว่างภาษาดังนั้นความท้าทายในการเขียนโค้ดจึงยอมรับโดยทั่วไปว่า "สิ่งที่เทียบเท่ากับภาษาของคุณ" แต่ฉันไม่รู้ว่าการเป็นตัวแทนที่แตกต่างกันอย่างไร
IMSoP

1
อะไรต่อไป? ปล่อยอีเมลหรือไม่ ส่งโทรเลขหรือไม่ ดำเนินการโพสต์หรือไม่
Sanchises

1
@Ourous ใช่ประเภทข้อมูลยืดหยุ่นตามที่ IMSoP อธิบาย
FlipTack

คำตอบ:



5

Husk , 16 ไบต์

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

ลองออนไลน์!

อินพุตคือรายการของบรรทัด (ลิงก์ TIO ใช้สตริงหลายบรรทัดเพื่อความชัดเจน) บรรทัดต้องมีความยาวเท่ากันและจะต้องไม่มีช่องว่างต่อท้ายพิเศษ

คำอธิบาย

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

เรติน่า 71 ไบต์

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

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

ลองออนไลน์! ลิงก์มีกรณีทดสอบขนาดเล็ก ต้องใช้บรรทัดแรกและบรรทัดสุดท้ายเพื่อเว้นวรรคตามความยาวของเส้นกลาง คำอธิบาย:

(.).
$1

ลบช่องว่างที่ไม่จำเป็น

sO$^`^\|.*|.

ย้อนกลับอักขระในรหัส แต่ถ้าบาร์โค้ดเริ่มต้นด้วย a |ให้เลือกรหัสทั้งหมดหรือแยกเป็นอักขระ จากนั้นย้อนกลับ 0นี้พลิกรหัสถ้ามันเริ่มต้นด้วย

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

ลบลำดับการเริ่ม / หยุดและแถวกลาง (ซึ่งไม่มีประโยชน์กับเรา)

\|
 |
+`\| 
 ||||

แปลงช่องว่างและ|s จากฐาน 4 เป็นเอกภาพ

.*¶$
$&$&

เพิ่มเป็นสองเท่าของบรรทัดสุดท้าย

\|

แปลงเป็นทศนิยม


2

Java (OpenJDK 8) , 181 160 ไบต์

ไม่โทรมเกินไปสำหรับโซลูชัน java ฉันแน่ใจว่ามีการเพิ่มประสิทธิภาพที่ฉันสามารถทำได้ แต่ฉันได้รับการจ้องมองที่นี้มานานเกินไป

ลดจำนวนไบต์สักสองสามตัวด้วยการทำให้ลูปสั้นลงแทนที่จะใช้สตริงย่อย

แข็งแรงเล่นกอล์ฟ

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

ลองออนไลน์!

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

เพิ่งลองใช้รหัสของคุณ แต่มีบาร์โค้ดที่กลับด้านของตัวอย่าง "| | |" "| | | | | | | | | | | และให้ฉัน 1024 ตกลงฉันลาดเทรูปแบบนี้ แต่หนึ่งในตัวอย่าง แต่ลอง exmple ที่คุณมี แต่ไม่มีการย้อนกลับของมันบางทีฉันได้ป้อนข้อมูลที่ไม่ดี :)
Java Gonzar

@JavaGonzalezArribas ฉันลองตัวอย่างแรก (ไม่พลิก) และดูเหมือนว่าจะทำงานได้ดี เป็นไปได้ไหมที่คุณจะใส่ช่องว่างน้อยเกินไปในบรรทัดแรกของอินพุต
ลุคสตีเวนส์

นั่นอาจเป็นปัญหาคำตอบที่ดี :)
Java Gonzar

แนะนำl+~iแทนl-1-i
ceilingcat

2

Java 8 , 208 166 157 151 ไบต์

การลองใช้อาจจะดีกว่าลดการตรวจสอบที่ไม่จำเป็น 42 ครั้ง -9 การลบตัวแปร -6 ขอบคุณ Luke Stevens

อินพุตคือ 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
หากคุณใช้อาร์เรย์ของตัวอักษรมากกว่า Strings คุณสามารถตรวจสอบ | โดยใช้> 32 แทนที่จะ == "|" ซึ่งช่วยประหยัด 2 ไบต์สำหรับการใช้งานแต่ละครั้ง (รวม 6 รายการ) นอกจากนี้คุณยังสามารถลบวงเล็บเหลี่ยมออกเมื่อ a ประกาศแลมบ์ดาอีกสองไบต์
ลุคสตีเวนส์


1

Pip , 46 43 42 ไบต์

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

นำบรรทัดของบาร์โค้ดเป็นอาร์กิวเมนต์บรรทัดคำสั่งสามข้อ บรรทัดแรกและบรรทัดที่สามต้องเพิ่มความยาวของบรรทัดที่สองด้วยช่องว่างลองออนไลน์!

คำอธิบาย

ก่อนเตรียมบาง:

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

ตอนนี้ให้สังเกตว่าถ้าเราไม่สนใจแถวกลางและ|ถือเป็น 1 และ เป็น 0 แต่ละแท่งจะเป็นเลขฐานสองแบบ 2 บิต:

(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

Husk , 39 38 ไบต์

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

ใช้อินพุตเป็นรายการของสตริง: ลองออนไลน์หรือลองชุดทดสอบ!

คำอธิบาย

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


0

อ็อกเทฟ , 80 75 68 ไบต์

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

ลองออนไลน์!

อยากรู้อยากเห็นbi2deเป็นค่าเริ่มต้น MSB ด้านขวามากกว่าด้านซ้ายที่นำไปสู่อาการปวดหัวในขณะที่บางที่ผมทำนี้ ... ฉันคิดว่าฉันควรจะมีวิธีที่ดีที่สุดของการพลิกอาร์เรย์ก่อนที่จะจัดทำดัชนีมัน แต่มีมากหลายวิธีที่จะทำมัน ( อย่างใดอย่างหนึ่งในการจัดทำดัชนีแรกหรือมีflipud, fliplr, rot90, '(transpose) ที่จัดทำดัชนีสุดท้าย ... ) ใช้อาร์เรย์สี่เหลี่ยมที่มีช่องว่างและ|s (ต้องใช้ช่องว่างต่อท้าย)

@(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 ไบต์

ฉันไม่ใช่นักกอล์ฟที่มีประสบการณ์ - ฉันแน่ใจว่าสิ่งนี้สามารถปรับปรุงได้ แต่ฉันชอบความท้าทายนี้! ฉันสงสัยเกี่ยวกับเครื่องหมายเหล่านั้นเสมอ

ฟังก์ชั่นfใช้รายการของสตริงที่มีช่องว่างต่อท้ายที่จำเป็น เพิ่มบรรทัดใหม่ในโค้ดด้านล่างเพื่อความชัดเจน (ไม่รวมอยู่ในจำนวนไบต์)

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)

การใช้

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

เวอร์ชันที่ไม่ดีพร้อมคำอธิบาย

// 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.