DEV Community

loading...
Cover image for Coding Puzzles: Week of 4/8

Coding Puzzles: Week of 4/8

aspittel profile image Ali Spittel Updated on ・1 min read

I'm bringing back the coding puzzles after a few month hiatus!

Every day, 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.

I'll be adding in the questions each day, so stay tuned and come back for more 😊

Excited to see your solutions!

Discussion (47)

pic
Editor guide
Collapse
aspittel profile image
Ali Spittel Author

Tuesday (7 KYU): Find the stray number

codewars.com/kata/57f609022f4d534f...

Collapse
laurieontech profile image
Laurie
function stray(arr) {
    return arr.reduce((a, b) => a ^ b)
}
Collapse
threeheadedcerb profile image
russ

What is this necromancy?

Thread Thread
laurieontech profile image
Laurie • Edited

Haha, bitwise xor. Since it's immutable and commutative it'll reduce down to the stray!

I should add that this only works because it’s an odd number of elements in the array. An even number of matching elements cancel each other out to result in the “stray”.

Thread Thread
threeheadedcerb profile image
russ

Oh my, it even works in python!

def stray(arr):
    count = {}
    for index, i in enumerate(arr):
        count[i] = count.setdefault(i, 0) + 1
        if index >= 2 and len(count.keys()) > 1:
            break
    return next(k for k, v in count.items() if v == 1)

from functools import reduce

def intstray(arr: [int]):
    return reduce(lambda x,y: x ^ y, arr)

assert(intstray([1, 1, 2]) == 2)
#nope..!
#assert(intstray([1, 1, 2, 1]) == 2)
assert(intstray([17, 17, 3, 17, 17, 17, 17]) == 3)
assert(intstray([1, 2, 2]) == 1)
assert(stray(["bob", "bob", "bob", "steve", "bob"]) == "steve")
Thread Thread
laurieontech profile image
Laurie

This is one of those moments when I wish gifs worked better on Dev. But yay!

Thread Thread
aspittel profile image
Ali Spittel Author

They should work in normal image markdown!

Thread Thread
laurieontech profile image
Laurie

Whaaa?! How did I not know this! ...game changer

Collapse
mihassan profile image
Md Imrul Hassan

Same idea in Haskell:

import Data.Bits

stray :: [Int] -> Int
stray = foldl1 xor
Collapse
jacobmgevans profile image
Jacob Evans

Well I can't think of a better answer for this particular problem domain.

Collapse
joshuagilless profile image
Joshua Gilless

XOR is a great idea, thanks!

Thread Thread
laurieontech profile image
Laurie

Math for the win! :D

Collapse
ahmedmusallam profile image
Ahmed Musallam • Edited

here my cheap solution:

function stray(array) {
    var sorted = array.sort((a,b) => a - b)
    if (sorted[0] === sorted[1]) return sorted.pop();
    else return sorted.shift()
}

or shorter and more unreadable:

function stray(array) {
    var sorted = array.sort((a,b) => a - b)
    return sorted[0] === sorted[1] ? sorted.pop() : sorted.shift();
}

Collapse
jellebekker profile image
Jelle Bekker

in c# using linq:

public static int Stray(int[] numbers)
{
    return numbers.Aggregate((x, y) => x ^ y);
}

or:

public static int Stray(int[] numbers)
{
    return numbers.GroupBy(x => x).Single(num => num.Count() == 1).Key;
}
Collapse
joshuagilless profile image
Joshua Gilless

Thanks for this! I don't really know C++, but I figured I'd give it a shot:

int stray(std::vector<int> numbers) {
    int n1, n2, n3;
    for (int i = 2; i < numbers.size(); i++) {
      n1 = numbers[i];
      n2 = numbers[i - 1];
      n3 = numbers[i - 2];
      if (n1 == n2 && n1 != n3) {
        return n3;
      } else if (n1 == n3 && n1 != n2) {
        return n2;
      } else if (n1 != n2 && n2 == n3) {
        return n1;
      }
    }
};
Collapse
joshuagilless profile image
Joshua Gilless • Edited

@laurieontech did something really cool in JS with a bitwise XOR (her answer is above), so I figured I'd update this C++ answer with a bitwise XOR since I love it!

int stray(std::vector<int> numbers) {
    int r = numbers[0];
    for (int i = 1; i < numbers.size(); i++)
    {
        r ^= numbers[i];
    }
    return r;
};
Collapse
threeheadedcerb profile image
russ

Looks a bit messy, but I was going for something that might not be too inefficient with a large input array

def stray(arr):
    count = {}
    for index, i in enumerate(arr):
        count[i] = count.setdefault(i, 0) + 1
        if index >= 2 and len(count.keys()) > 1:
            break
    return next(k for k, v in count.items() if v == 1)
Collapse
clandau profile image
Courtney • Edited

This is the first I'm finding this, excited to play along! Here is yesterday's (edited to make the colors show up):

function stray(numbers) {
  let num1 = numbers[0], num2;
  let dupOf1 = false;
  for(let i=1; i<numbers.length; i++) {
      if(numbers[i] === num1) {
        if(num2) return num2;
        else dupOf1 = true;
      }
      else if(numbers[i] === num2) return num1;
      else num2 = numbers[i];
    }
  return dupOf1 ? num2 : num1;
}
Collapse
aspittel profile image
Ali Spittel Author
def stray(arr):
    for item in arr:
        if arr.count(item) == 1:
            return item
Collapse
jacobmgevans profile image
Jacob Evans • Edited

I don't think this is better than the bitwise solution but it's a different one lol

const stray =(n)=> n.filter((ele,_,ar) => ele !== ar[1]).pop()
Collapse
aspittel profile image
Ali Spittel Author

Wednesday (6 KYU): Implement Syntax Highlighting

codewars.com/kata/roboscript-numbe...

Collapse
threeheadedcerb profile image
russ • Edited
import re

def highlight(cmd):
    colour_map = [
        (r'F+', 'pink'),
        (r'L+', 'red'),
        (r'R+', 'green'),
        (r'\d+', 'orange'),
        (r'()+', None),
    ]
    highlighted = []
    while(len(cmd)):
        for regex, colour in colour_map:
            match = re.match(regex, cmd)
            if match:
                idx_start, idx_end = match.span()
                highlighted.append((cmd[idx_start:idx_end], colour))
                cmd = cmd[idx_end:]
                break
        else:
            highlighted.append((cmd[0], None))
            cmd = cmd[1:]
    return ''.join(['<span style="color: {}">{}</span>'.format(colour, string) if colour else string for string, colour in highlighted])
Collapse
threeheadedcerb profile image
russ

And now with added re.sub with a callable, which I had no idea was a thing! These coding things are pretty nifty for leaning new tricks I must say!

import re

def highlight(cmd):
    colour_map = [
        (r'F+', 'pink'),
        (r'L+', 'red'),
        (r'R+', 'green'),
        (r'\d+', 'orange'),
        (r'()+', None),
    ]

    def replacer(match : re.Match):
        substr = match.group()
        colour = next((colour for regex, colour in colour_map if re.match(regex, substr)), None)
        return '<span style="color: {}">{}</span>'.format(colour, substr) if colour else substr

    return re.sub(r'(\D)\1*|(\d+)', replacer, cmd)
Collapse
laurieontech profile image
Laurie

Oooh, I like this. I was thinking about a dictionary but didn't think about a dictionary with the regex as a key!

Collapse
laurieontech profile image
Laurie • Edited

Booo regex

function highlight(code) {
  return code.replace(/(\D)\1+|(\d+|\D)/g, (substr) => {
      var color;
      let testChar = substr.charAt(0); 

      if (testChar === 'F') {
          color = 'pink';
      } else if (testChar === 'L') {
          color = 'red';
      } else if (testChar === 'R') {
          color = 'green';
      } else if (!isNaN(testChar)) {
          color = 'orange';
      } else {
        return substr;
      }
      return '<span style="color: ' + color + '">' + substr + '</span>';   
  })
}
Collapse
laurieontech profile image
Laurie • Edited

Quick edit with a dictionary.

function highlight(code) {
  const colorDict = {'F': 'pink', 'L': 'red', 'R':'green'};

  return code.replace(/(\D)\1*|\d+/g, (substr) => {
      let testChar = substr.charAt(0); 

      if (testChar in colorDict) {
        return '<span style="color: ' + colorDict[testChar] + '">' + substr + '</span>';   
      } else if (!isNaN(testChar)) {
        return '<span style="color: orange">' + substr + '</span>';   
      } else {
        return substr;
      }
  })
}
Collapse
threeheadedcerb profile image
russ

I had no idea you could use \1 in the same expression as the tagged group, never seen that before!

Thread Thread
laurieontech profile image
Laurie

Stackoverflow helped me with that one. I knew it was possible, but wasn't sure how. I actually started with the (.)\1* and iterated to the right regex from there.

Thread Thread
threeheadedcerb profile image
russ • Edited

You should be able to simplify it a little by changing the + to a * so you don't need the second \D I think?
(\D)\1*|(\d+)

Thread Thread
laurieontech profile image
Laurie

Ooh, you're right. I had it that way to start and then ran into problems with a test case that had 663. It was splitting that grouping because it hit the matching case first. But when I removed the capture group generic and made it non-digit that solved that. So can revert back. Thanks :)

Collapse
clandau profile image
Courtney

The answers to this kata on codewars are blowing my mind.

function highlight(code) {
    let codeString = '';
    let leftPointer, currentItem;
    let colorObj = {'F': '<span style=\"color: pink\">', 'L': '<span style=\"color: red\">', 'R': '<span style=\"color: green\">'};
    for(let i=0; i<code.length; i++){
        currentItem = code[i];
        if(!isNaN(code[i])) {
            codeString += '<span style=\"color: orange\">'
            leftPointer = i;
            while(i+1 < code.length && !isNaN(code[i+1])) {
                i++;
            }
            codeString += code.slice(leftPointer, i+1) + '</span>';
        }
        else if(colorObj[currentItem]) {
            codeString += colorObj[currentItem];
            while(i+1 < code.length && currentItem === code[i+1]) {
                i++;
                codeString += currentItem;
            }
        codeString += currentItem  + '</span>';
        }
        if(currentItem === '(' || currentItem === ')') codeString += currentItem;
    }
    return codeString;
  }
Collapse
aspittel profile image
Ali Spittel Author

Monday (8KYU): How many stairs will Suzuki climb in 20 years?

codewars.com/kata/56fc55cd1f5a93d6...

Collapse
laurieontech profile image
Laurie • Edited

Javascript (ES6):

function stairs_in_20(stairs) {
       return stairs.reduce((steps, day) => steps.concat(day)).reduce((sum, count) => sum + count) * 20;
}
Collapse
jellebekker profile image
Jelle Bekker

Not a one liner like you guys but C#:

using System;
public class Kata
{
  public static long StairsIn20(int[][] stairs)
  {
    long sum = 0;
    foreach (var weekday in stairs)
        foreach (var steps in weekday)
          sum += steps;

    return sum * 20;
   }           
}
Collapse
jellebekker profile image
Jelle Bekker

Okay, I couldn't help myself:

using System;
using System.Linq;

public class Kata
{
  public static long StairsIn20(int[][] stairs)
  {
    return stairs.SelectMany(x => x).Sum() * 20;
  }
}
Collapse
mihassan profile image
Md Imrul Hassan
def stairs_in_20(stairs):
    return 20*sum(sum(stairs, []))
Collapse
aspittel profile image
Ali Spittel Author • Edited

My Python solution:

def stairs_in_20(stairs):
      return sum(i for sublist in stairs for i in sublist)  * 20
Collapse
clandau profile image
Courtney

Practicing TypeScript for my upcoming internship. And I figured out how to add code highlighting!

function stairsIn20(stairs : number[][]) : number {
    let totalStairs : number = 0;
    for(let day of stairs) {
      totalStairs += day.reduce((total, num) => total + num);
    }
    return totalStairs * 20;
  }
Collapse
aspittel profile image
Collapse
aspittel profile image
Ali Spittel Author
n_cases = int(input())
for i in range(1, n_cases + 1):
    check_amount = int(input())
    unfound = True
    fours = [int(i) for i in str(check_amount)]
    others = ["1" if n == 4 else "0" for n in fours]
    n = int(''.join(others))
    print("Case #{}: {} {}".format(i, n, check_amount - n))
Collapse
clandau profile image
Courtney

brute force for me so far.

const readline = require('readline');

function foregone() {
    let argumentsArray = [], answerArray = [];
    let linecounter = 0, tests;

    const rl = readline.createInterface({ 
        input: process.stdin,
        output: process.stdout
    });
    rl.on('line', (line) => {
        linecounter++;
        if(linecounter === 1) tests = line;
        else {
            argumentsArray.push(line);
            if(linecounter > tests) rl.close();
        }
    }).on('close', () => {
        for(let i=0; i< argumentsArray.length; i++) {
            answerArray.push(noFours(argumentsArray[i]));
        }
        for(let i=0; i<answerArray.length; i++) {
            console.log(`Case #${i+1}: ${answerArray[i][0]} ${answerArray[i][1]}`)
        }
        process.exit(0);
    });

    function noFours(num) {
        let a = num - 1, b = num - a;
        while(a.toString().indexOf('4') !== -1 || b.toString().indexOf('4') !== -1 && a >= b) {
            a--, b++;
        }
        if(a.toString().indexOf('4') === -1 && b.toString().indexOf('4') === -1) return [a, b];
        else return undefined 
    }
}
Collapse
choroba profile image
E. Choroba
#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use Math::BigInt;

chomp( my $cases = <> );
for my $case (1 .. $cases) {
    chomp( my $n = <> );
    (my $i = $n) =~ tr/4/3/;
    my $j = 'Math::BigInt'->new($n) - 'Math::BigInt'->new($i);
    say "Case #$case: $i $j";
}
Collapse
jacobmgevans profile image
Jacob Evans
const stairsIn20 =(s) => [...s].map((ele)=> ele.reduce((ag, nx)=> ag+nx))
.reduce((ag, nx)=> ag+nx) * 20
Collapse
aspittel profile image
Ali Spittel Author

Thursday (5 KYU): Perimeter of squares in a rectangle

codewars.com/kata/559a28007caad2ac...

Collapse
choroba profile image
E. Choroba
#!/usr/bin/perl
use warnings;
use strict;

sub perimeters {
    my ($n) = @_;
    my @f = (1, 1);
    my $s = 0;
    for (0 .. $n) {
        $s += $f[0];
        @f = ($f[1], $f[0] + $f[1]);
    }
    return 4 * $s
}

# In a good TDD tradition, I started with these lines:
use Test::More tests => 2;
is perimeters(5), 80;
is perimeters(7), 216;
Collapse
clandau profile image
Courtney

TypeScript. Great practice!

export class G964 {
    public static perimeter = (n) => {
      let fibArray : number[] = [0, 1, 1];
      for(let i=3; i<=n+1; i++) {
        fibArray[i] = fibArray[i-1] + fibArray[i-2];
      }
      return fibArray.reduce((a, b) => a + b) * 4;
    }
}
Collapse
jacobmgevans profile image
Jacob Evans
const stairsIn20 =(s) => [...s].map((ele)=> ele.reduce((ag, nx)=> ag+nx)).reduce((ag, nx)=> ag+nx) * 20