CS107 Final Exam Practice Problem Solutions: Solution 1: Matchmaking
CS107 Final Exam Practice Problem Solutions: Solution 1: Matchmaking
CS107 Final Exam Practice Problem Solutions: Solution 1: Matchmaking
typedef struct {
char *girl;
char *boy;
} couple;
return couples;
}
{
int i;
void *elem;
// line 1 rosemary.thyme[0…1]
R1 = M[SP + 8]; // load old cumin
R2 = M[SP + 4]; // load this aka &this->thyme[0]
R3 =.1 M[R2]; // load first byte of this->thyme[0] cumin
R4 = R1 – R3; // compute index
R5 = R4 * 2; // scale by sizeof(short) this
R6 = R2 + R5; // compute address of rhs
R7 =.2 M[R6]; // compute rhs saved pc
R8 = R1 * R7; // compute new cumin value
M[SP + 8] = R8; // flush to space for cumin
// line 2
R10 = M[SP + 4]; // load this (again)
R11 = R10 + 8; // compute &this->parsley (and look, it’s a spice * now)
R12 = SP + 12; // prepare address of rosemary (which gets passed by ref)
SP = SP – 8; // make space for params
M[SP] = R11; // set down address of receiving object
M[SP + 4] = R12; // set down address backing salt reference
CALL <spice::saffron>
SP = SP + 8; // clean up params
R13 = M[RV]; // RV has spice ** backing spice *&, load real spice *
R14 = M[R13 + 8]; // load value of parsley
R15 = SP + 12; // load &rosemary
R16 = R14 – R15; // compute raw number of bytes in between the two
RV = R16 / 12; // scale back to quantum number of spice records between them
RET;
3
Solution 4: Cars
class car {
short mater[4];
car *mcqueen; 8 fillmore
};
sally
// sally["Pixar"][fillmore] += *mater; this
R1 = M[SP + 8];
SP = SP – 8; saved pc
M[SP] = R1; SP
M[SP + 4] = 1000;
CALL <car::operator[]> // RV has a char **
SP = SP + 8;
b)
(define (map-everywhere func structure)
(map (lambda (elem)
(if (list? elem) (map-everywhere func elem)
(func elem)))
structure))
4
Solution 6: Longest Common Subsequences
a)
;;
;; Function: longest-common-prefix
;; -------------------------------
;; Takes two lists and returns the longest prefix common
;; to both of them. If there is no common prefix, then
;; longest-common-prefix evaluates to the empty list
;;
;; Examples:
;; (longest-common-prefix '(a b c) '(a b d f)) --> (a b)
;; (longest-common-prefix '(s t e r n) '(s t e r n u m)) --> (s t e r n)
;; (longest-common-prefix '(1 2 3) '(0 1 2 3)) --> ()
;;
b)
;;
;; Function: mdp
;; -------------
;; Mapping routine which transforms a list of length n into another
;; list of length n, where each element of the new list is the result
;; of levying the specified func against the corresponding cdr of
;; the original.
;;
;; Examples:
;; (mdp length '(w x y z)) --> (4 3 2 1)
;; (mdp cdr '(2 1 2 8)) --> ((1 2 8) (2 8) (8) ())
;; (mdp reverse '("ba" "de" "foo" "ga")) -->
;; (("ga" "foo" "de" "ba") ("ga" "foo" "de") ("ga" "foo") ("ga"))
;;
c)
;;
;; Function: longest-common-sublist
;; --------------------------------
;; Analyzes the two sequences and computes the longest sublist that's
;; common to both of them. If there are no common elements at all, then
;; the empty list is returned.
;;
;; Function: generate-all-sublists
;; -------------------------------
;; Uses double mdpping to pair every suffix of the
;; first sequence with every suffix of the second,
5
;;
;; Function: list-length>?
;; -----------------------
;; Returns #t if and only if the first list
;; has more top-level elements than the second,
;; and returns #f otherwise.
;;
return totalNumBytes;
}
SemaphoreWait(numThreadsAllowed)
numBytes = DownloadMediaFile(server, filename);
SemaphoreSignal(numThreadsAllowed);
SemaphoreWait(byteCountLock);
*totalByteCountp += numBytes;
SemaphoreSignal(byteCountLock);
SemaphoreSignal(numThreadsCompleted);
}
6
typedef struct {
enum { Boolean, Integer, String, Symbol, Empty, List} type;
char value[8]; // value[0] stores '\0' for #f, anything else for #t
// above eight bytes are general-purpose bytes…
} Expression;
typedef struct {
Semaphore lock;
Semaphore answerReady;
Semaphore answerAccepted;
Expression *answer;
int numChildrenRemaining;
} AndExpressionInfo;
/**
* Function: evaluateConcurrentAnd
* -------------------------------
* Special function dedicated to the implementation of the
* concurrent-and special form. It returns the first #f Expression
* ever produced by a child, or if #f is never produced, then it
* returns the last Expression * produced by the last thread
* to complete.
*
* @param exprs an array of Expressions * to be concurrently evaluated.
* We assume there are no recursive calls to concurrent-and
* involved.
* @param n the length of the exprs array
* @return the result of the last child thread needed in order to produce
* an answer.
*/
SemaphoreWait(info->answerReady);
Expression *answer = info->answer;
SemaphoreSignal(info->answerAccepted);
return answer;
}
SemaphoreWait(info->lock);
bool lastToFinish = (--info->numChildrenRemaining == 0);
if (info->answer == NULL) {
if (lastToFinish ||
result->type != Expression::Boolean || result->value[0] == '\0') {
info->answer = result;
SemaphoreSignal(info->answerReady); // signal parent
SemaphoreWait(info->answerAccepted); // stall until parents reads answer
}
}
SemaphoreSignal(info->lock);
if (lastToFinish) { // must free here (or at least outside the parent thread)
SemaphoreFree(info->lock);
SemaphoreFree(info->answerReady);
SemaphoreFree(info->answerAccepted);
free(info);
}
}