HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Eight Directions Crossword

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
eightcrossworddirections

Problem

I solved a problem which you can read about here, but it gives me "time limit exceeded" even though it runs in 4 seconds. I really don't understand why.

I don't think my code can be any simpler, basically it has as many functions as there are solutions I think. At the start of my code I find the first letter matching the first letter of the word I am searching for, then when it finds it, it checks in 8 directions if it can make the whole word without going out of the crossword.

program ideone;
var
kar:array[1..1000, 1..1000] of char;
konacno:int64;
i2,i3,n,xx,yy:integer;
s:string;
procedure trag(y:integer; x:integer; y1:integer; x1:integer; i:integer);
        var
        x2,y2:integer;
    begin
    x2:=x+x1;
    y2:=y+y1;
    while (x20) and (y20) do begin
        if kar[y2,x2]=s[i+1] then
            if i=length(s)-1 then
            konacno:=konacno+1
            else
            trag(y2,x2,y1,x1,i+1);

    x2:=x2+x1;
    y2:=y2+y1;
    end;
    end;
begin
readln(n,s);
delete(s,1,1);
xx:=1;
yy:=1;
for i2:=1 to n do begin
for i3:=1 to n do
read(kar[i2,i3]);
readln();
end;
konacno:=0;

for i2:=1 to n*n do begin
    if kar[yy][xx]=s[1] then begin
        trag(yy,xx,-1,-1,1);
        trag(yy,xx,-1,0,1);
        trag(yy,xx,-1,1,1);
        trag(yy,xx,0,1,1);
        trag(yy,xx,1,1,1);
        trag(yy,xx,1,0,1);
        trag(yy,xx,1,-1,1);
        trag(yy,xx,0,-1,1);
    end;
    xx:=xx+1;
    if xx>n then begin
    xx:=1;
    yy:=yy+1;
    end;

end;

writeln(konacno);

end.


If you have any tips please tell me, I am new to Pascal, so I don't know all the tricks for speeding up the program, and I don't want to use C or C++.

Solution

First you can change those non-required letters to a specific character like '.'.

Turning the 2D array into a string or array of byte. For example:

1234
5678
90ab
cdef
=>
string1: 1234
string2: 5678
string3: 90ab
string4: cdef


Remove '.' in these string so that later u can check faster.

Also doing this with other rows, column, and oblique.

Scan result in -> or <- direction only.

Related algorithm you may find here.

Moreover, you can omit some impossible cases such as:

input:

8 aaaa
aaaaoooo
oooooooo
oooooooo
oooooooo
oooooooo
oooooooo
oooooooo
oooooooo


Find those which never touch required characters like the last three rows in this case and do not trag() with it.

I suggest using this algorithm to scan it:

For rows:

var 
    ignore: array[1..1000, 1..1000] of boolean;
    counter: integer;
counter:=0;
for i:=1 to n do
    while j length(s);
             break;
        end
        else
            counter:=0;
    end;

Code Snippets

1234
5678
90ab
cdef
=>
string1: 1234
string2: 5678
string3: 90ab
string4: cdef
8 aaaa
aaaaoooo
oooooooo
oooooooo
oooooooo
oooooooo
oooooooo
oooooooo
oooooooo
var 
    ignore: array[1..1000, 1..1000] of boolean;
    counter: integer;
counter:=0;
for i:=1 to n do
    while j<=n do
    begin
        ignore[i, j]:=false;
        if kar[i, j] = '.' then
        begin
             count:=count+1;
             ignore[i, j]:=counter> length(s);
             break;
        end
        else
            counter:=0;
    end;

Context

StackExchange Code Review Q#47007, answer score: 3

Revisions (0)

No revisions yet.