All SolutionsAll Solutions

☠️

X Marks the Spot

Week 2, 2026

Pseudocode Canvas | program52 | Pseudocode Solutions

//SET_MAX_EXECUTION_TIME=-1 //run on pseudocode.pro OUTPUT "Ensure you are running on the All Syllabuses/Extra Modules option - also download (https://program52.com/en/challenge/2026/2/map.jpg) the map as map.jpg and drag and drop it into this site" CONSTANT IMAGE_WIDTH = 1280 CONSTANT IMAGE_HEIGHT = 905 CONSTANT HEX_CHARS = "0123456789ABCDEF" TYPE BoundingBox DECLARE x, y, width, height : REAL ENDTYPE CALL CREATECANVAS("map", IMAGE_WIDTH, IMAGE_HEIGHT) CALL DRAWIMAGE("map", "map.jpg", 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT) DECLARE canvasBounds : BoundingBox DECLARE halfImageWidth, halfImageHeight : REAL DECLARE currentStrIndex, prevX, prevY, currentX, currentY, pairIndex : INTEGER DECLARE data, colourCode : STRING DECLARE dataPair : ARRAY[1:2] OF STRING OUTPUT "Paste all program input co-ordinate data:" INPUT data // data ← "" //can assign data to this variable rather than usign INPUT prompt halfImageWidth ← IMAGE_WIDTH / 2 halfImageHeight ← IMAGE_HEIGHT / 2 currentStrIndex ← LENGTH(data) dataPair ← getNextPair() prevX ← halfImageWidth + STR_TO_NUM(dataPair[1]) prevY ← halfImageHeight - STR_TO_NUM(dataPair[2]) // OUTPUT "Start X: ", prevX, " Start Y: ", prevY pairIndex ← 0 WHILE currentStrIndex > 0 DO dataPair ← getNextPair() // OUTPUT dataPair[1], " ", dataPair[2] currentY ← prevY + getMovement(dataPair[1]) currentX ← prevX + getMovement(dataPair[2]) IF pairIndex MOD 50 = 0 THEN colourCode ← getRandomHexColour() ENDIF CALL DRAWLINE("map", prevX, prevY, currentX, currentY, "red", 5) prevY ← currentY prevX ← currentX pairIndex ← pairIndex + 1 // OUTPUT prevX, " ", prevY, " ", currentX, " ", currentY CALL WAIT(1) ENDWHILE OUTPUT "Finished - click the in the middle of the 'X' drawn on the chart and check the console for the output co-ordinates" EVENT CLICK canvasBounds ← GETCANVASBOUNDS("map") OUTPUT "Click location: ", event.x - canvasBounds.x - halfImageWidth, ", ", halfImageHeight - (event.y - canvasBounds.y) ENDEVENT FUNCTION getNextPair() RETURNS ARRAY OF STRING DECLARE arr : ARRAY[1:2] OF STRING DECLARE currentNumStr : STRING DECLARE currentChar : CHAR DECLARE foundSpace : BOOLEAN DECLARE arrayIndex : INTEGER IF currentStrIndex = 0 THEN RETURN arr ENDIF currentNumStr ← "" foundSpace ← FALSE arrayIndex ← 2 WHILE foundSpace = FALSE AND currentStrIndex >= 1 DO currentChar ← MID(data, currentStrIndex, 1) IF currentChar = ' ' THEN arr[arrayIndex] ← currentNumStr foundSpace ← TRUE ELSE IF currentChar <> ',' THEN currentNumStr ← currentChar & currentNumStr ELSE arr[arrayIndex] ← currentNumStr currentNumStr ← "" arrayIndex ← arrayIndex - 1 ENDIF ENDIF currentStrIndex ← currentStrIndex - 1 ENDWHILE RETURN arr ENDFUNCTION FUNCTION getMovement(vector : STRING) RETURNS INTEGER DECLARE dir : CHAR dir ← LEFT(vector, 1) IF dir = 'N' OR dir = 'W' THEN RETURN STR_TO_NUM(RIGHT(vector, LENGTH(vector) - 1)) ELSE RETURN -STR_TO_NUM(RIGHT(vector, LENGTH(vector) - 1)) ENDIF ENDFUNCTION FUNCTION getRandomHexColour() RETURNS STRING DECLARE hex : STRING hex ← "#" FOR n ← 1 TO 6 hex ← hex & MID(HEX_CHARS, INT(RAND(16) + 1), 1) NEXT n RETURN hex ENDFUNCTION

HTML & JS Canvas | program52 | JavaScript Solutions

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>X Marks the Spot</title> <style> #map{ position: absolute; top: 0; left: 0; } canvas#canvas { position: absolute; top: 0; left: 0; } </style> </head> <body> <img id="map" src="map.jpg" alt=""> <canvas id="canvas"></canvas> <script> var map = document.getElementById("map") var canvas = document.getElementById("canvas") canvas.width = map.width canvas.height = map.height var ctx = canvas.getContext("2d") ctx.clearRect(0, 0, canvas.width, canvas.height) var imageMidX = map.width / 2 var imageMidY = map.height / 2 var s = prompt("Paste the program input data here:") function draw() { var spl = s.split(" ") var tmp = spl.pop().split(",") var xPos = parseInt(tmp[0]) var yPos = parseInt(tmp[1]) ctx.beginPath(); ctx.moveTo(xPos + imageMidX, imageMidY - yPos); // debugger ctx.strokeStyle = "blue" ctx.lineWidth = 7 var x = spl.length - 1 var int = setInterval(function () { var spl2 = spl[x].split(",") var yMove = spl2[0].charAt(0) === "N" ? -parseInt(spl2[0].substring(1)) : parseInt(spl2[0].substring(1)) var xMove = spl2[1].charAt(0) === "W" ? parseInt(spl2[1].substring(1)) : -parseInt(spl2[1].substring(1)) yPos = yPos + yMove xPos = xPos + xMove ctx.lineTo(xPos + imageMidX, imageMidY - yPos) ctx.stroke(); // console.log(xPos + imageMidX, imageMidY - yPos, xPos, yPos) x-- if (x < 0) { clearInterval(int) ctx.stroke(); alert("Finished - now click on the map where you think the treasure is to get the co-ordinates") } }, 5) } document.body.onclick = function (e) { alert(`${e.clientX - imageMidX}, ${imageMidY - e.clientY}`) } draw() </script> </body> </html>

Odin Plotting with Raylib | greenya | Odin Solutions

// - use "odin run ." to run the code // - input.txt should be nearby with the input data // - map.jpg should be nearby package main import "core:fmt" import "core:strconv" import "core:strings" import rl "vendor:raylib" input_txt_bytes := #load("input.txt") map_jpg_bytes := #load("map.jpg") main :: proc () { rl.SetTraceLogLevel(.WARNING) rl.SetConfigFlags({ .VSYNC_HINT }) map_img := rl.LoadImageFromMemory(".jpg", raw_data(map_jpg_bytes), i32(len(map_jpg_bytes))) rl.InitWindow(map_img.width, map_img.height, "week2") defer rl.CloseWindow() map_tex := rl.LoadTextureFromImage(map_img) rl.UnloadImage(map_img) defer rl.UnloadTexture(map_tex) path_tex, path_map_origin := plot() path_tex_center := [2] f32 { f32(path_tex.width/2), f32(path_tex.height/2) } defer rl.UnloadTexture(path_tex) path_tex_top_left: [2] f32 is_align_mode := true for !rl.WindowShouldClose() { if rl.IsMouseButtonPressed(.LEFT) do is_align_mode ~= true mouse_pos := rl.GetMousePosition() mouse_pos_map := [2] f32 { path_map_origin.x - path_tex_top_left.x + mouse_pos.x, path_map_origin.y + path_tex_top_left.y - mouse_pos.y, } if is_align_mode { path_tex_top_left = mouse_pos - path_tex_center } rl.BeginDrawing() rl.DrawTexture(map_tex, 0, 0, rl.WHITE) rl.DrawTextureV(path_tex, path_tex_top_left, rl.WHITE) hint_cstr := fmt.ctprintf( "1. Align start of the path with the ship\n" + "2. Click with LMB to toggle Align Mode [%s]\n" + "3. Mouse over the cross in the path to see coordinates %v of the treasure", is_align_mode ? "ON" : "OFF", mouse_pos_map, ) rl.DrawText(hint_cstr, 20+1, 20+2, 20, rl.BLACK) rl.DrawText(hint_cstr, 20, 20, 20, rl.YELLOW) rl.EndDrawing() free_all(context.temp_allocator) } } plot :: proc () -> (path_tex: rl.Texture, path_map_origin: [2] f32) { context.allocator = context.temp_allocator path_img := rl.GenImageColor(4000, 4000, {0,0,0,100}) path_off := [2] i32 { path_img.width/2, path_img.height/2 } path_pos := path_off path_box := struct { left, right, top, bottom: i32 } { left = path_pos.x, right = path_pos.x, top = path_pos.y, bottom = path_pos.y, } input := strings.trim(string(input_txt_bytes), "\n\t ") entries := strings.split(input, " ") last_pos: [2] i32 #reverse for entry in entries { values := strings.split(entry, ",") assert(len(values) == 2) v1_str, v2_str := values[0], values[1] if v1_str[0]!='N' && v1_str[0]!='S' { x, x_ok := strconv.parse_f32(v1_str) y, y_ok := strconv.parse_f32(v2_str) assert(x_ok && y_ok) assert(last_pos == {}, "last pos already set") last_pos = { i32(x), i32(y) } continue } for v in values { dist, dist_ok := strconv.parse_int(v[1:], base=10) assert(dist_ok) if dist != 0 { dir: [2] i32 switch v[0] { case 'N': dir = {0,+1} case 'S': dir = {0,-1} case 'W': dir = {+1,0} case 'E': dir = {-1,0} case : panic("unexpected direction") } path_pos += dir * i32(dist) } } assert(path_pos.x>=0 && path_pos.x<path_img.width, "plot x pos overflow") assert(path_pos.y>=0 && path_pos.y<path_img.height, "plot y pos overflow") path_box = { left = min(path_box.left, path_pos.x), right = max(path_box.right, path_pos.x), top = min(path_box.top, path_pos.y), bottom = max(path_box.bottom, path_pos.y), } rl.ImageDrawCircle(&path_img, path_pos.x, path_pos.y, 2, rl.WHITE) } rl.ImageCrop(&path_img, { x = f32(path_box.left), y = f32(path_box.top), width = f32(path_box.right - path_box.left + 1), height = f32(path_box.bottom - path_box.top + 1), }) path_tex = rl.LoadTextureFromImage(path_img) rl.UnloadImage(path_img) path_map_origin = [2] f32 { f32(path_box.left - path_off.x + last_pos.x), f32(-path_box.top + path_off.y + last_pos.y), } fmt.printfln("last pos: %v", last_pos) fmt.printfln("path box: %#v", path_box) fmt.printfln("path box size: %i x %i", path_box.right-path_box.left, path_box.bottom-path_box.top) fmt.printfln("path_map_origin: %v", path_map_origin) return }

Python solution for the treasure question | MushyZ | Python Solutions

import regex as re import matplotlib.pyplot as plt direction_pattern = re.compile(r'[NSEW]') magnitude_pattern = re.compile(r'\d+') with open("breakfun/data.txt", 'r') as file: data = file.read() directions = direction_pattern.findall(data) magnitudes = list(map(int, magnitude_pattern.findall(data))) def plot_backtrack(): x, y = 0, 0 xs = [x] ys = [y] # reverse order + reverse direction for d, m in reversed(list(zip(directions, magnitudes))): if d == 'N': y -= m elif d == 'S': y += m elif d == 'E': x -= m elif d == 'W': x += m xs.append(x) ys.append(y) plt.plot(xs, ys, marker='o') plt.title('Backtracked Path') plt.xlabel('X') plt.ylabel('Y') plt.grid() plt.show() plot_backtrack() # pirate coordinate logic X_coord = (894, -356) # X in the graph start_abs = (-576, 274.5) # LAST COORD ASSUMED TO BE STARTING POINT final = (start_abs[0] + X_coord[0], start_abs[1] + X_coord[1]) print("Treasure (most likely):", final)