Skip to content

Commit

Permalink
day 17
Browse files Browse the repository at this point in the history
  • Loading branch information
squell committed Dec 17, 2021
1 parent 3c69f4d commit 0f57b74
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
1 change: 1 addition & 0 deletions 17/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target area: x=150..171, y=-129..-70
51 changes: 51 additions & 0 deletions 17/solve.a68
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
MODE VECTOR = STRUCT(INT x,y);
MODE BOX = STRUCT([2]INT x,y);

BOX target area;

readf(($"target area: x=" g ".." g ", y=" g ".." g $, target area));

PROC in target area = (VECTOR pos)BOOL:
x OF pos >= (x OF target area)[1] AND x OF pos <= (x OF target area)[2] AND
y OF pos >= (y OF target area)[1] AND y OF pos <= (y OF target area)[2];

PROC step = (REF VECTOR pos, speed)VOID:
BEGIN
x OF pos +:= x OF speed;
y OF pos +:= y OF speed;
x OF speed -:= (x OF speed > 0 | 1 |:
x OF speed < 0 | -1 | 0);
y OF speed -:= 1
END;

PROC simulate = (VECTOR aim)UNION(VOID,INT):
BEGIN
INT max height := 0;
VECTOR speed := aim;
VECTOR pos := (0,0);
BOOL hit := FALSE;
WHILE NOT hit AND
y OF pos >= (y OF target area)[1] AND
x OF pos <= (x OF target area)[2]
DO
step(pos, speed);
IF y OF pos > max height THEN max height := y OF pos FI;
hit := in target area (pos)
OD;
(hit | max height | EMPTY)
END;

INT best shot := 0;
FOR x FROM 1 TO (x OF target area)[2] DO
FOR y FROM 1 TO (x OF target area)[2] DO
CASE simulate((x,y)) IN
(INT h):
BEGIN
printf(($"hit x="g(0)", y="g(0)"; max height="g(0)l$, x,y,h));
IF h > best shot THEN best shot := h FI
END
ESAC
OD
OD;

print(("most stylish shot:", best shot, new line))
51 changes: 51 additions & 0 deletions 17/solve2.a68
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
MODE VECTOR = STRUCT(INT x,y);
MODE BOX = STRUCT([2]INT x,y);

BOX target area;

readf(($"target area: x=" g ".." g ", y=" g ".." g $, target area));

PROC in target area = (VECTOR pos)BOOL:
x OF pos >= (x OF target area)[1] AND x OF pos <= (x OF target area)[2] AND
y OF pos >= (y OF target area)[1] AND y OF pos <= (y OF target area)[2];

PROC step = (REF VECTOR pos, speed)VOID:
BEGIN
x OF pos +:= x OF speed;
y OF pos +:= y OF speed;
x OF speed -:= (x OF speed > 0 | 1 |:
x OF speed < 0 | -1 | 0);
y OF speed -:= 1
END;

PROC simulate = (VECTOR aim)UNION(VOID,INT):
BEGIN
INT max height := 0;
VECTOR speed := aim;
VECTOR pos := (0,0);
BOOL hit := FALSE;
WHILE NOT hit AND
y OF pos >= (y OF target area)[1] AND
x OF pos <= (x OF target area)[2]
DO
step(pos, speed);
IF y OF pos > max height THEN max height := y OF pos FI;
hit := in target area (pos)
OD;
(hit | max height | EMPTY)
END;

INT hits := 0;
FOR x FROM 1 TO (x OF target area)[2] DO
FOR y FROM (y OF target area)[1] TO (x OF target area)[2] DO
CASE simulate((x,y)) IN
(INT h):
BEGIN
printf(($"hit x="g(0)", y="g(0)"; max height="g(0)l$, x,y,h));
hits +:= 1
END
ESAC
OD
OD;

print(("possible values", hits, new line))

0 comments on commit 0f57b74

Please sign in to comment.