คุณเห็นกี่ตึก


29

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

วิธีการทำงานของ Towers

วิธีการแก้ปริศนา Towers เป็นตารางละติน - เป็นn*nตารางซึ่งในทุกแถวและคอลัมน์ที่มีการเปลี่ยนแปลงของตัวเลขที่ผ่าน1 nตัวอย่างสำหรับn=5คือ:

4 3 5 2 1 
5 4 1 3 2 
1 5 2 4 3 
2 1 3 5 4 
3 2 4 1 5 

แต่ละแถวและคอลัมน์มีป้ายกำกับที่ปลายแต่ละด้านเช่น:

       2 3 1 4 5    
       v v v v v

 2 >   4 3 5 2 1   < 3
 1 >   5 4 1 3 2   < 4
 2 >   1 5 2 4 3   < 3
 3 >   2 1 3 5 4   < 2
 3 >   3 2 4 1 5   < 1 

       ^ ^ ^ ^ ^
       2 2 2 2 1

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

ภาพจาก Conceptis Puzzles

ตัวอย่างเช่นลองดูแถวแรก

 2 >   4 3 5 2 1   < 3

มันมีเงื่อนงำของ2จากซ้ายเพราะคุณสามารถดูและ4 บล็อกจากสายตาและทุกอย่างที่บล็อกอื่น จากทางด้านขวาคุณสามารถมองเห็นหอคอย, และ54353125

ข้อกำหนดของโปรแกรม

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้ในตารางของตัวเลขและเอาท์พุทหรือพิมพ์เบาะแสไปตามเข็มนาฬิกาจากด้านบนซ้าย

อินพุต

ละตินตารางด้วยn*n2<=n<=9

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

43521 54132 15243 21354 32415,

หรือสตริงที่ไม่มีช่องว่าง

คุณไม่ได้รับnเป็นส่วนหนึ่งของอินพุต

เอาท์พุต

ส่งคืนหรือพิมพ์ข้อมูลเริ่มต้นจากด้านบนซ้ายและไปตามเข็มนาฬิกา ดังนั้นก่อนที่เบาะแสด้านบนจะอ่านไปทางขวาจากนั้นเบาะแสด้านขวาจะอ่านลงด้านล่างและจากนั้นเบาะแสด้านล่างจะอ่านไปทางซ้ายส่วนด้านซ้ายจะอ่านขึ้นด้านบน

นี่จะเป็น23145 34321 12222 33212ตัวอย่างก่อนหน้า

       2 3 1 4 5    
       v v v v v

 2 >   4 3 5 2 1   < 3
 1 >   5 4 1 3 2   < 4
 2 >   1 5 2 4 3   < 3
 3 >   2 1 3 5 4   < 2
 3 >   3 2 4 1 5   < 1 

       ^ ^ ^ ^ ^
       2 2 2 2 1

เช่นเดียวกับอินพุตคุณสามารถใช้รายการสตริงหรือโครงสร้างที่เรียงลำดับ "กลุ่ม" สี่กลุ่มสามารถแยกออกได้หรือไม่ในโครงสร้างแบบซ้อนหรือแบบแบน แต่รูปแบบจะต้องเหมือนกันสำหรับแต่ละกลุ่ม

ตัวอย่างกรณีทดสอบ:

(รูปแบบอินพุต / เอาต์พุตของคุณไม่จำเป็นต้องเหมือนกัน)

>> [[1 2] [2 1]]

[2 1]
[1 2]
[2 1]
[1 2]

>> [[3 1 2] [2 3 1] [1 2 3]]

[1 2 2]
[2 2 1]
[1 2 3]
[3 2 1]

>> [[4 3 5 2 1] [5 4 1 3 2] [1 5 2 4 3] [2 1 3 5 4] [3 2 4 1 5]]

[2 3 1 4 5]
[3 4 3 2 1]
[1 2 2 2 2]
[3 3 2 1 2]

>> [[2 6 4 1 3 7 5 8 9] [7 2 9 6 8 3 1 4 5] [5 9 7 4 6 1 8 2 3] [6 1 8 5 7 2 9 3 4] [1 5 3 9 2 6 4 7 8] [3 7 5 2 4 8 6 9 1] [8 3 1 7 9 4 2 5 6] [9 4 2 8 1 5 3 6 7] [4 8 6 3 5 9 7 1 2]]

[4 2 2 3 3 3 3 2 1]
[1 3 3 2 2 2 2 3 3]
[4 3 2 1 2 3 3 2 2]
[3 1 2 4 3 3 2 2 5]

เพื่อความสะดวกของคุณนี่คือกรณีทดสอบเดียวกันในรูปแบบสตริงแบบแบน

>> 1221

21
12
21
12

>> 312231123

122
221
123
321

>> 4352154132152432135432415

23145
34321
12222
33212

>> 264137589729683145597461823618572934153926478375248691831794256942815367486359712

422333321
133222233
432123322
312433225

คำตอบ:


22

APL 19

≢¨∪/⌈\(⍉⍪⌽⍪⊖∘⌽∘⍉⍪⊖)

(golfed อีกเล็กน้อยหลังจากข้อเสนอแนะของ ngn ขอบคุณ)

คำอธิบาย:

(⍉⍪⌽⍪⊖∘⌽∘⍉⍪⊖)  rotates matrix 4 times appending results
⌈\ gets maximums for each row up to current column (example: 4 2 3 5 1 gives 4 4 4 5 5)
≢¨∪/ counts unique elements for each row

ลองใช้กับtryapl.org


1
คุณสามารถหลีกเลี่ยงการเพิ่ม 1:≢¨∪¨↓⌈\(⍉⍪⌽⍪⍉∘⌽∘⊖⍪⊖)
ngn

@ngn คุณพูดถูกขอบคุณ! ฉันยังใช้ char / ดังนั้น 1 ถ่านน้อยลง :)
Moris Zucca

ว้าว - นี่เป็นความท้าทายที่ APL ทำได้ดี
isaacg

12

Python 2, 115 ไบต์

def T(m):o=[];exec'm=zip(*m)[::-1]\nfor r in m[::-1]:\n n=k=0\n for x in r:k+=x>n;n=max(x,n)\n o+=[k]\n'*4;return o

มีรายการมากมายที่น่ากลัวที่เกิดขึ้นในนั้น

รับอินพุตเป็นรายการซ้อน (เช่นการโทรด้วยT([[4,3,5,2,1],[5,4,1,3,2],[1,5,2,4,3],[2,1,3,5,4],[3,2,4,1,5]])) เอาท์พุทเป็นรายการแบนเดียว

Ungolfed:

def T(m):
 o=[]
 for _ in [0]*4:
  m=zip(*m)[::-1]
  for r in m[::-1]:
   n=k=0
   for x in r:k+=x>n;n=max(x,n)
   o+=[k]
 return o

ทางเลือก 115:

def T(m):o=[];exec'm=zip(*m)[::-1];o+=[len(set([max(r[:i+1])for i in range(len(r))]))for r in m[::-1]];'*4;return o

ฉันไม่รู้ว่าทำไมสิ่งนี้ถึงใช้ได้กับ list comprehension แต่ chucks a NameErrorกับ comprehension set ...

ค่อนข้างยาวเกินไป แต่ถ้าใครสนใจ - ก็เป็นไปได้ที่จะเอาแลมบ์ดานี้ลงไป!

T=lambda m:[len({max(r[:i+1])for i in range(len(r))})for k in[1,2,3,4]for r in eval("zip(*"*k+"m"+")[::-1]"*k)[::-1]]

Pyth , 25 ไบต์

V4=Q_CQ~Yml{meS<dhkUd_Q)Y

พอร์ต Pyth ที่บังคับใช้

รายการ Input ผ่าน STDIN, [[4, 3, 5, 2, 1], [5, 4, 1, 3, 2], [1, 5, 2, 4, 3], [2, 1, 3, 5, 4], [3, 2, 4, 1, 5]]เช่น

ลองใช้ออนไลน์ ... เป็นสิ่งที่ฉันจะพูด แต่น่าเสียดายด้วยเหตุผลด้านความปลอดภัยล่ามออนไลน์ไม่อนุญาตให้ใช้ Eval ในวงเล็บซ้อนกัน ลองรหัสวิธีแก้ปัญหาแทนและการป้อนข้อมูลเป็นรายการบี้เช่นJcQ5V4=J_CJ~Yml{meS<dhkUd_J)Y[4, 3, 5, 2, 1, 5, 4, 1, 3, 2, 1, 5, 2, 4, 3, 2, 1, 3, 5, 4, 3, 2, 4, 1, 5]

(ขอบคุณ @isaacg ผู้ช่วยตีกอล์ฟออกไปไม่กี่ไบต์)


คู่ของ Pyth Golfs: <และ>เป็นหนึ่งในผู้ประกอบการด้านชิ้นจึงสามารถจะกลายเป็น:d0hk ในปัจจัยการผลิตคอลเลกชันเป็นเช่นเดียวกับเพื่อให้สามารถจะกลายเป็น <dhkUUlUldUd
isaacg

@isaacg ขอบคุณ - ดูเหมือนว่า Pyth ของฉันต้องการการอัปเดต เอกสารที่ฉันมีล้าสมัยแล้ว
Sp3000

11

CJam, 29 27 ไบต์

q~{z_{[{1$e>}*]_&,}%pW%}4*;

ใส่เหมือน

[[4 3 5 2 1] [5 4 1 3 2] [1 5 2 4 3] [2 1 3 5 4] [3 2 4 1 5]]

ผลผลิตเช่น

[2 3 1 4 5]
[3 4 3 2 1]
[1 2 2 2 2]
[3 3 2 1 2]

มันทำงานอย่างไร

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

q~                          "Read and evaluate the input.";
  {                    }4*  "Four times...";
   z                        "Transpose the grid.";
    _                       "Duplicate.";
     {            }%        "Map this block onto each row.";
      [       ]             "Collect into an array.";
       {    }*              "Fold this block onto the row.";
        1$                  "Copy the second-to-topmost element.":
          e>                "Take the maximum of the top two stack elements.";
                            "This fold replaces each element in the row by the
                             maximum of the numbers up to that element. So e.g.
                             [2 1 3 5 4] becomes [2 2 3 5 5].";
               _&,          "Count unique elements. This is how many towers you see.";
                    p       "Print array of results.";
                     W%     "Reverse the rows for the next run. Together with the transpose at
                             the start this rotates the grid counter-clockwise.";
                          ; "Get rid of the grid so that it isn't printed at the end.";




4

Mathematica, 230,120,116,113 110 ไบต์

f=(t=Table;a=#;s=Length@a;t[v=t[c=m=0;t[h=a[[y,x]];If[h>m,c++;m=h],{y,s}];c,{x,s}];a=Thread@Reverse@a;v,{4}])&

การใช้งาน:

f[{
  {4, 3, 5, 2, 1},
  {5, 4, 1, 3, 2},
  {1, 5, 2, 4, 3},
  {2, 1, 3, 5, 4},
  {3, 2, 4, 1, 5}
}]

{{2, 3, 1, 4, 5}, {3, 4, 3, 2, 1}, {1, 2, 2, 2, 2}, {3, 3, 2, 1, 2}}

a[[y]][[x]]a[[y,x]]เป็น และการใช้อาจจะสั้นกว่าArray Table
Martin Ender

4

JavaScript, 335 264 256 213

T=I=>((n,O)=>(S=i=>i--&&O.push([])+S(i)+(R=(j,a,x)=>j--&&R(j,0,0)+(C=k=>k--&&((!(a>>(b=I[(F=[f=>n-k-1,f=>j,f=>k,f=>n-j-1])[i]()][F[i+1&3]()])))&&++x+(a=1<<b))+C(k))(n)+O[i].push(x))(n,0,0))(4)&&O)(I.length,[],[])

ประเมินในคอนโซล JavaScript ของเบราว์เซอร์ (ฉันใช้ Firefox 34.0 ดูเหมือนจะไม่ทำงานใน Chrome 39 ??) ทดสอบด้วย:

JSON.stringify(T([[4, 3, 5, 2, 1], [5, 4, 1, 3, 2], [1, 5, 2, 4, 3], [2, 1, 3, 5, 4], [3, 2, 4, 1, 5]]));

นี่คืออวตารของโค้ดที่ไม่ได้รับการอวตารในปัจจุบัน - มันยากที่จะติดตาม:

function countVisibleTowers(input) {
  return ((n, out) =>
      (sideRecurse = i =>
          i-- &&
          out.push([]) +
          sideRecurse(i) +
          (rowRecurse = (j, a, x) =>
              j-- &&
              rowRecurse(j, 0, 0) +
              (columnRecurse = k =>
                  k-- &&
                  ((!(a >> (b = input[
                                        (offsetFtn = [
                                            f => n - k - 1,   // col negative
                                            f => j,           // row positive
                                            f => k,           // col positive
                                            f => n - j - 1    // row negative
                                        ])[i]()
                                     ]
                                     [
                                        offsetFtn[i + 1 & 3]()
                                     ]))) &&
                  ++x +
                  (a = 1 << b)) +
                  columnRecurse(k)
              )(n) +
              out[i].push(x)
          )(n, 0, 0)
      )(4) && out
  )(input.length, [], [])
}

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

ฉันหวังว่าจะมีวิธีการมากมายในการปรับปรุงสิ่งนี้บางทีอาจจะไม่คำนวณการออฟเซ็ต แต่ควรใช้ overflow / modulo ในอาร์เรย์อินพุต 1D บ้าง และอาจรวมลูปของฉันรับฟังก์ชั่นเพิ่มเติมซ้ำซ้อน

ข้อเสนอแนะใด ๆ ที่จะได้รับการชื่นชม!

อัปเดต # 1 : ความคืบหน้าเรามีเทคโนโลยี! ฉันสามารถกำจัดออฟเซ็ตที่คำนวณล่วงหน้าและทำให้พวกมันสอดคล้องกับตัวดำเนินการแบบไตรภาคด์ด้วยกัน ยังสามารถกำจัดคำสั่ง if ของฉันและแปลงลูปเป็น whiles ได้

อัปเดต # 2 : นี่ค่อนข้างน่าผิดหวัง ไม่มีปาร์ตี้พิซซ่าสำหรับฉัน ฉันคิดว่าการใช้งานได้และการใช้การเรียกซ้ำจะช่วยกำจัดไบต์จำนวนมาก แต่ความพยายามครั้งแรกของฉันก็จบลงด้วยการมีขนาดใหญ่ขึ้นถึง 100 ตัวอักษร! ด้วยความสิ้นหวังฉันได้ลองใช้ฟังก์ชั่นลูกศรไขมัน ES6 เพื่อกำจัดมันลง จากนั้นฉันก็ไปแทนที่ตัวดำเนินการบูลีนด้วยเลขคณิตและลบ parens, semi-colons และช่องว่างออกเท่าที่ฉันจะทำได้ ฉันยังเลิกประกาศ vars ของฉันและทำให้เนมสเปซส่วนกลางสกปรกด้วยสัญลักษณ์ท้องถิ่นของฉัน สกปรกสกปรก หลังจากความพยายามทั้งหมดนั้นฉันได้คะแนน Update # 1 ของฉันด้วยตัวละคร 8 ตัวเหลือ 256 ตัว Blargh!

ถ้าฉันใช้การเพิ่มประสิทธิภาพที่โหดเหี้ยมและเล่ห์เหลี่ยม ES6 กับฟังก์ชั่นอัปเดต # 1 ของฉันฉันจะได้คะแนนนี้เป็นไมล์ ฉันอาจทำการอัปเดต # 3 เพียงเพื่อดูว่ามีลักษณะอย่างไร

อัปเดต # 3 : เปิดใช้งานวิธีเรียกซ้ำแบบลูกศรไขมันที่มีชีวิตอยู่มากมายฉันแค่ต้องทำงานกับอินพุต 2 มิติโดยตรงแทนที่จะแบนราบและดีกว่าเกี่ยวกับการใช้ประโยชน์จากขอบเขตการปิด ฉันเขียนการคำนวณ offset ของ array ภายในอีกสองครั้งและได้คะแนนเท่ากันดังนั้นวิธีนี้อาจใกล้เคียงกับการขุดออกไปแล้ว!


3

Java เท่านั้น 352 350 325 ไบต์ ...

class S{public static void main(String[]a){int n=a.length,i=0,j,k,b,c;int[][]d=new int[n][n];for(;i<n;i++)for(j=0;j<n;)d[i][j]=a[i].charAt(j++);for(i=0;i<4;i++){int[][]e=new int[n][n];for(k=0;k<n;k++)for(j=0;j<n;)e[n-j-1][k]=d[k][j++];d=e;for(j=n;j-->(k=c=b=0);System.out.print(c))for(;k<n;k++)b=d[j][k]>b?d[j][k]+0*c++:b;}}}

ใส่เหมือน 43521 54132 15243 21354 32415

ผลลัพธ์เช่น: 23145343211222233212

เยื้อง:

class S{
    public static void main(String[]a){
        int n=a.length,i=0,j,k,b,c;
        int[][]d=new int[n][n];
        for(;i<n;i++)
            for(j=0;j<n;)d[i][j]=a[i].charAt(j++);
        for(i=0;i<4;i++){
            int[][]e=new int[n][n];
            for(k=0;k<n;k++)
                for(j=0;j<n;)e[n-j-1][k]=d[k][j++];
            d=e;
            for(j=n;j-->(k=c=b=0);System.out.print(c))
                for(;k<n;k++)b=d[j][k]>b?d[j][k]+0*c++:b;
        }
    }
}

เคล็ดลับใด ๆ ที่จะได้รับการชื่นชมอย่างมาก!


คุณมีช่องว่างพิเศษระหว่างforลูป
ภูมิใจ haskeller

@proud haskeller ขอขอบคุณ!
TheNumberOne

คุณอาจจะเปลี่ยนfor(;i<n;i++)ไปfor(;++i<n;)และเริ่มต้นที่จะi -1จากนั้นใช้สิ่งเหล่านี้เพื่อทำสิ่งต่างๆ คุณสามารถทำเช่นเดียวกันกับวงอื่น ๆ ได้เช่นกัน
ภูมิใจ haskeller

คุณสามารถใช้a[i].charAt(j)-'0'แทนที่จะแจงอย่างชัดเจน สิ่งนี้ยังไม่ต้องการตัวคั่นในอินพุต (ทำให้รูปแบบอินพุตเหมือนรูปแบบเอาต์พุต)
anatolyg

นอกจากนี้ในfor-loops คุณสามารถทำสิ่งที่มีประโยชน์ในส่วน "การเพิ่มลูป" เสมอ สิ่งนี้ทำให้รหัสคลุมเครือมากขึ้นและลบอัฒภาคหนึ่งรายการ ตัวอย่างเช่นfor(j=n;j-->0;System.out.print(c)).
anatolyg

1

Python 2 - 204 ไบต์

def f(l):n=len(l);k=[l[c]for c in range(n)if l[c]>([0]+list(l))[c]];return f(k)if k!=l else n
r=lambda m:(l[::-1]for l in m)
m=input();z=zip(*m);n=0
for t in z,r(m),r(z),m:print map(f,t)[::1-(n>1)*2];n+=1

นี่อาจเป็นสนามกอล์ฟที่น่าสงสารจริงๆ ฉันคิดว่าปัญหาน่าสนใจดังนั้นฉันตัดสินใจที่จะแก้ไขปัญหาโดยไม่ได้มองหาวิธีการแก้ปัญหาของคนอื่น ขณะที่ฉันพิมพ์ประโยคนี้ฉันยังไม่ได้ดูคำตอบของคำถามนี้ ฉันจะไม่แปลกใจถ้ามีคนทำโปรแกรม Python ที่สั้นกว่านี้แล้ว)

ตัวอย่าง I / O

$ ./towers.py <<< '[[4,3,5,2,1],[5,4,1,3,2],[1,5,2,4,3],[2,1,3,5,4],[3,2,4,1,5]]'
[2, 3, 1, 4, 5]
[3, 4, 3, 2, 1]
[1, 2, 2, 2, 2]
[3, 3, 2, 1, 2]

คุณอาจเลือกที่จะรวมช่องว่างในอินพุต สวยมากทุกที่โดยสุจริต ตราบใดที่คุณสามารถทำได้eval()มันจะทำงาน

คำอธิบาย

ส่วนที่น่าสนใจของโปรแกรมนี้คือบรรทัดแรก มันกำหนดฟังก์ชั่นf(l)ที่จะบอกคุณว่ามีกี่เสาที่สามารถมองเห็นได้ในแถวและส่วนที่เหลือของโปรแกรมก็ใช้ฟังก์ชันนั้นกับทุกตำแหน่งที่เป็นไปได้

เรียกว่าเมื่อพบความยาวของและบันทึกในตัวแปรl nจากนั้นมันจะสร้างตัวแปรใหม่kด้วยความเข้าใจรายการที่น่ากลัวนี้:

[l[c]for c in range(n)if l[c]>([0]+list(l))[c]]

มันไม่ได้เลวร้ายเกินไปเมื่อคุณทำลายมันลง เนื่องจากn==len(l)ทุกอย่างก่อนที่จะมีเพียงแค่แสดงให้เห็นถึงif lอย่างไรก็ตามการใช้ifเราสามารถลบองค์ประกอบบางอย่างออกจากรายการ เราสร้างรายการด้วย([0]+list(l))ซึ่งเป็นเพียง " lกับการ0เพิ่มไปยังจุดเริ่มต้น" (เพิกเฉยต่อการเรียกไปlist()นั่นเป็นเพียงเพราะบางครั้งlเป็นเครื่องกำเนิดไฟฟ้าและเราจำเป็นต้องตรวจสอบให้แน่ใจว่าเป็นรายการจริงที่นี่) จะใส่เพียงเข้าไปในรายการสุดท้ายถ้ามันมากกว่าl[c] ([0]+list(l))[c]สิ่งนี้ทำสองสิ่ง:

  • เนื่องจากมีองค์ประกอบใหม่ที่จุดเริ่มต้นของรายการดัชนีของแต่ละคนจะกลายเป็นl[c] c+1เรากำลังเปรียบเทียบแต่ละองค์ประกอบกับองค์ประกอบทางด้านซ้ายอย่างมีประสิทธิภาพ ถ้ายิ่งใหญ่กว่านั้นก็จะมองเห็นได้ มิฉะนั้นจะถูกซ่อนและลบออกจากรายการ
  • หอคอยแรกสามารถมองเห็นได้เสมอเพราะไม่มีสิ่งใดที่สามารถปิดกั้นได้ เนื่องจากเราใส่ 0 ไว้ที่จุดเริ่มต้นหอคอยแรกจึงใหญ่กว่าเสมอ (ถ้าเราไม่ได้ทำเช่นนี้[0]+เป็นเรื่องไร้สาระและเพียงแค่เปรียบเทียบl[c]เพื่อl[c-1], Python จะเปรียบเทียบหอแรกที่จะเป็นคนสุดท้าย (คุณสามารถจัดทำดัชนีลงในรายการจากปลายมี-1, -2ฯลฯ ) ดังนั้นหากหอที่ผ่านมาก็สูงกว่า ก่อนอื่นเราจะได้ผลลัพธ์ที่ผิด

เมื่อทุกคนพูดและทำlมีจำนวนหอคอยและkมีหอคอยที่ไม่สั้นกว่าเพื่อนบ้านทันทีทางด้านซ้าย ถ้าไม่มีพวกเขา (เช่นf([1,2,3,4,5])) l == kแล้ว เรารู้ว่าไม่มีสิ่งที่ต้องทำและส่งคืนn(ความยาวของรายการ) หากl != kนั่นหมายความว่ามีหอคอยอย่างน้อยหนึ่งแห่งที่ถูกลบออกไปในเวลานี้และอาจมีสิ่งที่ต้องทำอีกมาก f(k)ดังนั้นเรากลับมา พระเจ้าฉันรักการสอบถามซ้ำ ที่น่าสนใจfจะเกิดขึ้นซ้ำอีกระดับหนึ่งลึกกว่า "จำเป็น" อย่างเคร่งครัด เมื่อรายการที่จะถูกส่งคืนถูกสร้างขึ้นฟังก์ชั่นจะไม่มีทางรู้ว่าในตอนแรก

เมื่อฉันเริ่มเขียนคำอธิบายนี้โปรแกรมนี้มีความยาว 223 ไบต์ ในขณะที่อธิบายสิ่งต่าง ๆ ที่ฉันรู้ว่ามีวิธีการบันทึกตัวละครดังนั้นฉันดีใจที่ฉันพิมพ์มันขึ้นมา! ตัวอย่างที่ยิ่งใหญ่ที่สุดคือf(l)ตอนแรกที่มีการนำวงวนไม่สิ้นสุดที่แยกออกจากเมื่อการคำนวณเสร็จสิ้นก่อนที่ฉันจะรู้ว่าการสอบถามซ้ำจะได้ผล มันแสดงให้เห็นว่าทางออกแรกที่คุณคิดว่าไม่ดีที่สุดเสมอไป :)


0

Matlab, (123) (119)

function r=m(h);p=[h rot90(h) rot90(h,2) rot90(h,3)];for i=2:size(p) p(i,:)=max(p(i,:),p(i-1,:));end;r=sum(diff(p)>0)+1

ใช้แบบนี้:

m([
 4     3     5     2     1;
 5     4     1     3     2;
 1     5     2     4     3;
 2     1     3     5     4;
 3     2     4     1     5])

 [2 3 1 4 5 3 4 3 2 1 1 2 2 2 2 3 3 2 1 2]

C # ลงไปที่ 354 ...

วิธีการที่แตกต่างจาก TheBestOne ที่ใช้

using System;
using System.Linq;

class A
{
    static void Main(string[] h)
    {
        int m = (int)Math.Sqrt(h[0].Length),k=0;
        var x = h[0].Select(c => c - 48);
        var s = Enumerable.Range(0, m);
        for (; k < 4; k++)
        {
            (k%2 == 0 ? s : s.Reverse())
                .Select(j =>
                        (k > 0 && k < 3 ? x.Reverse() : x).Where((c, i) => (k % 2 == 0 ? i % m : i / m) == j)
                                                          .Aggregate(0, (p, c) =>
                                                                        c > p%10
                                                                            ? c + 10 + p/10*10
                                                                            : p, c => c/10))
                .ToList()
                .ForEach(Console.Write);
        }
    }
}

ดูเหมือนว่าคุณจะวางคอมพิวเตอร์\nแทนการขึ้นบรรทัดใหม่ฉันเพิ่งแทนที่มันด้วยช่องว่างดังนั้นโค้ดจะทำงานทันทีเมื่อมีคนคัดลอก และฉันอนุญาตให้ตัวเองลบล่าสุดend(ที่ปิดฟังก์ชั่นซึ่งไม่จำเป็น) ซึ่งช่วยเพิ่มตัวละครอีก 4 ตัวฉันหวังว่ามันจะโอเค =)
ข้อบกพร่อง

ดูเหมือนว่า matlab ไม่มีความสุขกับช่องว่างดังนั้นฉันจึงเปลี่ยนเป็นเครื่องหมายอัฒภาค จุดที่ดีเกี่ยวกับการติดตามendแม้ว่า, ขอบคุณ :)
zabalajka
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.