46
\$\begingroup\$

Today is November 11th, which for many regions is Remembrance Day.

If you don't know anything about the history or context of Remembrance Day, you can read about it in the wiki page, but it's not relevant for this challenge.

In Flanders Fields is a poem that is pretty well-known relating to this day. It opens like so:

In Flanders fields the poppies blow
Between the crosses, row on row

Challenge

You will be given a grid with crosses (represented below as +) on it. Your task is to grow poppies between all crosses. That is, fill the space between any two crosses that are on the same row or column with poppies (represented below as *).

Example

....+....
...+.+...
.........
....+....
..+...+..
.........
..+...+..

This becomes:

....+....
...+*+...
....*....
....+....
..+***+..
..*...*..
..+***+..

Rigorously defined, on a non-cylindrical grid, each grid space is + if it was +, and becomes * if it has a + in the same column above and below it, or in the same row to its left and right.

Test Cases

.....+...    .....+...
+......+.    +******+.
....+.+.. -> *...+*+..
+.+...+..    +*+***+..
...++.+..    ...++*+..



.+.....    .+.....
....+..    .*..+..
...+..+    .*.+**+
.+++...    .+++*.*
....... -> .****.*
.+++.+.    .+++*+*
.++.++.    .++*++*
.......    .*....*
.+....+    .+****+



.......    .......
...+...    ...+...
.....++    .....++
++.....    ++...**
+....+. -> +****+*
.....+.    .....+*
.......    ......*
.......    ......*
..+...+    ..+***+



.+.+..    .+*+..
.....+    .*.*.+
+.....    +*.*.*
.+....    .+.*.*
...+.+ -> ...+*+
......    ......
......    ......
....+.    ....+.

Rules and Specifications

Input requires a grid of two distinct values. You can take this in any convenient format, and you can choose to use any reasonable convenient values, like 0 and 1, for example.

Output requires a grid of three distinct values. Again, you can deliver this in any reasonable, convenient format.

Standard loopholes apply.

This is a challenge, so the shortest solution in each language wins. No answer will be accepted.

(Sorry for posting another challenge, especially another one, so soon, but I really wanted to do something for 11/11 and I thought of it after my pattern expansion one)

\$\endgroup\$

14 Answers 14

7
\$\begingroup\$

Python 2, 131 125 bytes

f=lambda A,p=1:map(''.join,zip(*[re.sub('\+.+\+',lambda x:re.sub('\.','*',x.group()),s)for s in p and f(A,0)or A]))
import re

Try it online!

Input is a list of strings; as is output.

\$\endgroup\$
  • \$\begingroup\$ Ended up with similar approach, maybe it will help you 122 bytes \$\endgroup\$ – Dead Possum Nov 12 at 14:09
  • \$\begingroup\$ 121 bytes with your recursive approach \$\endgroup\$ – Dead Possum Nov 12 at 14:13
6
\$\begingroup\$

Jelly, 12 bytes

ẒT.ịr/Ṭ»)Z$⁺

A monadic Link accepting a list of lists where:

  • crosses, +, are 2
  • spaces, ., are 0

which yields a list of lists as above with poppies, *, as 1.

Try it online! Or see one which translates IO.

How?

ẒT.ịr/Ṭ»)Z$⁺ - Link: list of lists
          $  - last two links as a monad  - i.e. f(Rows):
        )    -   for each Row in Rows:
Ẓ            -     is prime? (vectorises) (isCross() that work's once poppies are planted)
 T           -     truthy indices e.g. [0,0,1,0,0,1,1,0] -> [3,6,7]
  .          -     literal one half
   ị         -     index into (the truthy indices)  -- non-integer indices reference the 
             -         items on either side of that location & indexing is 1-based and
             -         modular, so [last,first]  e.g. [3,6,7]->[7,3] or [8] -> [8,8]
     /       -     reduce by:
    r        -       inclusive range  e.g. [7,3]->[7,6,5,4,3] or [8,8]->[8]
      Ṭ      -     un-truth  e.g. [7,6,5,4,3]->[0,0,1,1,1,1,1] or [8]->[0,0,0,0,0,0,0,1]
       »     -     maximum (with Row) (vectorises) (keep crosses, plant poppies)
         Z   -   transpose
           ⁺ - repeat the last link (plant the remaining column poppies and transpose back)
\$\endgroup\$
5
\$\begingroup\$

PowerShell, 96 bytes

param($a)$a=&($g={($a=$a-replace'(?<=\+.*)\.(?=.*\+)','*')[0]|% t*y|%{-join$a.chars($i++)}});&$g

Try it online!

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

J, 44 bytes

'.*+'{~[:(+:+-.*](+.|:)&(>./\.*>./\)|:)=&'+'

Try it online!

No regex used:

  • Takes the product of the max scan of the prefixes and the max scan of the suffixes to turn the in-between cells to 1.
  • Does this for both the input and its transpose (to get both directions)
  • "Or"s these two matrices.
  • Multiplies by one minus the input, to get rid of endpoints (ie, original crosses)
  • Add double the original matrix to that.
  • After all this, in-between points in both directions are 1, original points are 2, rest are 0.
  • We use that to index into '.*+.
\$\endgroup\$
4
\$\begingroup\$

Jelly, 18 14 bytes

UÄUaÄa2
ZÇZoÇ_

Try it online!

-4 bytes because I figured out what I did wrong with my cumulative sums

Input and output is as two-dimensional lists with . mapped to 0, + mapped to 1, and * mapped to 2. (The footer on TIO converts automatically for convenience.)

           Helper link:
     a2    Fill in 2s wherever
    Ä      there's at least one truthy value to the left
UÄUa       and at least one truthy value to the right.
           This fills in poppies between (and on) all crosses horizontally.

   oÇ      Overlay the horizontal poppies
ZÇZ        on the vertical poppies,
     _     and subtract the crosses out to recover them.
\$\endgroup\$
4
\$\begingroup\$

Japt -h, 16 bytes

2Æ=Õ®Ëd0E©nFÊÉ}S

No regex!

Try it

2Æ=Õ®Ëd0E©nFÊÉ}S     U = input
2Æ                   2 times do:
  =                    Set U to
   Õ                     U transposed
    ®                    Map each row:
     Ë        }S           Split each row on spaces (crosses), 
                           and pass each chunk through the following function, 
                           then rejoin on spaces
                           For each chunk:
      d0                     Replace all 0's (empty spaces)             
        E©nFÊÉ               And replace with 1 if this chunk wasn't the first or last chunk
-h                   Take final result of second iteration
\$\endgroup\$
3
\$\begingroup\$

Ruby, 101 bytes

->s{g=->x{x.map(&:chars).transpose.map(&:join).map{|l|l[w=/\+.+\+/]&&l[w]=l[w].tr(?.,?*);l}};g[g[s]]}

Try it online!

Not really satisfied with it, but it's a starting point.

\$\endgroup\$
3
\$\begingroup\$

Retina 0.8.2, 80 bytes

+`#( *)#
#$.1$**#
+ms`^(((.))*#.*^(?<-2>.)*(?(2)$)) (.*^(?<-3>.)*(?(3)$)#)
$1*$4

Try it online! Includes header/footer that translates input/output between . and + to something more regex-friendly for the actual code. Explanation:

+`#( *)#
#$.1$**#

Repeatedly horizontally fill all s between #s. (Since this requires an unbroken run of s, this has to repeat until completion before the second stage runs.)

+ms`

Repeat as many times as necessary, allow ^ to match after a newline, and allow . to match newlines.

^(((.))*#.*

Look for a # and capture its indent twice.

^(?<-2>.)*(?(2)$)) (.*

Look for a at the same indent.

^(?<-3>.)*(?(3)$)#)

Look for another # at the same indent.

$1*$4

Replace the with a *.

\$\endgroup\$
3
\$\begingroup\$

Japt v2.0a0 -h, 22 21 19 13 bytes

Uses <space> for +, * for . & 1 for *.

2Æ=Õr/ .+ /È×

Try it (Header & footer convert I/O to characters used in spec)

2Æ=Õr/ .+ /È×     :Implicit input of string U
2Æ                :Map the range [0,2)
  =               :Reassign to U
   Õ              :Transpose U
    r/ .+ /       :Global RegEx replacement
           È      :Pass each match through a function
            ×     :  Replace all * with 1
                  :Implicit output of last element in array
\$\endgroup\$
3
\$\begingroup\$

JavaScript (Node.js), 85 bytes

a=>(g=m=>m[0].map((_,i)=>m.map(l=>l.join``.replace(/(?<=x.*)-(?=.*x)/g,8)[i])))(g(a))

Try it online!

Input / Output as character matrix. Use x for +, - for ., 8 for *.

First, convert dots . between two crosses + in a row into star *.

l.join``.replace(/(?<=\+.*)\.(?=.*\+)/g,'*')

Then. rotate the matrix

a=>m=>m[0].map((_,i)=>m.map(l=>l[i]))

Repeat twice, and get the result.

\$\endgroup\$
  • \$\begingroup\$ You could save a few by using different, non-RegEx characters in the input instead. \$\endgroup\$ – Shaggy Nov 12 at 21:00
  • \$\begingroup\$ ... and another 2 using a digit instead of '*'. \$\endgroup\$ – Shaggy Nov 13 at 11:37
  • \$\begingroup\$ @Shaggy you are right... \$\endgroup\$ – tsh Nov 14 at 1:47
2
\$\begingroup\$

Red, 160 154 bytes

func[b][loop 2[t: collect[until[parse keep rejoin
collect[forall b[keep take b/1]][any[thru"+"change
copy p to"+"(replace/all p".""*")]]empty? b/1]]b: t]]

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Perl 5 (-p), 80 bytes

/
/;$l="."x"@-";1while s/(\+\S*)\.(\S*\+)|(\+$l(.$l)*)\.($l(.$l)*\+)/$1$3*$2$5/s

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python 3.8, 354 bytes

e,r=enumerate,range
def f(s):
	s=s.split('\n')
	t=[(x,y) for y,i in e(s) for x,c in e(i) if c=='+']
	#t is the '+'es coordinates
	m=sum((l for x,y in t for u,v in t 
		if (x==u)!=(y==v)and x<=u and y<=v and
		(l:=[[(y,j)for j in r(x+1,u)],[(i,x)for i in r(y+1,v)]][x==u]) and
		#l is coordinates of cells between two '+'es
		all(s[i][j]=='.' for i,j in l)),[])
	return '\n'.join(''.join([c,'*'][(y,x) in m]for x,c in e(i))for y,i in e(s))

Try it online! (without comments or unnecessary white-space)

\$\endgroup\$
0
\$\begingroup\$

Japt -R, 19 bytes

yV=_gZa0 oZb0)_p
yV

Try it

U = U.y // for each columns
(V = function(Z) { return 
  Z.g // modify 
(Z.a(0).o(Z.b(0)), // indexes from first cross to Last cross
function(Z) { return Z.p() // power of 2: -1 => 1
 })  });
V = U.y(V); // repeat transposing

Outputs a matrix of values:
-1 -> ground,  1 -> poppies,  0 -> cross
Footer maps to [' ','○','+']

With the help of @Shaggy and @Embodiment of Ignorance

\$\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.