Skip to content

Commit 0398726

Browse files
authored
Merge branch 'master' into errata-3-5-1
2 parents 8c23e60 + de8cf21 commit 0398726

File tree

9 files changed

+978
-638
lines changed

9 files changed

+978
-638
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
},
2626
"homepage": "https://sourceacademy.org/sicpjs",
2727
"devDependencies": {
28-
"@babel/node": "^7.24.6",
29-
"@babel/core": "^7.24.6",
30-
"@babel/preset-env": "^7.24.6",
28+
"@babel/node": "^7.24.7",
29+
"@babel/core": "^7.24.7",
30+
"@babel/preset-env": "^7.24.7",
3131
"fs-extra": "^11.2.0",
3232
"http-server": "^14.1.1",
3333
"husky": "^8.0.3",

xml/chapter2/section2/subsection3.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ function matrix_times_vector(m, v) {
14511451
function transpose(mat) {
14521452
return accumulate_n(<METAPHRASE>??</METAPHRASE>, <METAPHRASE>??</METAPHRASE>, mat);
14531453
}
1454-
function matrix_times_matrix(n, m) {
1454+
function matrix_times_matrix(m, n) {
14551455
const cols = transpose(n);
14561456
return map(<METAPHRASE>??</METAPHRASE>, m);
14571457
}

xml/chapter2/section5/subsection1.xml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,54 @@ function install_complex_package() {
994994
arithmetic package. This operation should work for ordinary numbers,
995995
rational numbers, and complex numbers.
996996
<LABEL NAME="ex:=zero?"/>
997+
<SOLUTION>
998+
<SNIPPET EVAL="no">
999+
<JAVASCRIPT>
1000+
// provided by GitHub user clean99
1001+
1002+
function is_equal_to_zero(x) {
1003+
return apply_generic("is_equal", list(x));
1004+
}
1005+
1006+
function install_javascript_number_package() {
1007+
// ...
1008+
1009+
put("is_equal_to_zero", "javascript_number",
1010+
x => x === 0);
1011+
1012+
// ...
1013+
}
1014+
1015+
function install_rational_package() {
1016+
// ...
1017+
1018+
function is_equal_to_zero(x) {
1019+
return numer(x) === 0;
1020+
}
1021+
1022+
put("is_equal_to_zero", "rational",
1023+
is_equal_to_zero);
1024+
1025+
// ...
1026+
}
1027+
1028+
function install_complex_package() {
1029+
// ...
1030+
1031+
function is_equal_to_zero(z) {
1032+
return real_part(z) === 0
1033+
? imag_part(z) === 0
1034+
: false;
1035+
}
1036+
1037+
put("is_equal_to_zero", "complex",
1038+
is_equal_to_zero);
1039+
1040+
//...
1041+
}
1042+
</JAVASCRIPT>
1043+
</SNIPPET>
1044+
</SOLUTION>
9971045
</EXERCISE>
9981046

9991047
<INDEX>generic arithmetic operations<CLOSE/></INDEX>

xml/chapter3/section3/subsection1.xml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,56 @@ display(count_pairs(cycle));
15221522
distinct pairs in any structure. (Hint: Traverse the structure, maintaining
15231523
an auxiliary data structure that is used to keep track of which pairs have
15241524
already been counted.)
1525+
<SOLUTION>
1526+
<SNIPPET>
1527+
<EXAMPLE>exercise_3_17_solution_example</EXAMPLE>
1528+
<JAVASCRIPT>
1529+
// solution provided by GitHub user clean99
1530+
1531+
function count_pairs(x) {
1532+
let counted_pairs = null;
1533+
function is_counted_pair(current_counted_pairs, x) {
1534+
return is_null(current_counted_pairs)
1535+
? false
1536+
: head(current_counted_pairs) === x
1537+
? true
1538+
: is_counted_pair(tail(current_counted_pairs), x);
1539+
}
1540+
function count(x) {
1541+
if(! is_pair(x) || is_counted_pair(counted_pairs, x)) {
1542+
return 0;
1543+
} else {
1544+
counted_pairs = pair(x, counted_pairs);
1545+
return count(head(x)) +
1546+
count(tail(x)) +
1547+
1;
1548+
}
1549+
}
1550+
return count(x);
1551+
}
1552+
</JAVASCRIPT>
1553+
</SNIPPET>
1554+
<SNIPPET HIDE="yes">
1555+
<NAME>exercise_3_17_solution_example</NAME>
1556+
<JAVASCRIPT>
1557+
const three_list = list("a", "b", "c");
1558+
const one = pair("d", "e");
1559+
const two = pair(one, one);
1560+
const four_list = pair(two, "f");
1561+
const seven_list = pair(two, two);
1562+
const cycle = list("g", "h", "i");
1563+
set_tail(tail(tail(cycle)), cycle);
1564+
1565+
// return 3; return 3; return 3;
1566+
display(count_pairs(three_list));
1567+
display(count_pairs(four_list));
1568+
display(count_pairs(seven_list));
1569+
1570+
// return 3
1571+
display(count_pairs(cycle));
1572+
</JAVASCRIPT>
1573+
</SNIPPET>
1574+
</SOLUTION>
15251575
</EXERCISE>
15261576

15271577
<EXERCISE>
@@ -1542,6 +1592,50 @@ display(count_pairs(cycle));
15421592
would go into an infinite loop. Exercise<SPACE/><REF NAME="ex:make-cycle"/>
15431593
constructed such lists.
15441594
<LABEL NAME="ex:find-cycle"/>
1595+
<SOLUTION>
1596+
<SNIPPET>
1597+
<EXAMPLE>exercise_3_18_solution_example</EXAMPLE>
1598+
<JAVASCRIPT>
1599+
// solution provided by GitHub user clean99
1600+
1601+
function contains_cycle(x) {
1602+
let counted_pairs = null;
1603+
function is_counted_pair(counted_pairs, x) {
1604+
return is_null(counted_pairs)
1605+
? false
1606+
: head(counted_pairs) === x
1607+
? true
1608+
: is_counted_pair(tail(counted_pairs), x);
1609+
}
1610+
function detect_cycle(x) {
1611+
if (is_null(x)) {
1612+
return false;
1613+
} else if (is_counted_pair(counted_pairs, x)) {
1614+
return true;
1615+
} else {
1616+
counted_pairs = pair(x, counted_pairs);
1617+
return detect_cycle(tail(x));
1618+
}
1619+
}
1620+
return detect_cycle(x);
1621+
}
1622+
</JAVASCRIPT>
1623+
</SNIPPET>
1624+
<SNIPPET HIDE="yes">
1625+
<NAME>exercise_3_18_solution_example</NAME>
1626+
<JAVASCRIPT>
1627+
const three_list = list("a", "b", "c");
1628+
const cycle = list("g", "h", "i");
1629+
set_tail(tail(tail(cycle)), cycle);
1630+
1631+
// displays false
1632+
display(contains_cycle(three_list));
1633+
1634+
// displays true
1635+
display(contains_cycle(cycle));
1636+
</JAVASCRIPT>
1637+
</SNIPPET>
1638+
</SOLUTION>
15451639
</EXERCISE>
15461640

15471641
<EXERCISE>

xml/chapter3/section3/subsection2.xml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,98 @@ print_queue(q); // prints: ["b", null]
951951
All operations should be accomplished in
952952
<LATEXINLINE>$\Theta(1)$</LATEXINLINE> steps.
953953
<LABEL NAME="ex:deque"/>
954+
<SOLUTION>
955+
<SNIPPET>
956+
<JAVASCRIPT>
957+
// solution provided by GitHub user clean99
958+
function make_deque() {
959+
return pair(null, null);
960+
}
961+
962+
function front_ptr(deque) {
963+
return head(deque);
964+
}
965+
966+
function rear_ptr(deque) {
967+
return tail(deque);
968+
}
969+
970+
function set_front_ptr(deque, item) {
971+
set_head(deque, item);
972+
}
973+
974+
function set_rear_ptr(deque, item) {
975+
set_tail(deque, item);
976+
}
977+
978+
function is_empty_deque(deque) {
979+
return is_null(front_ptr(deque))
980+
? true
981+
: is_null(rear_ptr(deque))
982+
? true
983+
: false;
984+
}
985+
986+
function is_one_item_deque(deque) {
987+
return front_ptr(deque) === rear_ptr(deque);
988+
}
989+
990+
function front_insert_deque(deque, item) {
991+
// use another pair to store a forward pointer
992+
const new_pair = pair(pair(item, null), null);
993+
if (is_empty_deque(deque)) {
994+
set_front_ptr(deque, new_pair);
995+
set_rear_ptr(deque, new_pair);
996+
} else {
997+
set_tail(new_pair, front_ptr(deque));
998+
// set forward pointer to new_pair
999+
set_tail(head(front_ptr(deque)), new_pair);
1000+
set_front_ptr(deque, new_pair);
1001+
}
1002+
}
1003+
1004+
function front_delete_deque(deque) {
1005+
if (is_empty_deque(deque)) {
1006+
error(deque, "front_delete_deque called with an empty deque");
1007+
} else if(is_one_item_deque(deque)) {
1008+
set_front_ptr(deque, null);
1009+
set_rear_ptr(deque, null);
1010+
return deque;
1011+
} else {
1012+
set_front_ptr(deque, tail(front_ptr(deque)));
1013+
return deque;
1014+
}
1015+
}
1016+
1017+
function rear_insert_deque(deque, item) {
1018+
if (is_empty_deque(deque)) {
1019+
const new_pair = pair(pair(item, null), null);
1020+
set_front_ptr(deque, new_pair);
1021+
set_rear_ptr(deque, new_pair);
1022+
} else {
1023+
// set new_pair forward pointer to last item
1024+
const new_pair = pair(pair(item, rear_ptr(deque)), null);
1025+
set_tail(rear_ptr(deque), new_pair);
1026+
set_rear_ptr(deque, new_pair);
1027+
}
1028+
}
1029+
1030+
function rear_delete_deque(deque) {
1031+
if (is_empty_deque(deque)) {
1032+
error(deque, "rear_delete_deque called with an empty deque");
1033+
} else if(is_one_item_deque(deque)) {
1034+
set_front_ptr(deque, null);
1035+
set_rear_ptr(deque, null);
1036+
return deque;
1037+
} else {
1038+
// update rear_ptr to last item's forward pointer
1039+
set_rear_ptr(deque, tail(head(rear_ptr(deque))));
1040+
return deque;
1041+
}
1042+
}
1043+
</JAVASCRIPT>
1044+
</SNIPPET>
1045+
</SOLUTION>
9541046
</EXERCISE>
9551047
<INDEX>queue<CLOSE/></INDEX>
9561048
</SUBSECTION>

xml/chapter3/section3/subsection3.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,52 @@ const put = operation_table("insert");
666666
</SPLITINLINE>
667667
for a local table.
668668
<LABEL NAME="ex:numeric-keys"/>
669+
<SOLUTION>
670+
<SNIPPET>
671+
<JAVASCRIPT>
672+
// Solution by GitHub user clean99
673+
674+
function make_table(same_key) {
675+
const local_table = list("*table*");
676+
function assoc(key, records) {
677+
return is_null(records)
678+
? undefined
679+
: same_key(key, head(head(records)))
680+
? head(records)
681+
: assoc(key, tail(records));
682+
}
683+
function lookup(key) {
684+
const record = assoc(key, tail(local_table));
685+
return is_undefined(record)
686+
? undefined
687+
: tail(record);
688+
}
689+
function insert(key, value) {
690+
const record = assoc(key, tail(local_table));
691+
if (is_undefined(record)) {
692+
set_tail(local_table,
693+
pair(pair(key, value), tail(local_table)));
694+
} else {
695+
set_tail(record, value);
696+
}
697+
return "ok";
698+
}
699+
function dispatch(m) {
700+
return m === "lookup"
701+
? lookup
702+
: m === "insert"
703+
? insert
704+
: error(m, "unknow operation -- table");
705+
}
706+
return dispatch;
707+
}
708+
709+
const operation_table = make_table((a, b) => a === b);
710+
const get = operation_table("lookup");
711+
const put = operation_table("insert");
712+
</JAVASCRIPT>
713+
</SNIPPET>
714+
</SOLUTION>
669715
</EXERCISE>
670716

671717
<EXERCISE>

0 commit comments

Comments
 (0)