 # Daily Challenge #275 - Casino Chips

Daily Challenge (273 Part Series)

You are given three piles of casino chips: white, green and black chips in the form of an array. Each day you need exactly two chips of different colors to play at the casino. You can chose any color, but you are not allowed to use two chips of the same color in a single day.

You will be given an array representing the number of chips of each color and your task is to return the maximum number of days you can play.

Examples:
solve([1,1,1]) = 1, because after you pick on day one, there will be only one chip left
solve([1,2,1] = 2, you can pick twice; you pick two chips on day one then on day two
solve([4,1,1]) = 2

Brute force is not the way to go here. Look for a simplifying mathematical approach.

Tests:
solve([8,1,4])
solve([7,4,10])
solve([12,12,12])
solve([1,23,2])

Good luck!

This challenge comes from KenKamau 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!

Daily Challenge (273 Part Series)

### Discussion This should do it

def solve(chips):
max_chips = max(chips)
chips.remove(max_chips)
remaining_count = sum(chips)
return min(max_chips, remaining_count)


EDIT: first solution does not work for all possible test cases, this should

def solve(chips):
chips.sort(reverse=True)
return min(sum(chips) >> 1, sum(chips[1:]))


Doesn't this fail the [12,12,12] input?

The output of solve([12,12,12]) is 12. But you don't have to take my word for it, you can always throw it in the shell and see for yourself.

ah I see the correct output should be 18

Yes exactly! I just stumbled upon your solution while looking through the comments for what values I should be outputting, and comparing answers to my code.

Your updated solution works great! I'm not sure I get the "math" side of it, as my solution is definitely brute force (recursively remove tokens until we can't anymore).

I get that your code sorts, then returns either the total number of chips / 2 OR the total number of chips in the smaller stacks, whichever is smaller.

Math-wise, I'll take a stab at understanding it.

If we have 1 larger / infinite stack, then we are limited by the other two. We pair a chip from the smaller stacks with one from the large stack everyday, and that's our total. That's the second half of the return statement.

However, if we have stacks that are somewhat even, we can rotate through and deplete them evenly. We code this by taking the total number of chips, and dividing them by the daily chip requirement (we can use the bitwise operator >> here since the daily chip requirement is 2).

I approached it like this: There's a case where it's better to split the highest stack in half to divvy between the lower 2 stacks, this only happens when the lower 2 stacks add up to be greater than the highest stack, then there are these "leftovers" in the stacks that you can combine.
I ended up with something looking like
high/2 + (mid + low)/2
which can be reduced mathematically to
(high + mid + low)/2
There was a point where it stopped making sense and I was just reducing the math and logic. This was a solution that helped me dev.to/juanrodriguezarc/comment/12o94

APL (using Dyalog APL):

      Solve←(⌊2÷⍨+/)⌊(+/-⌈/)
Solve 1 1 1
1
Solve 1 2 1
2
Solve 4 1 1
2
Solve 12 12 12
18
Solve 7 4 10
10


(Use the bookmarklet on this post to see the code with APL font and syntax highlighting.)

Explanation: Two possible answers are the sum of two lower values, and half of the entire sum (floored). We need to take the lower of the two.

(⌊2÷⍨+/)⌊(+/-⌈/)  ⍝ Input: an array of 3 numbers
⌊         ⍝ Take minimum of two sides...
⍝  Choice 1:
+/      ⍝   Sum (reduction / by addition +)
-     ⍝   Minus
⌈/   ⍝   Max (reduction / by max-of-two ⌈)
⍝  Choice 2:
+/           ⍝   Sum
2÷⍨             ⍝   Divided by 2
⌊                ⍝   Floor of the above


Nice explanation!

## "constant time" in Javascript

const solve = chips => {
const [low, mid, high] = [...chips].sort()
const extra = low & 1
const rings = low - extra
const tower = mid - rings
const last = (high !== mid) & extra
return rings * 3 + tower + last
}

1. first we take whole rings, (0-1, 1-2, 2-0)
2. then we take a the stack of lone pairs ("tower")
3. finally we see if remainder from rings that's not in the "tower" can last us one more day with remainder of tower.

In C with O(1):

#include <stdio.h>

int solve(int a,int b,int c)
{
int Days;
(a>=b)? (b>=c? (Days=c,c-=c):(Days=b,b-=b)):(a>=c? (Days=c,c-=c):(Days=a,a-=a));

Days+=(a==0) ? (b>=c? c:b):((b==0) ? (a>=c? c:a):((a>=b) ? b:a));

return Days;
}

int main(void)
{
printf("Days: %d \n",solve(4,1,1));
printf("Days: %d \n",solve(8,1,4));
printf("Days: %d \n",solve(7,4,10));
printf("Days: %d \n",solve(12,12,12));
printf("Days: %d \n",solve(1,23,2));
return 0;
}


## Rust

fn solve(mut chips: [u64; 3]) -> u64 {
chips.sort_unstable();
let [low, mid, high] = chips;
let extra = low & 1;
let rings = low - extra;
let tower = mid - rings;
let last = (high != mid) as u64 & extra;
rings * 3 + tower + last
}

fn main() {
assert_eq!(solve([1, 1, 1]), 1);
assert_eq!(solve([1, 2, 1]), 2);
assert_eq!(solve([4, 1, 1]), 2);
dbg!(solve([8, 1, 4]));
dbg!(solve([7, 4, 10]));
dbg!(solve([12, 12, 12]));
dbg!(solve([1, 23, 2]));
}


Look at it go!

Explaination in dev.to/qm3ster/comment/1303g

My Javascript solution

const solve = (chips) => {
chips.sort((a,b) => a - b)
let days = 0

while(days >= 0) {
if (chips > 0) {
days++
chips--
chips--
} else if (chips > 0 && chips > 0) {
days++
chips--
chips--
} else {
break; // no chips left! exit the loop
}
}

return days
}


code php

function solve(array $arr) {$maxDay = 0;
sort($arr);$checkDuplicateValue = array_unique($arr); if($arr !== $checkDuplicateValue) {$maxDay = $arr; return$maxDay;
}
$maxDay =$arr + 1;
return \$maxDay;
}

function solve(arr){
const [a,b,c] = arr.sort((a,b)=> b - a);
const [x,y] = [a, b+c];
const z = y > x ? Math.floor((x-y)/2): 0;
return y + z;
}



JavaScript

const solve = xs => {
if (xs === xs && xs === xs) return Math.floor(xs * 1.5)
xs.sort()
return Math.min(xs, xs + xs)
}


# Go #GoLang

package main

import (
"fmt"
"sort"
"math"
)

func main() {
fmt.Println("Hello, playground");
conins := []int{12,2,1}
res := play(conins)
fmt.Println(res)
}

func play(c []int) int {
if(c == c && c==c && c == c) {
return int(math.Floor(float64(c)*1.5))
}
sort.Ints(c)
return int(math.Min(float64(c), float64(c+c)));
}
`  