ยุบ ascii-art


12

ท้าทาย

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

กฎระเบียบ:

  • เอาต์พุตมีขนาดและตัวอักษรเหมือนกับอินพุต
  • เป็นตัวละครที่ไม่ใช่พื้นที่ที่(row a,column b)ไม่สามารถมีอักขระช่องว่าง' 'ที่(a-1, b), (a-1,b-1)หรือ(a-1,b+1)ที่แถวที่มีเลขขึ้นมาจากด้านล่างสุด นี่คือผลที่ตามมาว่ากองแนวตั้งทั้งหมดควรยุบไปด้านข้าง
  • อักขระที่ไม่เว้นวรรคสามารถเดินทางได้หลาย(initial height - final height)ที่ทางซ้ายหรือขวา (ดูรูปที่ 1)
  • คุณสามารถสมมติว่าภาพมีพื้นที่เพียงพอที่จะยุบลงโดยไม่มีตัวอักษรตกลงมาจากหน้าจอ

รูปที่ 1: ตำแหน่งสุดท้ายที่เป็นไปได้สำหรับตัวอักษรที่@#$แสดงx,y,zตามลำดับ

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

ลำดับการยุบอักขระสามารถเลือกได้อย่างอิสระ ช่องว่างต่อท้ายไม่เป็นไร แต่มีการขึ้นบรรทัดใหม่

นี่คือดังนั้นคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ!

ตัวอย่าง

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

หนึ่งเอาต์พุตที่เป็นไปได้:

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

เพียงชี้แจงให้ชัดเจนวิธีที่ตัวละครตกอยู่นั้นสามารถเขียนโค้ดได้ยากแทนที่จะสร้างแบบสุ่มทุกครั้ง?
ETHproductions

18
วัวตัวนั้นทำอะไรกับคุณ? :(
FlipTack

@ETHproductions ที่ถูกต้อง ตัวอย่างของฉันทำจากล่างขึ้นบนจากซ้ายไปขวา แต่ลำดับสุ่มหรืออย่างอื่นก็ใช้ได้ตราบใดที่กฎเป็นไปตาม
Angs

@ Flp.Tkc เป็นเพียงตัวอย่างเท่านั้น
Angs

1
@ ทำลายแตงโมถ้าตัวละครหลุดออกมาจากหน้าจอมันเป็นความผิดของพวกเขาไม่ใช่ของคุณ
Angs

คำตอบ:


4

JavaScript (ES6), 100 90 88 ไบต์

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))

ต้องการสตริงที่มีอย่างน้อยสองบรรทัดและทุกบรรทัดมีความยาวเท่ากัน เอาท์พุทสำหรับภาพตัวอย่าง:

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

โปรดทราบว่าในขณะที่มันพยายามที่จะย้ายองค์ประกอบไปทางขวาถ้าเป็นไปได้ที่*ไม่ได้ตกอยู่ระหว่างและHaveyou

แก้ไข: บันทึกแล้ว 10% ขอบคุณ @ETHproductions บันทึกอีก 2 ไบต์ต้องขอบคุณ @DanielIndie

เรติน่า 0.8.2 , 50 ไบต์

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

ลองออนไลน์! แนวทางที่แตกต่างกันเล็กน้อยสำหรับคำตอบ JavaScript ของฉันนี่ใช้กลุ่มสมดุลเพื่อจับคู่ช่องว่างด้านล่างอักขระที่ไม่ใช่ช่องว่าง (?<-1>)?ช่วยให้พื้นที่ที่จะเป็นหนึ่งคอลัมน์ด้านซ้ายในขณะที่.?ช่วยให้พื้นที่ที่จะเป็นหนึ่งคอลัมน์ทางด้านขวา

เรติน่า 40 ไบต์

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

ลองออนไลน์! คำตอบของ JavaScript พอร์ตของฉัน ส0L$เตจอะตอมมิกจะรับอินพุตและทดแทนความยาวทั้งสองลงในบรรทัดที่สองซึ่งส่งผลให้คำสั่งที่ดำเนินการแทนจริงซึ่งจะถูกประเมินบนอินพุตดั้งเดิมโดยส~เตจผสม


นี่เป็นอัลกอริทึมที่ยอดเยี่ยม! คุณสามารถแทนที่\nด้วยการขึ้นบรรทัดใหม่ตามตัวอักษรเพื่อให้ได้ตัวเลขสองหลัก ;-)
ETHproductions

นอกจากนี้ฉันคิดว่าคุณสามารถl=s.search`\n` บันทึกได้สองสามไบต์
ETHproductions

tio.run/##ZY/… 86 ไบต์
DanielIndie

@DanielIndie f=เป็นสิ่งจำเป็นสำหรับการเรียกซ้ำ แต่ก็ยังช่วยฉัน 2 ไบต์ขอบคุณ!
Neil

คุณพูดถูกแล้วขอโทษ: P
DanielIndie

3

Python 2, 298 ไบต์

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()

รับอินพุตเป็นรายการของสตริง (หนึ่งรายการต่อบรรทัด)

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

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

เอาท์พุท:

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

3

C, 252 ไบต์

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++]);}

รหัสทดสอบ Ungolfed:

#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();
}

ผลการทดสอบ:

ป้อนคำอธิบายรูปภาพที่นี่


2

Algodoo (ไม่แข่งขัน)

อินพุต - ตัวอย่างที่ใช้ลดลง

ติดตั้ง

Runnning - แรงโน้มถ่วงเริ่มต้นและการตีกลับ

วิ่ง

เอาท์พุท - ความแม่นยำสามารถปรับได้ผ่านการตั้งค่าแรงเสียดทานและความหนาแน่นของวัตถุ

เอาท์พุต

Algodoo เป็นตรรกะโปรแกรม


ทำไมสิ่งนี้จึงไม่ใช่การแข่งขัน โดยทั่วไปการไม่แข่งขันจะสงวนไว้สำหรับคำตอบในภาษาที่ใหม่กว่าความท้าทาย
Ad Hoc Garf Hunter

แม้ว่า Algodoo สามารถทำตรรกะได้จริง แต่การจำลองนี้เทียบเท่ากับการพิมพ์เอกสารย่อยของชิ้นงานย่อยลงบนพื้นและถ่ายภาพมัน ฉันไม่แน่ใจทันทีว่าจะจับภาพเอาต์พุตนั้นด้วยวิธีการเขียนโปรแกรมได้อย่างไร
wyldstallyns

และดูเหมือนผิดที่จะพูดว่า "โปรแกรม zero byte! ฉันชนะ!"
wyldstallyns

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

ฉันจะเปิดเมตานั้น
wyldstallyns

1

JavaScript ขนาด 286 ไบต์

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`')

ตัวอย่าง

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

เอาท์พุท:

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

ตัวอย่างอื่น:

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

เอาท์พุท:

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

ฟังก์ชั่น Ungolfed

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")
}

วิธีสั้น ๆ ในการทดสอบแบบไม่ว่างเปล่าคือc>" "ตำแหน่งที่cแสดงถึงตัวละครที่คุณกำลังทดสอบ
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.