ประติมากรรมแม่เหล็ก


14

นี้คือความต่อเนื่องหลวมของความท้าทายที่ก่อนหน้านี้ของฉันในกราฟก่อสร้าง

พื้นหลัง

ศิลปินคนประหลาดได้ว่าจ้างคุณให้ประเมินความสมบูรณ์ของโครงสร้างของประติมากรรมของเขา เขาสร้างผลงานศิลปะของเขาโดยนำแม่เหล็กรูปทรงลูกบาศก์จำนวนหนึ่งมาวางลงในกองใหญ่ทีละก้อน เพื่อวิเคราะห์วิธีการของเขาให้ดีขึ้นเราใช้โมเดลสองมิติต่อไปนี้ เราเริ่มต้นด้วยพื้นว่างและวางแม่เหล็ก#ที่พิกัดจำนวนเต็มใด ๆ พูดว่า0:

       |
       v
       #
===============
       0

หากแม่เหล็กตกอยู่ที่0หนึ่งมันจะจบลงที่ด้านบนของแม่เหล็กก่อนหน้า:

       |
       v
       #
       #
===============
       0

ตอนนี้ให้เราวางแม่เหล็กอีกหนึ่งที่0และอีกหนึ่งที่1:

        |
       #v
       ##
       #
===============
       0

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

      #   #
      ##|##
      # v #
      ### #
      #   #
===============
       0

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

อินพุต

รายการจำนวนเต็มแทนค่าพิกัดที่ศิลปินวางแม่เหล็กอ่านจากซ้ายไปขวา คุณอาจคิดว่าพิกัด-1024 <= i < 1024เป็นไปตามความยาวและความยาวของรายการมากที่สุด1024หากมีประโยชน์

เอาท์พุต

ช่องว่างแนวตั้งสูงสุดในประติมากรรมสุดท้าย ประติมากรรมที่ว่างเปล่ามีช่องว่าง-1และกรณีนี้จะรวมอยู่ด้วยเนื่องจากประติมากรของเราเป็นดาดา

กฎเพิ่มเติม

คุณอาจให้ฟังก์ชั่นหรือโปรแกรมเต็มรูปแบบ จำนวนไบต์ที่สั้นที่สุดชนะและช่องโหว่มาตรฐานไม่ได้รับอนุญาต ต้องการรหัสที่มีคำอธิบาย

กรณีทดสอบ

[] -> -1
[0,2,1] -> 0
[0,0,0,0,0,1,-1] -> 3
[0,0,0,0,0,1,1,1,2] -> 4
[1,1,2,2,2,2,2,2,1] -> 2
[1,1,2,2,2,2,2,2,1,0,1,0] -> 2
[1,2,1,2,1,2,1,2,2,2,2,1,0] -> 3
[-1,-1,-1,1,1,1,0] -> 1
[-1,-1,-1,-1,2,2,1,1,2,2,2,1,0] -> 2
[-2,-2,-2,-1,-1,-1,0,0,0,1,1,1,2,2,2,3,3,4,4,5,5,5,6] -> 6

คำตอบ:


1

Dyalog APL, 73 70 ตัวอักษร

{y←⍬⋄⌈/¯1,,¯1-2-/0,x⊢⌸{y,←⌈/(1+y/⍨0=⍵),Y⊃⍨2⊃⍒Y←1 1,∪y/⍨1=⍵}¨|x-¯1↓¨,\x←⍵}

{y←⍬⋄¯1⌈⌈/,¯1-2-/¯1,⍵⊢⌸{y,←⌈/(1+y/⍨0=⍵),⊃1↓{⍵[⍒⍵]}∪y/⍨1=⍵}¨|⍵-¯1↓¨,\⍵}

First statement:
       y←⍬  initialize semi-global variable y with an empty vector
Second statement, from right to left:
         ⍵  the vector of x coordinates
       ,\⍵  concat-scan: all prefixes of ⍵ of length 1, 2, ..., ≢⍵
   ¯1↓¨,\⍵  drop the last element of each prefix, lengths are 0, 1, ..., (≢⍵)-1
|⍵-¯1↓¨,\⍵  for each x: magnitudes of differences between x and its predecessors
 {...}¨...  execute the code in parens for each item of the argument
         ⍵  is now a single vector of differences from those described above
       1=⍵  boolean mask, where are our neighbouring xs?
    y/⍨1=⍵  select the ys corresponding to our neighbouring xs
   ∪y/⍨1=⍵  unique ys
   {⍵[⍒⍵]}  sort descending
       ⊃1↓  first of one-drop, i.e. get the second element if it exists, otherwise 0
       0=⍵  which previous xs are the same as our x?
  1+y/⍨0=⍵  select the corresponding ys and add 1 to them
        ⌈/  maximum of all the ys described so far
       y,←  append to the semi-global y
            the result from {} will be identical to y
  ⍵⊢⌸{...}  a matrix of ys, grouped in rows by x (which is now in ⍵) and zero-padded
       ¯1,  prepend ¯1 to the left of each row
       2-/  differences between consecutive horizontal elements, result is a matrix
       ¯1-  negative one minus each element of the matrix
         ,  ravel the matrix (linearize it to a vector)
        ⌈/  maximum; if the vector is empty, return ¯1.8e308, a very small number
     ¯1⌈⌈/  greater of ¯1 and the ⌈/  to avoid the very small number

หมายเหตุ: นี่ยาว 122 ไบต์ (ความท้าทายอยู่ในหน่วยไบต์) โดยถือว่าเป็น UTF-8
MtnViewMark


ฉันค่อนข้างเห็นอกเห็นใจ: ฉันมักจะได้รับความนิยมจากการใช้อักขระที่ไม่ใช่ ASCII ในสนามกอล์ฟของฉัน Haskell ตั้งแต่นั้นมาฉันก็ค่อนข้างจะระมัดระวังถ้า Q ระบุจำนวนด้วยอักขระหรือไบต์
MtnViewMark

@MtnViewMark การให้คะแนนตามไบต์ไม่ได้หมายถึงการให้คะแนนโดย UTF-8 ไบต์ การทำเช่นนี้สำหรับ APL เป็นการลงโทษเพราะเก่าเกินไปที่จะยอมรับว่า ASCII เป็นมาตรฐานที่สำคัญ APL ของชุดอักขระควรได้อย่างง่ายดายภายในเพจรหัสไบต์เดี่ยวและเพจรหัสที่มีอยู่ ดังนั้นการใช้เพจรหัสดังกล่าวเป็นการเข้ารหัสอักขระแต่ละตัวจึงเป็นไบต์ ในทางกลับกันถ้าคุณใช้อักขระที่ไม่ใช่ ASCII ใน Haskell คุณจะต้องใช้การเข้ารหัสซึ่งมีทั้งอักขระ ASCII และอักขระที่ไม่ใช่ ASCII ซึ่งโดยปกติจะเป็น UTF-8
Martin Ender

@ngn - ขณะนี้ได้อ่านโพสต์เมตาส่วนใหญ่ในตอนนี้ดูเหมือนว่าสิ่งต่าง ๆ เป็นอนิจจายังคงเต็มไปด้วยโคลน อย่างไรก็ตามอาจเป็นการดีที่สุดเมื่อความท้าทายได้คะแนนเป็นไบต์ให้คะแนน APL เป็นไบต์ แต่พูดถึงการเข้ารหัสที่ใช้
MtnViewMark

4

Haskell - 217 185 182 Bytes

import Data.List
r g n m|m==n=max(head(g m)+1)((reverse.(0:).nub.sort$g(m-1)++g(m+1))!!1):g m|1<3=g m
j x=(-1)-minimum(0:(map(foldl r(\_->[0])x)[-1024..1024]>>=(tail>>=zipWith(-))))

การใช้งาน:

j [1,2,1,2,1,2,1,2,2,2,2,1,0]

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


วิธีการที่ฉลาด! หวังว่าคุณคงไม่รังเกียจว่าฉันจะตีมันลงสักหน่อย
MtnViewMark

@MtnViewMark: ไม่เลย ฉันได้พบ 3 ไบต์ต่อไปเพื่อประหยัด: ไม่ไปกับตัวเลขที่ติดลบและใช้ flip-minimum
Nimi

ใน repo ของฉันคุณสามารถค้นหารหัสนี้42997-Magnetic.hsซึ่งรวมถึงสายรัดทดสอบสำหรับกรณีทดสอบและ visualizer ที่แสดงรูปปั้น
MtnViewMark

3

Javascript, 201 193

F=P=>{m=[];for(p of P){s=2;c=m[p]=m[p]||[];for(i=1e4;~i&&s;i--){if((m[p-1]||[])[i]||(m[p+1]||[])[i])s--;if(c[i-1]) s=0}c[++i]=1}g=-1;m.map(c=>{ d=0;for(i in c){g=i-d>g?i-d:g;d=++i} });return g}

F ([1,1,2,2,2,2,2,2,2,1]) === 2

หรือรุ่นที่อ่านได้

F=P=>{
  m=[];  // magnet positions
  for(p of P){ // every dropped magnet
    s=2; // initial speed
    c=m[p]=m[p]||[]; // column where magnet is dropping
    for(i=1e4;~i&&s;i--){ // continue until at floor or zero speed
      if((m[p-1]||[])[i]||(m[p+1]||[])[i])s--;  // magnet on either side, decrease speed
      if(c[i-1]) s=0; // magnet is directly below
    }
    c[++i]=1;
  }
  g=-1; // maximum gap
  m.map(c=>{ 
          d=0;for(i in c){g=i-d>g?i-d:g;d=++i;} 
       });
  return g;
};

2

Python 2.7, 327

from itertools import * 
s=input()
if s:m=min(s);l=[[] for _ in range(max(s)-m+3)]
for t in s:
    i=t-m+1;r=l[i];c=[x or y for x,y in izip_longest(l[i-1],l[i+1])][::-1][1:];j=len(c)-c.index(1)-1-len(r) if any(c) else 0;l[i]=r+[0]*j+[1]
print -1 if not s else max([len(list(q)) if b==0 else 0 for k in l for b,q in groupby(k)])

ก่อนเล่นกอล์ฟในพื้นที่สีขาวมันมีลักษณะดังนี้

from itertools import * 
s=input()
if s:
    m=min(s)
    l=[[] for _ in range(max(s)-m+3)]
for t in s:
    i=t-m+1;r=l[i]
    c=[x or y for x,y in izip_longest(l[i-1],l[i+1])][::-1][1:]
    j=len(c)-c.index(1)-1-len(r) if any(c) else 0
    l[i]=r+[0]*j+[1]
print -1 if not s else max([len(list(q)) if b==0 else 0 for k in l for b,q in groupby(k)])

นี่คือคำอธิบายของเส้นที่ซับซ้อนมากขึ้นส่วนใหญ่เพื่อผลประโยชน์ของฉันเอง

l=[[] for _ in range(max(s)-m+3)] 

สิ่งนี้สร้างอาร์เรย์ของรายการที่ว่างของความยาวสูงสุด (ลดลง) -min (ลดลง) +1 บวกกับตัวยึดตำแหน่งที่ด้านใดด้านหนึ่ง ฉันมักจะต้องการเขียน [[]] * K เพื่อสร้างอาร์เรย์ของรายการที่ว่างเปล่า แต่นั่นทำให้ K ตัวชี้ไปยังรายการที่ว่างเปล่าเดียวกัน

c=[x or y for x,y in izip_longest(l[i-1],l[i+1])][::-1][1:] 

ฟังก์ชั่น izip_longest จาก itertools นั้นเหมือน zip แต่จะเติมรายการที่สั้นกว่าด้วย None เพื่อซิปรายการด้วยกัน การแบ่ง [:: - 1] กลับรายการของ 0 และ 1 จากการเปรียบเทียบ "หรือ" รายการจะกลับรายการเพื่อใช้วิธีการดัชนีในบรรทัดถัดไปซึ่งค้นหาอินสแตนซ์แรกขององค์ประกอบ เนื่องจากองค์ประกอบสุดท้ายของคอลัมน์ที่ไม่ว่างจะต้องเป็น 1 นี่คือองค์ประกอบแรกในรายการที่กลับรายการและจะถูกละเว้นผ่านชิ้น [1:]

j=len(c)-c.index(1)-1-len(r) if any(c) else 0 
l[i]=r+[0]*j+[1]

ขั้นแรกให้คำนวณความแตกต่างระหว่างความยาวของคอลัมน์ i และตำแหน่งของ 1 ที่สองในคอลัมน์ที่อยู่ติดกัน หากความแตกต่างเป็นค่าบวกให้เพิ่มศูนย์จำนวนมากไปยังคอลัมน์ i ก่อนเพิ่ม 1 หมายเลขที่ไม่ใช่เชิงลบใด ๆ คูณด้วย [0] คือรายการว่าง

max([len(list(q)) if b==0 else 0 for k in l for b,q in groupby(k)])

ฟังก์ชั่น groupby จาก itertools แยกรายการเป็นองค์ประกอบขององค์ประกอบที่ต่อเนื่องกัน บรรทัดนี้ค้นหาความยาวสูงสุดของทุกองค์ประกอบของศูนย์ในคอลัมน์ทั้งหมด มันจำเป็นต้องใช้การเรียงลำดับคิวในรายการเนื่องจาก groupby ส่งคืนตัวกำเนิด (เช่นฟังก์ชัน itertools ทั้งหมด) ซึ่งโดยธรรมชาติไม่สนับสนุนเมธอด len


1

Java - 281 ไบต์

ตรงไปตรงมาสวย

ก่อนอื่นมันสร้างรูปปั้นในอาร์เรย์

จากนั้นจะพบช่องว่างที่ยิ่งใหญ่ที่สุด

int a(int[]b){
        int[][]d=new int[9999][9999];
        int g,r,t,y=-1;
        for(int c:b){
            c+=5000;
            g=0;
            for(r=9998;r>=0;r--){
                if(r==0||d[c][r-1]==1){d[c][r]=1;break;}
                if((d[c-1][r]==1||d[c+1][r]==1)&&++g==2){d[c][r]=1;break;}
            }
        }
        for(int[] k:d){
            t=0;
            for(int i:k){
                if(i==0)t++;
                else{if(t>y)y=t;t=0;}
            }
        }
        return y;
    }

ขนาดเล็ก -

int a(int[]b){int[][]d=new int[9999][9999];int g,r,t,y=-1;for(int c:b){c+=5000;g=0;for(r=9998;r>=0;r--){if(r==0||d[c][r-1]==1){d[c][r]=1;break;}if((d[c-1][r]==1||d[c+1][r]==1)&&++g==2){d[c][r]=1;break;}}}for(int[] k:d){t=0;for(int i:k){if(i==0)t++;else{if(t>y)y=t;t=0;}}}return y;}

คุณสามารถบันทึกไบต์โดยการเปลี่ยนครั้งแรกด้วย|| |นอกจากนี้การกลับมาyแทนที่จะพิมพ์จะช่วยประหยัด 9 ไบต์
Ypnypn

@Ypnypn ขอบคุณ! BTW คำสั่งแรกของคุณดูเหมือนจะโยนข้อยกเว้น ArrayIndexOutOfBounds (-1) (ฉันไม่ได้มีประสบการณ์มากมายกับผู้ประกอบการระดับบิต)
Stretch Maniac

จะได้รับประมาณ 1.5 ปี แต่คุณสามารถกอล์ฟมันบางมากขึ้น: ( 272 ไบต์int a(int[]b){int z=9999,d[][]=new int[z][z],g,r,t,y=-1;for(int c:b){c+=z/2;g=0;for(r=z;--r>-2;){if(r==0||d[c][r-1]==1){d[c][r]=1;break;}if((d[c-1][r]==1|d[c+1][r]==1)&&++g==2){d[c][r]=1;break;}}}for(int[]k:d){t=0;for(int i:k){if(i==0)t++;else{if(t>y)y=t;t=0;}}}return y;} ): สรุปการเปลี่ยนแปลง: z=9999มีการเพิ่มและใช้งาน intและการint[][]เริ่มต้นฟิลด์ได้ถูกรวมเข้าเป็นหนึ่งเดียว; วินาที||ถูกแทนที่ด้วย|; for(r=9998;r>=0;r--)ถูกเปลี่ยนเป็นfor(r=z;--r>-2;)
Kevin Cruijssen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.