จำลองการหมุนกระดาน


14

บทนำ

คุณกำลังเล่นเกมจับคู่ซึ่งมีการแทรกเหรียญที่ด้านบนและตกไปที่ด้านล่าง (บนเหรียญด้านบน) เนื่องจากแรงโน้มถ่วง

ดังนั้นนี่

O <- inserting this coin

OO O
OOOOO

จะกลายเป็นสิ่งนี้

O
OO O
OOOOO

ทีนี้ลองจินตนาการว่ามีคนหมุนกระดานตามเข็มนาฬิกา สิ่งต่อไปนี้จะเกิดขึ้น:

1. กระดานหมุน

OOO
OO
O
OO
O

2. เหรียญล้มลงเนื่องจากแรงโน้มถ่วง

O
O
OO
OO
OOO

งานของคุณ

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

อินพุต

อินพุตจะเป็นสตริงซึ่งมีอักขระ 3 ชนิด:

  • O (ตัวใหญ่ o) หรือ 0 (ศูนย์) - เหรียญ (คุณเป็นผู้ตัดสินใจว่าโซลูชันของคุณรองรับแบบใด)
  • (ช่องว่าง) - ช่องว่าง
  • \ n (บรรทัดใหม่) - สิ้นสุดแถว

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

เอาท์พุต

ผลลัพธ์คือสถานะใหม่ของบอร์ดหลังจากการหมุน เอาต์พุตประกอบด้วยอักขระ 3 ชนิดเดียวกันกับอินพุต เอาต์พุตสามารถส่งคืนจากฟังก์ชันของคุณหรือสามารถเขียนไปยังเอาต์พุตมาตรฐานหรือไปที่ไฟล์

ตัวอย่าง

อินพุต 1:

O
OO O
OOOOO

Output1:

O
O
OO
OO
OOO

input2:

O O
O O

Output2:

OO
OO

คุณสามารถใช้ภาษาใดก็ได้และไลบรารีมาตรฐานของภาษาที่เลือก โปรแกรมที่สั้นที่สุดเป็นไบต์ชนะ


เส้นที่สั้นกว่านั้นถูกเสริมด้วยช่องว่างต่อท้ายหรือไม่?
Ventero

หากคุณต้องการใช่แล้ว
David Frank

ข้อกำหนดสำหรับขนาดกระดานมีอะไรบ้าง? ฉันสามารถเลือกขนาดสูงสุดที่เหมาะสมหรือแอปพลิเคชัน / ฟังก์ชั่นจำเป็นต้องใช้กับขนาดที่เป็นไปได้ทั้งหมดหรือไม่
Fors

2
หากแรงโน้มถ่วงถูกนำไปใช้หลังการหมุนอินพุท 2 กลายเป็นเอาท์พุต 2 อย่างไร ฉันคิดว่ามันน่าจะลดเหรียญชั้นนำลง แต่ไม่ใช่แนวนอน?
Matt

2
@Matt หมายเหตุว่าไม่มีแถวว่างใน Input2 หรือใน Output2 (SE จะแสดงระยะขอบระหว่างแถว)
David Frank

คำตอบ:


16

GolfScript 14 14ตัวอักษร

' '-n%zip$n*

ต้องป้อนข้อมูลใน STDIN ตัวอักษรสำหรับเหรียญสามารถเป็นอักขระที่ไม่ใช่ช่องว่าง ลองที่นี่ ขอบคุณ Peter ที่ชี้ให้เห็นถึงการลดตัวละครสองตัว


โอ้สิ่งที่ฉันจะไม่ยอมแพ้transposeใน Ruby ที่สามารถจัดการกับอาร์เรย์ที่มีความยาวต่างกันได้ ...
Ventero

@Ventero มากที่สุดเท่าที่ผมใช้รุ่น hacky ([nil]*a.map(&:size).max).zip(*a)นี้: ไม่ดีสำหรับการเล่นกอล์ฟแม้ว่า
Howard

คุณสามารถบันทึกตัวอักษร 2: ตั้งแต่สายที่ยาวที่สุดมักจะจบลงที่ด้านล่างคุณสามารถแทนที่ด้วย-1% $
Peter Taylor

@ PeterTaylor คุณพูดถูก - เราสามารถบันทึกลงใน chars ได้ ขอขอบคุณ.
Howard

1
@PeterTaylor " "ดีฉันไม่รวมนามแฝงหนึ่งตัวอักษรสำหรับ
aditsu ออกจากเพราะ SE นั้นชั่วร้าย

6

Javascript (E6) 103

ลองครั้งแรกเพียงแค่การดำเนินการเมทริกซ์ แต่ละแถวในสตริงอินพุตต้องถูกเสริม
ค่อนข้างพูดมาก

R=t=>(x=t.split('\n').reverse().map(x=>[...x].sort()),x.map((c,i)=>x.map(r=>r[i]).join('')).join('\n'))

รหัสหลอก

  1. string -> อาร์เรย์ของแถว
  2. อาร์เรย์ย้อนกลับขึ้น / ลง
  3. แต่ละแถว -> อาร์เรย์ถ่าน
  4. จัดเรียงแต่ละแถว (เหรียญ 'ตกลง' ไปทางขวา)
  5. transpose
  6. ถ่านแต่ละแถวในแถว -> สตริง
  7. เข้าร่วมอาร์เรย์ -> สตริงเดียว

โอ้วววการเรียงลำดับนั้นฉลาด (+1)! ถ้าฉันจะขโมยมัน
seequ

ฉันไม่เคยเห็นไวยากรณ์[...x]มาก่อน มันเรียกว่าอะไร?
ComFreek

2
@ComFreak มีชื่อว่าspread[ developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
edc65

2
@ edc65 คุณทำลายลิงค์ของคุณเองด้วยวงเล็บ นี่คือลิงค์ที่ถูกต้อง
Chris Cirefice

6

Ruby 2.0, 59 ตัวอักษร

puts$<.map(&:chars).reverse.transpose.sort[1,50].map &:join

อินพุตผ่าน stdin สมมติว่าบรรทัดทั้งหมดมีความยาวเท่ากัน นี่อาจนานกว่าที่จำเป็นมาก แต่อย่างน้อยก็อ่านได้ ...


ฉันคิดว่าคุณสามารถใช้$<.mapแทน
Howard

@Howard นั่นเป็นสิ่งหนึ่งที่ฉันมักจะลืม ขอบคุณ!
Ventero

1
[1,50] กำลังทำอะไรที่นั่น?
ไม่ใช่ชาร์ลส์ที่

1
@Charles มันข้ามแถวแรกซึ่งมีบรรทัดใหม่ทั้งหมดจากอินพุต เดวิดพูดถึงความคิดเห็นที่ 50x50 เป็นขนาดสูงสุดที่เป็นไปได้ดังนั้นแทนที่จะเลือกทั้งหมดยกเว้นแถวแรก ( 1..-1) ฉันเลือก 50 แถวโดยเริ่มจากแถวที่สอง ( 1,50)
Ventero

@Ventero เข้าใจแล้ว เย็น. ขอบคุณ!
ไม่ใช่ชาร์ลส์

3

J - 49 31 24 24 ไบต์

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

รุ่นใหม่ได้แรงบันดาลใจจากคำตอบ Javascript ของ edc65 :

f=:[:|."1@|:[:/:~"1,;._2

คำอธิบาย:

f=:[:|."1@|:[:/:~"1,;._2
                   ,;._2 Split the string at every fret, which is the last character in the string (newline).
              /:~"1      Sort every row separately.
     |."1@|:             Rotate the array clockwise.

เวอร์ชั่นเก่า:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)

คำอธิบาย:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)
                                          (,;._2) Split the string at every fret, which is the last character in the string (newline).
                                (|."1@|:)@        Rotate the array clockwise.
                             |:@                  Reverse the axes (columns become rows and vice-versa).
       ((#~=&' '),=&'O'#])"1                      Function that applies the "gravity"
                          "1                       Apply to every row separately:
                  =&'O'#]                           Get the O's in the row.
       (#~=&' ')                                    Get the spaces in the row.
                ,                                   Join them, spaces come first.
  [:|:                                            Reverse axes again.

ตัวอย่าง (โปรดสังเกตว่าสตริงหลายบรรทัดเริ่มต้นด้วย0 : 0และลงท้ายด้วยวงเล็บ):

   f 0 : 0
O
OO O
OOOOO
) NB. output starts now
O  
O  
OO 
OO 
OOO
   f 0 : 0
O O
O O
) NB. Output starts now.

OO
OO

หากคุณสามารถเรียงลำดับก่อนที่จะหมุน
edc65

@ edc65 คุณเป็นคนฉลาด
seequ

2

Haskell - 86

เพียงแค่เรียนรู้ดังนั้นฉันแน่ใจว่าสิ่งนี้สามารถปรับปรุงได้

import Data.List
c=putStr.unlines.filter(/="").sort.map(filter(/=' ')).transpose.lines

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

let a = "O    \nOO O \nOOOOO"
let b = " O O \n O O "
c a
c b

ตัวอย่างผลลัพธ์:

O
O
OO
OO
OOO

OO
OO

2

Python 2 (69) (79)

for c in sorted(zip(*raw_input().split("\\n"))):print''.join(c[::-1])

ใช้อินพุตที่มีช่องว่างเพื่อให้ทุกบรรทัดมีความยาวเท่ากัน splitสร้าง arrat ของแต่ละบรรทัด การzipสลับอาเรย์อย่างมีประสิทธิภาพ จากนั้นsortedเรียงลำดับ tuples ตามลำดับพจนานุกรมทำให้เหรียญทั้งหมดตกลงไปด้านล่าง ในที่สุดเราพิมพ์แต่ละบรรทัดเปลี่ยนเป็นสตริงแม้ว่าเราจะต้องย้อนกลับก่อน การทำprint'O'*c.count('O')เทียบเท่าและใช้จำนวนอักขระเท่ากัน

ตัวอย่างการเรียกใช้:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO

1

C, 167 119 ไบต์

รุ่นที่สั้นกว่านี้ (น่าเสียดาย?) ชัดเจนกว่าต้นฉบับด้วย

m;j;b[99];r;main(){while(j=getchar()+1)j-11?m+=j-33&&++b[r]>m:++r;for(j=r;m+1;putchar(j--?m<b[j]?79:32:(j=r,m--,10)));}

0

แร็กเก็ต: 130

(let l((a'()))(let((b(sort(string->list(read-line))char<?)))(if
(null? b)(apply map(λ x(map display x)(newline))a)(l(cons b a)))))

มันต้องการให้คุณเสริมด้วยช่องว่างเพื่อให้เส้นมีค่าเท่ากัน


0

C # - 209 174 ไบต์

ใช่ฉันต้องลองกอล์ฟรหัสนี้ ณ จุดที่ฉันคิด สร้างฟังก์ชั่น (r) ที่หมุนบอร์ดและพิมพ์ ฉันเดาว่าฉันโกงนิดหน่อยเมื่อฉันพิมพ์ชุดอักขระ char แต่ถ้าคุณไม่สามารถเข้าใจได้ว่าทำไมคุณถึงไม่ควรบ้า :)

ขอบคุณ ProgramFOX สำหรับเคล็ดลับ :)

void r(string s){int x=s.IndexOf('\n'),j,i=-1,k,z=x+1;var y=new char[x*x+x];for(;++i<x;y[z*(i+1)-1]='\n')for(k=j=x;j>0;)if(s[i*z+--j]=='0')y[k--*z-i-2]='0';Console.Write(y);}

โกง

new char[x*x+x]เติมอาร์เรย์ด้วย'\0'หรือไม่' '


1
การลบบรรทัดใหม่และลบช่องว่างระหว่างchar[]และyจะลดจำนวนอักขระของคุณเป็น 192 อักขระ นอกจากนี้ยังไม่จำเป็นต้องให้คำหลักstaticเมื่อโพสต์คำตอบที่นี่ การลบมันจะลดจำนวนอักขระของคุณเป็น 185 ตัว
ProgramFOX

ฉันยังสามารถลบ 'ref' ที่ถูกลืมไปตั้งแต่ที่เคยลองมาก่อนหน้านี้
WozzeC
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.