DEV Community

dev.to staff
dev.to staff

Posted on

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!

Top comments (11)

Collapse
 
cipharius profile image
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
Collapse
 
savagepixie profile image
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}℅`
}
Collapse
 
jehielmartinez profile image
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;
};


`

Collapse
 
nijeesh4all profile image
Nijeesh Joshy

nice function name :D

Collapse
 
aminnairi profile image
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)
Collapse
 
madza profile image
Madza • Edited

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.

Collapse
 
candidateplanet profile image
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'))
Collapse
 
kerldev profile image
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
    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")))

Collapse
 
nijeesh4all profile image
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

Collapse
 
ruanengelbrecht profile image
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}%`;
};
Collapse
 
idanarye profile image
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);
}