Thu gọn ascii-art


12

Thử thách

Đưa ra một lưới hình chữ nhật gồm các ký tự ascii có thể in thành một chuỗi hoặc thông qua đầu vào tiêu chuẩn, viết một hàm hoặc chương trình thu gọn các ký tự không phải khoảng trắng thành một đống ở phía dưới.

Những quy định:

  • Đầu ra có cùng kích thước và ký tự như đầu vào.
  • Một nhân vật không phải không gian tại (row a,column b)không thể có một ký tự khoảng trắng ' 'tại (a-1, b), (a-1,b-1)hoặc (a-1,b+1), nơi các hàng được đánh số từ dưới cùng. Điều này có hậu quả là tất cả các cọc thẳng đứng sẽ sụp đổ sang một bên.
  • Một nhân vật không phải không gian có thể di chuyển ở hầu hết các (initial height - final height)nơi bên trái hoặc bên phải (xem Hình 1).
  • Bạn có thể giả sử hình ảnh có đủ không gian để thu gọn mà không có nhân vật rơi ra khỏi màn hình.

Hình 1: vị trí cuối cùng có thể cho các ký tự @#$được hiển thị x,y,ztương ứng.

..............
...@..........
..xxx.........
.xxxxx...#....
xxxxxxx.yyy.$.

Thứ tự mà các nhân vật sụp đổ có thể được chọn tự do. Không gian lưu trữ không ổn nhưng dấu vết mới là.

Đây là , vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng!

Thí dụ

                 (__)
                 (oo)
           /------\/
          / |    ||
         *  /\---/\
            ~~   ~~
..."Have you mooed today?"...

Một đầu ra có thể:

 
 
 
                --(_
           /----|/|(o_)
          /|/~\---~\\/o)
..."Have*you~mooed~today?"...

Chỉ cần làm rõ, cách các nhân vật rơi có thể được mã hóa cứng hơn là được tạo ngẫu nhiên mỗi lần?
Sản xuất ETH

18
Con bò đó đã làm gì với bạn ?? :(
FlipTack

@ETHproductions đó là chính xác. Ví dụ của tôi thực hiện từ dưới lên trên, từ trái sang phải nhưng thứ tự ngẫu nhiên hoặc một cái gì đó khác là tốt, miễn là các quy tắc được tuân theo.
Angs

@ Flp.Tkc Nó chỉ là một mô hình.
Angs

1
@DeststallibleWateriwi nếu một nhân vật rơi ra khỏi màn hình, đó là lỗi của họ, không phải của bạn.
Angs

Câu trả lời:


4

JavaScript (ES6), 100 90 88 byte

f=s=>s==(l=s.search`
`,s=s.replace(eval(`/(\\S)([^]{${l-1},${l+1}}) /`),` $2$1`))?s:f(s)
s=`                 (__)        
                 (oo)        
           /------\\/         
          / |    ||          
         *  /\\---/\\          
            ~~   ~~          
..."Have you mooed today?"...`
console.log(s)
console.log(f(s))

Yêu cầu chuỗi phải có ít nhất hai dòng và tất cả các dòng được đệm với độ dài bằng nhau. Đầu ra cho hình ảnh ví dụ:

              ( --           
            /|---/|-(o__     
          */~~\---~\|\/o))   
..."Have you/mooed~today?"...

Lưu ý rằng vì nó cố gắng di chuyển các phần tử sang bên phải nếu có thể, phần tử *không nằm giữa Haveyou.

Chỉnh sửa: Đã lưu 10% nhờ @ETHproductions. Đã lưu thêm 2 byte nhờ @DanielIndie.

Võng mạc 0.8.2 , 50 byte

+`(?<=(.)*)(\S)(.*¶(?<-1>)?(?>(?<-1>.)*).?) 
 $3$2

Hãy thử trực tuyến! Một cách tiếp cận hơi khác với câu trả lời JavaScript của tôi, phương pháp này sử dụng một nhóm cân bằng để khớp với một khoảng trắng bên dưới ký tự không phải không gian; các (?<-1>)?phép không gian là một cột bên trái trong khi .?cho phép không gian là một cột bên phải.

Võng mạc , 40 byte

~0L$`.(.*)¶
+s`(\S)(.{$.1,$.&}) ¶ $$2$$1

Hãy thử trực tuyến! Cổng câu trả lời JavaScript của tôi. Các 0L$giai đoạn nguyên tử mất đầu vào và thay thế hai chiều dài vào dòng thứ hai dẫn đến lệnh đó thực sự thực hiện việc thay đổi, sau đó được đánh giá trên cơ nhập ban đầu của ~giai đoạn hợp chất.


Đây là một thuật toán tuyệt vời! Bạn có thể thay thế \nbằng một dòng mới theo nghĩa đen để giảm xuống còn hai chữ số ;-)
ETHproductions

Ngoài ra, tôi nghĩ bạn có thể l=s.search`\n` để tiết kiệm một vài byte.
Sản phẩm ETH


@DanielIndie f=Yêu cầu cho đệ quy, nhưng nó vẫn tiết kiệm cho tôi 2 byte, cảm ơn!
Neil

bạn nói đúng, xin lỗi: P
DanielIndie

3

Python 2, 298 byte

a=input()
L=len(a);s=' '
a=[list(s*L+l.ljust(L+max(map(len,a))))for l in a]
t=1
while t:
 t=0
 for y in range(L-1):
  for x in range(len(a[y])):
   c=a[y][x];C=a[y+1][x-1:x+2]
   if s!=c and s in C:t=1;a[y][x]=s;a[y+1][[[x+1,x][C[1]==s],x-1][C[0]==s]]=c
for l in map(''.join,a):print l[L:].rstrip()

Lấy đầu vào dưới dạng danh sách các chuỗi (mỗi chuỗi trên một dòng)

Ví dụ: Đầu vào:

['                 (__)',
'                 (oo)',
'           /------\/',
'          / |    ||',
'         *  /\---/\ ',
'            ~~   ~~',
'..."Have you mooed today?"...']

Đầu ra:

              (
            -----/|-(o__
         //|~~\---~\|\/o))
..."Have*you/mooed~today?"...

3

C, 252 byte

e=1,l,c,i,j,p,r,w,a[999];f(){while((i=getchar())>0)a[w++]=i,i<16?l++:0,l?0:c++;while(e)for(i=e=0;i<c;i++)for(j=l;j>=0;j--)e=(r=a[p=j*(c+1)+i]-32?a[r=p+c+1]-32?a[r=p+c]-32?a[r=p+c+2]-32?0:r:r:r:0)?l=a[p],a[p]=a[r],a[r]=l:e;for(i=0;i<w;)putchar(a[i++]);}

Mã kiểm tra bị đánh cắp:

#include <stdio.h>

e=1,l,c,i,j,p,r,w,a[999];
f()
{
    // counting lines and columns
    while ((i = getchar())>0)a[w++] = i, i<16 ? l++ : 0, l ? 0 : c++;
    // main shaking loop
    while (e) // repeat while collapsing
        for (i = e = 0; i < c; i++) // columns loop
            for (j = l; j >= 0; j--) // lines loop
                e = ( // remember that collapsing was
                     r = // find place to collapse
                         a[p = j*(c + 1) + i] - 32 ? // if not space
                             a[r = p + c + 1] - 32 ? // if char under the current is not a space
                                 a[r = p + c] - 32 ? // see one position left
                                    a[r = p + c + 2] - 32 ? 0 // then one position right
                                                          : r
                                    : r
                                 : r
                             : 0
                         ) ? // and if place was found
                           l=a[p],a[p]=a[r],a[r]=l // replace values in positions p and r
                           : e;
    //print resulting picture
    for(i=0;i<w;)putchar(a[i++]);
}

int main(void)
{
    int cnt;
    FILE * testf = fopen("caw.txt","w");
    char testd[][31] = {
        "                 (__)        \n",
        "                 (oo)        \n", 
        "           /------\\/         \n", 
        "          / |    ||          \n", 
        "         *  /\\---/\\          \n", 
        "            ~~   ~~          \n", 
        "...\"Have you mooed today ? \"...",
        "" };
    // prepare data for test
    printf("Initial data:\n");
    for(cnt = 0; cnt < 7; cnt++)
    {
        printf("%s", testd[cnt]);
        fprintf(testf, testd[cnt]);
    }
    fclose(testf);
    // redirect standard input
    freopen("caw.txt", "r", stdin);
    printf("\n\nResult:\n");
    // start test
    f();
}

Kết quả kiểm tra:

nhập mô tả hình ảnh ở đây


2

Algodoo (không cạnh tranh)

Đầu vào - ví dụ suy biến được sử dụng.

Thiết lập

Runnning - trọng lực mặc định và nảy.

Đang chạy

Đầu ra - độ chính xác có thể được điều chỉnh thông qua cài đặt Ma sát và Mật độ trên các đối tượng.

Đầu ra

Algodoo là lập trình logic .


Tại sao điều này không cạnh tranh? Không cạnh tranh thường được dành riêng cho câu trả lời trong các ngôn ngữ mới hơn thách thức.
Đăng Rock Garf Hunter

Mặc dù Algodoo có thể thực hiện logic thực tế, nhưng mô phỏng này tương đương với việc thả một bản in ra khỏi đầu vào trên sàn và chụp ảnh nó. Tôi không chắc chắn làm thế nào để nắm bắt đầu ra đó theo cách lập trình.
wyldstallyns

Và có vẻ sai khi nói "chương trình byte không! Tôi thắng!"
wyldstallyns

Tôi nghi ngờ rằng đây thực tế không phải là một câu trả lời bằng không. Bạn nói về các cài đặt điều chỉnh có vẻ tương đương với viết mã. Nó có thể là một ý tưởng tốt để mở một câu hỏi meta về việc ghi điểm Algodoo. Tôi cũng không nghĩ có gì sai khi có chương trình byte không.
Đăng Rock Garf Hunter

Tôi sẽ mở meta đó.
wyldstallyns

1

JavaScript, 286 byte

b=>eval('f=b=>b==null||" "==b;b=b.split`\n`.map(b=>[...b]);a:for(;;){for(c=0;c<b.length-1;c++)for(g=b[c],d=0;d<g.length;d++){h=g[d];if(!f(h)){e=0;f(b[c+1][d])?e=2:f(b[c+1][d-1])?e=1:f(b[c+1][d+1])&&(e=3);if(e){b[c+1][d+e-2]=h;b[c][d]=" ";continue a}}}break}b.map(b=>b.join``).join`\n`')

Ví dụ

// Here I assume that you've assigned the above function to `fall`
console.log(fall(`
                 (__)
                 (oo)
           /------\/
          / |    ||
         *  /\---/\\
            ~~   ~~
..."Have you mooed today?"...`))

Đầu ra:

                -       
            /--(-\--(__  
          /|~~---/~||/oo))
..."Have*you/mooed~today?"...

Một vi dụ khac:

console.log(fall(`
 (\__/)  .~    ~. ))
 /O O  ./      .'
{O__,   \    {
  / .  . )    \\
  |-| '-' \    }
 .(   _(   )_.'
'---.~_ _ _&`))

Đầu ra:

    _ , /            
  OO/__'_.. .         
 {.(|-|.(O'))/.~{      
/('---.~___-_&)_.'}\~.'))

Chức năng

function fall(input) {
  let move = true
  let lines = input.split("\n").map(line => line.split(""))
  let isSpace = c => c == null || c == " "
  loop: for (;;) {
    for (let y = 0; y < lines.length - 1; y++) {
      let line = lines[y]
      for (let x = 0; x < line.length; x++) {
        let ch = line[x]
        if (!isSpace(ch)) {
          let dx = 0
          if (isSpace(lines[y+1][x])) { dx = 2 }
          else if (isSpace(lines[y+1][x-1])) { dx = 1 }
          else if (isSpace(lines[y+1][x+1])) { dx = 3 }
          if (dx) {
            lines[y + 1][x + dx - 2] = ch
            lines[y][x] = " "
            continue loop
          }
        }
      }
    }
    break
  }
  return lines.map(line => line.join("")).join("\n")
}

Một cách ngắn để kiểm tra không trống là c>" "nơi cđại diện cho nhân vật bạn đang kiểm tra.
Neil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.