DEV Community

dev.to staff
dev.to staff

Posted on

8

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!

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

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

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay