dev.to staff

Posted on

# Daily Challenge #260 - Subtract the Sum

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!

## Top comments (16)

peter279k

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];
}
``````

Victor Chan

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"
}

``````

Pierre Bouillon • Edited

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[0]),
row => row[1]);
}
``````

Alex Turner • Edited

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.

Kushal

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)
``````

Mario

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
``````

Boris Quiroz • Edited

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
``````

Riccardo Bernardini • Edited

``````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"
``````

Vidit Sarkar

Here is a solution,

``````return "apple";
``````

Vidit Sarkar

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)
``````

Alex Lohr

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()
}
``````

willsmart • Edited

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 ??

Amin • Edited

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
``````

saswat

Python grill:

Travailleur Lorick

why I always get apple 😅 ?

Riccardo Bernardini

Sum all the digits of n.

Base ten is implicit, I suppose.