Simulate aliens invading a planet and report back the remaining cities.
Requirements:
- City maps are provided in files in a specific format detailed here
- Any remaining cites at end of simulation should be reported in same format as input city maps.
- As cities fall to aliens, they are reported in specfic format detailed here
- Ability to control of the number of aliens in simulation
Simulation will honor the following aliens characteristics:
- If two aliens enter a city, the city MUST be destroyed along with the aliens.
- Once all aliens have landed in various cities, in the next round they MUST move to a neighboring city if there is one. They MUST NOT stay in the same city. If there is no neighboring city to move to, they would be trapped in that city for the duration of the simulation.
- Destroyed cites MUST be removed from the map of available cities reported at the end of the simulation.
- On initial landing, if a city is already destroyed then incoming aliens MUST NOT land in that destroyed city. This honors above requirement.
- If all remaining aliens are dead, simulation MAY end
- If no cities remain, simulation MAY end
- If all remaining aliens are trapped, simulation MAY end
- Aliens from a previous round in a given city MUST NOT interact with incoming aliens in the next round. For example, if in round
2
, alien10
was in a cityX
. Then in round3
alien99
enters cityX
. This will not trigger a fight between aliens10
and99
.
Items of note:
- Because of the above requirements, aliens might oscilate between two cities until the end of the simulation. This happens when two cities only have one remaining exit path and that is to eachother. For example, if the only way out of Boston is to Bangor and the only way out of Bangor is to Boston and each city has a single alien then the aliens will constantly pass eachother in each round until the end of the simulation.
Golang should be installed in PATH. Any version should work but testing with Go v1.18 on Ubuntu 20.4
cd cmd/alien-invasion
go run . < ../../testdata/small-map.txt
Sample Output:
2022/07/13 20:04:19 invasion starting round
2022/07/13 20:04:19 alien 0 invading NewYork
2022/07/13 20:04:19 alien 1 invading NewYork
NewYork has been destroyed by alien 1 and alien 0!
2022/07/13 20:04:19 alien 4 invading Boston
2022/07/13 20:04:19 alien 7 invading Albany
2022/07/13 20:04:19 alien 8 invading Boston
Boston has been destroyed by alien 8 and alien 4!
2022/07/13 20:04:19 invasion 1 round
2022/07/13 20:04:19 no more aliens
Albany
Bangor
Columbus
Trenton
Usage of ./alien-invasion: < city-map-file > report
-numAliens int
Number of aliens invading (default 10)
-numRounds int
Limit the number of rounds the aliens perform before giving up (default 10000)
-outputFile string
Optional remaining cities output file
-seed int
Optional random seed to control pseudo random results. Default of zero for random each time
-silent
Supress log output but still output city report and fallen cities
-strict
Use a more strict parse that does not back link any cities in opposite directions
go test .
Sample city input file:
Boston north=Bangor south=NewYork west=Albany
NewYork south=Trenton west=Columbus
Format Assumptions:
- City names cannot contain spaces
- If a city references another city, that referenced city is not required to have a separate line. So in
Boston north=Bangor
thenBangor south=Boston
is not required - If a map contains inconsistent data with regard to neighboring references then those inconstencies will not be allowed. Example of bad data:
Boston north=Bangor
Bangor south=Portland
When a city falls to aliens, the city and the responsible aliens are reported in this format:
NewYork has been destroyed by alien 1 and alien 0!
Where NewYork
is the city name. Aliens 1
and 0
are the responsible aliens.
Developer Note - Golden Files in Unit Testing
Golden files are used to ensure large datasets only change when desired and in precise ways. If a unit test fails because the output doesn't match a "golden file" there are two options. First inspect the "diff" and if the difference is expected, simply accept the difference by running the test again with the -update
flag. This strategy is used in the Golang SDK but not exclusive any single computer language.
Example:
go test -run TestMediumInvasion
Diff:
--- Expected
+++ Actual
@@ -4,3 +4,2 @@
Trenton has been destroyed by alien 7 and alien 4!
-Bogus
Boston
Test: TestSmallInvasion
If difference is expected, then run following command to update the golden file
go test -run TestMediumInvasion -update
If difference is not expected, then you found a bug in your code.
Some unit tests set the random number seed to get consistent random values, or "pseudo random" values. Together with golden files, very complex code with randomness can have a predictable output to test against. In order for this to work, certain code may have to avoid iterating Golang maps as that iteration is not deterministic.
To inspect unit test coverage:
go test -coverprofile cp.out .
go tool cover -html=cp.out