Düşen Kayaları Tahmin Edin


18

Bu meydan okumada, yandan bakıldığında iki boyutlu bir arazinin haritası verilir. Ne yazık ki, arazinin bazı kısımları havada yüzüyor, yani çöküyorlar. İşiniz nereye ineceklerini tahmin etmektir.

Girdi

Girişiniz, yalnızca karakterleri #(bir sayı işareti, bir kayayı gösteren) veya .(boş alanı gösteren bir nokta ) içeren eşit uzunlukta eşit uzunluktaki bir veya daha fazla satırla ayrılmış dizedir .

Çıktı

Çıktınız girişle aynı biçime sahip, ancak aşağıdaki değişikliklerle. Girdi dizesini iki boyutlu bir kaya ızgarası olarak görelim. Bitişik kayalar yolu ile ızgaranın tabanına bağlanan girişteki her kaya sağlamdır ; diğer kayalar gevşek . Çapraz olarak bitişik kayalar bitişik olarak kabul edilmez. Tüm gevşek kayalar düz olarak düşecek ve sağlam bir kayanın veya alt sıranın üstünde bir yığın olarak ortaya çıkacaktır. Gevşek kayalar birbirine bağlı değildir, bu nedenle büyük oluşumlar olarak değil, ayrı ayrı düşer. Çıktı, sonuçta oluşan ızgaradır.

Örnekler

  • Girdi

    ..###.
    .##.#.
    .#....
    .##.#.
    

    gevşek kayalar içermediğinden, çıktı onunla aynıdır.

  • Girdi

    ...#..
    .#..#.
    .#..##
    .#...#
    .#####
    .#...#
    

    üst kısmında gevşek bir kaya vardır, bu da altındaki sağlam kayaya düşer. Çıktı

    ......
    .#..#.
    .#..##
    .#.#.#
    .#####
    .#...#
    
  • Girdi

    .#####....
    .#....####
    ###.###..#
    #.#...##..
    .####..#.#
    ......###.
    ..#...#..#
    ..#...#..#
    

    solda büyük bir grup gevşek kayaç vardır. Kayalar düştükçe grup parçalanır, dolayısıyla çıktı

    ..........
    ....######
    ..#.###..#
    . #...##..
    .##....#..
    .##...####
    ####..#..#
    #####.#..#
    

Açıklamalar

  • Girişi STDIN'den alabilir ve STDOUT'a gönderebilir veya bir işlev yazabilirsiniz.
  • Bu kod golf, bu yüzden en kısa program (bayt cinsinden) kazanır.
  • Standart boşluklara izin verilmez.

Yanıtlar:


12

CJam, 180 ... 133101 ... 94 90 87 bayt

qN/~'#/S*_,):L;]N*_,_,*{:A1$='#={[W1LL~)]Af+{W>},1$f=S&,{ASct}*}*}/N/z{S/{$W%}%'#*}%zN*

Kesinlikle çok golf var, ama tamamen çalışmak için aldıktan sonra ilk göndermek istedim.

Bak anne! Kaydırma çubuğu yok!

STDIN'den ( sondaki yeni satırdan oluşan .ve #içermeyen) kaya ızgarasını alır ve çıktıyı STDOUT'a yazdırır

GÜNCELLEME : Sağlam kayaları bulmak için verimsiz ancak daha kısa kısmi taşkın dolgu kullanılması.

GÜNCELLEME 2 : Kayaların düşmesi için algoritma değiştirildi. Artık çok daha kısa!

GÜNCELLEME 3 : Birkaç küçük optimizasyon yaptım ve sonunda bayt sayısını orijinal kodun yarısına indirebildim!

Nasıl çalışır :

qN/~'#/S*_,):L;]N*             "Preparations";
qN/~                           "Read the input, split by new line and expand the array";
    '#/S*                      "In the last row, replace # by space";
         _,):L                 "Copy the last row and store length + 1 in L";
              ;]N*             "Pop the length, wrap everything in array and join by \n";

_,_,*{ ... }/                  "Flood fill";
_,                             "Copy the array and calculate its length";
  _,                           "Copy the length and calculate [0 - length] array";
    *                          "Repeat the above array, length times";
     { ... }/                  "Run the code block on each element of the array";

:A1$='#={ ... }*               "Process only #";
:A1$                           "Store the number in A and copy the input array to stack";
    =                          "Get Ath index element from input array";
     '#={ ... }*               "Run the code block if Ath element equals #";

[W1LL~)]Af+{W>},1$f=S&,{ASct}* "Flood fill spaces";
[W1LL~)]Af+                    "Get the indexes of the 4 elements on the cross formed by"
                               "the Ath index";
           {W>},               "Filter out the negative values";
                1$f=           "For each of the index, get the char from input string";
                    S&,        "Check if space is one of the 4 chars from above step";
                       {    }* "Run the code block if space is present";
                        ASct   "Make the Ath character of input string as space";

N/z{S/{$W%}%'#*}%zN*           "Let the rocks fall";
N/z                            "Split the resultant string by newlines and"
                               "transpose the matrix";
   {           }%              "Run the code block for each row (column of original)";
    S/{   }%                   "Split by space and run the code block for each part";
       $W%                     "Sort and reverse. This makes # come down and . to go up";
            '#*                "Join by 3, effectively replacing back spaces with #";
                 zN*           "Transpose to get back final matrix and join by newline";

Taşkın dolgusu için, tüm ızgara uzunluğu (ızgara) süreleri boyunca tekrarlanır. Her yinelemede, #doğrudan bir boşluğa (boşluk) dokunan en az 1'i dönüştürmemiz garanti edilir . Buradaki alan sağlam bir kaya grubunu temsil eder. Böylece uzunluk (ızgara) yinelemelerinin sonunda, tüm sağlam kayaların boşluklarla temsil edileceği garanti edilir.

Buradan çevrimiçi deneyin


15

Perl 5: 98

98, 2 komut satırı bayrağı dahil.

#!perl -p0
1while/
/,($x="($`)")=~y!#!.!,s/#(.*
$)/%$1/+s/#$x?%|%$x?#/%$1$2%/s;1while s/#$x\./.$1#/s;y!%!#!

Açıklama:

#!perl -p0 #read entire input to $_ and print at the end
/\n/;($x="($`)")=~y!#!.!; #calculate pattern matching space
                          #between two characters in the same column
                          #looks like "(......)" 
1 while s/#(.*\n$)/%$1/+s/#$x?%|%$x?#/%$1$2%/s;
                          #flood fill solid rock with %
1 while s/#$x\./.$1#/s;   #drop loose rock
y!%!#!                    #change % back to #

@Optimizer Doğru şekilde bitirilen son girdi satırına güveniyorum bkz: ideone.com/7E3gQh Bu güven olmadan bir karakter yalnız (ya da karşısındaki kısa bir güven - nihai EOL eksikliği) olurdu.
nutki

1
CJam'ı neredeyse% 30 yenmek mi? İnanılmaz. Seni kutlarım.
DLosc

@DLosc Artık değil: P
Optimizer

Diğer zorunlu dilleri% 100-300 yenmek mi? İnanılmaz. Seni kutlarım. ;)
DLosc

@DLosc Yukarıdaki cevaba baktığımda, Perl'i artık zorunlu diller listesine dahil etmeyeceğim: P
Optimizer

5

JavaScript (ES6) 232

s=>{for(s=[...s+'1'.repeat(r=1+s.search('\n'))];s=s.map((c,p)=>c=='#'&(s[p+1]|s[p-1]|s[p-r]|s[p+r])?f=1:c,f=0),f;);for(;s.map((c,p)=>c=='#'&s[p+r]=='.'&&(s[p]='.',f=s[p+r]=c),f=0),f;);return s.join('').replace(/1/g,rok).slice(0,-r)}

Bir string parametresi olan ve bir string döndüren bir fonksiyon olarak.

İlk önce, toprak hattını tanımlamak için bir '1' alt satırı ekleyin.
İlk döngü sabit kayaları arar ('1' yakınında) ve bunları '1' olarak işaretler. Arama daha sağlam kayalar bulunana kadar tekrarlanır.
İkinci döngü kalan '#' karakterlerini alt satıra doğru hareket ettirir. Yine, hiçbir kaya hareket ettirilinceye kadar bu tekrarlanır.
Sonunda, '1'i tekrar' # 'ile değiştirin ve alt satırı kesin.

Daha az golf

s=>{
  r = 1+s.search('\n');
  s = [...s+'1'.repeat(r)];
  for (; s = s.map((c,p) => c=='#' & (s[p+1]|s[p-1]|s[p-r]|s[p+r])?f=1:c,f=0),f; );
  for (; s.map((c,p) => c=='#' & s[p+r]=='.'&& (s[p] ='.', s[p+r]=c, f=1),f=0),f; );
  return s.join('')
    .replace(/1/g,'#')
    .slice(0,-r)
}

Test (Hangi kayaların sağlam olduğunu ve neyin düştüğünü kanıtlayabilirsiniz)

F=
s=>{for(s=[...s+'1'.repeat(r=1+s.search('\n'))];s=s.map((c,p)=>c=='#'&(s[p+1]|s[p-1]|s[p-r]|s[p+r])?f=1:c,f=0),f;);for(;s.map((c,p)=>c=='#'&s[p+r]=='.'&&(s[p]='.',f=s[p+r]=c),f=0),f;);return s.join('').replace(/1/g,rok).slice(0,-r)}

var rok // using rok that is 3 chars like '#'

function update() {
  rok = C.checked ? '@' : '#';
  O.textContent=F(I.textContent)
}

update()
td { padding: 5px }
pre { border: 1px solid #000; margin:0 }
<table><tr><td>Input</td><td>Output</td></tr>
<tr><td><pre id=I>.#####....
.#....####
###.###..#
#.#...##..
.####..#.#
......###.
..#...#..#
..#...#..#</pre></td>
<td><pre id=O></pre>
</td></tr></table>
<input type='checkbox' id=C oninput='update()'>Show firm rocks


3

APL, 130 119

'.##'[1+⊖1↓⍉↑↑{,/{⍵[⍒⍵]}¨x⊂⍨2=x←2,⍵}¨↓ ⍉⊃⌈/(1,¨⍳⍴⊃↓x){x←⍵⋄(⍺⌷x)∧←2⋄x≡⍵:x⋄⊃⌈/((⊂⍴⍵)⌊¨1⌈(,∘-⍨↓∘.=⍨⍳2)+⊂⍺)∇¨⊂x}¨⊂⊖'#'=x←⎕]

Giriş istendiğinde (bildiğim kadarıyla) yeni satır girmek mümkün olmadığından, bu program girdi olarak bir karakter matrisi alır.

Kullanılan algoritma önce bir ikili matrise ( 0hava ve 1kaya) dönüştürülüyor, ardından sağlam kayaları işaretlemek için alt sıradan taşkın dolgusu 2. Daha sonra her sütunu "sert kayaçlar arasındaki boşluklara" ayırın ve gevşek kayayı havaya "düşürmek" için her bölümü ayırın.

Edit1: Bazı farklı bir taşkın dolgu algoritması kullanarak golf


Test çalıştırmaları

Koşu 1

Bir karakter matrisi tanımlayın Ave yazdırın:

      A←↑('.#####....') ('.#....####') ('###.###..#') ('#.#...##..') ('.####..#.#') ('......###.') ('..#...#..#') ('..#...#..#')
      A
.#####....
.#....####
###.###..#
#.#...##..
.####..#.#
......###.
..#...#..#
..#...#..#

Sonra Aprograma besleyin :

      '.##'[1+⊖1↓⍉↑↑{,/{⍵[⍒⍵]}¨x⊂⍨2=x←2,⍵}¨↓⍉(1,¨⍳⊃⌽⍴x){⍵≡y←⊃⌈/x←⍺{x←⍵⋄(⍺⌷x)∧←2⋄x}¨⊂⍵:y⋄((⊂⍴⍵)⌊¨1⌈,(,∘-⍨↓∘.=⍨⍳2)∘.+⍺/⍨x≢¨⊂⍵)∇y}⊖'#'=x←⎕]
⎕:
      A
..........
....######
..#.###..#
..#...##..
.##....#..
.##...####
####..#..#
#####.#..#

Koşu 2

      A←↑('#######')('#.....#')('#.#.#.#')('#.....#')('#######')
      A
#######
#.....#
#.#.#.#
#.....#
#######
      '.##'[1+⊖1↓⍉↑↑{,/{⍵[⍒⍵]}¨x⊂⍨2=x←2,⍵}¨↓⍉(1,¨⍳⊃⌽⍴x){⍵≡y←⊃⌈/x←⍺{x←⍵⋄(⍺⌷x)∧←2⋄x}¨⊂⍵:y⋄((⊂⍴⍵)⌊¨1⌈,(,∘-⍨↓∘.=⍨⍳2)∘.+⍺/⍨x≢¨⊂⍵)∇y}⊖'#'=x←⎕]
⎕:
      A
#######
#.....#
#.....#
#.#.#.#
#######

2

JS - 443 bayt

function g(b){function f(b,c,e){return b.substr(0,c)+e+b.substr(c+1)}function e(d,c){"#"==b[c][d]&&(b[c]=f(b[c],d,"F"),1<d&&e(d-1,c),d<w-1&&e(d+1,c),1<c&&e(d,c-1),c<h-1&&e(d,c+1))}b=b.split("\n");w=b[0].length;h=b.length;for(i=0;i<w;i++)"#"==b[h-1][i]&&e(i,h-1);for(j=h-2;-1<j;j--)for(i=0;i<w;i++)if(k=j+1,"#"==b[j][i]){for(;k<h&&"F"!=b[k][i]&&"#"!=b[k][i];)k++;k--;b[j]=f(b[j],i,".");b[k]=f(b[k],i,"#")}return b.join("\n").replace(/F/g,"#")};

Sel, kayaları alttan doldurur, daha sonra taşkın doldurulmamış kayaları indirir. Taşkın dolgusu ile çok fazla özyineleme kullanır, böylece tarayıcınızı biraz geciktirebilir.

Bu bir işlev - ile çağırın g("input")

JSFiddle: http://jsfiddle.net/mh66xge6/1/

Ungolfed JSFiddle: http://jsfiddle.net/mh66xge6/


1

Python 3, 364 bayt

Eminim bundan daha fazlası sıkılabilir ... ama yine de CJam ve Perl ile asla rekabet etmeyecek.

z="%";R=range
def F(r,c,g):
 if z>g[r][c]:g[r][c]=z;[F(r+d%2*(d-2),c+(d%2-1)*(d-1),g)for d in R(4)]
def P(s):
 t=s.split()[::-1];w=len(t[0]);g=[list(r+".")for r in t+["."*w]];[F(0,c,g)for c in R(w)]
 for c in R(w):
  for r in R(len(g)):
   while g[r][c]<z<g[r-1][c]and r:g[r][c],g[r-1][c]=".#";r-=1
 return"\n".join(''.join(r[:w])for r in g[-2::-1]).replace(z,"#")

Diğer cevaplara benzer. Bir tuhaflık, önce ızgarayı baş aşağı çevirir (döngü indekslerini daha uygun hale getirmek için) ve ekstra bir satır ve sütun ekler .(kaydırma -1indeksleriyle ilgili sorunları önlemek için ). Arayarak çalıştırın P(string).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.