loading...

Daily Challenge #251 - Largest Number in a Sequence

thepracticaldev profile image dev.to staff ・1 min read

In a six digit (or larger) number, locate the greatest sequence of five consecutive digits found within the number given.

Example

In the following 10 digit number:
1234567890
67890 is the greatest sequence of 5 consecutive digits.

Tests

digit5(7316717)
digit5(1234567898765)


This challenge comes from jhoffner on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

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

Posted on by:

thepracticaldev profile

dev.to staff

@thepracticaldev

The hardworking team behind dev.to ❤️

Discussion

markdown guide
 

Rust

🔗 the below code in a runnable playground

"imperative"

fn bige(input: u64) -> u64 {
    let mut current = input;
    let mut max = 0;
    for _ in 0..16 {
        let five = current % 100_000;
        if five > max {
            max = five;
        }
        current /= 10;
        // // optional optimization, might be harmful, but division is slow
        // // I wonder if dividing zero is fast though? Probably.
        // if current == 0 {
        //     break;
        // }
    }
    max
}

iterator

unwrapping is safe, because even with 0 we will have at least one element
(actually we will consider 0 15 times)

fn bige_iter(input: u64) -> u64 {
    let mut current = input;
    std::iter::from_fn(|| {
        let yeld = current;
        current /= 10;
        Some(yeld)
    })
    .take(15)
    .map(|x| x % 100_000)
    .max()
    .unwrap()
}

immutable

bad: leads to dividing bigger numbers

fn bige_imut(input: u64) -> u64 {
    (0..16)
        .into_iter()
        .map(|i| (input / 10_u64.pow(i)) % 100_000)
        .max()
        .unwrap()
}

strings

good: can be longer than u64

fn bige_string(input: &str) -> u32 {
    // use use atoi::FromRadix10; in real life to avoid checking for utf8 first.
    input
        .as_bytes()
        .windows(5)
        .filter_map(|x| std::str::from_utf8(x).ok()?.parse::<u32>().ok())
        .max()
        .unwrap()
}

usage

fn main() {
    dbg!(bige(18446744073709551615));
    dbg!(bige_iter(18446744073709551615));
    dbg!(bige_imut(18446744073709551615));
    dbg!(bige_iter(0));
    dbg!(bige_imut(0));
    dbg!(bige_string("18446744073709551615"));
}
 

Javascript version:

const largest = num => [...`${num}`].reduce((c,_,i,ar)=>Math.max(+ar.slice(i, i+5).join(''), c), 0)

 

Here is a Python solution,

def digit5(number : str) -> int:
    return max(int(number[i:i+5]) for i in range(len(number)-4))   

print(digit5("1234567890")) # output -> 67890
print(digit5("7316717")) # output -> 73167
print(digit5("123456")) # output -> 23456
print(digit5("1234567898765")) # output -> 98765

 

Haskell

chunks :: String -> [String]
chunks (a:b:c:d:e:rest) = [a, b, c, d, e] : chunks (b:c:d:e:rest)
chunks _ = []

digit5 :: Int -> Int
digit5 number =
    read $ foldl max "" $ chunks $ show number

main :: IO ()
main = do
    print $ digit5 1234567890       -- 67890
    print $ digit5 1234567898765    -- 98765
    print $ digit5 7316717          -- 73167
 
(defn digit5 [n] (apply max (sequence (comp (map (partial apply str)) (map #(Long/parseLong %))) (partition 5 1 (str n)))))
 

To be honest, the solutions I provide here would NEVER pass code review. But I get it working at a REPL, and it's just too tempting to post as-is 😊

Here is a nearly identical solution (sans the transducer), written in a readable way:

(defn digit5
 [n]
 (->> (str n)
      (partition 5 1)
      (map (partial apply str))
      (map #(Long/parseLong %))
      (apply max)))
 
import Data.List (tails)
digit5 :: Int -> Int
digit5 = maximum 
       . map read 
       . filter ((== 5) . length) 
       . map (take 5) 
       . tails
       . show