dev.to staff

Posted on

# Daily Challenge #58 - Smelting Iron Ingots

Minecraft has gotten to be a very popular game. No doubt many reading this have played it themselves or watched someone else. In Minecraft, collected ore must be smelted in a furnace to change the resource into a usable form.

Each ingot takes 11 seconds to produce. Steve has the following fuel options to add to the furnace:

`Buckets of lava, each lasts 800 seconds`
`Blaze rod, each lasts 120 seconds`
`Coals, each lasts 80 seconds`
`Blocks of Wood, each lasts 15 seconds`
`Sticks, each lasts 1 second*`

Write a function that calculates the minimum amount of fuel needed to produce a certain number of iron ingots.

Ruby: `{:lava => 2, :blaze_rod => 1, :coal => 1, :wood => 0, :stick => 0}`
JavaScript: `{lava: 2, blazeRod: 1, coal: 1, wood: 0, stick: 0}`

Good luck!~

Today's challenge comes from arwengu 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!

Donald Feury

Time to Go smelting!

ingots.go

``````package ingots

const (
blazeRodDuration int = 120
coalDuration     int = 80
woodDuration     int = 15
)

// Requirements represents the differents types of fuel and in what amounts needed to complete the smelting job
type Requirements struct {
Lava     int
BlazeRod int
Coal     int
Wood     int
Stick    int
}

// Fuel determines the fuel requirements to smelt the given number of ingots
func Fuel(ingots int) Requirements {
if ingots <= 0 {
return Requirements{0, 0, 0, 0, 0}
}

duration := ingots * 11

return Requirements{
BlazeRod: duration/blazeRodDuration + 1,
Coal:     duration/coalDuration + 1,
Wood:     duration/woodDuration + 1,
Stick:    duration,
}
}

``````

ingots_test.go

``````package ingots

import "testing"

func TestFuel(t *testing.T) {
testCases := []struct {
description string
input       int
expected    Requirements
}{
{
"a few ingots",
2,
Requirements{1, 1, 1, 2, 22},
},
{
"wow that is alot of ingots",
500,
Requirements{7, 46, 69, 367, 5500},
},
{
"negative amount of ingots",
-5,
Requirements{0, 0, 0, 0, 0},
},
{
"no ingots",
0,
Requirements{0, 0, 0, 0, 0},
},
}

for _, test := range testCases {
if result := Fuel(test.input); result != test.expected {
t.Fatalf("FAIL: %s - Fuel(%d): %+v - expected: %+v", test.description, test.input, result, test.expected)
}
t.Logf("PASS: %s", test.description)
}
}

``````

mrsamse

My solution in JavaScript:

``````const calcFuel = (n) => {
const secsPerIngot = 11;
let time = n * secsPerIngot;

const lava = Math.floor(time / 800);
time = time - lava * 800;
const blazeRod = Math.floor(time / 120);
time = time - blazeRod * 120;
const coal = Math.floor(time / 80);
time = time - coal * 80;
const wood = Math.floor(time / 15);
time =  time - wood * 15;
const stick = Math.floor(time / 1);

return {lava, blazeRod, coal, wood, stick};
};
``````

Chris Achard

I think I interpreted this correctly (though "minimum number" could mean a few different things here...)

Here's my solution using javascript's `reduce`:

``````const fuel = ingots => {
let need = ingots * 11

const types = [
{name: 'lava', sec: 800},
{name: 'blazeRod', sec: 120},
{name: 'coal', sec: 80},
{name: 'wood', sec: 15},
{name: 'stick', sec: 1},
]

return types.reduce((r, v) => {
r[v.name] = Math.floor(need / v.sec)
need = need - (r[v.name] * v.sec)
return r
}, {})
}
``````

And you can watch me solve it here! youtu.be/wtA4CKbZipA

Mat-R-Such

Python

``````def fuel(a):
a = a * 11
i= 0
tab = []
t1 = [800,120,80,15,1]
t2 = ['lava','blazeRod','coal','wood','stick']
while a > 0:
if  a > t1[i]:
if a % t1[i] == 0:
tab.append([t2[i],  a // t1[i]])
a = 0
else:
tab.append([t2[i], a // t1[i]])
a = a % t1[i]
else:
tab.append([t2[i],  0])
i+=1
if i < 5:
while i <5:
tab.append([t2[i],  0])
i+=1
return tab
``````

Carlos Fuentes

The challenge was a little bit ambiguous about the requirement. If I understand correctly, is asking about at least how many resources of each fuel you require to try to smelt iron ingots.
With this, I wrote the following solution in JavaScript

``````const calculateFuelForIrons = ironCubesQty => {
const FUEL_DURATION = {
lava: 800,
blazeRod: 120,
coal: 80,
wood: 15,
stick: 1
};

const smeltingTime = ironCubesQty * 11;

return Object.keys(FUEL_DURATION).reduce((result, key) => {
const newResult = {
...result,
[key]: Math.floor(smeltingTime / FUEL_DURATION[key])
};

return { ...newResult };
}, {});
};

console.log(calculateFuelForIrons(10));
console.log(calculateFuelForIrons(110));
console.log(calculateFuelForIrons(11000));
console.log(calculateFuelForIrons(0));
``````

Craig McIlwrath

I'm not sure if I'm correctly interpreting the problem, but:

``````data Fuels a = Fuels { lava :: a
, blazeRod :: a
, coal :: a
, wood :: a
, stick :: a
} deriving (Show, Eq)

defFuels :: (Integral a) => Fuels a
defFuels = Fuels 0 0 0 0 0

minFuel :: (Integral a) => a -> Fuels a
minFuel items = defFuels{lava = ceiling \$ fromIntegral items * 11 / 800}
``````

The minimum amount of fuel to cook `n` items will always be only lava buckets...

My other interpretation was the amount of fuel to get the exact correct smelting time. I did work on a solution for that, but it felt very verbose with a lot of repeated code to work with my `Fuels` type. I'm pretty new to Haskell, so I'm not sure if this is the best thing to use in this situation. I did think about using a map, but then I would have to deal with `Maybe`s when looking up items from the map. Any advice or reccomendations would be appreciated.

Cagatay Kaya
``````const furnace = (ingot = 0) => {
var fuel = [
{ type: "lava", duration: 800, count: 0 },
{ type: "blazeRod", duration: 120, count: 0 },
{ type: "coal", duration: 80, count: 0 },
{ type: "wood", duration: 15, count: 0 },
{ type: "stick", duration: 1, count: 0 }
];

let pTime = ingot * 11;
if (pTime <= 0 || isNaN(pTime)) {
console.log("No fuel consumption is necessary");
} else {
fuel.map(item => {
item.count = Math.floor(pTime / item.duration);
pTime = pTime - item.count * item.duration;
});
fuel.forEach(item => console.log(`\${item.type}: \${item.count}`));
}
};
``````

Daniel Barwikowski