Skip to content

Commit a11e5fa

Browse files
authored
add grade-school exercism#405
1 parent 8ae6377 commit a11e5fa

File tree

7 files changed

+359
-0
lines changed

7 files changed

+359
-0
lines changed

config.json

+8
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,14 @@
854854
"practices": [],
855855
"prerequisites": [],
856856
"difficulty": 2
857+
},
858+
{
859+
"slug": "grade-school",
860+
"name": "Grade School",
861+
"uuid": "e5ab14bd-9eeb-4c63-8143-55e1e56b4ac1",
862+
"practices": [],
863+
"prerequisites": [],
864+
"difficulty": 5
857865
}
858866
]
859867
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Instructions
2+
3+
Given students' names along with the grade that they are in, create a roster for the school.
4+
5+
In the end, you should be able to:
6+
7+
- Add a student's name to the roster for a grade
8+
- "Add Jim to grade 2."
9+
- "OK."
10+
- Get a list of all students enrolled in a grade
11+
- "Which students are in grade 2?"
12+
- "We've only got Jim just now."
13+
- Get a sorted list of all students in all grades.
14+
Grades should sort as 1, 2, 3, etc., and students within a grade should be sorted alphabetically by name.
15+
- "Who all is enrolled in school right now?"
16+
- "Let me think.
17+
We have Anna, Barb, and Charlie in grade 1, Alex, Peter, and Zoe in grade 2 and Jim in grade 5.
18+
So the answer is: Anna, Barb, Charlie, Alex, Peter, Zoe and Jim"
19+
20+
Note that all our students only have one name (It's a small town, what do you want?) and each student cannot be added more than once to a grade or the roster.
21+
In fact, when a test attempts to add the same student more than once, your implementation should indicate that this is incorrect.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"authors": [
3+
"kmarker1101"
4+
],
5+
"files": {
6+
"solution": [
7+
"grade-school.el"
8+
],
9+
"test": [
10+
"grade-school-test.el"
11+
],
12+
"example": [
13+
".meta/example.el"
14+
]
15+
},
16+
"blurb": "Given students' names along with the grade that they are in, create a roster for the school.",
17+
"source": "A pairing session with Phil Battos at gSchool"
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
;;; grade-school.el --- Grade School (exercism) -*- lexical-binding: t; -*-
2+
3+
;;; Commentary:
4+
5+
;;; Code:
6+
7+
8+
(require 'cl-lib)
9+
10+
(cl-defstruct school (roster (make-hash-table :test 'equal)))
11+
12+
(defun add (school name grade)
13+
(let ((current-roster (school-roster school)))
14+
(if (cl-loop for g being the hash-keys of current-roster
15+
thereis (member name (gethash g current-roster)))
16+
nil
17+
(puthash grade (sort (cons name (gethash grade current-roster)) #'string<) current-roster)
18+
t)))
19+
20+
(defun roster (school)
21+
(let ((grades-and-names (list)))
22+
(maphash (lambda (grade names) (push (cons grade names) grades-and-names))
23+
(school-roster school))
24+
(apply #'append
25+
(mapcar #'cdr
26+
(sort grades-and-names (lambda (a b) (< (car a) (car b))))))))
27+
28+
(defun grade (school grade)
29+
(gethash grade (school-roster school)))
30+
31+
(defun set-grade (school grade newval)
32+
(puthash grade (sort newval #'string<) (school-roster school)))
33+
34+
35+
(provide 'grade-school)
36+
;;; grade-school.el ends here
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[a3f0fb58-f240-4723-8ddc-e644666b85cc]
13+
description = "Roster is empty when no student is added"
14+
15+
[9337267f-7793-4b90-9b4a-8e3978408824]
16+
description = "Add a student"
17+
18+
[6d0a30e4-1b4e-472e-8e20-c41702125667]
19+
description = "Student is added to the roster"
20+
21+
[73c3ca75-0c16-40d7-82f5-ed8fe17a8e4a]
22+
description = "Adding multiple students in the same grade in the roster"
23+
24+
[233be705-dd58-4968-889d-fb3c7954c9cc]
25+
description = "Multiple students in the same grade are added to the roster"
26+
27+
[87c871c1-6bde-4413-9c44-73d59a259d83]
28+
description = "Cannot add student to same grade in the roster more than once"
29+
30+
[c125dab7-2a53-492f-a99a-56ad511940d8]
31+
description = "A student can't be in two different grades"
32+
include = false
33+
34+
[a0c7b9b8-0e89-47f8-8b4a-c50f885e79d1]
35+
description = "A student can only be added to the same grade in the roster once"
36+
include = false
37+
reimplements = "c125dab7-2a53-492f-a99a-56ad511940d8"
38+
39+
[d7982c4f-1602-49f6-a651-620f2614243a]
40+
description = "Student not added to same grade in the roster more than once"
41+
reimplements = "a0c7b9b8-0e89-47f8-8b4a-c50f885e79d1"
42+
43+
[e70d5d8f-43a9-41fd-94a4-1ea0fa338056]
44+
description = "Adding students in multiple grades"
45+
46+
[75a51579-d1d7-407c-a2f8-2166e984e8ab]
47+
description = "Students in multiple grades are added to the roster"
48+
49+
[7df542f1-57ce-433c-b249-ff77028ec479]
50+
description = "Cannot add same student to multiple grades in the roster"
51+
52+
[6a03b61e-1211-4783-a3cc-fc7f773fba3f]
53+
description = "A student cannot be added to more than one grade in the sorted roster"
54+
include = false
55+
reimplements = "c125dab7-2a53-492f-a99a-56ad511940d8"
56+
57+
[c7ec1c5e-9ab7-4d3b-be5c-29f2f7a237c5]
58+
description = "Student not added to multiple grades in the roster"
59+
reimplements = "6a03b61e-1211-4783-a3cc-fc7f773fba3f"
60+
61+
[d9af4f19-1ba1-48e7-94d0-dabda4e5aba6]
62+
description = "Students are sorted by grades in the roster"
63+
64+
[d9fb5bea-f5aa-4524-9d61-c158d8906807]
65+
description = "Students are sorted by name in the roster"
66+
67+
[180a8ff9-5b94-43fc-9db1-d46b4a8c93b6]
68+
description = "Students are sorted by grades and then by name in the roster"
69+
70+
[5e67aa3c-a3c6-4407-a183-d8fe59cd1630]
71+
description = "Grade is empty if no students in the roster"
72+
73+
[1e0cf06b-26e0-4526-af2d-a2e2df6a51d6]
74+
description = "Grade is empty if no students in that grade"
75+
76+
[2bfc697c-adf2-4b65-8d0f-c46e085f796e]
77+
description = "Student not added to same grade more than once"
78+
79+
[66c8e141-68ab-4a04-a15a-c28bc07fe6b9]
80+
description = "Student not added to multiple grades"
81+
82+
[c9c1fc2f-42e0-4d2c-b361-99271f03eda7]
83+
description = "Student not added to other grade for multiple grades"
84+
85+
[1bfbcef1-e4a3-49e8-8d22-f6f9f386187e]
86+
description = "Students are sorted by name in a grade"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
;;; grade-school-test.el --- Grade School (exercism) -*- lexical-binding: t; -*-
2+
3+
;;; Commentary:
4+
5+
;;; Code:
6+
7+
8+
(load-file "grade-school.el")
9+
(declare-function roster "grade-school.el" (students))
10+
(declare-function add "grade-school.el" (students))
11+
(declare-function grade "grade-school.el" (desired-grade students))
12+
13+
14+
(ert-deftest roster-is-empty-when-no-student-is-added ()
15+
(let ((test-school (make-school)))
16+
(should (equal (roster test-school) '()))))
17+
18+
19+
(ert-deftest add-a-student ()
20+
(let ((test-school (make-school)))
21+
(should (add test-school "Aimee" 2))))
22+
23+
24+
(ert-deftest student-is-added-to-the-roster ()
25+
(let ((test-school (make-school)))
26+
(add test-school "Aimee" 2)
27+
(should (equal (roster test-school) '("Aimee")))))
28+
29+
30+
(ert-deftest adding-multiple-students-in-the-same-grade-in-the-roster ()
31+
(let ((test-school (make-school)))
32+
(should (add test-school "Blair" 2))
33+
(should (add test-school "James" 2))
34+
(should (add test-school "Paul" 2))))
35+
36+
37+
(ert-deftest multiple-students-in-the-same-grade-are-added-to-the-roster ()
38+
(let ((test-school (make-school)))
39+
(add test-school "Blair" 2)
40+
(add test-school "James" 2)
41+
(add test-school "Paul" 2)
42+
(should (equal (roster test-school) '("Blair" "James" "Paul")))))
43+
44+
45+
(ert-deftest cannot-add-student-to-same-grade-in-the-roster-more-than-once ()
46+
(let ((test-school (make-school)))
47+
(should (add test-school "Blair" 2))
48+
(should (add test-school "James" 2))
49+
(should-not (add test-school "James" 2))
50+
(should (add test-school "Paul" 2))))
51+
52+
53+
(ert-deftest student-not-added-to-same-grade-in-the-roster-more-than-once ()
54+
(let ((test-school (make-school)))
55+
(add test-school "Blair" 2)
56+
(add test-school "James" 2)
57+
(add test-school "James" 2)
58+
(add test-school "Paul" 2)
59+
(should (equal (roster test-school) '("Blair" "James" "Paul")))))
60+
61+
62+
(ert-deftest adding-students-in-multiple-grades ()
63+
(let ((test-school (make-school)))
64+
(should (add test-school "Chelsea" 3))
65+
(should (add test-school "Loagan" 7))))
66+
67+
68+
(ert-deftest students-in-multiple-grades-are-added-to-the-roster ()
69+
(let ((test-school (make-school)))
70+
(add test-school "Chelsea" 3)
71+
(add test-school "Logan" 7)
72+
(should (equal (roster test-school) '("Chelsea" "Logan")))))
73+
74+
75+
(ert-deftest cannot-add-same-student-to-multiple-grades-in-the-roster ()
76+
(let ((test-school (make-school)))
77+
(should (add test-school "Blair" 2))
78+
(should (add test-school "James" 2))
79+
(should-not (add test-school "James" 3))
80+
(should (add test-school "Paul" 3))))
81+
82+
83+
(ert-deftest student-not-added-to-multiple-grades-in-the-roster ()
84+
(let ((test-school (make-school)))
85+
(add test-school "Blair" 2)
86+
(add test-school "James" 2)
87+
(add test-school "James" 3)
88+
(add test-school "Paul" 3)
89+
(should (equal (roster test-school) '("Blair" "James" "Paul")))))
90+
91+
92+
(ert-deftest students-are-sorted-by-grades-in-the-roster ()
93+
(let ((test-school (make-school)))
94+
(add test-school "Jim" 3)
95+
(add test-school "Peter" 2)
96+
(add test-school "Anna" 1)
97+
(should (equal (roster test-school) '("Anna" "Peter" "Jim")))))
98+
99+
100+
(ert-deftest students-are-sorted-by-name-in-the-roster ()
101+
(let ((test-school (make-school)))
102+
(add test-school "Peter" 2)
103+
(add test-school "Zoe" 2)
104+
(add test-school "Alex" 2)
105+
(should (equal (roster test-school) '("Alex" "Peter" "Zoe")))))
106+
107+
108+
(ert-deftest students-are-sorted-by-grades-and-then-by-name-in-the-roster ()
109+
(let ((test-school (make-school)))
110+
(add test-school "Peter" 2)
111+
(add test-school "Anna" 1)
112+
(add test-school "Barb" 1)
113+
(add test-school "Zoe" 2)
114+
(add test-school "Alex" 2)
115+
(add test-school "Jim" 3)
116+
(add test-school "Charlie" 1)
117+
(should (equal (roster test-school) '("Anna" "Barb" "Charlie" "Alex" "Peter" "Zoe" "Jim")))))
118+
119+
120+
(ert-deftest grade-is-empty-if-no-students-in-the-roster ()
121+
(let ((test-school (make-school)))
122+
(should (equal (grade test-school 1) '()))))
123+
124+
125+
(ert-deftest grade-is-empty-if-no-students-in-that-grade ()
126+
(let ((test-school (make-school)))
127+
(add test-school "Peter" 2)
128+
(add test-school "Zoe" 2)
129+
(add test-school "Alex" 2)
130+
(add test-school "Jim" 3)
131+
(should (equal (grade test-school 1) '()))))
132+
133+
134+
(ert-deftest student-not-added-to-same-grade-more-than-once ()
135+
(let ((test-school (make-school)))
136+
(add test-school "Blair" 2)
137+
(add test-school "James" 2)
138+
(add test-school "James" 2)
139+
(add test-school "Paul" 2)
140+
(should (equal (grade test-school 2) '("Blair" "James" "Paul")))))
141+
142+
143+
(ert-deftest student-not-added-to-multiple-grades ()
144+
(let ((test-school (make-school)))
145+
(add test-school "Blair" 2)
146+
(add test-school "James" 2)
147+
(add test-school "James" 3)
148+
(add test-school "Paul" 3)
149+
(should (equal (grade test-school 2) '("Blair" "James")))))
150+
151+
152+
(ert-deftest student-not-added-to-other-grade-for-multiple-grades ()
153+
(let ((test-school (make-school)))
154+
(add test-school "Blair" 2)
155+
(add test-school "James" 2)
156+
(add test-school "James" 3)
157+
(add test-school "Paul" 3)
158+
(should (equal (grade test-school 3) '("Paul")))))
159+
160+
161+
(ert-deftest students-are-sorted-by-name-in-a-grade ()
162+
(let ((test-school (make-school)))
163+
(add test-school "Franklin" 5)
164+
(add test-school "Bradley" 5)
165+
(add test-school "Jeff" 1)
166+
(should (equal (grade test-school 5) '("Bradley" "Franklin")))))
167+
168+
169+
(provide 'grade-school-test)
170+
;;; grade-school-test.el ends here
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
;;; grade-school.el --- Grade School (exercism) -*- lexical-binding: t; -*-
2+
3+
;;; Commentary:
4+
5+
;;; Code:
6+
7+
8+
(defun roster (students)
9+
(error "Delete this S-Expression and write your own implementation"))
10+
11+
(defun add (students)
12+
(error "Delete this S-Expression and write your own implementation"))
13+
14+
(defun grade (desired-grade students)
15+
(error "Delete this S-Expression and write your own implementation"))
16+
17+
18+
(provide 'grade-school)
19+
;;; grade-school.el ends here
20+

0 commit comments

Comments
 (0)