Skip to content

Commit 4248b45

Browse files
[Go] Elon's Toys
1 parent ac811d6 commit 4248b45

File tree

8 files changed

+461
-0
lines changed

8 files changed

+461
-0
lines changed

go/elons-toys/HELP.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Help
2+
3+
## Running the tests
4+
5+
To run the tests run the command `go test` from within the exercise directory.
6+
7+
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
8+
flags:
9+
10+
go test -v --bench . --benchmem
11+
12+
Keep in mind that each reviewer will run benchmarks on a different machine, with
13+
different specs, so the results from these benchmark tests may vary.
14+
15+
## Submitting your solution
16+
17+
You can submit your solution using the `exercism submit elons_toys.go` command.
18+
This command will upload your solution to the Exercism website and print the solution page's URL.
19+
20+
It's possible to submit an incomplete solution which allows you to:
21+
22+
- See how others have completed the exercise
23+
- Request help from a mentor
24+
25+
## Need to get help?
26+
27+
If you'd like help solving the exercise, check the following pages:
28+
29+
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
30+
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
31+
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
32+
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
33+
34+
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
35+
36+
To get help if you're having trouble, you can use one of the following resources:
37+
38+
- [How to Write Go Code](https://golang.org/doc/code.html)
39+
- [Effective Go](https://golang.org/doc/effective_go.html)
40+
- [Go Resources](http://golang.org/help)
41+
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

go/elons-toys/HINTS.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Hints
2+
3+
## 1. Drive a car
4+
5+
- Add a field to the `Car` struct that keeps track of the driven distance
6+
- Create a [method][method] that has a receiver of type `Car` and updates the driven distance
7+
8+
## 2. Display the distance driven
9+
10+
- Create a [method][method] that has a receiver of type `Car`
11+
- Show the value of the _distance_ field
12+
13+
## 3. Display the battery percentage
14+
15+
- Create a [method][method] that has a receiver of type `Car`
16+
- Show the value of the _battery_ field
17+
18+
## 4. Check if a remote car can finish a race
19+
20+
- Remember the car has a [method][method] to retrieve the distance it has driven
21+
- Consider what to do when the battery has been drained before reaching the finish line
22+
23+
[method]: https://tour.golang.org/methods/1

go/elons-toys/README.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# Elon's Toys
2+
3+
Welcome to Elon's Toys on Exercism's Go Track.
4+
If you need help running the tests or submitting your code, check out `HELP.md`.
5+
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
6+
7+
## Introduction
8+
9+
A method is a function with a special _receiver_ argument. The receiver appears in its own argument list between `func` keyword and the name of the method.
10+
11+
```go
12+
func (receiver type) MethodName(parameters) (returnTypes) {
13+
}
14+
```
15+
16+
You can only define a method with a receiver whose type is defined in the same package as the method.
17+
18+
```go
19+
package person
20+
21+
type Person struct {
22+
Name string
23+
}
24+
25+
func (p Person) Greetings() string {
26+
return fmt.Sprintf("Welcome %s!", p.Name)
27+
}
28+
```
29+
30+
The method on the struct can be called via dot notation.
31+
32+
```go
33+
p := Person{Name: "Bronson"}
34+
fmt.Println(p.Greetings())
35+
// Output: Welcome Bronson!
36+
```
37+
38+
Notice the way we called the method `Greetings()` on the `Person` instance `p`.
39+
It’s exactly like the way you call methods in an object-oriented programming language.
40+
41+
Remember: a method is just a function with a receiver argument.
42+
Methods help to avoid naming conflicts - since a method is tied to a particular receiver type, you can have the same method name on different types.
43+
44+
```go
45+
import "math"
46+
47+
type rect struct {
48+
width, height int
49+
}
50+
func (r rect) area() int {
51+
return r.width * r.height
52+
}
53+
54+
type circle struct {
55+
radius int
56+
}
57+
func (c circle) area() float64 {
58+
return math.Pow(float64(c.radius), 2) * math.Pi
59+
}
60+
```
61+
62+
There are two types of receivers, value receivers, and pointer receivers.
63+
64+
All the methods we have seen so far have a value receiver which means they will receive a copy of the value passed to the method, meaning that any modification done to the receiver inside the method is not visible to the caller.
65+
66+
You can declare methods with pointer receivers in order to modify the value to which the receiver points.
67+
This is done by prefixing the type name with a `*`.
68+
For example with the `rect` type, a pointer receiver would be declared as `*rect`.
69+
Such modifications are visible to the caller of the method as well.
70+
71+
```go
72+
type rect struct {
73+
width, height int
74+
}
75+
func (r *rect) squareIt() {
76+
r.height = r.width
77+
}
78+
79+
r := rect{width: 10, height: 20}
80+
fmt.Printf("Width: %d, Height: %d\n", r.width, r.height)
81+
// Output: Width: 10, Height: 20
82+
83+
r.squareIt()
84+
fmt.Printf("Width: %d, Height: %d\n", r.width, r.height)
85+
// Output: Width: 10, Height: 10
86+
```
87+
88+
## Instructions
89+
90+
Note: This exercise is a continuation of the `need-for-speed` exercise.
91+
92+
In this exercise you'll be organizing races between various types of remote controlled cars. Each car has its own speed and battery drain characteristics.
93+
94+
Cars start with full (100%) batteries. Each time you drive the car using the remote control, it covers the car's speed in meters and decreases the remaining battery percentage by its battery drain.
95+
96+
If a car's battery is below its battery drain percentage, you can't drive the car anymore.
97+
98+
The remote controlled car has a fancy LED display that shows two bits of information:
99+
100+
- The total distance it has driven, displayed as: `"Driven <METERS> meters"`.
101+
- The remaining battery charge, displayed as: `"Battery at <PERCENTAGE>%"`.
102+
103+
Each race track has its own distance. Cars are tested by checking if they can finish the track without running out of battery.
104+
105+
## 1. Drive the car
106+
107+
Implement the `Drive` method on the `Car` that updates the number of meters driven based on the car's speed, and reduces the battery according to the battery drainage:
108+
109+
```go
110+
speed := 5
111+
batteryDrain := 2
112+
car := NewCar(speed, batteryDrain)
113+
car.Drive()
114+
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
115+
```
116+
117+
Note: You should not try to drive the car if doing so will cause the car's battery to be below 0.
118+
119+
## 2. Display the distance driven
120+
121+
Implement a `DisplayDistance` method on `Car` to return the distance as displayed on the LED display as a `string`:
122+
123+
```go
124+
speed := 5
125+
batteryDrain := 2
126+
car := NewCar(speed, batteryDrain)
127+
128+
fmt.Println(car.DisplayDistance())
129+
// Output: "Driven 0 meters"
130+
```
131+
132+
## 3. Display the battery percentage
133+
134+
Implement the `DisplayBattery` method on `Car` to return the battery percentage as displayed on the LED display as a `string`:
135+
136+
```go
137+
speed := 5
138+
batteryDrain := 2
139+
car := NewCar(speed, batteryDrain)
140+
141+
fmt.Println(car.DisplayBattery())
142+
// Output: "Battery at 100%"
143+
```
144+
145+
## 4. Check if a remote control car can finish a race
146+
147+
To finish a race, a car has to be able to drive the race's distance. This means not draining its battery before having crossed the finish line. Implement the `CanFinish` method that takes a `trackDistance int` as its parameter and returns `true` if the car can finish the race; otherwise, return `false`:
148+
149+
```go
150+
speed := 5
151+
batteryDrain := 2
152+
car := NewCar(speed, batteryDrain)
153+
154+
trackDistance := 100
155+
156+
car.CanFinish(trackDistance)
157+
// => true
158+
```
159+
160+
## Source
161+
162+
### Created by
163+
164+
- @tehsphinx
165+
166+
### Contributed to by
167+
168+
- @oanaOM
169+
- @mcastorina

go/elons-toys/car.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package elon
2+
3+
// Car implements a remote controlled car.
4+
type Car struct {
5+
speed int
6+
batteryDrain int
7+
8+
battery int
9+
distance int
10+
}
11+
12+
// NewCar creates a new car with given specifications.
13+
func NewCar(speed, batteryDrain int) *Car {
14+
return &Car{
15+
speed: speed,
16+
batteryDrain: batteryDrain,
17+
battery: 100,
18+
}
19+
}

go/elons-toys/elons_toys.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package elon
2+
3+
import (
4+
"fmt"
5+
"math"
6+
)
7+
8+
9+
10+
func (c *Car) Drive() {
11+
if c.battery < c.batteryDrain {
12+
return
13+
}
14+
15+
c.battery -= c.batteryDrain
16+
c.distance += c.speed
17+
}
18+
19+
func (c *Car) DisplayDistance() string {
20+
return fmt.Sprintf("Driven %d meters", c.distance)
21+
}
22+
23+
func (c *Car) DisplayBattery() string {
24+
return fmt.Sprintf("Battery at %d%%", c.battery)
25+
}
26+
27+
func (c *Car) CanFinish(trackDistance int) bool {
28+
drivesNeeded := int(math.Ceil(float64(trackDistance) / float64(c.speed)))
29+
drivesLeft := int(float64(c.battery) / float64(c.batteryDrain))
30+
return drivesLeft >= drivesNeeded
31+
}

0 commit comments

Comments
 (0)