14
\$\begingroup\$

Inspired by my geography class, Sandboxed

Simulate weathering / erosion.

Input

Input will be given as a string of any 2 characters (or see below) you like in the shape of the rock (here i use spaces and hashes):

   ###
  ####
 #####
#######
#######
########

Or if your language doesn't support strings, a square matrix of 1s and 0s, a matrix of chars, whatever makes your answer more golfier.

Process

The rock will erode until it disappears completely. Lets take example of input:

    ##
 ## ### #
#########
###########

First we find which part of the rock is exposed (that is there is no rock particle directly above / below / left / right) to the air (i use @ to show such particles here):

    @@
 @@ @#@ @
@##@###@@
@########@@

NOTE: The bottom most rock particles are touching the ground and they are not touching air, hence we don't count these particles.

Then we randomly (50% chance individually for each particle) remove the rock particles (here #) (apply gravity similar to this challenge that are exposed to the air:

    #
    ##  
 ## ### #
##########

And be repeat the process until the rock disappears and output the rock in between each iteration (including the original input). In this case we output:

    ##
 ## ### #
#########
###########
    #
    ##  
 ## ### #
##########
     
       
 ## ## 
 #########
     
       
 #  #  
 ## #### #
     
        
 #    
 #  # # #
     
        
      
 #    #

This is code-golf, answer in the shortest amount of bytes wins.

\$\endgroup\$
8
  • \$\begingroup\$ Apply gravity... But a rock in shape "###/#.#/###" is possible in real life. And the # in top middle will not fail down. \$\endgroup\$
    – tsh
    Dec 6 '21 at 10:04
  • \$\begingroup\$ Can we output with additional leading/trailing spaces (e.g. input "# #\n# #\n###" would be output in the first iteration as " # # \n # # \n ### " - the output will always be two wider than the input with padded spaces)? \$\endgroup\$ Dec 6 '21 at 11:52
  • \$\begingroup\$ @KevinCruijssen Yes, you can \$\endgroup\$
    – PyGamer0
    Dec 6 '21 at 12:41
  • 1
    \$\begingroup\$ @tsh But then you can technically have some rock like '##\n\n###' which is not possible in real life. \$\endgroup\$
    – PyGamer0
    Dec 6 '21 at 12:43
  • \$\begingroup\$ @Edward what do you mean? \$\endgroup\$
    – PyGamer0
    Dec 7 '21 at 4:44
4
\$\begingroup\$

Charcoal, 58 bytes

≔Eθ⁰ηWSUMη⁺κ⁼#§ιλ⊞η⁰W⌈η«Mι↓↑Eη×#κ⸿UMη↨¹Eκ∨‹μ⌊⟦§η⊖λ⊖κ§η⊕λ⟧‽

Try it online! Link is to verbose version of code. Assumes input is a rectangular newline-terminated list of strings. Explanation:

≔Eθ⁰ηWSUMη⁺κ⁼#§ιλ

Calculate the height of each column of the rock.

⊞η⁰

Add a padding entry to prevent wrapping.

W⌈η«

Repeat until the rock has been eroded away.

Mι↓

Leave space to display the rock.

↑Eη×#κ

Output the rock.

⸿

Leave a blank line between rocks. (Otherwise they just crash into each other making the output impossible to interpret.)

UMη↨¹Eκ∨‹μ⌊⟦§η⊖λ⊖κ§η⊕λ⟧‽

For each column, for each particle, check whether it's exposed, and add up all of the unexposed particles and randomly the exposed particles.

\$\endgroup\$
4
\$\begingroup\$

05AB1E (legacy), 42 bytes

0ì€Ć[ø€{ø=ÐSO_#ø‚εεDT‚00.:ø}}`ø‚øεøεSÚΩ}J

I/O as a list of equal-sized strings, with digits 0 for spaces and 1 for rocks. The output will be two wider than the input, due to a leading/trailing column of spaces/0s.

Try it online or try it online pretty-printed.

Uses the legacy version of 05AB1E, because ø works on lists of strings. In the new 05AB1E version, most of the ø should be €SøJ instead.

Explanation:

0ì€Ć                   # Add a leading/trailing 0 to each line of the (implicit)
                       # input-list:
0ì                     #  Prepend a 0 in front of each line
  €                    #  Map over each line:
   Ć                   #   Enclose it, appending its own head
[                      # Then start an infinite loop:
 ø€{ø                  #  Apply gravity:
 ø                     #   Zip/transpose; swapping rows/columns
  €{                   #   Sort each row
    ø                  #   Zip/transpose back
     =                 #  Print the result with newline (without popping)
     Ð                 #  Triplicate the current result
      S                #  Convert the top one to a flattened list of digits
       O               #  Sum this list
        _              #  If it's 0:
         #             #   Stop the infinite loop
      ø                #  Zip/transpose the top; swapping rows/columns
       ‚               #  Pair it with its untransposed list
        ε              #  Map over this pair:
         ε             #   Map over each row:
          D            #    Duplicate the current row
           T           #    Push 10
            Â          #    Bifurcate it; short for Duplicate & Reverse copy
             ‚         #    Pair them together: [10,"01"]
              00.:     #    Replace all "10" and "01" in the copy with "00"
                  ø    #    Create cell-pairs of the row and modified row
        }}             #  Close both maps
          `            #  Pop and push both separated to the stack
           ø           #  Transpose the top copy back
            ‚          #  Pair them back together
             ø         #  Transpose this pair of matrices
              ε        #  Map over each pair of rows
               ø       #   Zip/transpose to pair together cell-pairs
                ε      #   Map over each pair of cells-pairs:
                 S     #    Convert it to a flattened list of four digits
                  Ú    #    Uniquify it
                   Ω   #    Pop and push a random value from this list
                }      #   Close the inner map
                 J     #   Join the list of characters back to a string-line

I'm not happy with }}`ø‚øεøεSÚΩ}J at all, but I'm unable to find something shorter to concat the values of two matrices. Adding values of two matrices together is no problem, since that is just +, but concatenation on the other hand.. (An equal-bytes alternative for this portion could be }}`øδ+εNèεÚΩ}J.)
Feel free to try and find something shorter here.

\$\endgroup\$
2
\$\begingroup\$

Perl 5 + -n0, 99 bytes

I'm hoping to continue working on this tonight, but this is a start (which I think covers the requirements?)

Accepts a rectangular multi-line string of 1s and 0s which are transliterated from # and space in the link.

while(/1/){say;/
/;($-)=@-;s/1(?!1)|(?<!1)1|(?<=0.{$-})1/0|rand 2/ges;1while s/1(.{$-})0/0${1}1/gs}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ @PyGamer0 Hmmm, it should be, it includes this code: Try it online! Did you see a specific example that was broken? \$\endgroup\$ Dec 6 '21 at 13:58
  • 1
    \$\begingroup\$ Seems to be working, my eyes have deceived me. \$\endgroup\$
    – PyGamer0
    Dec 6 '21 at 14:01
1
\$\begingroup\$

Python 3, 356 bytes

import random as r,re
y=lambda _:[' ','#'][r.choice([0,1])]
g=lambda x:[*map(''.join,zip(*[(' '*(len(x)-i.count('#')))+('#'*i.count('#'))for i in zip(*x)]))]
f=lambda x:[w:=g([re.sub('#' if not i else'#(?=[^#])|(?<=[^#])#',y,a)for i,a in enumerate(x)])]+(f(w)if any(i.strip()for i in w)else[])
h=lambda x:[*map('\n'.join,f([f' {i} 'for i in x.split('\n')]))]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.