From 9658133fd02fe90ccd3b07b8a6c0d5c1c18de9eb Mon Sep 17 00:00:00 2001 From: Adam Spragg Date: Thu, 12 Jan 2023 17:49:57 +0000 Subject: Puzzle 22: Add functions for orienting a cube To figure out where you're going on a net (as far as I can figure) you need to be able to tell which faces of a cube are connected to each other, and which direction they are in relative to each other. --- 22.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/22.c b/22.c index 180969f..e877c5a 100644 --- a/22.c +++ b/22.c @@ -39,6 +39,114 @@ direction_name(enum direction dir) } +// For each face of a cuboid, list adjoining faces in anti-clockwise order +// +// The faces are numbered as a right-handed six-sided die labelled 0 to 5. +// Opposite pairs add up to 5 (0/5, 1/4 and 2/3), and if you imagine curling the +// fingers of your right hand from the 0 to the 1, the 2 is on the face that +// your thumb is pointing to. e.g. if the 0 is on the front, and the 1 is on +// top, the 2 is on the left side. +// +// When a face is "oriented" a certain way, then if that face is on top, the +// first adjoining face listed in table below is in that direction. +// +// e.g. If the 3 face is on the top of the cuboid and "oriented" west, then the +// 4 face is to its west, the 5 is to its south, the 1 is to its east, and the 0 +// is to its north. +static int const faceids[6][4] = { + { 1, 2, 4, 3 }, // 0 sees 1, 2, 4, 3 + { 0, 3, 5, 2 }, // 1 sees 0, 3, 5, 2 + { 5, 4, 0, 1 }, // 2 sees 5, 4, 0, 1 + { 4, 5, 1, 0 }, // 3 sees 4, 5, 1, 0 + { 3, 0, 2, 5 }, // 4 sees 3, 0, 2, 5 + { 2, 1, 3, 4 }, // 5 sees 2, 1, 3, 4 +}; + + +// Given an oriented top face, which face do we see in a given direction? +int +faceid_look(int topid, enum direction orient, enum direction look) +{ + static enum direction const dirs[] = { D_NORTH, D_WEST, D_SOUTH, D_EAST }; + int topdir, destdir; + + if (topid < 0 || topid >= 6) + return -1; + + // Go through `dirs` until we find the one that topid is pointing to + for (topdir = 0; topdir < 4; ++topdir) + if (dirs[topdir % 4] == orient) + break; + if (topdir >= 4) + return -1; + + // Keep going through `dirs` until we find the one that the caller wants + for (destdir = topdir; destdir < topdir + 4; ++destdir) + if (dirs[destdir % 4] == look) + break; + if (destdir >= topdir + 4) + return -1; + + // Look up the destination face id. + return faceids[topid][destdir - topdir]; +} + + +// Given an oriented top face, which direction do we look to see another face? +enum direction +faceid_find(int topid, enum direction orient, int destid) +{ + static enum direction const dirs[] = { D_NORTH, D_WEST, D_SOUTH, D_EAST }; + int topdir, destix; + + // Go through the directions until we find the one that fsrc is pointing + for (topdir = 0; topdir < 4; ++topdir) + if (dirs[topdir % 4] == orient) + break; + if (topdir >= 4) + return -1; + + // Go through topid's faces until we find destid + for (destix = 0; destix < 4; ++destix) + if (faceids[topid][destix] == destid) + break; + if (destix >= 4) + return -1; + + // Return the direction that dest should be in + return dirs[(topdir + destix) % 4]; +} + + +// Given a top face, if we see another face in one direction, what is the +// orientation of the top face? +enum direction +faceid_orientation(int topid, int destid, enum direction destdir) +{ + static enum direction const dirs[] = { D_NORTH, D_WEST, D_SOUTH, D_EAST }; + int topdir, destix; + + // Go through topid's faces until we find destid + for (destix = 0; destix < 4; ++destix) + if (faceids[topid][destix] == destid) + break; + if (destix >= 4) + return -1; + + // From faceid_find(), if dirs[topdir + destix] points to destdir, + // then we just go through possible topdirs until we find the one + // that makes this true + for (topdir = 0; topdir < 4; ++topdir) + if (dirs[(topdir + destix) % 4] == destdir) + break; + if (topdir >= 4) + return -1; + + // Return the direction that dest should be in + return dirs[topdir]; +} + + struct map { char * _buf; int cols; -- cgit v1.2.1