I am writing a function similar to this to read in binary formatted .ply files.
The linked function reads the header and the skips to the binary array, reading that in with numpy and I would like to do the same in Octave.
My code for reading the header is
fid = fopen('/path/to/file.ply');
tline = fgetl(fid); % read first line
len = 0;
prop = {};
dtype = {};
fmt = 'binary';
while ~strcmp(tline, "end_header")
len = len + length(tline) + 1; % increase header length, +1 includes EOL
tline = strsplit(tline); % split string
if strcmp('format', tline{1}) && strcmp('ascii', tline{2}) % test whether file is ascii
fmt = 'ascii';
end
if strcmp('element', tline{1}) && strcmp('vertex', tline{2}) % number of points
N = tline{3};
end
if strcmp('property', tline{1}) % identify fields
dtype = [dtype, tline{2}];
prop = [prop, tline{3}];
end
tline = fgetl(fid);
end
len = len + length(tline) + 1; % add 'end_header' to len
So I have arrays of data types
dtype =
{
[1,1] = float
[1,2] = float
[1,3] = float
[1,4] = int
[1,5] = int
[1,6] = int
[1,7] = float
[1,8] = float
[1,9] = float
}
and I know the shape of the array.
N = 61415
Is there a function that replicates numpy's fromfile and can I seek to the right location in my file (I know where the binary data starts in the file as I have len)
Following #tasos-papastylianou answer I tried
fseek(fid, len);
fread(fid, 3, 'float')
Which returns the correct 3 values, but the next value is an integer and therefore gives the incorrect answer.
fread(fid, 4, 'float')
arr =
-1.4298e+00
-5.3943e+00
1.6623e+01
1.5274e-43 <<<< should be 109
My solution
function pts = read_ply(fn)
fid = fopen(fn);
tline = fgetl(fid); % read first line
len = 0;
prop = {};
% dtype_map = {'float': 'f4', 'uchar': 'B', 'int':'i'}
dtype = {};
fmt = 'binary';
while ~strcmp(tline, "end_header")
len = len + length(tline) + 1; % increase header length, +1 includes EOL
tline = strsplit(tline); % split string
if strcmp('format', tline{1}) && strcmp('ascii', tline{2}) % test whether file is ascii
fmt = 'ascii';
elseif strcmp('element', tline{1}) && strcmp('vertex', tline{2}) % number of points
N = str2num(tline{3});
elseif strcmp('property', tline{1}) % identify fields
dtype = [dtype, tline{2}];
prop = [prop, tline{3}];
endif
tline = fgetl(fid);
endwhile
len = len + length(tline) + 1; % add 'end_header
% total file length minus header
fseek(fid, 0, 1);
file_length = ftell(fid) - len;
types = struct('float', 4, 'int', 4, 'float64', 8);
pts = struct();
seek_plus = 0;
for i = 1:length(prop)
fseek(fid, len + seek_plus);
dt = types.(dtype{i}); % dtype for field
pts.(prop{i}) = fread(fid, N, dtype{i}, int32(file_length / N) - dt);
seek_plus = seek_plus + dt;
endfor
This does not answer my original question as it involves a loop, but it seems fairly efficient. Arrays can be constructed as so.
xyz = [pts.x, pts.y, pts.z];
Your question confuses me a bit towards the end, since the most direct equivalent to numpy's saving an array in a numpy-specific binary format is octave's save which saves an array to an octave-specific binary format.
Having said that, this doesn't sound like what you want so I'm assuming the fromfile reference is a red herring.
In general if you have a binary file you want to open, read, or seek (i.e. place the cursor at a particular position), you can use the fopen, fread, and fseek commands. Also useful, ftell, frewind, etc.
These are all fairly simple commands. Just have a look at their documentation in the terminal (e.g. help fseek ).
I am trying to write a functionality, (using macro, generated function or something), that effectively vectorizes Julia function calls to functions that I've written. Basically, I'm trying to write my own version of the #. macro, but instead, I'd like it to accept functions instead of a for loop--- if I understand this correctly. Here are some documents that I've read on the subject:
https://docs.julialang.org/en/v1/manual/functions/#man-vectorized-1
https://github.com/JuliaLang/julia/blob/master/base/broadcast.jl
https://julialang.org/blog/2017/01/moredots
https://docs.julialang.org/en/v1/manual/metaprogramming/index.html#Code-Generation-1
Here is my preliminary toy example that I'm working with to achieve such a functionality:
function add!(v_add::Vector{Float64}, a_add::Float64, j::Int64)
v_add[j] = v_add[j]+a_add
end
function add!(v_add::Vector{Float64}, a_add::Float64)
for j in 1:length(v_add)
v_add[j] = v_add[j]+a_add
end
end
macro vectorize(args)
print("\n****************** args\n")
print(args)
print("\n******************\n")
e = :(:call,
$args[1],
$args[2],
$args[3])
print("\n****************** expression\n")
show(e)
print(e)
print("\n******************\n")
return e
end
function test!(v_test, a_test)
# # Traverse vector twice
# add!(v_test, a_test)
# add!(v_test, a_test)
# Traverse vector once
args = [
add!, v_test, a_test,
add!, v_test, a_test
]
e = #vectorize(args)
# eval(e) # Next step
end
v_main = Vector([Float64(i) for i in 1:3])
a_main = Float64(2.0)
print("\n",v_main, "\n")
Main.test!(v_main, a_main)
print("\n",v_main, "\n")
The problem I'm having so far is that I can't even get the de-vectorized version running using macros. This example results in the LoadError: UndefVarError: args not defined. I would definitely appreciate any help in getting this script working as expected (input is [1, 2, 3], and output should be [5, 6, 7]).
Any help/suggestions are greatly appreciated.
Update
More concretely, given the following defined functions:
function add!(v::Vector{Float64}, a::Float64)
for j in 1:length(v)
v[j]+= a
end
end
function add!(v::Vector{Float64}, a::Float64, j::Int64)
v[j]+= a
end
I would like to be able to use a macro to convert the following lines of code:
v = [Float64(j) for j in 1:10]
a = 1
b = 2
#vectorize_I_would_like_to_define(
# I don't know the exact form that the args to this macro should take.
add!(v, a),
add!(v, b)
)
To generate code that is compiled like this:
v = [Float64(j) for j in 1:10]
a = 1
b = 2
for j in 1:length(v)
add!(v, a, j)
add!(v, b, j)
end
My goal is to write code that requires a single memory traversal.
Even better, if I could generate code that looks like this at compile time:
v = [Float64(j) for j in 1:10]
a = 1
b = 2
for j in 1:length(v)
v[j]+= a # taken from add!(v::Vector{Float64}, a::Float64, j::Int64)
v[j]+= b # taken from add!(v::Vector{Float64}, a::Float64, j::Int64)
end
But I'm not sure if this is as feasable for more complex cases that I'm considering compared to this toy example.
** Update 2**
Here is a MWE of #Bogumił Kamiński's solution---except that I've moved the macro call into a function, so now it doesn't work because it complains that v_test is not defined.
macro vectorize(args...)
expr = :()
for arg in args
a = deepcopy(arg) # for safety in case arg is also used somewhere else
push!(a.args, :j)
expr = :($expr; $a)
end
quote
for j in 1:length(v)
$expr
end
end
end
function add!(v::Vector{Float64}, a::Float64)
for j in 1:length(v)
v[j]+= a
end
end
function add!(v::Vector{Float64}, a::Float64, j::Int64)
v[j]+= a
end
v = [Float64(j) for j in 1:10]
a = 1.0
b = 2.0
function test!(v_test, a_test, b_test)
#vectorize(
add!(v_test, a_test),
add!(v_test, b_test)
)
end
test!(v, a, b)
Is this what you want?
macro vectorize(args...)
expr = :()
for arg in args
a = deepcopy(arg) # for safety in case arg is also used somewhere else
push!(a.args, :j)
expr = :($expr; $a)
end
quote
for j in 1:length(v)
$expr
end
end
end
and now
function add!(v::Vector{Float64}, a::Float64)
for j in 1:length(v)
v[j]+= a
end
end
function add!(v::Vector{Float64}, a::Float64, j::Int64)
v[j]+= a
end
v = [Float64(j) for j in 1:10]
a = 1.0
b = 2.0
#vectorize(add!(v, a), add!(v, b))
Note that I have changed a and b definitions as your add! required Float64 as a second argument.
EDIT: If you want to use this macro inside a function the simplest thing to do is to esc its whole return value:
macro vectorize(args...)
expr = :()
for arg in args
a = deepcopy(arg) # for safety in case arg is also used somewhere else
push!(a.args, :j)
expr = :($expr; $a)
end
esc(quote
for j in 1:length(v)
$expr
end
end)
end
Then you can define e.g.:
function f()
v = [Float64(j) for j in 1:10]
a = 1.0
b = 2.0
#vectorize(add!(v, a), add!(v, b))
v
end
and run f() to get the same result as above in global scope.
EDIT 2: I just realized that actually I have to sanitize j as otherwise the following code will fail:
test!(v_test, j, b_test) =
#vectorize(add!(v_test, j), add!(v_test, b_test))
Here is how you should do it:
macro vectorize(args...)
expr = :()
j = gensym()
for arg in args
a = deepcopy(arg) # for safety in case arg is also used somewhere else
push!(a.args, j)
expr = :($expr; $a)
end
esc(quote
for $j in 1:length(v)
$expr
end
end)
end
As you can see developing macros is a non-obvious task (hopefully the final recipe is bug-free :)).
EDIT 3: Here is the code that correctly handles length. Also now in each expression actually you can pass a different value as a first argument (so you can independently process different vectors). If you do want to process the same vector check is a.args[2] is always the same symbol:
macro vectorize(args...)
expr = :()
j = gensym()
for arg in args
a = deepcopy(arg) # for safety in case arg is also used somewhere else
var = a.args[2]
push!(a.args, j)
q = quote
for $j in 1:length($var)
$a
end
end
expr = :($expr; $q)
end
esc(expr)
end
For my encryption code, I am trying to a return a value from one function because it is used in the next. I keep getting an error, telling me that the name 'cipher_text' is not defined. Please help!
Error:
(line 7)
decryption (cipher_text, shift)
NameError: name 'cipher_text' is not defined
def main():
user_input = input ("Enter string: ")
shift = int(input ("Enter a shift that is between 1 and 26: "))
while shift<1 or shift>26:
shift = input ("ERROR: Shift must be between 1 and 26: ")
encryption (user_input, shift)
decryption (cipher_text, shift)
frequency (user_input)
def frequency(user_input):
freq_char = None
for char in user_input:
charcount = user_input.count(char)
if (charcount != 0):
freq_char = char
print (freq_char)
return fre_char
def encryption(user_input, shift):
cipher_text = ''
for char in user_input: #for every character in input
if char == ' ':
cipher = char
cipher_text += cipher
else:
cipher_num = (ord(char))+(shift)%26 #using ordinal to find the number
cipher= ''
cipher = chr(cipher_num)# using chr to convert back to a letter
cipher_text += cipher
print ("The encrypted text is:",cipher_text)
return(cipher_text)
def decryption (cipher_text, shift):
decrypt_text = ''
cipher_text = ''
for char in cipher_text: #for every character in the encrpted text
decrypt_num = (ord(char))+(int(shift))%26
decrypt= ''
decrypt = chr(decrypt_num)
decrypt_text += decrypt
print("The decrypted text is:", decrypt_text)
return(decrypt_text)
main()
Your problem is in the lines
encryption (user_input, shift)
decryption (cipher_text, shift)
as the exception tells you. If you had included the traceback with your question this would be very clear.
Variables you declare in one function are local to that function. This is a good thing! It lets you write functions like
def foo():
x = 1
return x * x
def bar():
for x in xrange(10):
print "Count: %s" % x
without them blowing each other up.
If you call a function that returns something and you want to use it, you need to use it directly, or assign it to something:
# assign
x = foo()
print x
# use directly
print "x is %s" % foo()
in your case, you can make a minimal change to assign the result of encryption to a new variable cipher_text
def main():
...
cipher_text = encryption(user_input, shift)
decryption(cipher_text, shift)
it would be equivalent (though less clear) to call this anything else
foobar = encryption(user_input, shift)
decryption(foobar, shift)
or even to avoid use of a variable altogether
decryption(encryption(user_input, shift), shift)
def main() should be def main(cipher_text)
You can also set a default value for cipeher_text:
def main(cipher_text=""):
user_input = input ("Enter string: ")
shift = int(input ("Enter a shift that is between 1 and 26: "))
while shift<1 or shift>26:
shift = input ("ERROR: Shift must be between 1 and 26: ")
encryption (user_input, shift)
decryption (cipher_text, shift)
frequency (user_input)
And then just call main() using a value example main('some value') or just empty if you defined a default value as said before.
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.
The challenge
The shortest code by character count to solve the input lights out board.
The lights out board is a 2d square grid of varying size composed of two characters - . for a light that is off and * for a light that is on.
To solve the board, all "lights" have to be turned off. Toggling a light (i.e. turning off when it is on, turning on when it is off) is made 5 lights at a time - the light selected and the lights surround it in a + (plus) shape.
"Selecting" the middle light will solve the board:
.*.
***
.*.
Since Lights Out! solution order does not matter, the output will be a new board with markings on what bulbs to select. The above board's solution is
...
.X.
...
Turning off a light in a corner where there are no side bulbs to turn off will not overflow:
...
..*
.**
Selecting the lower-right bulb will only turn off 3 bulbs in this case.
Test cases
Input:
**.**
*.*.*
.***.
*.*.*
**.**
Output:
X...X
.....
..X..
.....
X...X
Input:
.*.*.
**.**
.*.*.
*.*.*
*.*.*
Output:
.....
.X.X.
.....
.....
X.X.X
Input:
*...*
**.**
..*..
*.*..
*.**.
Output:
X.X.X
..X..
.....
.....
X.X..
Code count includes input/output (i.e full program).
Perl, 172 characters
Perl, 333 251 203 197 190 172 characters. In this version, we randomly push buttons until all of the lights are out.
map{$N++;$E+=/\*/*1<<$t++for/./g}<>;
$C^=$b=1<<($%=rand$t),
$E^=$b|$b>>$N|($%<$t-$N)*$b<<$N|($%%$N&&$b/2)|(++$%%$N&&$b*2)while$E;
die map{('.',X)[1&$C>>$_-1],$_%$N?"":$/}1..$t
Haskell, 263 characters (277 and 285 before edit) (according to wc)
import List
o x=zipWith4(\a b c i->foldr1(/=)[a,b,c,i])x(f:x)$tail x++[f]
f=0>0
d t=mapM(\_->[f,1>0])t>>=c t
c(l:m:n)x=map(x:)$c(zipWith(/=)m x:n)$o x l
c[k]x=[a|a<-[[x]],not$or$o x k]
main=interact$unlines.u((['.','X']!!).fromEnum).head.d.u(<'.').lines
u=map.map
This includes IO code : you can simply compile it and it works.
This method use the fact that once the first line of the solution is determined, it is easy to determine what the other lines should look like. So we try every solution for the first line, and verify that the all lights are off on the last line, and this algorithm is O(n²*2^n)
Edit : here is an un-shrunk version :
import Data.List
-- xor on a list. /= works like binary xor, so we just need a fold
xor = foldr (/=) False
-- what will be changed on a line when we push the buttons :
changeLine orig chg = zipWith4 (\a b c d -> xor [a,b,c,d]) chg (False:chg) (tail chg ++ [False]) orig
-- change a line according to the buttons pushed one line higher :
changeLine2 orig chg = zipWith (/=) orig chg
-- compute a solution given a first line.
-- if no solution is given, return []
solution (l1:l2:ls) chg = map (chg:) $ solution (changeLine2 l2 chg:ls) (changeLine l1 chg)
solution [l] chg = if or (changeLine l chg) then [] else [[chg]]
firstLines n = mapM (const [False,True]) [1..n]
-- original uses something equivalent to "firstLines (length gris)", which only
-- works on square grids.
solutions grid = firstLines (length $ head grid) >>= solution grid
main = interact $ unlines . disp . head . solutions . parse . lines
where parse = map (map (\c ->
case c of
'.' -> False
'*' -> True))
disp = map (map (\b -> if b then 'X' else '.'))
Ruby, 225 221
b=$<.read.split
d=b.size
n=b.join.tr'.*','01'
f=2**d**2
h=0
d.times{h=h<<d|2**d-1&~1}
f.times{|a|e=(n.to_i(2)^a^a<<d^a>>d^(a&h)>>1^a<<1&h)&f-1
e==0&&(i=("%0*b"%[d*d,a]).tr('01','.X')
d.times{puts i[0,d]
i=i[d..-1]}
exit)}
F#, 672 646 643 634 629 628 chars (incl newlines)
EDIT: priceless: this post triggered Stackoverflow's human verification system. I bet it's because of the code.
EDIT2: more filthy tricks knocked off 36 chars. Reversing an if in the second line shaved off 5 more.
Writing this code made my eyes bleed and my brain melt.
The good: it's short(ish).
The bad: it'll crash on any input square larger than 4x4 (it's an O(be stupid and try everything) algorithm, O(n*2^(n^2)) to be more precise). Much of the ugliness comes from padding the input square with zeroes on all sides to avoid edge and corner cases.
The ugly: just look at it. It's code only a parent could love. Liberal uses of >>> and <<< made F# look like brainfuck.
The program accepts rows of input until you enter a blank line.
This code doesn't work in F# interactive. It has to be compiled inside a project.
open System
let rec i()=[let l=Console.ReadLine()in if l<>""then yield!l::i()]
let a=i()
let m=a.[0].Length
let M=m+2
let q=Seq.sum[for k in 1..m->(1L<<<m)-1L<<<k*M+1]
let B=Seq.sum(Seq.mapi(fun i s->Convert.ToInt64(String.collect(function|'.'->"0"|_->"1")s,2)<<<M*i+M+1)a)
let rec f B x=function 0L->B&&&q|n->f(if n%2L=1L then B^^^(x*7L/2L+(x<<<M)+(x>>>M))else B)(x*2L)(n/2L)
let z=fst<|Seq.find(snd>>(=)0L)[for k in 0L..1L<<<m*m->let n=Seq.sum[for j in 0..m->k+1L&&&(((1L<<<m)-1L)<<<j*m)<<<M+1+2*j]in n,f B 1L n]
for i=0 to m-1 do
for j=0 to m-1 do printf"%s"(if z&&&(1L<<<m-j+M*i+M)=0L then "." else "X")
printfn""
F#, 23 lines
Uses brute force and a liberal amount of bitmasking to find a solution:
open System.Collections
let solve(r:string) =
let s = r.Replace("\n", "")
let size = s.Length|>float|>sqrt|>int
let buttons =
[| for i in 0 .. (size*size)-1 do
let x = new BitArray(size*size)
{ 0 .. (size*size)-1 } |> Seq.iter (fun j ->
let toXY n = n / size, n % size
let (ir, ic), (jr, jc) = toXY i, toXY j
x.[j] <- ir=jr&&abs(ic-jc)<2||ic=jc&&abs(ir-jr)<2)
yield x |]
let testPerm permutation =
let b = new BitArray(s.Length)
s |> Seq.iteri (fun i x -> if x = '*' then b.[i] <- true)
permutation |> Seq.iteri (fun i x -> if x = '1' then b.Xor(buttons.[i]);() )
b |> Seq.cast |> Seq.forall (fun x -> not x)
{for a in 0 .. (1 <<< (size * size)) - 1 -> System.Convert.ToString(a, 2).PadLeft(size * size, '0') }
|> Seq.pick (fun p -> if testPerm p then Some p else None)
|> Seq.iteri (fun i s -> printf "%s%s" (if s = '1' then "X" else ".") (if (i + 1) % size = 0 then "\n" else "") )
Usage:
> solve ".*.
***
.*.";;
...
.X.
...
val it : unit = ()
> solve "**.**
*.*.*
.***.
*.*.*
**.**";;
..X..
X.X.X
..X..
X.X.X
..X..
val it : unit = ()
> solve "*...*
**.**
..*..
*.*..
*.**.";;
.....
X...X
.....
X.X.X
....X
C89, 436 characters
Original source (75 lines, 1074 characters):
#include <stdio.h>
#include <string.h>
int board[9][9];
int zeroes[9];
char presses[99];
int size;
int i;
#define TOGGLE { \
board[i][j] ^= 4; \
if(i > 0) \
board[i-1][j] ^= 4; \
if(j > 0) \
board[i][j-1] ^= 4; \
board[i+1][j] ^= 4; \
board[i][j+1] ^= 4; \
presses[i*size + i + j] ^= 118; /* '.' xor 'X' */ \
}
void search(int j)
{
int i = 0;
if(j == size)
{
for(i = 1; i < size; i++)
{
for(j = 0; j < size; j++)
{
if(board[i-1][j])
TOGGLE
}
}
if(memcmp(board[size - 1], zeroes, size * sizeof(int)) == 0)
puts(presses);
for(i = 1; i < size; i++)
{
for(j = 0; j < size; j++)
{
if(presses[i*size + i + j] & 16)
TOGGLE
}
}
}
else
{
search(j+1);
TOGGLE
search(j+1);
TOGGLE
}
}
int main(int c, char **v)
{
while((c = getchar()) != EOF)
{
if(c == '\n')
{
size++;
i = 0;
}
else
board[size][i++] = ~c & 4; // '.' ==> 0, '*' ==> 4
}
memset(presses, '.', 99);
for(c = 1; c <= size; c++)
presses[c * size + c - 1] = '\n';
presses[size * size + size] = '\0';
search(0);
}
Compressed source, with line breaks added for your sanity:
#define T{b[i][j]^=4;if(i)b[i-1][j]^=4;if(j)b[i][j-1]^=4;b[i+1][j]^=4;b[i][j+1]^=4;p[i*s+i+j]^=118;}
b[9][9],z[9],s,i;char p[99];
S(j){int i=0;if(j-s){S(j+1);T S(j+1);T}else{
for(i=1;i<s;i++)for(j=0;j<s;j++)if(b[i-1][j])T
if(!memcmp(b[s-1],z,s*4))puts(p);
for(i=1;i<s;i++)for(j=0;j<s;j++)if(p[i*s+i+j]&16)T}}
main(c){while((c=getchar())+1)if(c-10)b[s][i++]=~c&4;else s++,i=0;
memset(p,46,99);for(c=1;c<=s;c++)p[c*s+c-1]=10;p[s*s+s]=0;S(0);}
Note that this solution assumes 4-byte integers; if integers are not 4 bytes on your system, replace the 4 in the call to memcmp with your integer size. The maximum sized grid this supports is 8x8 (not 9x9, since the bit flipping ignores two of the edge cases); to support up to 98x98, add another 9 to the array sizes in the declarations of b, z and p and the call to memset.
Also note that this finds and prints ALL solutions, not just the first solution. Runtime is O(2^N * N^2), where N is the size of the grid. The input format must be perfectly valid, as no error checking is performed -- it must consist of only ., *, and '\n', and it must have exactly N lines (i.e. the last character must be a '\n').
Ruby:
class Array
def solve
carry
(0...(2**w)).each {|i|
flip i
return self if solved?
flip i
}
end
def flip(i)
(0...w).each {|n|
press n, 0 if i & (1 << n) != 0
}
carry
end
def solved?
(0...h).each {|y|
(0...w).each {|x|
return false if self[y][x]
}
}
true
end
def carry
(0...h-1).each {|y|
(0...w).each {|x|
press x, y+1 if self[y][x]
}
}
end
def h() size end
def w() self[0].size end
def press x, y
#presses = (0...h).map { [false] * w } if #presses == nil
#presses[y][x] = !#presses[y][x]
inv x, y
if y>0 then inv x, y-1 end
if y<h-1 then inv x, y+1 end
if x>0 then inv x-1, y end
if x<w-1 then inv x+1, y end
end
def inv x, y
self[y][x] = !self[y][x]
end
def presses
(0...h).each {|y|
puts (0...w).map {|x|
if #presses[y][x] then 'X' else '.' end
}.inject {|a,b| a+b}
}
end
end
STDIN.read.split(/\n/).map{|x|x.split(//).map {|v|v == '*'}}.solve.presses
Lua, 499 characters
Fast, uses Strategy to find a quicker solution.
m={46,[42]=88,[46]=1,[88]=42}o={88,[42]=46,[46]=42,[88]=1}z={1,[42]=1}r=io.read
l=r()s=#l q={l:byte(1,s)}
for i=2,s do q[#q+1]=10 l=r()for j=1,#l do q[#q+1]=l:byte(j)end end
function t(p,v)q[p]=v[q[p]]or q[p]end
function u(p)t(p,m)t(p-1,o)t(p+1,o)t(p-s-1,o)t(p+s+1,o)end
while 1 do e=1 for i=1,(s+1)*s do
if i>(s+1)*(s-1)then if z[q[i]]then e=_ end
elseif z[q[i]]then u(i+s+1)end end
if e then break end
for i=1,s do if 42==q[i]or 46==q[i]then u(i)break end u(i)end end
print(string.char(unpack(q)))
Example input:
.....
.....
.....
.....
*...*
Example output:
XX...
..X..
X.XX.
X.X.X
...XX
Some of these have multiple answers. This seems to work but it's not exactly fast.
Groovy: 790 chracters
bd = System.in.readLines().collect{it.collect { it=='*'}}
sl = bd.collect{it.collect{false}}
println "\n\n\n"
solve(bd, sl, 0, 0, 0)
def solve(board, solution, int i, int j, prefix) {
/* println " ".multiply(prefix) + "$i $j"*/
if(done(board)) {
println sl.collect{it.collect{it?'X':'.'}.join("")}.join("\n")
return
}
if(j>=board[i].size) {
j=0; i++
}
if(i==board.size) {
return
}
solve(board, solution, i, j+1, prefix+1)
flip(solution, i, j)
flip(board, i, j)
flip(board, i+1, j)
flip(board, i-1, j)
flip(board, i, j+1)
flip(board, i, j-1)
solve(board, solution, i, j+1, prefix+1)
}
def flip(board, i, j) {
if(i>=0 && i<board.size && j>=0 && j<board[i].size)
board[i][j] = !board[i][j]
}
def done(board) {
return board.every { it.every{!it} }
}
For Haskell, here's a 406 376 342 character solution, though I'm sure there's a way to shrink this. Call the s function for the first solution found:
s b=head$t(b,[])
l=length
t(b,m)=if l u>0 then map snd u else concat$map t c where{i=[0..l b-1];c=[(a b p,m++[p])|p<-[(x,y)|x<-i,y<-i]];u=filter((all(==False)).fst)c}
a b(x,y)=foldl o b[(x,y),(x-1,y),(x+1,y),(x,y-1),(x,y+1)]
o b(x,y)=if x<0||y<0||x>=r||y>=r then b else take i b++[not(b!!i)]++drop(i+1)b where{r=floor$sqrt$fromIntegral$l b;i=y*r+x}
In its more-readable, typed form:
solution :: [Bool] -> [(Int,Int)]
solution board = head $ solutions (board, [])
solutions :: ([Bool],[(Int,Int)]) -> [[(Int,Int)]]
solutions (board,moves) =
if length solutions' > 0
then map snd solutions'
else concat $ map solutions candidates
where
boardIndices = [0..length board - 1]
candidates = [
(applyMove board pair, moves ++ [pair])
| pair <- [(x,y) | x <- boardIndices, y <- boardIndices]]
solutions' = filter ((all (==False)) . fst) candidates
applyMove :: [Bool] -> (Int,Int) -> [Bool]
applyMove board (x,y) =
foldl toggle board [(x,y), (x-1,y), (x+1,y), (x,y-1), (x,y+1)]
toggle :: [Bool] -> (Int,Int) -> [Bool]
toggle board (x,y) =
if x < 0 || y < 0 || x >= boardSize || y >= boardSize then board
else
take index board ++ [ not (board !! index) ]
++ drop (index + 1) board
where
boardSize = floor $ sqrt $ fromIntegral $ length board
index = y * boardSize + x
Note that this is a horrible breadth-first, brute-force algorithm.
F#, 365 370, 374, 444 including all whitespace
open System
let s(r:string)=
let d=r.IndexOf"\n"
let e,m,p=d+1,r.ToCharArray(),Random()
let o b k=m.[k]<-char(b^^^int m.[k])
while String(m).IndexOfAny([|'*';'\\'|])>=0 do
let x,y=p.Next d,p.Next d
o 118(x+y*e)
for i in x-1..x+1 do for n in y-1..y+1 do if i>=0&&i<d&&n>=0&&n<d then o 4(i+n*e)
printf"%s"(String m)
Here's the original readable version before the xor optimization. 1108
open System
let solve (input : string) =
let height = input.IndexOf("\n")
let width = height + 1
let board = input.ToCharArray()
let rnd = Random()
let mark = function
| '*' -> 'O'
| '.' -> 'X'
| 'O' -> '*'
| _ -> '.'
let flip x y =
let flip = function
| '*' -> '.'
| '.' -> '*'
| 'X' -> 'O'
| _ -> 'X'
if x >= 0 && x < height && y >= 0 && y < height then
board.[x + y * width] <- flip board.[x + y * width]
let solved() =
String(board).IndexOfAny([|'*';'O'|]) < 0
while not (solved()) do
let x = rnd.Next(height) // ignore newline
let y = rnd.Next(height)
board.[x + y * width] <- mark board.[x + y * width]
for i in -1..1 do
for n in -1..1 do
flip (x + i) (y + n)
printf "%s" (String(board))
Python — 982
Count is 982 not counting tabs and newlines. This includes necessary spaces. Started learning python this week, so I had some fun :). Pretty straight forward, nothing fancy here, besides the crappy var names to make it shorter.
import re
def m():
s=''
while 1:
y=raw_input()
if y=='':break
s=s+y+'\n'
t=a(s)
t.s()
t.p()
class a:
def __init__(x,y):
x.t=len(y);
r=re.compile('(.*)\n')
x.z=r.findall(y)
x.w=len(x.z[0])
x.v=len(x.z)
def s(x):
n=0
for i in range(0,x.t):
if(x.x(i,0)):
break
def x(x,d,c):
b=x.z[:]
for i in range(1,x.v+1):
for j in range(1,x.w+1):
if x.c():
break;
x.z=b[:]
x.u(i,j)
if d!=c:
x.x(d,c+1)
if x.c():
break;
if x.c():
return 1
x.z=b[:]
return 0;
def y(x,r,c):
e=x.z[r-1][c-1]
if e=='*':
return '.'
elif e=='x':
return 'X'
elif e=='X':
return 'x'
else:
return '*'
def j(x,r,c):
v=x.y(r+1,c)
x.r(r+1,c,v)
def k(x,r,c):
v=x.y(r-1,c)
x.r(r-1,c,v)
def h(x,r,c):
v=x.y(r,c-1)
x.r(r,c-1,v)
def l(x,r,c):
v=x.y(r,c+1)
x.r(r,c+1,v)
def u(x,r,c):
e=x.z[r-1][c-1]
if e=='*' or e=='x':
v='X'
else:
v='x'
x.r(r,c,v)
if r!=1:
x.k(r,c)
if r!=x.v:
x.j(r,c)
if c!=1:
x.h(r,c)
if c!=x.w:
x.l(r,c)
def r(x,r,c,l):
m=x.z[r-1]
m=m[:c-1]+l+m[c:]
x.z[r-1]=m
def c(x):
for i in x.z:
for j in i:
if j=='*' or j=='x':
return 0
return 1
def p(x):
for i in x.z:
print i
print '\n'
if __name__=='__main__':
m()
Usage:
*...*
**.**
..*..
*.*..
*.**.
X.X.X
..X..
.....
.....
X.X..