Peter’s blog ✴ Week 215 ✴ 1 May 2023

THE WEEKLY CHALLENGE
Adopt a chilly ghost

The Perl Camel

Task 2

Number placement

You are given a list of numbers, all just 0 or 1. You are also given placement $count >=1.

Write a script to find out if it is possible to replace 0 with 1 in the given list $count times. The only condition is that you can only replace when there is no 1 on either side. Print 1 if it is possible, otherwise 0.

Examples


Example 1
Input:  = (1,0,0,0,1),  = 1
Output: 1
You are asked to replace only one 0 as given count is 1.
We can easily replace middle 0 in the list i.e.
   (1,0,1,0,1).

Example 2
Input:  = (1,0,0,0,1),  = 2
Output: 0
You are asked to replace two 0's as given count is 2.
It is impossible to replace two 0's.

Example 3
Input:  = (1,0,0,0,0,0,0,0,1),  = 3
Output: 1

Analysis

The easiest way to do this - in my opinion - is to make the list into a string using join(). You can then try replacing a 0 with a 1 using s|||.

The examples all show replacing 000 with 010, but the rule implies that you can also replace an initial 00 with 10 or a final 00 with 01 so we'd better allow for that too.

The important line of code is:
$done ++ if ($string =~ s|000|010|
   or $string =~ s|^00|10| or $string =~ s|00$|01|);

which is executed $count times, and success is then given by $count == $done.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Numbers (eg 1, 0, 0, 0, 1):

Count (eg 2):

Script


#!/usr/bin/perl

use v5.16;    # The Weekly Challenge - 2023-05-01
use utf8;     # Week 215 task 2 - Number placement
use strict;   # Peter Campbell Smith
use warnings; # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

number_placement([1, 0, 0, 0, 1], 1);
number_placement([1, 0, 0, 0, 1], 2);
number_placement([0, 0, 1, 0, 0, 0, 1, 0, 0], 3);

sub number_placement {

    my (@numbers, $count, $string, $j, $done);
    
    @numbers = @{$_[0]};
    $count = $_[1];
    
    $string = join('', @numbers);
    for $j (1 .. $count) {
        $done ++ if ($string =~ s|000|010| or 
            $string =~ s|^00|10| or $string =~ s|00$|01|);
    }
    say qq[\nInput:  \@numbers = (] . join(', ', @numbers) .
        qq[), \$count = $count];
    say qq[Output: ] . ($done == $count ? 1 : 0);
    
}

11 lines of code

Output from script


Input:  @numbers = (1, 0, 0, 0, 1), $count = 1
Output: 1

Input:  @numbers = (1, 0, 0, 0, 1), $count = 2
Output: 0

Input:  @numbers = (0, 0, 1, 0, 0, 0, 1, 0, 0), $count = 3
Output: 1

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain