Mars Lander 1


This puzzle is the first of a series of 3. It focuses on a purely vertical landing, which can be reused for the other levels. You can solve this problem by simulating next turns to compute the lander speed when it reaches the ground (as I did in C). You can also solve it mathematically and reduce this algorithm to a simple comparison (as I did in Python and Java).

C

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char** argv)
{
    int N;
    scanf("%d\n", &N);

    int surfaceX[N];
    int surfaceY[N];
    for (int i = 0; i < N; i++)
        scanf("%d %d\n", &surfaceX[i], &surfaceY[i]);

    while (1) {
        int X, Y, dX, dY, fuel, rotate, power;
        scanf("%d %d %d %d %d %d %d", &X, &Y, &dX, &dY, &fuel, &rotate, &power);
        
        // Finds landing altitude by Looking for 2 consecutive points w/ same Y
        int groundY = -1;
        for (int i = 0; (i < N && groundY == -1); i++)
            if (surfaceX[i] <= X && X <= surfaceX[i+1])
                groundY = surfaceY[i];

        /* Finds out if it is safe to start braking only next turn, by
           simulating it and analyzing vertical speed at landing
           If it is safe, waits, else starts braking*/
        double vdY = (double)dY;
        double vY = (double)Y;
        for (double i = 0.0; i <= 4; i++) {
            vdY += i - 3.711;
            vY += vdY;
        }
        while (vY > groundY && vdY < 0) {
            vdY += 0.289; // 4-3.711;
            vY += vdY;
        }
        printf((vdY >= 0 || vdY > -40.0) ? "0 0\n" : "0 4\n");
    }
    return EXIT_SUCCESS;
}
            

Java

import java.util.*;
import java.math.*;

class Player {
    public static void main(String args[]) {
        Scanner in = new Scanner(System.in);

        int N = in.nextInt();
    
        int[] surfaceX = new int[N];
        int[] surfaceY = new int[N];
        for (int i = 0; i < N; i++) {
            surfaceX[i] = in.nextInt();
            surfaceY[i] = in.nextInt();
        }
        
        while (true) {
            int X = in.nextInt();
            int Y = in.nextInt();
            int dX = in.nextInt();
            int dY = in.nextInt();
            in.nextInt(); in.nextInt(); in.nextInt();

            // Finds landing altitude by Looking for 2 consecutive points w/ same Y
            int groundY = -1;
            for (int i = 0; (i < N && groundY == -1); i++)
                if (surfaceX[i] <= X && X <= surfaceX[i+1])
                    groundY = surfaceY[i];

            /* Finds out if it is safe to start braking only next turn, by
               simulating it and analyzing vertical speed at landing
               If it is safe, waits, else starts braking*/
            double vdY = dY - 8.555;
            double vY = Y - 36.665 + 5*dY;
            long t = Math.round((-40-vdY)/0.289);
            if (vY + t*(vdY+0.289*(1+t)/2) > groundY)
                System.out.println("0 0");
            else
                System.out.println("0 4");
        }
    }
}
            

Python 3

import math

N = int(input())
surfaceX, surfaceY = [], []
for i in range(N):
    landX, landY = [int(j) for j in input().split()]
    surfaceX.append(landX)
    surfaceY.append(landY)

while 1:
    X, Y, dX, dY, fuel, rotate, power = [int(i) for i in input().split()]
    
    # Finds landing altitude by Looking for 2 consecutive points w/ same Y
    groundY, i = -1, 0
    while (i < N) and (groundY == -1):
        if (surfaceX[i] <= X) and (X <= surfaceX[i+1]):
            groundY = surfaceY[i]
        i+=1
        
    # Finds out if it is safe to start braking only next turn, by
    # simulating it and analyzing vertical speed at landing
    # If it is safe, waits, else starts braking
    vdY , vY = dY-8.555, Y-36.665+5*dY;
    t = math.ceil((-40-vdY)/0.289);
    if (vY + t*(vdY+0.289*(1+t)/2) > groundY):
        print(0, 0)
    else:
        print(0, 4)