DEV Community

loading...

Daily Challenge #18 - Triple Trouble

thepracticaldev profile image dev.to staff ・1 min read

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 numbers num1 and num2 and returns 1 if there is a straight triple of a number at any place in num1 and also a straight double of the same number in num2. If this isn't the case, return 0

Good luck, and happy coding!


Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge for a future post? Email yo+challenge@dev.to with your suggestions!

Discussion

pic
Editor guide
Collapse
alvaromontoro profile image
Alvaro Montoro

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.

Collapse
alvaromontoro profile image
Alvaro Montoro

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)

Collapse
coreyja profile image
Corey Alexander

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

Thread Thread
alvaromontoro profile image
Alvaro Montoro

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) {
Collapse
_morgan_adams_ profile image
morgana

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)
Collapse
yzhernand profile image
Yozen Hernandez

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.

Collapse
barbaraips profile image
Bárbara Perdigão

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;
    }
Collapse
coreyja profile image
Corey Alexander

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);
    }
}
Collapse
kerrishotts profile image
Kerri Shotts

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...

Collapse
jeremy profile image
Jeremy Schuurmans

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
Collapse
aoneill01 profile image
Andy O'Neill

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;
}
Collapse
sdyalor profile image