Skip to content

Commit

Permalink
dj
Browse files Browse the repository at this point in the history
  • Loading branch information
Skydev0h committed Dec 26, 2023
1 parent e05a93b commit ecd3045
Show file tree
Hide file tree
Showing 2 changed files with 270 additions and 5 deletions.
273 changes: 268 additions & 5 deletions contracts/task4.fc
Original file line number Diff line number Diff line change
@@ -1,12 +1,275 @@
#include "imports/stdlib.fc";

() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
() main() { }

int tlen(tuple list) asm "TLEN";

forall X -> tuple t:+(tuple t, X value) asm "TPUSH";
forall X -> (tuple, ()) ~t:+(tuple t, X value) asm "TPUSH";
forall X -> (tuple, X) t:-(tuple t) asm "TPOP";

forall X -> X t:(tuple t, int index) asm "INDEXVAR";
forall X -> X t::(tuple t, int index1, int index2) asm(index2 t index1) "INDEXVAR SWAP INDEXVAR";

forall X -> tuple t:=(tuple t, X value, int index) asm "SETINDEXVAR";
forall X -> (tuple, ()) ~t:=(tuple t, X value, int index) asm "SETINDEXVAR";

{-
C dc hx X ? .
. 46 2E | 0...0...1...0
? 63 3F | 0...1...1...0
E 69 45 | 0...0...1...0
S 83 53 | 0...0...0...0
X 88 58 | 1...0...1...0
-}

const int empty_tile_shift = 16;
const int weak_tile_shift = 16 + empty_tile_shift; ;; 32
const int strong_tile_shift = 16 + weak_tile_shift; ;; 48
const int infinity_shift = 16 + strong_tile_shift; ;; 64

const int key_len = infinity_shift;
const int vkeylen = empty_tile_shift;

const int empty_tile_price = 1 << empty_tile_shift;
const int weak_tile_price = (1 << weak_tile_shift) | empty_tile_price;
const int strong_tile_price = (1 << strong_tile_shift) | empty_tile_price;
const int final_tile_price = empty_tile_price;
const int infinity_price = (1 << infinity_shift) - 1;

(cell, cell, int, tuple) update(slice empty, cell to_visit, cell visited, int ch, int cp, tuple tp'y, tuple atp'y, int x', int y') inline {
int xy' = y' + (x' << 8);
int pr = atp'y.t:(x') + xy';
int pr' = cp + tp'y.t:(x') + xy';
int fin = pr' & 0x80;
if (pr' < pr) {
pr' -= fin;
atp'y~t:=(pr', x');
ch |= 1 | fin;
(_, int is_visited) = visited.udict_get?(vkeylen, xy');
ifnot (is_visited) {
if (pr < infinity_price) {
to_visit~udict_delete?(key_len, pr);
}
to_visit~udict_set(key_len, pr', empty);
}
}
return (to_visit, visited, ch, atp'y);
}

(int, int, int) walker(int nx, int ny, int cp, tuple atp'y, int x, int y) inline {
int cp' = atp'y.t:(x);
if (cp' < cp) {
cp = cp';
nx = x;
ny = y;
}
return (nx, ny, cp);
}

;; . X S E ? !
;; (int, int, int, tuple, tuple) solve(int n, int m, tuple maze) method_id {
(int, int, int, tuple) solve(int n, int m, tuple maze) method_id {
int ly = n; int lx = m;
;; ###########################################################
tuple tile_prices = empty_tuple();
int z = 0;
repeat(46) { tile_prices~t:+(z); } ;; 0...45
tile_prices~t:+(empty_tile_price); ;; 46
repeat(16) { tile_prices~t:+(z); } ;; 47..62
tile_prices~t:+(weak_tile_price); ;; 63
repeat(5) { tile_prices~t:+(z); } ;; 64..68
tile_prices~t:+(final_tile_price); ;; 69
repeat(18) { tile_prices~t:+(z); } ;; 70..87
tile_prices~t:+(strong_tile_price); ;; 88
;; ###########################################################

int Sx = 0; int Sy = 0;
int Ex = 0; int Ey = 0;

tuple tp = empty_tuple();
int y = 0;
repeat(ly) {
tuple t = maze.t:(y);
tuple r = empty_tuple();
int x = 0;
repeat(lx) {
int c = t.t:(x);
if (c == "S"u) { Sx = x; Sy = y; }
int ctp = tile_prices.t:(c);
if (c == "E"u) { ctp = ctp | 0x80; Ex = x; Ey = y; }
r~t:+( ctp );
x += 1;
}
tp~t:+(r);
y += 1;
}

tuple atp = empty_tuple();
tuple row = empty_tuple();
repeat(lx) { row~t:+(infinity_price); }
repeat(ly) { atp~t:+(row); }
atp~t:=(atp.t:(Sy).t:=(0, Sx), Sy);

slice empty = get_data().begin_parse();

cell to_visit = new_dict();
cell visited = new_dict();

;; to_visit~udict_set(key_len, Sy | (Sx << 8), empty);
;; (int key, _, int ok) = to_visit~udict_delete_get_min(key_len);
int key = Sy + (Sx << 8);
int ok = true;

int ly' = ly - 1; int lx' = lx - 1;

while (ok) {

int xy = key & 0xFFFF;
int y = xy & 0xFF;
int x = xy >> 8;
int cp = key - xy;

visited~udict_set(vkeylen, xy, empty);

tuple tp'y = tp.t:(y);
tuple atp'y = atp.t:(y);
int ch = 0;
int fin = 0;

if (x != 0) {
(to_visit, visited, ch, atp'y) = update(empty, to_visit, visited, ch, cp, tp'y, atp'y, x - 1, y);
}

if (x != lx') {
(to_visit, visited, ch, atp'y) = update(empty, to_visit, visited, ch, cp, tp'y, atp'y, x + 1, y);
}

if (ch) {
atp~t:=(atp'y, y);
fin = fin | (ch & 0x80);
ch = 0;
}

if (y != 0) {
int y' = y - 1;
tuple tp'y' = tp.t:(y');
tuple atp'y' = atp.t:(y');

if (x != 0) {
(to_visit, visited, ch, atp'y') = update(empty, to_visit, visited, ch, cp, tp'y', atp'y', x - 1, y');
}

(to_visit, visited, ch, atp'y') = update(empty, to_visit, visited, ch, cp, tp'y', atp'y', x, y');

if (x != lx') {
(to_visit, visited, ch, atp'y') = update(empty, to_visit, visited, ch, cp, tp'y', atp'y', x + 1, y');
}

if (ch) {
atp~t:=(atp'y', y');
fin = fin | (ch & 0x80);
ch = 0;
}
}

if (y != ly') {
int y' = y + 1;
tuple tp'y' = tp.t:(y');
tuple atp'y' = atp.t:(y');

if (x != 0) {
(to_visit, visited, ch, atp'y') = update(empty, to_visit, visited, ch, cp, tp'y', atp'y', x - 1, y');
}

(to_visit, visited, ch, atp'y') = update(empty, to_visit, visited, ch, cp, tp'y', atp'y', x, y');

if (x != lx') {
(to_visit, visited, ch, atp'y') = update(empty, to_visit, visited, ch, cp, tp'y', atp'y', x + 1, y');
}

if (ch) {
atp~t:=(atp'y', y');
fin = fin | (ch & 0x80);
;; ch = false;
}
}

if (fin) {
ok = false;
} else {
(key, _, ok) = to_visit~udict::delete_get_min(key_len);
}

}

int finpr = atp.t::(Ey, Ex);
int strong = (finpr >> strong_tile_shift) & 0xFFFF;
int weak = (finpr >> weak_tile_shift) & 0xFFFF;
int dist = (finpr >> empty_tile_shift) & 0xFFFF;

tuple sol = maze;

int walk = true;
int wx = Ex;
int wy = Ey;

int mask = ~ 0xFFFF;

while (walk) {

int cp = atp.t::(wy, wx) & mask;
int nx = wx; int ny = wy;

tuple atp'wy = atp.t:(wy);

if (wx != 0) {
(nx, ny, cp) = walker(nx, ny, cp, atp'wy, wx - 1, wy);
}

if (wx != lx') {
(nx, ny, cp) = walker(nx, ny, cp, atp'wy, wx + 1, wy);
}

if (wy != 0) {
int wy' = wy - 1;
tuple atp'wy' = atp.t:(wy');

if (wx != 0) {
(nx, ny, cp) = walker(nx, ny, cp, atp'wy', wx - 1, wy');
}

(nx, ny, cp) = walker(nx, ny, cp, atp'wy', wx, wy');

if (wx != lx') {
(nx, ny, cp) = walker(nx, ny, cp, atp'wy', wx + 1, wy');
}
}

if (wy != ly') {
int wy' = wy + 1;
tuple atp'wy' = atp.t:(wy');

if (wx != 0) {
(nx, ny, cp) = walker(nx, ny, cp, atp'wy', wx - 1, wy');
}

(nx, ny, cp) = walker(nx, ny, cp, atp'wy', wx, wy');

if (wx != lx') {
(nx, ny, cp) = walker(nx, ny, cp, atp'wy', wx + 1, wy');
}
}

wx = nx; wy = ny;

if ((wx == Sx) & (wy == Sy)) {
walk = false;
} else {
sol~t:=(sol.t:(wy).t:=("!"u, wx), wy);
}

}

;;-1 obs len maze
(int, int, int, tuple) solve_maze(int n, int m, tuple maze) method_id {
return (-1, 0, 0, null());
return (strong, weak, dist, sol);
;; return (strong, weak, dist, sol, atp);
}
2 changes: 2 additions & 0 deletions contracts/task4_basic.fc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ forall T1, T2, T3, T4, T5, T6, T7 -> (T1, T2, T3, T4, T5, T6, T7) untuple7([T1,
}
-}

{-
;;-1 obs len maze
(int, int, int, tuple) solve(int n, int m, tuple maze) method_id {

Expand Down Expand Up @@ -159,3 +160,4 @@ forall T1, T2, T3, T4, T5, T6, T7 -> (T1, T2, T3, T4, T5, T6, T7) untuple7([T1,

return (-1, 0, 0, null());
}
-}

0 comments on commit ecd3045

Please sign in to comment.