# Daily Challenge #173 - Pandemia

### Setup

In this challenge, the world has been hit with a new virus! There is a new pandemic that humanity is struggling to fight against. The continents are separated by oceans, but some infected people have traveled before the quarantine.

You'll be given a map of the world in the form of a string:

```s = "01000000X000X011X0X"

"0" : uninfected

"1" : infected

"X" : ocean```
• If one person gets infected on a continent, the entire continent will get infected.
• The first and last continents are not connected.
• The virus cannot spread across the ocean.
• For maps without `X`, there are no oceans so the entire planet would become infected, return `0%`
• For maps without `0` or `1`, there are no people, return `0`.

Return the percentage of the population that are infected by the virus.

### Example

```start: map1 = "01000000X000X011X0X"
end:   map1 = "11111111X000X111X0X"
total = 15
infected = 11
percentage = 100*11/15 = 73.33333333333333```

### Tests

Which worlds are doomed? Which ones are saved?

```A: 01000000X000X011X0X
B: 01X000X010X011XX
C: XXXXX
D: 00000000X00X0000
E: 0000000010
F: 000001XXXX0010X1X00010
G: X00X000000X10X0100```

Good luck!

This challenge comes from JJason on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions! Valts Liepiņš

Ruby with heavy use of regexp and functional paradigm:

``````def infectionPercentage str
total = str.scan(/\d/).length
return 0 if total == 0
infected = str.gsub(/\d*1\d*/) { |x| x.split("").map {1}.join }.scan(/1/).length
"#{infected / total.to_f * 100}%"
end
`````` SavagePixie • Edited

JavaScript:

``````const getInfected = str => {
const pop = str
.replace(/[^10X]/g, '')
.split('X')
.reduce(
(a, b) => b.includes('1')
? { infected: a.infected + b.length, total: a.total + b.length
: { ...a, total: a.total + b.length }
, { infected: 0, total: 0})
return `\${pop.infected / pop.total * 100}℅`
}
`````` Jehiel Martinez

In Javascript

``````function doomPercentage(s) {
let infected = 0;
let total = 0;

if(!s.includes('1') || !s.includes('0')){
return 0;
}

s.split('X').forEach(continent => {
if(continent.includes('1')){
continent = continent.replace(/0/gi, '1');
infected += continent.length;
}
total += continent.length
});

return 100*infected/total;
};
``````

` Nijeesh Joshy

nice function name :D Amin

PHP

``````<?php

declare(strict_types=1);

function getInfectedPercentage(string \$world): float {
\$infected = 0;
\$population = 0;

foreach (explode("X", \$world) as \$continent) {
\$continentPopulation = strlen(\$continent);

\$population += \$continentPopulation;

if (strpos(\$continent, "1") !== false) {
\$infected += \$continentPopulation;
}
}

if (\$population === 0) {
return 0;
}

return \$infected / \$population * 100;
}

var_dump(getInfectedPercentage("01000000X000X011X0X"));
var_dump(getInfectedPercentage("01X000X010X011XX"));
var_dump(getInfectedPercentage("XXXXX"));
var_dump(getInfectedPercentage("00000000X00X0000"));
var_dump(getInfectedPercentage("0000000010"));
var_dump(getInfectedPercentage("000001XXXX0010X1X00010"));
var_dump(getInfectedPercentage("X00X000000X10X0100"));

// float(73.333333333333)
// float(72.727272727273)
// float(0)
// float(0)
// float(100)
// float(100)
// float(42.857142857143)
`````` js

``````// Please specify Input conditions:

// Will 'X' always be Uppercase in string?
// Will str always consist just of '1', 'X' and '0'?

// Assuming BOTH above are TRUE:

function getPercentage(str){

if(!['0','1'].some(el=>str.includes(el))){return '0';}
if (!str.includes('X')){return '0%'};

var continents = str.split('X');

var totalPeople = 0;
var totalInfected = 0;

for(var i = 0; i<continents.length; i++){
if(continents[i].includes('1')){
totalInfected+=continents[i].length;
}
totalPeople+=continents[i].length;
}

return 100*totalInfected/totalPeople;

}

// Maps without people are strings without '1' AND '0'. Fix that.
// 'No people case' should return false and 'just land case' - number type 0.
// Hide the percentage formula as that should be part of task.

`````` lusen / they / them 🏳️‍🌈🥑
``````
def _process_continent(continent):
total = 0
infected = False
for person in continent:
total += 1
if person == '1':
infected = True
if infected:
return (total, total)
else:
return (total, 0)

def percent_infected(map):
continents = map.split('X')
total = 0
infected = 0

for continent in continents:
ct, ci = _process_continent(continent)
total += ct
infected += ci

if total == 0:
return 0

return infected/total*100

print('A', percent_infected('01000000X000X011X0X'))
print('B', percent_infected('01X000X010X011XX'))
print('C', percent_infected('XXXXX'))
print('D', percent_infected('00000000X00X0000'))
print('E', percent_infected('0000000010'))
print('F', percent_infected('000001XXXX0010X1X00010'))
print('G', percent_infected('X00X000000X10X0100'))
`````` Kyle Jones

Alternative to @candidateplanet 's Python implementation:

``````OCEAN = 'X'
INFECTED = '1'

def calculate_percentage_infected(map_in):
'''
Calculate the Percentage of the Population that will be Infected.
'''
total_infected = 0
total = 0
for continent in map_in.split(OCEAN):
total += len(continent)
if INFECTED in continent:
result = INFECTED * len(continent)
total_infected += len(continent)

if total == 0:
return (total_infected / total) * 100

print("INFECTED PERCENTAGE: {}%".format(calculate_percentage_infected("01000000X000X011X0X")))
print("INFECTED PERCENTAGE: {}%".format(calculate_percentage_infected("01X000X010X011XX")))
print("INFECTED PERCENTAGE: {}%".format(calculate_percentage_infected("XXXXX")))
print("INFECTED PERCENTAGE: {}%".format(calculate_percentage_infected("00000000X00X0000")))
print("INFECTED PERCENTAGE: {}%".format(calculate_percentage_infected("0000000010")))
print("INFECTED PERCENTAGE: {}%".format(calculate_percentage_infected("000001XXXX0010X1X00010")))
print("INFECTED PERCENTAGE: {}%".format(calculate_percentage_infected("X00X000000X10X0100")))

`````` Nijeesh Joshy • Edited

RUBY

``````#TESTS
require 'minitest'

class IsDivisibleTest < MiniTest::Test
def test_calculate_infected_percentage
assert_equal  100 * 11.00 / 15.0 , calculate_infected_percentage('01000000X000X011X0X')
assert_equal 100 * 8.00 / 11, calculate_infected_percentage('01X000X010X011XX')
assert_equal 100.0, calculate_infected_percentage('000001XXXX0010X1X00010')
assert_equal 100 * 6.00 / 14, calculate_infected_percentage('X00X000000X10X0100')
end

def test_no_peoples
assert_equal 0, calculate_infected_percentage('XXXXX')
end

def test_none_infected
assert_equal 0, calculate_infected_percentage('00000000X00X0000')
end

def no_islands
assert_equal 100.0, calculate_infected_percentage('0000000010')
end
end

#============CODE==================

def calculate_infected_percentage(world='')
return 0 if !world.include?('0') || !world.include?('1')
continents = world.split('X')
total_population = 0
infected = 0
continents.each do  |continent|
total_population += continent.length
infected+= continent.length if continent.include?('1')
end

(infected * 100.00) / total_population
end

``````
``````> MiniTest.run

Run options: --seed 34491

# Running:

...

Finished in 0.002091s, 1434.6125 runs/s, 3347.4292 assertions/s.

4 runs, 7 assertions, 0 failures, 0 errors, 0 skips
=> true

`````` Ruan Engelbrecht

Late to the party. JavaScript.

``````const infectedPercentage = s => {
let population = s.split('X');

if (!population.some(x => x)) return '0';

let infected = population
.map(x => (x.includes('1') ? x.length : 0))
.reduce((acc, v) => acc + v, 0);

return `\${(infected / population.join('').length) * 100}%`;
};
`````` Idan Arye

Rust:

``````fn infected(map: &str) -> f64 {
#[derive(Debug)]
enum Cell {
Uninfected,
Infected,
Ocean,
}
let mut map: Vec<_> = map.chars().map(|c| match c {
'0' => Cell::Uninfected,
'1' => Cell::Infected,
'X' => Cell::Ocean,
_ => panic!("Illegal cell type {}", c),
}).collect();

fn propagate<'a>(cells: impl Iterator<Item = &'a mut Cell>) {
let mut infecting = false;
for cell in cells {
match cell {
Cell::Uninfected => {
if infecting {
*cell = Cell::Infected;
}
}
Cell::Infected => {
infecting = true;
}
Cell::Ocean => {
infecting = false;
}
}
}
}
propagate(map.iter_mut());
propagate(map.iter_mut().rev());

let mut infected = 0usize;
let mut total = 0usize;
for cell in map {
match cell {
Cell::Uninfected => {
total += 1;
}
Cell::Infected => {
total += 1;
infected += 1;
}
Cell::Ocean => {}
}
}
if total == 0 {
0.0
} else {
100.0 * infected as f64 / total as f64
}
}

fn main() {
assert_eq!(infected("01000000X000X011X0X"), 73.33333333333333);
assert_eq!(infected("01X000X010X011XX"), 72.72727272727273);
assert_eq!(infected("XXXXX"), 0.0);
assert_eq!(infected("00000000X00X0000"), 0.0);
assert_eq!(infected("0000000010"), 100.0);
assert_eq!(infected("000001XXXX0010X1X00010"), 100.0);
assert_eq!(infected("X00X000000X10X0100"), 42.857142857142854);
}
``````