Changing all the colors in Lilypond - lilypond

In Lilypond I can change the color of one type of object with a line like
\override Staff.Clef #'color = #(rgb-color 0.4 0.5 0.6)
I'd like to have everything in the same (non-default) color, but I neither found a list of all the objects I could color nor did I find a command to change all the colors at once. Could anybody please point me to either?

The LilyPond Snippet Repository has a solution that iterates through the list of objects contained in all-grob-descriptions:
#(define (override-color-for-all-grobs color)
(lambda (context)
(let loop ((x all-grob-descriptions))
(if (not (null? x))
(let ((grob-name (caar x)))
(ly:context-pushpop-property context grob-name 'color color)
(loop (cdr x)))))))
% Example of usage:
\relative c' {
\applyContext #(override-color-for-all-grobs (x11-color 'blue))
c4\pp\< d e f
\grace { g16[( a g fis]) } g1\ff\!
}
Note that this will change the color of every graphical object only if you run it in the proper context (Score, I think, will generally suffice), so you may need to do the following if you're in the middle of, say, a Voice context:
\stopStaff
\context Score
\applyContext #(override-color-for-all-grobs (x11-color 'blue))
\startStaff

The list of graphical objects you need is at the bottom of this page. So a simple albeit tedious approach would be to iterate through all those objects you use, e.g.
\override Staff.Clef #'color = #(rgb-color 0.4 0.5 0.6)
\override Staff.NoteHead #'color = #(rgb-color 0.4 0.5 0.6)
\override Staff.Beam #'color = #(rgb-color 0.4 0.5 0.6)
\override Staff.Slur #'color = #(rgb-color 0.4 0.5 0.6)
etc.
There's probably a much better way but I can't figure it out. Alternatively, as has been suggested before you could consider doing some post-processing on the output from Lilypond, which may be simpler depending on the tools you have available.
I strongly recommend that you read the excellent documentation, in particular how to navigate the Internals Reference as covered by the Learning Manual and the Notation Reference
Also you may obtain a better answer from the lilypond-user mailing list.

Related

How can I use scipy interp1d with N-D array for x without for loop

How can I use scipy.interpolate.interp1d when my x array is an N-D array, instead of a 1-D array, without using a loop?
The function f from interp1d then needs to be used with numpy.percentile with one of the arrays as an input.
I think there should be a way to do it with a list comprehension or lambda function, but I am still learning these tools.
(Note that this is different than my recent question here because I mixed up the x and y arrays in the posted question, and this problem was not reproducible.)
Problem statement/example:
# a is y in interp1d docs
a = np.array([97,4809,4762,282,3879,17454,103,2376,40581,])
# b is x in interp1d docs
b = np.array([
[0.14,0.11,0.29,0.11,0.09,0.68,0.09,0.18,0.5,],
[0.32,0.25,0.67,0.25,0.21,1.56,1.60, 0.41,1.15,],]
)
Just trying this, below, fails with ValueError: x and y arrays must be equal in length along interpolation axis. The expected return is array(97, 2376). Using median here, but will need to consider 10th, 90th, etc. percentiles.
f = interpolate.interp1d(b, a, axis=0)
f(np.percentile(b, 50, axis=0))
However this, below, works and prints array(97.)
f = interpolate.interp1d(b[0,:], a, axis=0)
f(np.percentile(b[0,:], 50, axis=0))
A loop works, but I am wondering if there is a solution using list comprehensions, lambda functions, or some other technique.
l = []
for _i in range(b.shape[0]):
_f = interpolate.interp1d(b[_i,:], a, axis=0)
l.append(_f(np.percentile(b[_i,:], 50, axis=0)))
print(out)
# returns
# [array(97.), array(2376.)]
Efforts:
I understand I can loop through the b array with a list comprehension.
[b[i,:] for i in range(b.shape[0])]
# returns
# [array([0.14, 0.11, 0.29, 0.11, 0.09, 0.68, 0.09, 0.18, 0.5 ]),
# array([0.32, 0.25, 0.67, 0.25, 0.21, 1.56, 1.6 , 0.41, 1.15])]
And I also understand that I can use a list comprehension to create the scipy function f for each dimension in b:
[interpolate.interp1d(b[i, :], a, axis=0) for i in range(b.shape[0])]
# returns
# [<scipy.interpolate.interpolate.interp1d at 0x1b72e404360>,
# <scipy.interpolate.interpolate.interp1d at 0x1b72e404900>]
But I don't know how to combine these two list comprehensions to apply the np.percentile function.
Using Python 3.8.3, NumPy 1.18.5, SciPy 1.3.2
If you have large data arrays, you want to stay away from for loops, map, np.vectorize and comprehensions. They will all be slow. Instead, it's always better to use vectorized numpy or scipy operations whenever possible.
In this particular case, you can implement the vectorization pretty trivially yourself. interp1d defaults to a linear interpolation, which is very simple to code by hand. For a general interpolator, the first step would be to sort x and y, which is why scipy can't support multiple x for a given y. If the x rows all have different sort order, what do you do with the y?
Luckily, there are a couple of things you can do to make this much faster than having to build a full interpolator or argsort y multiple times. For example, start by argsorting x:
idx = b.argsort(axis=1)
idx is now an array such that b[np.arange(2)[:, None], idx] gives the sorted version of b along axis 1, and also, a[idx] is the corresponding y-values. Since you are taking the median (50th precentile), and the rows have an odd number of elements, the value of x is just the middle of each row, and y is given by
a[idx[:, len(a) // 2]]
If you had an even number of elements, you would have to average the elements surrounding the middle:
i = len(a) // 2 - 1
a[idx[:, i:i + 2]].mean(axis=1)
You can reduce algorithmic complexity by using np.argpartition instead of a full-blown np.argsort to get the middle element(s).
interp1d and other interpolators from scipy.interpolate only support 1D x arrays. So you'll need to loop over the dimensions of x manually.

How to bring back the colour to the dots in a fretboard in Lilypond 2.20?

I need help with a rather obscure problem. But important to me as an educator.
In Lilypond 2.18 and before, using the colouring scheme from the snippets (https://t1p.de/b7s8) I was able to colour the dots of the fretboard with the root note colour. I would simply use the code:
\override FretBoard #'color = #color-notehead.
(top part of the attached image)
When I upgraded to Lilypond 2.20, the colour from the dots vanished, replaced by black (as in the bottom part of the attached image).
I didn't change any of the code (which I can provide if needed).
Now, with
\override FretBoard #'(fret-diagram-details dot-color) = #'white
I can override the dot-colour to some static colours - but it's a far cry from the beauty of dynamically coloured dots.
Could someone advise where this went wrong?
Attached image with 2.18 and 2.20 renditions of the same code
Here's a Minimal code sample, which colours dynamically the dots by it's root note in 2.18, but leaves them with a static colour in 2.20
\version "2.20.0"
\header { title = "Guitar Chords"}
{
%Chords
\storePredefinedDiagram #default-fret-table \chordmode {a}
#guitar-tuning #"o;o;2-2;2-3;2-4;o;"
\storePredefinedDiagram #default-fret-table \chordmode {bes}
#guitar-tuning #"1-1-(;1-1;3-2;3-3;3-4;1-1-);"
\storePredefinedDiagram #default-fret-table \chordmode {c}
#guitar-tuning #"3-3;3-4;2-2;o;1-1;o;"
}
%Colour map
#(define color-mapping
(list
(cons (ly:make-pitch 0 0 NATURAL) (x11-color 'red3))
(cons (ly:make-pitch 0 5 NATURAL) (x11-color 'blue3))
(cons (ly:make-pitch 0 6 FLAT) (x11-color 'magenta3))
)
)
%Compare pitch and alteration (not octave).
#(define (pitch-equals? p1 p2)
(and
(= (ly:pitch-alteration p1) (ly:pitch-alteration p2))
(= (ly:pitch-notename p1) (ly:pitch-notename p2))))
#(define (pitch-to-color pitch)
(let ((color (assoc pitch color-mapping pitch-equals?)))
(if color
(cdr color))))
#(define (color-notehead grob)
(pitch-to-color
(ly:event-property (event-cause grob) 'pitch)))
chordNames = \chordmode { a2 bes c }
\score {
<<
\new ChordNames \chordNames
\new FretBoards
{ \override FretBoards.FretBoard #'size = #'2.0
\override FretBoard #'(fret-diagram-details finger-code) = #'in-dot
\override FretBoard #'(fret-diagram-details orientation) = #'portrait
%This command changes the colour of the fretboard (and used to change the dots in 2.18)
\override FretBoard #'color = #color-notehead
\chordNames
}
>>
}
On the Lilypond Forum, Harm posted a hack. When added, it colours the dots in the same colour as the fretboard. It's a temporary solution, but works as a charm.
\override FretBoards.FretBoard.before-line-breaking =
#(lambda (grob)
(ly:grob-set-nested-property! grob '(fret-diagram-details dot-color)
(color-dot grob)))

polygon-offsetting in GNU Octave

I have a simple, not self-intersecting polygonal chain and want to create a second polygonal chain with parallels with fixed distance.
I think this topic is called polygon offsetting or buffering (this finds for example An algorithm for inflating/deflating (offsetting, buffering) polygons)
MATLAB has bufferm and polybuffer but none of them is implemented in GNU Octave.
I've started my own implementation:
close all
rotm = #(a) [cos(a) -sin(a); sin(a) cos(a)];
h = 3; # distance from existing polygon
p = [1 5 18.7 21 34 34;
36.1 36.1 42.1 22.5 16.0 13];
dp = diff(p, [], 2);
a = atan2 (dp (2, :), dp(1, :));
da = diff (a);
horiz = abs (da) < 16 * eps;
f = 2 * h./sin(da).*sin(da/2);
f(horiz) = h;
f = [h f h];
r = a(1:end-1) + diff(a)/2;
r = pi/2 + [a(1) r a(end)];
p2 = zeros(size(p));
for k=1:columns(p)
p2(:,k) = p(:,k) + rotm(r(k)) * [f(k); 0];
line ([p(1, k);p2(1,k)], [p(2, k);p2(2,k)], "color", "magenta");
endfor
line (p(1, :), p(2, :), "color", "green");
line (p2(1, :), p2(2, :), "color", "red");
axis equal
grid on
but at that point I really think there might be an easier way to do this.
Is there an easier way or some already implemented function which might help?
(btw, I haven't vectorized the code yet)
This is not as simple as it may initallly seem. For example, offsetting complex
polygons involves collisions between the offsets:
Image from CGAL manual, Chap.16: 2D Straight Skeleton and Polygon Offsetting

Mathematica plot is a straight line

So I'm trying to knock out this last problem, and I'm following my teacher's guide but my graph seems to still be off, the problem is:
Use the FindRoot command in Mathematica to define an inverse function g(y) to y = f(x) = 3x + tan(x) with the restriction ‑pi/2 < x < pi/2. Use x = tan-1(y) as a starting value. Then use the Plot command to make a graph of g(y).
This is how I wrote it out:
g[y_] := x /. FindRoot[3 x + Tan[x] == y, {x, ArcTan[y]}]
Plot[g[y], {y, (-Pi/2), (Pi/2)}]
I'm not sure exactly what the problem is, but it shows the graph as just being a straight line through the origin. I'm not sure if this is how it's supposed to be (which I assume it's not), but any and all help would be much appreciated!
Having your equation,
3 x + Tan[x] == y
You can check the correctness of the plot of g(y) by plotting y(x):
Plot[3 x + Tan[x], {x, -.4, .4}]
As you can easily see, it is a straight line through the origin. g(y) is inverse of y(x) by definition, so you can get a plot of g(y) it just by exchanging the y and x axes:
Plot[3 x + Tan[x], {x, -.4, .4},
PlotRange -> All] /. {x_Real, y_Real} :> {y, x}

Code Golf: Rotating Maze

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Code Golf: Rotating Maze
Make a program that takes in a file consisting of a maze. The maze has walls given by #. The maze must include a single ball, given by a o and any number of holes given by a #. The maze file can either be entered via command line or read in as a line through standard input. Please specify which in your solution.
Your program then does the following:
1: If the ball is not directly above a wall, drop it down to the nearest wall.
2: If the ball passes through a hole during step 1, remove the ball.
3: Display the maze in the standard output (followed by a newline).
Extraneous whitespace should not be displayed.
Extraneous whitespace is defined to be whitespace outside of a rectangle
that fits snugly around the maze.
4: If there is no ball in the maze, exit.
5: Read a line from the standard input.
Given a 1, rotate the maze counterclockwise.
Given a 2, rotate the maze clockwise.
Rotations are done by 90 degrees.
It is up to you to decide if extraneous whitespace is allowed.
If the user enters other inputs, repeat this step.
6: Goto step 1.
You may assume all input mazes are closed. Note: a hole effectively acts as a wall in this regard.
You may assume all input mazes have no extraneous whitespace.
The shortest source code by character count wins.
Example written in javascript:
http://trinithis.awardspace.com/rotatingMaze/maze.html
Example mazes:
######
#o ##
######
###########
#o #
# ####### #
#### #
#########
###########################
# #
# # # #
# # # ##
# # ####o####
# # #
# #
# #########
# #
######################
Perl, 143 (128) char
172 152 146 144 143 chars,
sub L{my$o;$o.=$/while s/.$/$o.=$&,""/meg;$_=$o}$_.=<>until/
/;{L;1while s/o / o/;s/o#/ #/;L;L;L;print;if(/o/){1-($z=<>)||L;$z-2||L&L&L;redo}}
Newlines are significant.
Uses standard input and expects input to contain the maze, followed by a blank line, followed by the instructions (1 or 2), one instruction per line.
Explanation:
sub L{my$o;$o.="\n"while s/.$/$o.=$&,""/meg;$_=$o}
L is a function that uses regular expressions to rotate the multi-line expression $_ counterclockwise by 90 degrees. The regular expression was used famously by hobbs in my favorite code golf solution of all time.
$_.=<>until/\n\n/;
Slurps the input up to the first pair of consecutive newlines (that is, the maze) into $_.
L;1 while s/o / o/;s/o#/ */;
L;L;L;print
To drop the ball, we need to move the o character down one line is there is a space under it. This is kind of hard to do with a single scalar expression, so what we'll do instead is rotate the maze counterclockwise, move the ball to the "right". If a hole ever appears to the "right" of the ball, then the ball is going to fall in the hole (it's not in the spec, but we can change the # to an * to show which hole the ball fell into). Then before we print, we need to rotate the board clockwise 90 degrees (or counterclockwise 3 times) so that down is "down" again.
if(/o/) { ... }
Continue if there is still a ball in the maze. Otherwise the block will end and the program will exit.
1-($z=<>)||L;$z-2||L+L+L;redo
Read an instruction into $z. Rotate the board counterclockwise once for instruction "1" and three times for instruction "2".
If we used 3 more characters and said +s/o[#*]/ */ instead of ;s/o#/ */, then we could support multiple balls.
A simpler version of this program, where the instructions are "2" for rotating the maze clockwise and any other instruction for rotating counterclockwise, can be done in 128 chars.
sub L{my$o;$o.=$/while s/.$/$o.=$&,""/meg;$_=$o}$_.=<>until/
/;L;{1while s/o / o/+s/o#/ #/;L,L,L;print;if(/o/){2-<>&&L,L;redo}}
GolfScript - 97 chars
n/['']/~{;(#"zip-1%":|3*~{{." o"/"o "*"#o"/"# "*.#>}do}%|~.n*."o"/,(}{;\~(2*)|*~\}/\[n*]+n.+*])\;
This isn't done as well as I hoped (maybe later).
(These are my notes and not an explanation)
n/['']/~ #[M I]
{
;(# #[I c M]
"zip-1%":|3*~ #rotate
{{." o"/"o "*"#o"/"# "*.#>}do}% #drop
|~ #rotate back
.n* #"display" -> [I c M d]
."o"/,( #any ball? -> [I c M d ?]
}{ #d is collected into an array -> [I c M]
;\~(2*)|*~ #rotate
\ #stack order
}/
\[n*]+n.+*])\; #output
Rebmu: 298 Characters
I'm tinkering with with my own experiment in Code Golf language design! I haven't thrown matrix tricks into the standard bag yet, and copying GolfScript's ideas will probably help. But right now I'm working on refining the basic gimmick.
Anyway, here's my first try. The four internal spaces are required in the code as it is, but the line breaks are not necessary:
.fFS.sSC L{#o#}W|[l?fM]H|[l?m]Z|[Tre[wH]iOD?j[rvT]t]
Ca|[st[xY]a KrePC[[yBKx][ntSBhXbkY][ntSBhYsbWx][xSBwY]]ntJskPCmFkSk]
Ga|[rtYsZ[rtXfZ[TaRE[xY]iTbr]iTbr]t]B|[gA|[ieSlFcA[rnA]]]
MeFI?a[rlA]aFV[NbIbl?n[ut[++n/2 TfCnIEfLtBRchCbSPieTHlTbrCHcNsLe?sNsZ]]
gA|[TfCaEEfZfA[prT][pnT]nn]ulBbr JmoADjPC[3 1]rK4]
It may look like a cat was on my keyboard. But once you get past a little space-saving trick (literally saving spaces) called "mushing" it's not so bad. The idea is that Rebmu is not case sensitive, so alternation of capitalization runs is used to compress the symbols. Instead of doing FooBazBar => foo baz bar I apply distinct meanings. FOObazBAR => foo: baz bar (where the first token is an assignment target) vs fooBAZbar => foo baz bar (all ordinary tokens).
When the unmush is run, you get something more readable, but expanded to 488 characters:
. f fs . s sc l: {#o#} w: | [l? f m] h: | [l? m] z: | [t: re [w h] i od?
j [rv t] t] c: a| [st [x y] a k: re pc [[y bk x] [nt sb h x bk y] [nt sb
h y sb w x] [x sb w y]] nt j sk pc m f k s k] g: a| [rt y s z [rt x f z
[t: a re [x y] i t br] i t br] rn t] b: | [g a| [ie s l f c a [rn a]]]
m: e fi? a [rl a] a fv [n: b i bl? n [ut [++ n/2 t: f c n ie f l t br
ch c b sp ie th l t br ch c n s l e? s n s z]] g a| [t: f c a ee f z f
a [pr t] [pn t] nn] ul b br j: mo ad j pc [3 1] r k 4]
Rebmu can run it expanded also. There are also verbose keywords as well (first instead of fs) and you can mix and match. Here's the function definitions with some comments:
; shortcuts f and s extracting the first and second series elements
. f fs
. s sc
; character constants are like #"a", this way we can do fL for #"#" etc
L: {#o#}
; width and height of the input data
W: | [l? f m]
H: | [l? m]
; dimensions adjusted for rotation (we don't rotate the array)
Z: | [t: re [w h] i od? j [rv t] t]
; cell extractor, gives series position (like an iterator) for coordinate
C: a| [
st [x y] a
k: re pc [[y bk x] [nt sb h x bk y] [nt sb h y sb w x] [x sb w y]] nt j
sk pc m f k s k
]
; grid enumerator, pass in function to run on each cell
G: a| [rt y s z [rt x f z [t: a re [x y] i t br] i t br] t]
; ball position function
B: | [g a| [ie sc l f c a [rn a]]]
W is the width function and H is the height of the original array data. The data is never rotated...but there is a variable j which tells us how many 90 degree right turns we should apply.
A function Z gives us the adjusted size for when rotation is taken into account, and a function C takes a coordinate pair parameter and returns a series position (kind of like a pointer or iterator) into the data for that coordinate pair.
There's an array iterator G which you pass a function to and it will call that function for each cell in the grid. If the function you supply ever returns a value it will stop the iteration and the iteration function will return that value. The function B scans the maze for a ball and returns coordinates if found, or none.
Here's the main loop with some commenting:
; if the command line argument is a filename, load it, otherwise use string
m: e fi? a [rl a] a
; forever (until break, anyway...)
fv [
; save ball position in n
n: B
; if n is a block type then enter a loop
i bl? n [
; until (i.e. repeat until)
ut [
; increment second element of n (the y coordinate)
++ n/2
; t = first(C(n))
t: f C n
; if-equal(first(L), t) then break
ie f l t br
; change(C(B), space)
ch C B sp
; if-equal(third(L),t) then break
ie th L t br
; change(C(n), second(L))
ch C n s L
; terminate loop if "equals(second(n), second(z))"
e? s n s z
]
]
; iterate over array and print each line
g a| [t: f c a ee f z f a [pr t] [pn t] nn]
; unless the ball is not none, we'll be breaking the loop here...
ul b br
; rotate according to input
j: mo ad j pc [3 1] r k 4
]
There's not all that much particularly clever about this program. Which is part of my idea, which is to see what kind of compression one could get on simple, boring approaches that don't rely on any tricks. I think it demonstrates some of Rebmu's novel potential.
It will be interesting to see how a better standard library could affect the brevity of solutions!
Latest up-to-date commented source available on GitHub: rotating-maze.rebmu
Ruby 1.9.1 p243
355 353 characters
I'm pretty new to Ruby, so I'm sure this could be a lot shorter - theres probably some nuances i'm missing.
When executed, the path to the map file is the first line it reads. I tried to make it part of the execution arguments (would have saved 3 characters), but had issues :)
The short version:
def b m;m.each_index{|r|i=m[r].index(?o);return r,i if i}end;def d m;x,y=b m;z=x;
while z=z+1;c=m[z][y];return if c==?#;m[z-1][y]=" "; return 1 if c==?#;m[z][y]=?o;end;end;
def r m;m.transpose.reverse;end;m=File.readlines(gets.chomp).map{|x|x.chomp.split(//)};
while a=0;w=d m;puts m.map(&:join);break if w;a=gets.to_i until 0<a&&a<3;
m=r a==1?m:r(r(m));end
The verbose version:
(I've changed a bit in the compressed version, but you get the idea)
def display_maze m
puts m.map(&:join)
end
def ball_pos m
m.each_index{ |r|
i = m[r].index("o")
return [r,i] if i
}
end
def drop_ball m
x,y = ball_pos m
z=x
while z=z+1 do
c=m[z][y]
return if c=="#"
m[z-1][y]=" "
return 1 if c=="#"
m[z][y]="o"
end
end
def rot m
m.transpose.reverse
end
maze = File.readlines(gets.chomp).map{|x|x.chomp.split(//)}
while a=0
win = drop_ball maze
display_maze maze
break if win
a=gets.to_i until (0 < a && a < 3)
maze=rot maze
maze=rot rot maze if a==1
end
Possible improvement areas:
Reading the maze into a clean 2D array (currently 55 chars)
Finding and returning (x,y) co-ordinates of the ball (currently 61 chars)
Any suggestions to improve are welcome.
Haskell: 577 509 527 244 230 228 chars
Massive new approach: Keep the maze as a single string!
import Data.List
d('o':' ':x)=' ':(d$'o':x)
d('o':'#':x)=" *"++x
d(a:x)=a:d x
d e=e
l=unlines.reverse.transpose.lines
z%1=z;z%2=l.l$z
t=putStr.l.l.l
a z|elem 'o' z=t z>>readLn>>=a.d.l.(z%)|0<1=t z
main=getLine>>=readFile>>=a.d.l
Nods to #mobrule's Perl solution for the idea of dropping the ball sideways!
Python 2.6: ~ 284 ~ characters
There is possibly still room for improvement (although I already got it down a lot since the first revisions).
All comments or suggestions more then welcome!
Supply the map file on the command line as the first argument:
python rotating_maze.py input.txt
import sys
t=[list(r)[:-1]for r in open(sys.argv[1])]
while t:
x=['o'in e for e in t].index(1);y=t[x].index('o')
while t[x+1][y]!="#":t[x][y],t[x+1][y]=" "+"o#"[t[x+1][y]>" "];x+=1
for l in t:print''.join(l)
t=t[x][y]=='o'and map(list,(t,zip(*t[::-1]),zip(*t)[::-1])[input()])or 0
C# 3.0 - 650 638 characters
(not sure how newlines being counted)
(leading whitespace for reading, not counted)
using System.Linq;
using S=System.String;
using C=System.Console;
namespace R
{
class R
{
static void Main(S[]a)
{
S m=S.Join("\n",a);
bool u;
do
{
m=L(m);
int b=m.IndexOf('o');
int h=m.IndexOf('#',b);
b=m.IndexOf('#',b);
m=m.Replace('o',' ');
u=(b!=-1&b<h|h==-1);
if (u)
m=m.Insert(b-1,"o").Remove(b,1);
m=L(L(L(m)));
C.WriteLine(m);
if (!u) return;
do
{
int.TryParse(C.ReadLine(),out b);
u=b==1|b==2;
m=b==1?L(L(L(m))):u?L(m):m;
}while(!u);
}while(u);
}
static S L(S s)
{
return S.Join("\n",
s.Split('\n')
.SelectMany(z => z.Select((c,i)=>new{c,i}))
.GroupBy(x =>x.i,x=>x.c)
.Select(g => new S(g.Reverse().ToArray()))
.ToArray());
}
}
}
Reads from commandline, here's the test line I used:
"###########" "#o #" "# ####### #" "#### #" " #########"
Relied heavily on mobrule's Perl answer for algorithm.
My Rotation method (L) can probably be improved.
Handles wall-less case.