# Daily Challenge #260 - Subtract the Sum

Daily Challenge (262 Part Series)

Complete the function which get an input number n such that n >= 10 and n < 10000, then:

Sum all the digits of n.
Subtract the sum from n, and it is your new n.
If the new n is in the list below return the associated fruit, otherwise return back to task 1.

Example
n = 325
sum = 3+2+5 = 10
n = 325-10 = 315 (not in the list)
sum = 3+1+5 = 9
n = 315-9 = 306 (not in the list)
sum = 3+0+6 = 9
n =306-9 = 297 (not in the list)
...
. ...until you find the first n in the list below.

Here are all possible values of n:

1-kiwi
2-pear
3-kiwi
4-banana
5-melon
6-banana
7-melon
8-pineapple
9-apple
10-pineapple
11-cucumber
12-pineapple
13-cucumber
14-orange
15-grape
16-orange
17-grape
18-apple
19-grape
20-cherry
21-pear
22-cherry
23-pear
24-kiwi
25-banana
26-kiwi
27-apple
28-melon
29-banana
30-melon
31-pineapple
32-melon
33-pineapple
34-cucumber
35-orange
36-apple
37-orange
38-grape
39-orange
40-grape
41-cherry
42-pear
43-cherry
44-pear
45-apple
46-pear
47-kiwi
48-banana
49-kiwi
50-banana
51-melon
52-pineapple
53-melon
54-apple
55-cucumber
56-pineapple
57-cucumber
58-orange
59-cucumber
60-orange
61-grape
62-cherry
63-apple
64-cherry
65-pear
66-cherry
67-pear
68-kiwi
69-pear
70-kiwi
71-banana
72-apple
73-banana
74-melon
75-pineapple
76-melon
77-pineapple
78-cucumber
79-pineapple
80-cucumber
81-apple
82-grape
83-orange
84-grape
85-cherry
86-grape
87-cherry
88-pear
89-cherry
90-apple
91-kiwi
92-banana
93-kiwi
94-banana
95-melon
96-banana
97-melon
98-pineapple
99-apple
100-pineapple


Tests:
SubtractSum(10)
SubtractSum(1204)

Good luck!

This challenge comes from aryan-firouzian 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 (262 Part Series)

### Discussion Here is my simple solution to find the fruit name with PHP:

function subtractSum($n) { // fruit name "apple"$fruitArray = ["kiwi",
"pear",
"kiwi",
"banana",
"melon",
"banana",
"melon",
"pineapple",
"apple",
"pineapple",
"cucumber",
"pineapple",
"cucumber",
"orange",
"grape",
"orange",
"grape",
"apple",
"grape",
"cherry",
"pear",
"cherry",
"pear",
"kiwi",
"banana",
"kiwi",
"apple",
"melon",
"banana",
"melon",
"pineapple",
"melon",
"pineapple",
"cucumber",
"orange",
"apple",
"orange",
"grape",
"orange",
"grape",
"cherry",
"pear",
"cherry",
"pear",
"apple",
"pear",
"kiwi",
"banana",
"kiwi",
"banana",
"melon",
"pineapple",
"melon",
"apple",
"cucumber",
"pineapple",
"cucumber",
"orange",
"cucumber",
"orange",
"grape",
"cherry",
"apple",
"cherry",
"pear",
"cherry",
"pear",
"kiwi",
"pear",
"kiwi",
"banana",
"apple",
"banana",
"melon",
"pineapple",
"melon",
"pineapple",
"cucumber",
"pineapple",
"cucumber",
"apple",
"grape",
"orange",
"grape",
"cherry",
"grape",
"cherry",
"pear",
"cherry",
"apple",
"kiwi",
"banana",
"kiwi",
"banana",
"melon",
"banana",
"melon",
"pineapple",
"apple",
"pineapple",];

$number =$n;
while(true) {
$str = (string)$number;
$sum = 0; for($index=0; $index<strlen($str); $index++) {$sum += (int)$str[$index];
}

$number =$number - $sum; if ($number <= 99) {
break;
}

}

return  $fruitArray[$number-1];
}


Heres my solution in Javascript:
It seems like it always returns apple, pretty neat question huh (Unless im wrong? 😅)

const SubtractSum = return () => "apple"


How I found this out:

const fruits = [
"kiwi",
"pear",
"kiwi",
"banana",
...
"melon",
"pineapple",
"apple",
"pineapple",
]

const SubtractSum = x => {
const sum = ${x}.split("").reduce((p, c) => +p + +c, 0) const y = x - sum return y <= 99 ? fruits[y - 1] : SubtractSum(y) } //Testing out all possible combinations 10 -- 10000 for (let i = 10; i < 10000; i++) { console.log(i, SubtractSum(i)) //Prints "apple" }  Here is a solution, return "apple";  And here is a recursive Python solution, fruits = [ "kiwi", "pear", .... "melon", "pineapple", "apple", "pineapple" ] def SubtractSum(number : int) -> str: temp = number - sum(map(int ,str(number))) if(1 <= temp <= 100): return fruits[temp-1] return SubtractSum(temp)  Some python-that-can-be-improved: elements = [ "1-kiwi", "2-pear", "3-kiwi", "4-banana", "5-melon", "6-banana", "7-melon", "8-pineapple", "9-apple", "10-pineapple", "...", "100-pineapple" ] def substractSum(n): if 10 <= n <= 10000: sum_n = 0 for digit in str(n): sum_n += int(digit) result = n - sum_n while result > 100: for digit in str(n): sum_n += int(digit) result = n - sum_n print(n, result, elements[result-1]) else: print("{}: Use value between 10 and 10000".format(n)) substractSum(9) substractSum(10) substractSum(31) substractSum(110) substractSum(111) substractSum(325) substractSum(1204) substractSum(1316) substractSum(2888) substractSum(10000) substractSum(10001)  Output of the above: ❯ python 260.py 9: Use value between 10 and 10000 10 9 9-apple 31 27 27-apple 110 100 100-pineapple 111 99 99-apple 325 95 95-melon 1204 98 98-pineapple 1316 95 95-melon 2888 80 80-cucumber 10000 100 100-pineapple 10001: Use value between 10 and 10000  Yanother Ruby solution FRUIT = { '1' => 'kiwi', # ... '100' => 'pineapple' } def subtract_sum(number) return unless (10...10_000).cover?(number) loop do number_split = number.to_s.split('') to_subtract = number_split.reduce(0) { |sum, i| sum += i.to_i } number -= to_subtract return FRUIT[number.to_s] if FRUIT.key?(number.to_s) end end  Ada solution with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; subtype Parameter_Type is Integer range 10 .. 9999; subtype Fruit_Index is Integer range 1 .. 100; Names : array(Fruit_Index) of Unbounded_String := ( -- Fill with names ); function SubctractSum(N : Parameter_Type) return Unbounded_String is (if N in Fruit_Index then Names(N) else "apple"); -- Explanation: -- N can be written as -- -- N = a*1000 + b*100 + c*10 + d -- -- if N <= 100, we access directly the name array. -- -- If N > 100 (which means b >= 1) the new N is -- -- New_N = a*1000 + b*100 + c*10 + d - (a+b+c+d) -- = a*999 + b*99 + c*9 -- -- If the iteration stops with New_N it must be -- New_N <= 100 which implies a = 0, b=1 -- (it cannot be b=0 otherwise we would had -- not done another iteration) and c=0, that is, -- New_N = 99. -- -- Therefore, unless N<=100, the result is "apple"  Rust solution: const FRUITS: [&'static str; 100] = [ "kiwi", "pear", "kiwi", "banana", "melon", "banana", "melon", "pineapple", "apple", "pineapple", "cucumber", "pineapple", "cucumber", "orange", "grape", "orange", "grape", "apple", "grape", "cherry", "pear", "cherry", "pear", "kiwi", "banana", "kiwi", "apple", "melon", "banana", "melon", "pineapple", "melon", "pineapple", "cucumber", "orange", "apple", "orange", "grape", "orange", "grape", "cherry", "pear", "cherry", "pear", "apple", "pear", "kiwi", "banana", "kiwi", "banana", "melon", "pineapple", "melon", "apple", "cucumber", "pineapple", "cucumber", "orange", "cucumber", "orange", "grape", "cherry", "apple", "cherry", "pear", "cherry", "pear", "kiwi", "pear", "kiwi", "banana", "apple", "banana", "melon", "pineapple", "melon", "pineapple", "cucumber", "pineapple", "cucumber", "apple", "grape", "orange", "grape", "cherry", "grape", "cherry", "pear", "cherry", "apple", "kiwi", "banana", "kiwi", "banana", "melon", "banana", "melon", "pineapple", "apple", "pineapple", ]; fn subtract_sum(sum: i32) -> &'static str { let mut s = sum; *FRUITS .iter() .nth(loop { if s <= 100 { break (s - 1) as usize; } s -= s .to_string() .chars() .map(|c| (c as u8 - 48) as i32) .sum::<i32>(); }) .unwrap() }  Simple PHP solution using array_reduce function substractTheSum(int$number): string {
$fruitList = [ 1 => 'kiwi', 2 => 'pear', // ... ]; while($number > 100) {
$number -= array_reduce(str_split((string)$number), fn($carry, string$num) => $carry += (int)$num);
}
return $fruitList[$number];
}


A quick JS one:

First up, set up the base fruit mapping by splitting that string:

const
inputFruitMappingString = 1-kiwi
2-pear
...other entries...
99-apple
100-pineapple,
baseFruitMapping = Object.fromEntries(
inputFruitMappingString.split('\n').map(line => line.split('-'))
)


The fruit-fetching-function itself:

function fruitForIndex(i) {
return baseFruitMapping[i] ??
fruitForIndex(
[...String(i)].reduce((acc, digit) => acc - digit, i)
);
}


The guts of that is: [...String(i)].reduce((acc, digit) => acc - digit, i)
Breaking that up:

• String(i): i is a number so to split it into characters, render it into a standard decimal string
• [...String(i)]: Easy way to split the string into chars
• [...String(i)].reduce((acc, digit) => acc - digit, i): The reduce function is passed the number itself as its initial value and then goes through the array of digits, subtracting each from the running total.

Bit of sanity checking...

// Debug version of the function
function fruitForIndex(i) {
console.log(i),
return baseFruitMapping[i] ?? fruitForIndex([...String(i)].reduce((acc, digit) => acc - digit, i));
}

> fruitForIndex(1)
1
< "kiwi"

> fruitForIndex(100)
100
< "pineapple"

> fruitForIndex(101)
101
99
< "apple"

> fruitForIndex(200)
200
198
180
171
162
153
144
135
126
117
108
99
< "apple"


Note that it's worth making sure you have a modern JS engine
Caniuse for Object.fromEntries
Caniuse for ??

My version, in C# 😄

    public static string GetMatchingWordFor(int number)
{
var nValues = GetDictionaryFromRawString(RawValues);

while (!nValues.ContainsKey(number))
{
number -= number.ToString()
.Select(digit => int.Parse(digit.ToString()))
.Aggregate(0, (acc, x) => acc + x);
}

return nValues[number];
}


The helper function to convert the raw list into a usable dictionary:

    public static Dictionary<int, string> GetDictionaryFromRawString(string raw)
{
return raw.Split("\n")
.Select(str =>
str.Trim()
.Split("-"))
.ToDictionary(
row => int.Parse(row),
row => row);
}


Here is Ruby solution,

FRUITS = {
1 => 'kiwi',
...
100 => 'pineapple'
}

def substract_sum(num)
if num >= 10 && num < 10000
sum_of_digits = num.to_s.chars.map(&:to_i).inject(:+)
if FRUITS.keys.include?(sum_of_digits)
puts FRUITS[sum_of_digits]
else
puts "#{sum_of_digits} (not in the list)"
end
else
puts 'Enter valid number'
end
end

substract_sum(10)
substract_sum(1204)


I think this might be called a naive solution...

import random

def number_fruit():
fruit_list = []
fruit_dict = {
1:'kiwi',
2:'pear',
3:'kiwi',
4:'banana',
5:'melon',
6:'banana',
7:'melon',
8:'pineapple',
9:'apple',
10:'pineapple',
11:'cucumber',
12:'pineapple',
13:'cucumber',
14:'orange',
15:'grape',
16:'orange',
17:'grape',
18:'apple',
19:'grape',
20:'cherry',
21:'pear',
22:'cherry',
23:'pear',
24:'kiwi',
25:'banana',
26:'kiwi',
27:'apple',
28:'melon',
29:'banana',
30:'melon',
31:'pineapple',
32:'melon',
33:'pineapple',
34:'cucumber',
35:'orange',
36:'apple',
37:'orange',
38:'grape',
39:'orange',
40:'grape',
41:'cherry',
42:'pear',
43:'cherry',
44:'pear',
45:'apple',
46:'pear',
47:'kiwi',
48:'banana',
49:'kiwi',
50:'banana',
51:'melon',
52:'pineapple',
53:'melon',
54:'apple',
55:'cucumber',
56:'pineapple',
57:'cucumber',
58:'orange',
59:'cucumber',
60:'orange',
61:'grape',
62:'cherry',
63:'apple',
64:'cherry',
65:'pear',
66:'cherry',
67:'pear',
68:'kiwi',
69:'pear',
70:'kiwi',
71:'banana',
72:'apple',
73:'banana',
74:'melon',
75:'pineapple',
76:'melon',
77:'pineapple',
78:'cucumber',
79:'pineapple',
80:'cucumber',
81:'apple',
82:'grape',
83:'orange',
84:'grape',
85:'cherry',
86:'grape',
87:'cherry',
88:'pear',
89:'cherry',
90:'apple',
91:'kiwi',
92:'banana',
93:'kiwi',
94:'banana',
95:'melon',
96:'banana',
97:'melon',
98:'pineapple',
99:'apple',
100:'pineapple'
}

num_int = random.randint(10,10000)
num_str = str(num_int)
num_list = list(num_str)
num_list_int = []

for x in num_list:
xint = int(x)
num_list_int.append(xint)

sum_num_int_list = sum(num_list_int)
new_n = num_int - sum_num_int_list

if new_n in fruit_dict:
print(new_n,'=',fruit_dict[new_n])
else:
number_fruit()

number_fruit()



...and neither do I understand recursion (maximum recursion depth exceeded while calling a Python object) and why it always comes up apple.

Go

EDIT: just realized this challenge was a trap, but leaving the (wrong) solution here for people wanting to try out Go (it's awesome, try it).

Commands for initializing the project.

$mkdir$GOPATH/src/fruits
$cd$GOPATH/src/fruits
$touch fruits.go  The source-code. // Set of utilities for manipulating fruits. package fruits // Find a fruit based on its index. func FindFromInteger(integer uint16) string { if integer < 9 { switch (integer) { case 1: return "kiwi" case 2: return "pear" case 3: return "kiwi" case 4: return "banana" case 5: return "melon" case 6: return "banana" case 7: return "melon" case 8: return "pineapple" } } return "apple" }  Commands for the unit tests. $ touch fruits_test.go


The source-code for unit tests.

package fruits_test

import "testing"
import "fruits"
import "fmt"

func TestFindFromInteger(t *testing.T) {
var valuesExpectations map[uint16]string = map[uint16]string{
0: "apple",
1: "kiwi",
2: "pear",
3: "kiwi",
4: "banana",
5: "melon",
6: "banana",
7: "melon",
8: "pineapple",
9: "apple",
10: "apple",
100: "apple",
1_000: "apple",
325: "apple",
10_000: "apple",
}

for value, expectation := range valuesExpectations {
var result string = fruits.FindFromInteger(value)

if result != expectation {
t.Errorf("Expected fruits.FindFromInteger(%d) to equal %s but got %s.", value, expectation, result)
}
}
}

func BenchmarkFindFromInteger(b *testing.B) {
for index := 0; index < b.N; index++ {
fruits.FindFromInteger(10_000)
}
}

func ExampleFindFromInteger() {
fmt.Printf("Fruit for index %d is %q.\n", 15, "apple")
// Output: Fruit for index 15 is "apple".
}


Commands for the tests, benchmark and coverage.

\$ go test -cover -bench .
goos: linux
goarch: amd64
pkg: fruits
BenchmarkFindFromInteger-4      482598516                2.58 ns/op
PASS
coverage: 100.0% of statements
ok      fruits  1.500s


Sum all the digits of n.

Base ten is implicit, I suppose.

why I always get apple 😅 ?  