Daily Challenge #18 - Triple Trouble

dev.to staff on July 18, 2019

We've got more trouble! Today's challenge comes from jon_pot on Codewars. You are asked to: Write a function tripledouble(num1,num2) which takes ... [Read Full]
markdown guide
 

JavaScript

const tripleTrouble = (num1, num2) => {
  const min = Math.min(num1, num2);
  const strNum1 = num1.toString();
  const strNum2 = num2.toString();

  let found = 0;

  for (let x = 1; x < min && found === 0; x++)
    if (strNum1.indexOf(x*3) > -1 && strNum2.indexOf(x*2) > -1)
      found = 1;

  return found;
}

A quick solution using JavaScript, I need to improve it later. Live demo on CodePen.

 

Hmmm.... reading other answers I might have misinterpreted what was required in this challenge. What is it exactly? For example, if num1 = 121 and num2 = 141, would they be triple troubled numbers? (because 7*3 = 21, and 7*2 =14) Or would it be num1 = 8777and num2 = 877 be triple troubled numbers? (because 7 repeats 3 times in the first one and 2 in the second one)

 

I'm getting caught up a few days behind, but I understood this is three digits in a row. Which I think is confirmed by the linked challenge examples.

So num1 = 8777 and num2 = 877 would return true for this!

Starting on my version now

To achieve that, the only change would be in the if statement. Instead of doing x*3 and x*2, it would be ''+x+x+x and ''+x+x respectively:

if (strNum1.indexOf(''+x+x+x) > -1 && strNum2.indexOf(''+x+x) > -1) {
 

A python solution. Assumes numbers are strings.

def gettriples(n):
    s = set()
    for x in range(len(n)-2):
        if n[x]*3 == n[x:x+3]:
            s.add(n[x]*3)
    return s

def tripledouble(n1, n2):
    s1 = gettriples(n1)
    s2 = gettriples(n2)
    return bool(s1 & s2)
 

Java:

static int tripleDouble(String a, String b) {

        for (String item : a.split("")) {
            int triple = Integer.valueOf(item) * 3;
            int doubl = Integer.valueOf(item) * 2;

            if (a.contains(String.valueOf(triple))) {
                if (b.contains(String.valueOf(doubl))) return 1;
            } else return 0;
        }
        return 0;
    }
 

Here's my Perl solution. Works even if the first triple is not a double in the second number. Also uses regex backreferences, but only uses a regex for the first number. The much faster index is used to find the exact string in the second number.

#!/usr/bin/perl

use v5.24;
use strict;
use warnings;
use feature qw(signatures);
no warnings "experimental::signatures";
use List::Util qw(any);

sub tripledouble ($num1, $num2) {
    any { index($num2, "$_$_") > 0 } $num1 =~ /(\d)\1\1/g;
}

use Test::More tests => 3;
ok(tripledouble(451999277, 41177722899), "(451999277, 41177722899) has triple/double");
ok(tripledouble(4519992777, 4117772289), "(4519992777, 4117772289) has triple/double");
ok(!tripledouble(45199277, 411777228999), "(4519992777, 4117772289) does not have triple/double");

any from List::Util lets us search all "triples" from the global regex, and as long as one of them matches as a double in $num2, this will return a true value.

 

Seems like a good problem for regex with backreferences. JavaScript:

function tripledouble(num1, num2) {
    return /(\d)\1\1.*,.*\1\1/.test(`${num1},${num2}`) ? 1 : 0;
}
 

Rust Solution!

Used a regex to find groups of 3 digits. Then checked if the digits were the same. If they were we check the second number for the digit twice, again using a regex!

#[macro_use]
extern crate lazy_static;

pub fn triple_double(num1: u64, num2: u64) -> bool {
    use regex::Regex;

    lazy_static! {
        static ref first_num_regex: Regex = Regex::new(r"(\d{3})").unwrap();
    }

    let string1 = num1.to_string();
    let string2 = num2.to_string();

    for i in first_num_regex.captures_iter(&string1) {
        let regex_match = i.get(0).unwrap().as_str();

        if regex_match[0..1] == regex_match[1..2] && regex_match[1..2] == regex_match[2..3] {
            let second_layer_regex = Regex::new(&regex_match[0..2]).unwrap();

            if second_layer_regex.is_match(&string2) {
                return true;
            }
        }
    }

    false
}

#[cfg(test)]
mod tests {
    use crate::*;

    #[test]
    fn it_for_true_examples() {
        assert_eq!(triple_double(451999277, 41177722899), true);
        assert_eq!(triple_double(666789, 12345667), true);
    }

    #[test]
    fn it_for_false_examples() {
        assert_eq!(triple_double(1222345, 12345), false);
        assert_eq!(triple_double(12345, 12345), false);
    }
}
 

Ruby solution:

def triple_double(num1,num2)
  triples = num1.to_s.split("").chunk_while{|i, j| i == j }.to_a.select{|el| el.count >= 3 }.flatten
  doubles = num2.to_s.split("").chunk_while{|i, j| i == j }.to_a.select{|el| el.count >= 2 }.flatten

  common_integer = triples.uniq & doubles.uniq

  common_integer.empty? ? 0 : 1
end
 

A day late to the party, but here's my solution:

const makeRun = (v, {ofLength = 1} = {}) => Array.from({length: ofLength}, () => v).join("");

const hasTripleTrouble = (triple, double) => {
    const [tripleStr, doubleStr] = [triple, double].map(v => String(v));
    return (Array.from({length: 10}, (_, idx) => idx)
                 .some(digit => (tripleStr.indexOf(makeRun(digit, {ofLength: 3})) > -1
                              && doubleStr.indexOf(makeRun(digit, {ofLength: 2})) > -1)));
}

Gist: gist.github.com/kerrishotts/85214d...

 
code of conduct - report abuse