ตำแหน่งหน้าอก Minecraft


20

วิดีโอเกมMinecraftนั้นเกี่ยวกับการวางและลบบล็อกประเภทต่าง ๆ ในโครงร่างจำนวนเต็ม 3 มิติที่ประกอบขึ้นเป็นโลกเสมือนจริง จุดขัดแตะแต่ละจุดสามารถมีหนึ่งบล็อกแน่นอนหรือว่างเปล่า ( บล็อก " อากาศ " อย่างเป็นทางการ) ในความท้าทายนี้เราจะได้รับการที่เกี่ยวข้องกับระนาบเดียวแนว 2D ของโลก 3 มิติและประเภทหนึ่งของบล็อก: ทรวงอก

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

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

ตัวอย่างเช่นสมมติว่า.เป็นพื้นที่ว่างเปล่าและCเป็นหน้าอก: (ตัวเลขนี้เป็นพื้นที่ว่างเปล่าและเพื่อจุดประสงค์ในการระบุตัวตน)

.......C..
.1.C2.C3..
........5C
.CC4..CC..
..........
  • สามารถวางหีบในจุดที่ 1 ได้เนื่องจากเพื่อนบ้านทั้ง 4 นั้นว่างเปล่า
  • หน้าอกสามารถวางในจุดที่ 2 เพราะหน้าอกที่อยู่ใกล้เคียงไม่ได้เป็นส่วนหนึ่งของหน้าอกคู่
  • ไม่สามารถใส่หน้าอกในจุดที่ 3 ได้เนื่องจากจะมีความกำกวมว่าหน้าอกสองชั้นก่อตัวอย่างไร
  • ไม่สามารถวางหน้าอกในจุดที่ 4 เนื่องจากหน้าอกที่อยู่ใกล้เคียงเป็นส่วนหนึ่งของหน้าอกคู่แล้ว
  • สามารถวางหน้าอกในจุดที่ 5 หน้าอกคู่ที่อยู่ติดกันในแนวทแยงมุมจะไม่ส่งผลกระทบอะไรเลย

สมมติว่าพื้นที่ที่อยู่นอกกริดนั้นว่างเปล่าการเปลี่ยนทุกอย่าง.ในกริดเป็น a *ถ้าหน้าอกสามารถวางไว้ที่นั่นจะส่งผลให้เกิดสิ่งนี้:

******.C**
***C**C.**
*..***..*C
.CC.*.CC.*
*..***..**

ไม่*สามารถเว้นวรรคทั้งหมดได้พร้อมกับหีบในเวลาเดียวกัน แต่ถ้าคุณมีหน้าอกเพียงอันเดียวก็สามารถวางไว้ในหีบใดก็ได้

ท้าทาย

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้ใน a .และCกริดและเปลี่ยนทุกอย่าง.เป็น a *หากวางหน้าอกไว้ที่นั่นพิมพ์หรือคืนกริดที่ได้

  • อินพุตอาจมาจาก stdin หรือไฟล์หรือเป็นอาร์กิวเมนต์สตริงไปยังฟังก์ชัน

  • คุณอาจสันนิษฐานว่าอินพุตนั้นมีรูปแบบที่ดี - เช่นกริดของข้อความอย่างสมบูรณ์แบบสี่เหลี่ยมอย่างน้อย 1 ตัวกว้างและสูงเท่านั้นที่มี.และCคุณอาจจะคิดว่ามีการขึ้นบรรทัดใหม่หลังจากแถวสุดท้าย (และอาจมีหนึ่งในเอาต์พุต )

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

  • หากต้องการคุณอาจจะใช้ใด ๆ ที่แตกต่างกันสามASCII พิมพ์ตัวอักษรในสถานที่ของ., และC *คุณไม่สามารถใช้งานอย่างอื่นแทนการขึ้นบรรทัดใหม่

  • ทรวงอกทั้งหมดเป็นทรวงอกปกติ ไม่หีบติดกับดักหรือหีบพลิก

เกณฑ์การให้คะแนน

การส่งที่มีจำนวนไบต์น้อยที่สุดจะเป็นผู้ชนะ

สำหรับความท้าทายที่เกี่ยวข้อง Minecraft ที่ท้าทายความสามารถมากขึ้นอีกนิดลองNether พอร์ทัลการตรวจสอบ


5
จากมุมมองของ Minecrafting ฉันพบว่าเกมนี้น่ารำคาญ สิ่งที่ดีมีทรวงอกที่ติดอยู่: P
Sp3000

เมื่อนำอินพุตกริดจาก stdin หรืออาร์กิวเมนต์สตริงเดียวเป็นที่ยอมรับหรือไม่ที่จะใช้มิติกริดเป็นอินพุตเพิ่มเติม? หรือจะต้องมีการอนุมานจากการขึ้นบรรทัดใหม่และความยาวสตริง?
Level River St

@steveverrill จะต้องมีการอนุมาน
งานอดิเรกของ Calvin

เพิ่งออกมาจากความอยากรู้ทำไมทุกคำตอบรวมถึงตัวฉันเองมีหนึ่ง downvote? ฉันสามารถสันนิษฐานได้ว่ามันเป็นคนคนเดียวกันพวกเขาจะอธิบายหรือไม่?
เลเวลริเวอร์เซนต์

สำหรับความท้าทายพิเศษผู้เขียนสามารถเขียนโปรแกรมเพื่อค้นหาตำแหน่งที่เหมาะสมที่สุดสำหรับทรวงอก นั่นคือค้นหาการกำหนดค่าที่อนุญาตให้มีจำนวนสูงสุดของหีบเพิ่มเติมที่จะวางโดยไม่ทำลายกฎแม้ระหว่างหีบใหม่
AJMansfield

คำตอบ:


11

CJam, 82 76 66 62 58 54 ไบต์

qN/::~4{[8_]f/[9_]f*z{[{1$8-g)+}*]W%}%}*{_8<\2<8?}f%N*

รูปแบบอินพุตคาดหวัง0สำหรับเซลล์อากาศและ8เซลล์อก เอาท์พุทมี1สำหรับเซลล์ทั้งหมดที่สามารถวางกับหน้าอก

UPDATE : แก้ไขข้อบกพร่อง เพิ่มขึ้น 3 ไบต์ :( golfed เพิ่มเติม :) บันทึกได้ 4 ไบต์ด้วย @ Sp3000

อินพุตตัวอย่าง:

0000000800
0008008000
0000000008
0880008808
0000000000

เอาท์พุท:

1111110811
1110018010
1008800108
0880088008
1008800110

ฉันคิดว่าตอนนี้ฉันเล่นกอล์ฟเสร็จแล้ว ...

คำอธิบาย

qN/::~                   "This part converts the input into array of integer array";
qN/                      "Split input on new line";
   ::~                   "Parse each character in each row as integer";

4{[8_]f/[9_]f*z{[{1$8-g)+}*]W%}%}*

4{   ...z{       W%}%}*  "Run the logic 4 times, first, columns in correct order, then,";
                         "columns in reverse order, then for rows";
  [8_]f/[9_]f*           "Convert adjacent chests represented by two 8 into two 9";
                         "This happens for all the rows in the columns iterations and";
                         "for all the columns in the rows iterations";
  {               }%     "For each row/column";
   [{        }*]         "Reduce and wrap it back in the array";
     :I8-                "Store the second number in I, remove 8 from it";
         g               "Do signum. Now we have -1 for < 8 number, 0 for 8 and 1 for > 8";
          )+I            "Increment to get 0, 1 & 2. Add it to first number and put I back";

{_8<\2<8?}f%N*           "This part converts the output from previous iterations";
                         "to 3 character based final output and prints it";
{        }f%             "Map each row using the code block";
 _8<   8?                "If the value is greater than 7, make it 8, else:";
    \2<                  "If the value is greater than 1, make it 0, else 1";
            N*           "Join the arrays using new line";

ลองออนไลน์ได้ที่นี่


8

.NET Regex ( Retina ), 434 416 310 + 1 = 311 ไบต์

หลังจากความท้าทายครั้งสุดท้ายที่ฉันตอบใน regex (ความท้าทาย Nether Portal ที่เชื่อมโยงกับความท้าทายนี้) ในที่สุดฉันก็เริ่มเขียนเครื่องมือบรรทัดคำสั่งซึ่งทำหน้าที่เป็นล่ามสำหรับนิพจน์ปกติสไตล์ NET ดังนั้นฉันจึงสามารถตอบคำถามได้ ด้วย regex โดยไม่ถูกท้าทายว่าพวกเขาไม่ใช่ภาษาแบบสแตนด์อะโลน ฉันตั้งชื่อมันว่า Retina

ตอนนี้ความท้าทายนี้ไม่ได้ให้ยืม Regex ได้ดี แต่ฉันต้องใช้ Retina ตอนนี้ ;) (บวก Sp3000 ท้าให้ฉันทำเช่นนั้นในการแชท) ดังนั้นนี่คือ:

ไฟล์ Regex

m`(?<=(?=.(.)*).*)(?<=((?<=(?<2>C|C(?(1)!)(\n|(?<-1>.))*)?)C(?=(?<2>C|(\n|(?<-1>.))*(?(1)!)C)?)(()(?(6)!)|(?<=^(?(7)!)(?<-7>.)*C).*\n(.)*()(?(8)!)))?){2}_(?=(?<2>((?(10)!)()|(?(11)!)()(.)*\n.*(?=C(?<-12>.)*(?(12)!)$))(?<=(?<2>C|C(?(1)!)(\n|(?<-1>.))*)?)C(?=(?<2>C|(\n|(?<-1>.))*(?(1)!)C)?))?){2}(?<-2>)?(?(2)!)

ไฟล์ทดแทน

*

ไฟล์ regex ส่วนใหญ่เป็นเพียง regex ยกเว้นว่า`ให้คุณใส่ตัวเลือกบางอย่างในไฟล์ในกรณีนี้ก็คือโหมดหลายบรรทัด เมื่อได้รับไฟล์สองไฟล์ Retina จะถือว่าโหมดการแทนที่ทั้งหมดโดยอัตโนมัติ ทั้งสองไฟล์กำหนดโปรแกรมที่อ่านอินพุตจาก STDIN และพิมพ์ผลลัพธ์ไปที่ STDOUT

นอกจากนี้คุณยังสามารถทดสอบบนRegexHeroและRegexStorm regex ทำงานทั้งที่มีและไม่มีต่อท้ายบรรทัดใหม่และการใช้งานในสถานที่ของ_ .(เห็นได้ชัดว่า RegexStorm บางครั้งมีปัญหาหากไม่มีการขึ้นบรรทัดใหม่ แต่ RegexHero ดูเหมือนว่าจะจัดการกับทั้งสองกรณีปรับ)

มีการทำซ้ำจำนวนมากที่น่ากลัวใน regex และฉันมีความคิดสองสามอย่างที่จะทำให้สั้นลงอย่างมีนัยสำคัญ ... ฉันจะลองอีกครั้งในภายหลังแล้วเพิ่มคำอธิบาย ในระหว่างนี้โปรดแจ้งให้เราทราบหากคุณสามารถค้นหาอินพุตใด ๆ ที่ให้ผลลัพธ์ที่ผิด


7

J, 75 73 ไบต์

((,.|.)0 _1 0 1)(+:@](LF,@:,.~'*.C'{~>.)(2=f)+.[f]*f=.[:+/|.!.0)'C'&=;._2

ใช้รูปแบบในคำถามโดยใช้./ */ Cสำหรับช่องว่าง / ช่องว่างที่ใช้ได้ / หีบตามลำดับ

แก้ไข: แก้ไขข้อผิดพลาดเล็ก ๆ (ฉันใช้ torus โดยไม่ได้ตั้งใจแทนที่จะจัดการกับสภาพแวดล้อมโดยรอบให้เป็นพื้นที่ว่าง)

คำอธิบาย

## Preparation
              'C'&=;._2  NB. Map ./C to 0/1, turn into matrix
((,.|.)0 _1 0 1)         NB. Compute offsets to shift into each direction
                         NB. (i.e. [[_1 0], [1 0], [0 _1], [0 1]] in any order)


## "Part B"
(2=f)+.[f]*f=.[:+/|.!.0  NB. This part computes a matrix that is 1 for cells that
                         NB. cannot contain a chest:
              [:+/|.!.0  NB. Sum of shifts: shift in each of the four cardinal
                         NB. directions (using the array above) and then sum up.
           f=.           NB. Define this function as `f`; we'll use it some more.
         ]*              NB. Multiply by the "is chest" matrix: this isolates
                         NB. double-chests.
       [f                NB. Sum of shifts--1 for double-chest neighbours.
(2=f)                    NB. Isolate cells with two neighbouring chest.
     +.                  NB. Boolean or--either two neighbouring chests or next
                         NB. to a double-chest.

## Wrap up the result
(+:@] (fmt >.) PartB)    NB. Maximum of the array from the above and twice the "is
 +:@]      >.  PartB     NB. chest" matrix--this is 0,1,2 for '*', '.' or chest,
                         NB. respectively.

## Output formatting
LF,@:,.~'*.C'{~          NB. Format output...
        '*.C'{~          NB. Map 0,1,2 to '*.C' by using the value as index
LF   ,.~                 NB. Append line feed at end of each line
  ,@:                    NB. Ravel into one line

4

C 193

2 บรรทัดใหม่ที่ไม่จำเป็นเพื่อความชัดเจน การเปลี่ยนแปลงที่เกี่ยวกับรหัสที่ไม่ได้บรรจุ ได้แก่ : ตัวอักษรเป็นรหัส ASCII แทนที่จะเป็นตัวอักษรตัวอักษร; การจัดเรียงใหม่ของ v = 0, strlen และ strchr เพื่อบันทึกอักขระ (strchr เป็นสิ่งที่น่าเกลียดที่สุดเนื่องจากมันหมายความว่าการคำนวณที่จะดำเนินการเพียงครั้งเดียวเท่านั้นจะดำเนินการ 5 ครั้งต่อเซลล์!)

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

g(char*q){int v,j,w,l;
int f(p,d){int s=0,i=w=strchr(q,10)-q+1,r;for(;w/i;i-=i-1?w-1:2)r=p+i,r>-1&r<l&&q[r]==67&&++s&&d&&f(r,0);v|=s>d;}
for(j=l=strlen(q);j--;f(j,1),46-q[j]||v||(q[j]=42))v=0;}

ในการสรุปกฎ:

สแควร์เปล่า (ที่ไม่มี C หรือขึ้นบรรทัดใหม่) สามารถแปลงหากมีเพื่อนบ้านสูงสุด 1 ที่มี C

... และเพื่อนบ้านนั้นไม่มีเพื่อนบ้านที่มี C.

ฟังก์ชั่น g ประกอบด้วยฟังก์ชั่น f ที่f(r,0)วนซ้ำจากความลึก 1 ถึงความลึก 0 ด้วยการเรียกซ้ำเพียง 2 ระดับการเรียกซ้ำแบบง่ายจะทำไม่จำเป็นต้องใช้f(r,d-1)!

โค้ด Ungolfed ในโปรแกรมทดสอบ

สตริงการทดสอบอินพุตเป็นฮาร์ดโค้ด getsและscanfจะไม่ยอมรับสตริงอินพุตที่มีการขึ้นบรรทัดใหม่ พวกเขาสับมันเป็นชิ้นที่แต่ละบรรทัดใหม่

char n[]=".......C..\n...C..C...\n.........C\n.CC...CC..\n..........";

g(char*q){

  int v,j,w,l;

  int f(p,d){                    //p=cell to be checked,d=recursion depth
    int s=0,i=w,r;               //sum of C's found so far=0, i=width
    for(;w/i;i-=i-1?w-1:2)       //For i in   w,1,-1,-w   = down,right,left,up
      r=p+i,                     //r=cell adjacent to p
      r>-1&r<l&&q[r]=='C'&&++s   //If r not out of bounds and equal to C, increment s...
        &&d&&f(r,0);             //...and if recursion depth not yet at zero, try again one level deeper. 
    v|=s>d;                      //If the local s exceeds d, set global v to true to indicate invalid.
  }

  w=strchr(q,10)-q+1;            //width equals index of first newline + 1                   
  l=strlen(q);                   //length of whole string;
  for(j=l;j--;)                  //for l-1 .. 0 
    v=0,                         //clear v
    f(j,1),                      //and scan to see if it should be set
    '.'-q[j]||v||(q[j]='*');     //if the character is a '.' and v is not invalid, change to '*'
}

main(){
  g(n);
  puts(n);
}

เอาต์พุตตามตัวอย่างคำถาม

******.C**
***C**C.**
*..***..*C
.CC.*.CC.*
*..***..**

1

JavaScript (ES6) 124 129

ใช้อักขระ 0 (*), 6 (C), 7 (.)

F=s=>[for(c of(d=[o=~s.search('\n'),-o,1,i=-1],s))
   d.map(j=>t-=s[i+j]==6&&~d.some(k=>s[i+j+k]==6),t=i++)|c<7|t>i&&c
].join('')

Ungolfedและอธิบาย

F=s=>
{
  o=~s.search('\n') // offset to prev row (~ is shorter than +1 and sign does not matter)
  d=[o,-o,1,-1] // array of offset to 4 neighbors
  i=-1
  result = '' // in golfed code, use array comprehension to build the result into an array, then join it
  for (c of s) // scan each char
  {
    t = i++ // set a starting value in t and increment current position in i
    d.forEach(j => // for each near cell, offset in j
    {         
      if (s[i+j]==6) // if cell contains a Chest, must increment t
      {  
        // In golfed code "~some(...)" will be -1(false) or -2(true), using decrement instead of increment
        if (d.some(k=>s[i+j+k]==6)) // look for another Cheast in the neighbor's neighbors
        {
          // more than one chest, position invalid
          t += 2
        }
        else
        {
          t += 1
        }
      }
    })
    if (c < 7 // current cell is not blank
        || t > i) // or t incremented more than once, position invalid
    {
       result += c // curent cell value, unchanged
    }
    else
    {
       result += 0 // mark a valid position 
    }
  }
  return result
}

ทดสอบในคอนโซล Firefox / FireBug

a='\
7777777677\n\
7776776777\n\
7777777776\n\
7667776677\n\
7777777777\n';

console.log(F(a))

เอาท์พุต

0000007600
0006006700
0770007706
7667076670
0770007700

1

Perl, 66

ความขัดแย้งของการจับคู่หน้าอกของ regexp นั้นจบลงที่ทางยาวดังนั้นจึงไม่ได้แข่งขันกับ CJam ในครั้งนี้

#!perl -p0
/.
/;$"=".{@-}";s%0%s/\G0/2/r!~/2((.$")?2(.$")?|2$"|$"2)2/s*1%eg

ใช้ 0 และ 2 สำหรับช่องว่างและช่องว่างบนอินพุต 1 เพื่อทำเครื่องหมายจุดบนเอาต์พุต

ลองมันนี่


0

Python 2 - 281 ไบต์

f=lambda x,y:sum(m[y][x-1:x+2])+m[y-1][x]+m[y+1][x]
m=[];o=''
try:
 while 1:m+=[map(int,'0%s0'%raw_input())]
except:a=len(m[0]);l=len(m);m+=[[0]*a]
for y in range(l*2):
 for x in range(1,a-1):
    if y<l:m[y][x]*=f(x,y)
    else:o+=`2if m[y-l][x]else +(f(x,y-l)<5)`
 if y>=l:print o;o=''

(บรรทัดที่ 8 และ 9 นั้นมีอักขระแท็บเดียวซึ่ง SE แปลงเป็นช่องว่าง 4 บรรทัดทุกบรรทัดในโปรแกรมนี้มีช่องว่างนำหน้า 0 หรือ 1 ไบต์)

อินพุต: 0สำหรับไม่มีหน้าอก2สำหรับหน้าอก
Ouput: 0สำหรับไม่มีหน้าอก2สำหรับหน้าอกที่มีอยู่1สำหรับหน้าอกใหม่ที่เป็นไปได้


พระเจ้านี่มันช่างน่ากลัว ฉันจะต้องออกจากการปฏิบัติอย่างจริงจัง ฉันโยนทุกอย่างที่ฉันรู้และมันก็ออกมา ... เอ่อมันออกมาเป็น 281 ไบต์แพ้ทุกคำตอบยกเว้นอันที่regexฮ่าฮ่า ฉันรู้สึกเหมือนกับว่าฉันเล่นกอล์ฟได้ดีจริง ๆ ดังนั้นฉันเดาว่าอัลกอริทึมของฉันนั้นน้อยกว่าอุดมคติ

Ungolfed:

def f(x,y):
    """Given x,y coords of the board, return the sum of that point and all
    adjacent points.
    """
    return (sum(board[y][x-1:x+2]) # (x-1,y) + (x,y) + (x+1,y)
            + board[y-1][x]
            + board[y+1][x])
board=[]
output=''
try:
    while True:
        row = '0%s0' % raw_input() # line from stdin with a leading and trailing 0
        board.append(map(int, row)) # convert to list of ints
except:
    pass # exception is thrown when stdin is empty

board_width = len(board[0])
board_height = len(board)

board.append([0]*board_width) # new row of all 0s

for y in xrange(board_height*2):
    # board_height multiplied by 2 so we can use this loop to simulate two
    for x in xrange(1,board_width-1):
        if y < board_height: # "first loop"
            board[y][x] *= f(x,y) # multiply everything on the board by itself + sum
                                  # of neighbours
                                  # empty cells (0) stay 0 no matter what
                                  # lone chests (2 surrounded by 0) become 2*2==4
                                  # double chests (2 touching another 2) are weird:
                                  # - one chest becomes 2*(2+2)==8
                                  # - the other chest becomes 2*(2+8)==20
        else: # "second loop"
            if board[y - board_height][x] != 0:
                output += '2' # anything not equal to 0 is an existing chest
            else:
                valid = f(x, y - board_height) < 5 # if the sum of neighbours > 4, the
                                                   # current cell is either beside a
                                                   # double chest or more than one
                                                   # single chest
                output += '01'[valid]
    if y >= board_height: # only print during the "second loop"
        print output
        output=''
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.