dev.to staff

Posted on

# Daily Challenge #18 - Triple Trouble

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!

Alvaro Montoro • Edited

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.

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)

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

Alvaro Montoro • Edited

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) {

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]:
return s

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

Yozen Hernandez • Edited

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.

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;
}

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);
}
}

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)));
}

Jeremy Schuurmans • Edited

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

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;
}