DEV Community

Cover image for Daily Coding Puzzles - Nov 11th - Nov 16th
Ali Spittel
Ali Spittel

Posted on • Edited on

Daily Coding Puzzles - Nov 11th - Nov 16th

Every day on Twitter, I post coding puzzles. These are quick coding challenges that increase in difficulty across the span of the week -- with Monday being the most beginner friendly and Friday being super tough. I love seeing other people's solutions as well, and so people post their solution to the problem in any programming language.

Here's more about them.

I wanted to try posting these here. I'm going to post each question from this week as a comment below, and then we will thread answers under those questions. Please feel free to post your solutions to the ones you are interested in below! Then, you can comment with insights into people's solutions below that! I will also add a meta thread if you have advice on how to format this in the future!

Excited to see your solutions!

Top comments (52)

Collapse
 
aspittel profile image
Ali Spittel

Tuesday - Don't give me five! (7 KYU)

In this kata you get the start number and the end number of a region and should return the count of all numbers except numbers with a 5 in it. The start and the end number are both inclusive!

codewars.com/kata/dont-give-me-five

Collapse
 
ihate1999 profile image
Abubakar Nur Khalil • Edited

Quick JS solution

const dgmf = (init, lim) => {
    let count = 0

    for (var i = init-1;i < lim+1;i++) {
        count = String(i).includes('5') ? count : count + 1
        // count = i % 5 != 0 ? count + 1 : count
    }

    return count
}
Collapse
 
theluk profile image
Lukas Klinzing

This removes more than 5s

Thread Thread
 
ihate1999 profile image
Abubakar Nur Khalil

True, just realized 😂

Changing the conditional expression should fix that

// ...
// Loop code
count = String(i).includes('5') ? count : count + 1
Collapse
 
choroba profile image
E. Choroba

Perl solution, test included:

#! /usr/bin/perl
use warnings;
use strict;

sub count_without_5 {
    my ($from, $to) = @_;
    return scalar grep $_ !~ /5/, $from .. $to
}

use Test::More tests => 2;
is count_without_5(1,9), 8;
is count_without_5(4,17), 12;
Collapse
 
pulljosh profile image
Josh Pullen

Any application that can be written in JavaScript, will eventually be written in JavaScript:

const dontGiveMeFive = (min, max) =>
  [...Array(max - min + 1).keys()]
  .map(n => n + min)
  .filter(n => !`${n}`.includes('5'))
Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
jessicacastro profile image
Jessica Castro • Edited

Cool solution! But this will timeout with large numbers!

Collapse
 
sdicke profile image
Sebastian Martin Dicke • Edited

Another Haskell solution:

dont_give_me_five :: [Int] -> Int
dont_give_me_five = foldl (\x y -> if notElem '5' $ show y then x + y else x) 0

Or a little bit shorter in the same language:

dont_give_me_five :: [Int] -> Int
dont_give_me_five = foldl1 (\x y -> if notElem '5' $ show y then x + y else x)
Collapse
 
wodin profile image
Michael Wood

Clojure

(defn no5? [num]
  (not-any? #{\5} (str num)))

(defn dont-give-me-five! [start end]
  (->>
    (range start (inc end))
    (filter no5?)
    count))

user=> (dont-give-me-five! 1 9)
8
user=> (dont-give-me-five! 4 17)
12
Collapse
 
gypsydave5 profile image
David Wickes

Common Lisp

(defun dont-give-me-five (start end)
  (loop for x from start to end
     when (not (contains-5-p x)) collect x))

(defun contains-5-p (n)
  (position #\5 (write-to-string n)))
Collapse
 
cookavich profile image
Paul Cook

Another JS solution:

const dontGiveMeFive = (start, end) => range(start, end).filter(noFive).length;
const range = (start, end) => [...Array(end - start + 1).keys()].map(i => i + start);
const noFive = num => !`${num}`.includes('5');
Collapse
 
kungtotte profile image
Thomas Landin

Here's my Nim solution :)

There are filter and keepIf functions defined in the sequtils standard library but that feels like cheating :P

$ is Nim's stringify operator, and the find procedure returns -1 if it doesn't find the substring :)

import strutils # for the 'find' procedure

proc my_filter(start, stop: int): seq[int] =
  for i in start..stop:
    if find($i, "5") == -1:
      result.add(i)

echo my_filter(1,9).len
echo my_filter(4,17).len
Collapse
 
jdsteinhauser profile image
Jason Steinhauser

Elixir:

no_fives = fn x, y -> x..y |> Enum.map(& Integer.to_string(&1)) |> Enum.filter(& !String.contains?(&1, "5")) |> Enum.count() end

And surprise! I wrote an F# solution in a similar fashion:

let no_fives x y =
  [x .. y]
  |> Seq.map string
  |> Seq.filter (fun x -> x.Contains("5") |> not)
  |> Seq.length
Collapse
 
sdicke profile image
Sebastian Martin Dicke • Edited

Haskell

-- The first line is not necessary
dont_give_me_five :: [Int] -> Int
dont_give_me_five list = sum $ filter (\x -> notElem '5' $ show x) list
Collapse
 
ben profile image
Ben Halpern • Edited

Ruby

def dont_give_me_five(start, end)
  (start..end).to_a.reject { |n| n.to_s.include? "5" }.size
end
Collapse
 
aspittel profile image
Ali Spittel
def dont_give_me_five(start, end):
    return len([n for n in range(start, end + 1) if '5' not in str(n)])
Collapse
 
jay profile image
Jay

Rust Solution:

fn dont_give_me_5(start: usize, end: usize) -> u8 {
    (start..=end)
        .map(|n| n.to_string())
        .filter(|n| !n.contains('5'))
        .count() as u8
}
Collapse
 
aspittel profile image
Ali Spittel

Wednesday - Format words into a sentence (6 KYU)

Complete the method so that it formats the words into a single comma separated value. The last word should be separated by the word 'and' instead of a comma.

codewars.com/kata/format-words-int...

Collapse
 
arnemahl profile image
Arne Mæhlum

This is a fun way of doing it, though it might be a bit confusing at first glance 😂

const format_words = words =>
  words
    .filter(Boolean)
    .join(', ')
    .split('').reverse().join('')
    .replace(' ,', ' dna ')
    .split('').reverse().join('')
Collapse
 
jay profile image
Jay

Rust Solution:

fn format_words(words: &[&str]) -> String {
    let words: Vec<&str> = words
        .into_iter()
        .filter(|&w| !w.is_empty())
        .map(|&x| x)    // deref &&str -> &str
        .collect();
      words
        .iter()
        .enumerate()
        .fold(String::new(), |mut sent, (i, w)| {
            if i == 0 {
                sent += w
            } else if i == words.len() - 1 {
                sent += &format!(" and {}", w);
            } else {
                sent += &format!(", {}", w);
            }
            sent
        })
}
Collapse
 
aspittel profile image
Ali Spittel
def format_words(words):
    sentence = ''
    if words:
        words = [word for word in words if word]
        for index, word in enumerate(words):
            if index == 0:
                sentence += word
            elif index == len(words) - 1:
                sentence += " and " + word
            else:
                sentence += ", " + word
    return sentence
Collapse
 
skyller360 profile image
Anthony Tomson

My Js solution:

function formatWords(words) {
  if (!words || words.length < 1) return '';

  words = words.filter(val => !!val);
  const length = words.length;

  if (!length) return '';


  return words.reduce((acc, cumul, index) => {
    return index + 1 === length ?
      `${acc} and ${cumul}` :
      `${acc}, ${cumul}`
  });
}
Collapse
 
kungtotte profile image
Thomas Landin • Edited

My Nim solution :)

Nim supports specifying ranges both in absolute terms and in relative terms. ^2 would be the second to last position of a range, etc :) As you can see at the end of the procedure you can also supply just one end of the range and Nim will infer the other end, so filtered[^1] would be just the final element of the sequence.

import sequtils # for filter

proc format_words(words: seq[string]): string =
  result = ""
  if words.len > 0:
    var filtered = filter(words, proc(w: string): bool = w.len > 0)
    for word in filtered[0..^2]:
      result.add(word & ", ")
    return result[0..^3] & (" and " & filtered[^1])

echo format_words(@["ninja","samurai","ronin","leonardo","michelangelo","donatello","raphael"])
echo format_words(@["ninja","samurai","ronin"])
echo format_words(@["ninja","", "ronin"])
echo format_words(@[])
Collapse
 
gypsydave5 profile image
David Wickes • Edited

Common Lisp

Inhumane format version:

(defun format-words (words)
  (format nil "~{~#[~;~a~;~a and ~a~:;~@{~a~#[~;, and ~:;, ~]~}~]~}" words))

appropriated from Practical Common Lisp


More humane version (kinda like a string builder but using a stream):

(defun format-words (words)
  (with-output-to-string (s)
    (format s "~{~a~^, ~}" (butlast words))
    (unless (= 1 (length words))
      (format s " and "))
    (format s "~a" (car (last words)))))
Collapse
 
clandau profile image
Courtney • Edited
function formatWords(words) {
    if(!words) return '';
    words = words.filter((word) => word.length);
    let returnString = '';
    for(let i=0; i<words.length; i++) {
        if(i === words.length - 1 && i > 0) {
        returnString += ` and `;
        }
        else if (i > 0){
            returnString += `, `;
        }
        returnString += words[i];
    }
    return returnString;
}
Collapse
 
choroba profile image
E. Choroba

Perl solution, tests included:

#! /usr/bin/perl
use warnings;
use strict;

sub format_words {
    my @words = grep length, @_;
    my $last = pop @words;
    return join(', ', @words) . (@words ? " and $last" : "")
}

use Test::More tests => 3;
is format_words('ninja', 'samurai', 'ronin'), 'ninja, samurai and ronin';
is format_words('ninja', '', 'ronin'), 'ninja and ronin';
is format_words(), "";
Collapse
 
ben profile image
Ben Halpern • Edited

Ruby

def format_words(words)
  words.reject(&:blank?).join(", ").reverse.sub(',', 'dna ').reverse
end
Collapse
 
aspittel profile image
Ali Spittel

Monday - Transportation on vacation (8 KYU):

You will need a rental car in order for you to get around in your vacation. The manager of the car rental makes you some good offers.

codewars.com/kata/transportation-o...

Collapse
 
aspittel profile image
Ali Spittel

Java (!!) solution

public class Kata {
  public static int rentalCarCost(int d) {
    int total = d * 40;
    if(d >= 7)
      total -= 50;
    else if(d >= 3)
      total -= 20;
    return total;
  }
}
Collapse
 
sdicke profile image
Sebastian Martin Dicke • Edited

Haskell solution:

transportation_on_vacation :: Int -> Int
transportation_on_vacation days
    | days > 6 = max_costs - 50
    | days > 3 = max_costs - 20
    | otherwise = max_costs
    where
    max_costs = 40 * days 
Collapse
 
choroba profile image
E. Choroba

Perl solution, tests included:

#! /usr/bin/perl
use warnings;
use strict;

my @discounts = ([7, 50], [3, 20], [0, 0]);
sub total {
    my ($days) = @_;
    my $total = $days * 40;
    for (@discounts) {
        my ($at_least, $discount) = @$_;
        return $total - $discount if $days >= $at_least;
    }
}

use Test::More tests => 8;
is total(1), 40;
is total(2), 80;
is total(3), 3 * 40 - 20;
is total(4), 4 * 40 - 20;
is total(5), 5 * 40 - 20;
is total(6), 6 * 40 - 20;
is total(7), 7 * 40 - 50;
is total(8), 8 * 40 - 50;
Collapse
 
kungtotte profile image
Thomas Landin

My solution in Nim, my new favourite language :)

It provides an automatic default return variable called "result" that you can just start stuffing things into and it will automatically return it without you doing anything :)

let
  rate = 40.0
  weekly_discount = 50.0
  weekend_discount = 20.0
  test_data = [1, 2, 3, 4, 5, 6, 7, 8, 9]

proc total_cost(days: int): float =
  result = days.float * rate
  if days >= 7:
    result -= weekly_discount
  elif days >= 3:
    result -= weekend_discount

for n in test_data:
  echo "Cost for ", n, " days is: ", total_cost(n)
Collapse
 
jay profile image
Jay

I try to use the func keyword when defining methods, that way the compiler can guarantee that I have pure function with no side effects.
func is just sugar for proc {.noSideEffect.}.

func rental_car_cost(days: int): int =
  result = days * 40
  if days > 7:
    result -= 50
  elif days >= 3:
    result -= 20
Thread Thread
 
kungtotte profile image
Thomas Landin

I haven't gotten into the habit of doing that yet. I know I should and I think it's a great idea in general, but years of habits are hard to break and the func keyword is still a fairly recent addition to the language :)

Collapse
 
clandau profile image
Courtney • Edited
function rentalCarCost(d : number) : number {
    let discount : number = 0;
    if(d >= 7) discount = 50;
    else if(d >= 3) discount = 20;
    return (d * 40) - discount;
}

//one-liner
function rentalCarCost2(d : number) : number {
    return d >= 7 ? ((d * 40) - 50) : (d >= 3 ? (d * 40) - 20 : d * 40);
}
Collapse
 
jay profile image
Jay

Rust Solution:

fn rental_car_cost(days: i32) -> i32 {
    (days * 40) - match days {
        n if n > 7 => 50,
        n if n >= 3 => 20,
        _ => 0,
    }
}
Collapse
 
ben profile image
Ben Halpern

Ruby

def rental_price(num_days)
  price = num_days * 40
  return price - 50 if num_days >= 7
  return price - 20 if num_days >= 3
  price
end
Collapse
 
aspittel profile image
Ali Spittel

Thursday - Queue from two stacks (Hacker Rank Medium)

Complete the put, pop, and peek methods in the editor below. They must perform the actions as described above.

hackerrank.com/challenges/ctci-que...

Collapse
 
choroba profile image
E. Choroba

Perl solution. Passes all the tests on HackerRank.

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{   package Queue;

    use enum qw( LIFO FIFO );

    sub new  { bless [[], []], shift }
    sub Push { push @{ $_[0][LIFO] }, $_[1]; }
    sub Pop  { @{ $_[0][FIFO] } or $_[0]->_restack; pop @{ $_[0][FIFO] }; }
    sub Peek { @{ $_[0][FIFO] } or $_[0]->_restack; say $_[0][FIFO][-1]; }
    sub _restack {
        push @{ $_[0][FIFO] }, pop @{ $_[0][LIFO] } while @{ $_[0][LIFO] };
    }
}

my %dispatch = (
    1 => 'Push',
    2 => 'Pop',
    3 => 'Peek',
);

my $q = 'Queue'->new;

<>;  # skip the 1st line.
while (<>) {
    my ($operation, $argument) = split;
    $q->${\$dispatch{$operation}}($argument);
}
Collapse
 
susickypavel profile image
Pavel Susicky
const Queue = {
    in: [],
    out: [],
    enqueue: function(x) {
        this.in.push(x);
    },
    dequeue: function() {
        if (this.out.length == 0) {
            while (this.in.length != 0) {
                this.out.push(this.in.pop());
            }
        }
        return this.out.length == 0 ? "Cannot dequeue" : this.out.pop();
    },
    front: function() {
        if (this.out.length == 0) {
            while (this.in.length != 0) {
                this.out.push(this.in.pop());
            }
        }
        return this.out.length == 0 ? "Cannot show front value" : this.out[this.out.length - 1];
    }
};
Collapse
 
aspittel profile image
Ali Spittel
class MyQueue(object):
    def __init__(self):
        self.stack1 = []
        self.stack2 = []

    def peek(self):
        if not self.stack2:
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2[-1]

    def pop(self):
        if not self.stack2: 
            while self.stack1:
                self.stack2.append(self.stack1.pop())
        return self.stack2.pop()

    def put(self, value):
        self.stack1.append(value)
Collapse
 
clandau profile image
Courtney
function processData(input) {
    class Node {...}
    class Stack {...}
    const inputArray = input.split('\n');
    let stackIn = new Stack();
    let stackOut = new Stack();
    let valArry, result = '';
    for(let i=1; i<=inputArray[0]; i++) {
        valArry = inputArray[i].split(' ');
        switch(valArry[0]) {
            case '1':
                enqueue(valArry[1]);
                break;
            case '2':
                dequeue();
                break;
            case '3':
                result += `${front()}\n`;
                break;
        }
    } 

    function enqueue(val) {
        stackIn.push(val);
    }

    function dequeue() {
        if(stackOut.size === 0) {
            while(stackIn.size > 0) {
                let item = stackIn.pop();
                stackOut.push(item);
            }
        }
        stackOut.pop();
    }

    function front() {
        if(stackOut.size === 0) {
            while(stackIn.size > 0) {
                let item = stackIn.pop();
                stackOut.push(item);
            }
        }
        return stackOut.peek();
    }
    return process.stdout.write(result);
} 
Collapse
 
jay profile image
Jay

Rust Solution:

struct MyQueue {
    stack1: Vec<i32>,
    stack2: Vec<i32>,
}

impl MyQueue {
    pub fn new() -> Self {
        MyQueue {
            stack1: vec![],
            stack2: vec![],
        }
    }

    pub fn push(&mut self, x: i32) {
        self.stack1.push(x);
    }

    pub fn pop(&mut self) {
        if self.stack2.is_empty() {
            while !self.stack1.is_empty() {
                self.stack2.push(self.stack1.pop().unwrap());
            }
        }
        self.stack2.pop();
    }

    pub fn peek(&mut self) -> i32 {
        if self.stack2.is_empty() {
            while !self.stack1.is_empty() {
                self.stack2.push(self.stack1.pop().unwrap());
            }
        }
        *self.stack2.last().unwrap()
    }
}
Collapse
 
aspittel profile image
Ali Spittel • Edited

Friday - Cruise Control (Code Jam):

Annie is a bus driver with a high-stress job. She tried to unwind by going on a Caribbean cruise, but that also turned out to be stressful, so she has recently taken up horseback riding...

codejam.withgoogle.com/codejam/con...

Collapse
 
choroba profile image
E. Choroba

The Perl solution I submitted back in 2017:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

my $test_count = <>;
for my $test_case (1 .. $test_count) {
    my ($destination, $horse_count) = split ' ', <>;
    my $other_max = 0;
    for my $horse (1 .. $horse_count) {
        my ($position, $max_speed) = split ' ', <>;
        my $speed = ($destination - $position) / $max_speed;
        $other_max = $speed if $other_max < $speed;
    }
    say "Case #$test_case: ", $destination / $other_max;
}
Collapse
 
jay profile image
Jay

Rust Solution:

use std::f64;
use std::io::{self, prelude::*};

fn cruise_control(distance: f64, horses: &[(f64, f64)]) -> f64 {
    let time = horses
        .iter()
        .map(|&(d, s)| (distance - d) / s)
        .fold(f64::NAN, f64::max);
    distance / time
}

fn parse_line(s: &str) -> (f64, f64) {
    let vec: Vec<f64> = s
        .to_string()
        .split_whitespace()
        .map(|c| c.to_string().parse().unwrap())
        .collect();
    (vec[0], vec[1])
}

fn main() -> Result<(), io::Error> {
    let mut buffer = String::new();
    io::stdin().read_to_string(&mut buffer)?;
    let mut buf_lines = buffer.lines();
    let cases: u8 = buf_lines.next().unwrap().parse().unwrap();
    for case in 0..cases {
        let (dist, number) = parse_line(buf_lines.next().unwrap());
        let mut horses_info = buf_lines.clone().take(number as usize);
        let mut horses = vec![];
        for horse in horses_info {
            buf_lines.next();
            horses.push(parse_line(horse));
        }
        match io::stdout()
            .write(format!("Case #{}: {}\n", case + 1, cruise_control(dist, &horses)).as_bytes())
        {
            Ok(_) => (),
            Err(why) => panic!(why),
        }
    }
    Ok(())
}
Collapse
 
aspittel profile image
Ali Spittel
def clean_input_file(file_name):
    inp = open(file_name)
    inp = inp.read()
    inp = inp.split('\n')
    cases = int(inp[0])
    inp.pop(0)
    inp.pop()
    return inp, cases


def cruise_control(distance, horse):
    return float(distance - horse[0]) / horse[1]


def get_speeds(distance, horses):
    speeds = []
    for horse in horses:
        speeds.append(cruise_control(distance, horse))
    return distance / max(speeds)

input_file, cases = clean_input_file('test.in')
write_file = open('solution.txt', 'w+')

row = 0

for case in range(cases):
    case_info = input_file[row].split(' ')
    speed = int(case_info[0])
    n_horses = int(case_info[1])

    horses = []
    for _ in range(n_horses):
        row += 1
        horse = input_file[row].split(' ')
        horses.append((int(horse[0]), int(horse[1])))
    write_file.write("Case #{}: {}\n".format(case + 1, "{0:.2f}".format(get_speeds(speed, horses))))
    row += 1
Collapse
 
clandau profile image
Courtney

I had to resort to following along with a youtube video of the challenge, but I understand it now, so...learning?

But seriously, tons of new things learned this week, like handling stdin and stdout data, reading test data from a file and writing answers to a file. Glad to have these challenges to follow!

function processData(input) {
    let resultStr = '';
    const inputArray = input.split('\n');
    const cases = parseInt(inputArray.shift());
    for(let i=0; i<cases; i++) {
        resultStr += `Case # ${i+1}: `;
        let me = inputArray.shift().split(' ');
        let destination = parseFloat(me[0]);
        let numHorses = parseInt(me[1]);
        let horses = [];
        for(let j=0; j<numHorses; j++) {
            let horse = inputArray.shift().split(' ');
            horses.push({ velocity: parseFloat(horse[1]), location: parseFloat(horse[0])});
        }
        let sortedHorses = horses.sort((a, b) => b.location-a.location);
        resultStr += `${cruiseControl(destination, sortedHorses)}\n`;
    }
    return process.stdout.write(resultStr);
}

function cruiseControl(dest, horseArry) {
    let B = horseArry[0].location, vB = horseArry[0].velocity;
    for (let i=1; i<horseArry.length; i++) {
        let A = horseArry[i].location, vA = horseArry[i].velocity;
        if(vB === vA) B = A, vB = vA;
        else {
            let x = (vB * A - vA * B) / (vB - vA);
            if(x > dest || x < A) {
                B = A, vB = vA;
            } 
        }
    }
    let tB = (dest - B) / vB;
    return dest / tB;
}


Collapse
 
eljayadobe profile image
Eljay-Adobe

Python 3

def format_words(words):
    if len(words) < 2:
        return "".join(words)
    return ", ".join(words[:-1]) + " and " + words[-1]


words = ["ninja", "samurai", "ronin", "leonardo", "michelangelo", "donatello", "raphael"]
print(f"{format_words(words)}")
words = ["alpha", "beta"]
print(f"{format_words(words)}")
words = ["alone"]
print(f"{format_words(words)}")
words = []
print(f"{format_words(words)}")
Collapse
 
samjwatkins profile image
Sam J Watkins

Don't give me 5 answer.
If a number ends in 5 it is divisible by five but not by 10, in java...

void printNumbersNotEndingIn5 (int beginning, int last){
try {
for (int i=beginning;i <= last; i++){
if ((i%5!=0) || ((i%5==0) && (i%10==0))) System.out.println (i);
}
}
catch (Exception e){
}
}

printNumbersNotEndingIn5 (out, 1, 30);

Collapse
 
aspittel profile image
Ali Spittel

Meta