DEV Community

dev.to staff
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!

Top comments (8)

Collapse
 
dak425 profile image
Donald Feury

Time to Go smelting!

ingots.go

package ingots const ( lavaDuration int = 800 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{ Lava: duration/lavaDuration + 1, 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) } } 
Collapse
 
mrsamse profile image
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}; }; 
Collapse
 
chrisachard profile image
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

Collapse
 
craigmc08 profile image
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 Maybes when looking up items from the map. Any advice or reccomendations would be appreciated.

Collapse
 
metcoder profile image
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)); 
Collapse
 
matrossuch profile image
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 
Collapse
 
cgty_ky profile image
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}`)); } }; 
Collapse
 
dbarwikowski profile image
Daniel Barwikowski

link to codewars?