Camel
Peter
Peter Campbell Smith

Odd game

Weekly challenge 306 — 27 January 2025

Week 306: 27 Jan 2025

Task 2

Task — Last element

You are given a array of integers, @ints. Write a script to play a game where you pick two biggest integers in the given array, say x and y. Then do the following:
a) if x == y then remove both from the given array
b) if x != y then remove x and replace y with (y - x)

At the end of the game, there is at most one element left. Return the last element if found otherwise return 0.

Examples


Example 1
Input: @ints = (3, 8, 5, 2, 9, 2)
Output: 1
Step 1: pick 8 and 9 => (3, 5, 2, 1, 2)
Step 2: pick 3 and 5 => (2, 2, 1, 2)
Step 3: pick 2 and 1 => (1, 2, 2)
Step 4: pick 2 and 1 => (1, 2)
Step 5: pick 1 and 2 => (1)

Example 2
Input: @ints = (3, 2, 5)
Output: 0
Step 1: pick 3 and 5 => (2, 2)
Step 2: pick 2 and 2 => ()

Analysis

In order to get the results in the examples it is necessary to require that x > y, which is not quite clear from the task description.

The order of @ints is not significant, so my solution starts by reverse-sorting it, so that x is $ints[0] and y is $ints[1]. I then apply the rules repetitively, using shift to pull x and y off @ints.

It is interesting to note that if @ints is populated with more than around 100 random positive integers, even with numbers up to a million or more, it almost always converges to 1 or to 0 (ie 1, 1).

Try it 

Try running the script with any input:



example: 12, 23, 34, 45, 56

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2025-01-27
use utf8;     # Week 306 - task 2 - Last element
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

last_element(3, 8, 5, 2, 9, 2);
last_element(3, 2, 5);
last_element(43, 21, 56, 86, 2, 69, 10, 43, 77, 30);

sub last_element {
    
    my (@ints, $x);
    
    # initialise
    @ints = @_;
    say qq[\nInput:  \@ints = (] . join(', ', @_) . ')';
    
    # loop until 0 or 1 element left
    while ($#ints > 0) {
        @ints = sort {$b <=> $a} @ints;
        
        # if x == y
        if ($ints[0] == $ints[1]) {
            shift @ints; 
            shift @ints;
        
        # if x != y
        } else {
            $x = shift @ints;
            $ints[0] = $x - $ints[0];
        }
    }
    say qq[Output: ] . ($ints[0] or 0);
}
 

Output


Input:  @ints = (3, 8, 5, 2, 9, 2)
Output: 1

Input:  @ints = (3, 2, 5)
Output: 0

Input:  @ints = (43, 21, 56, 86, 2, 69, 10, 43, 77, 30)
Output: 1

 

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