DEV Community

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

Daily Coding Puzzles - Nov 11th - Nov 16th

Ali Spittel on November 17, 2018

Every day on Twitter, I post coding puzzles. These are quick coding challenges that increase in difficulty across the span of the week -- with Mond...
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