Challenge 18 Megathread

Welcome to challenge 18! Use this thread for any and all questions relating to challenge 18.

1 Like
const countTickets = (tickets) => {
  return tickets.reduce((acc, cv) => {
    return {...acc, [cv]: acc[cv] + 1 }
  }, { red: 0, green: 0, blue: 0 })
}

const bestOdds = (tickets, raffleEntries) => {
  const ticketCounts = countTickets(tickets);
  const winningColor = Object.keys(ticketCounts).reduce((acc, cv) => {
    return ticketCounts[cv] / raffleEntries[cv] > ticketCounts[acc] / raffleEntries[acc] ? cv : acc;
  });
  return `You have the best odds of winning the ${winningColor} raffle.`
}

Here is my answer

3 Likes

I’m interested in the reasoning behind making a null value (as opposed to 0) incorrect, for tickets that don’t appear in the input array?

Here is my solution please let me know if i can do anything to improve it .

const countTickets = (tickets) => {
  // Code here!
  let obj = {
    red:0,green:0,blue:0};
  tickets.forEach(e=>{
    if(e in obj){
    obj[e]++;
    }
    
  });
  return obj;
}

const bestOdds = (tickets, raffleEntries) => {
  // Code here!
  let obj = countTickets(tickets);
  let oddc = [];
  for(let p  in raffleEntries)
  {
    oddc.push([p,obj[p]/raffleEntries[p]]);
  }
  oddc.sort(function(a, b) {
    return b[1] - a[1];
});

return `You have the best odds of winning the ${oddc[0][0]} raffle.`
 
  
}
2 Likes

image

1 Like
Summary
const countTickets = tickets => tickets
  .reduce((tally, color) => (
    { ...tally, [color]: tally[color] ? ++tally[color] : 1 }
  ) ,{});

This code works correctly in the console when fed the following array:

['red', 'red', 'green', 'blue', 'green'] => {red: 2, green: 2, blue: 1}

Yet the second test is not passing. Any help would be appreciated.

const countTickets = (array) => {
  // Code here!
  var count1 = 0;
for(var i = 0; i < array.length; ++i){
    if(array[i] == 'red')
        count1++;
}

var count2 = 0;
for(var i = 0; i < array.length; ++i){
    if(array[i] == 'green')
        count2++;
}

var count3 = 0;
for(var i = 0; i < array.length; ++i){
    if(array[i] == 'blue')
        count3++;
}
  return {
  red: count1,
  green: count2,
  blue: count3
}
}

const bestOdds = (tickets, raffleEntries) => {
  const value = countTickets(tickets)

  raffleEntries['red'] = raffleEntries['red'] + value['red']
raffleEntries['blue'] = raffleEntries['blue'] + value['blue']
raffleEntries['green'] = raffleEntries['green'] + value['green']

  if (raffleEntries['green']<=raffleEntries['blue'] && raffleEntries['green']<=raffleEntries['red']){
    return "You have the best odds of winning the green raffle."
  }
  
    if (raffleEntries['red']<=raffleEntries['green'] && raffleEntries['red']<=raffleEntries['blue']){
    return "You have the best odds of winning the red raffle."
  }
  
    if (raffleEntries['blue']<=raffleEntries['green'] && raffleEntries['blue']<=raffleEntries['red']){
    return "You have the best odds of winning the blue raffle."
  }
  

  // Code here!
}

very inefficient answer lol

Hi guys,

Does anyone have any idea why my countTickets function isn’t working? It’s running and producing an object, but the numbers aren’t incrementing, so they’re all still at 0 when I return. Please note: I’m a beginner, so I know it’s probably something basic about how I’m referencing the properties in my object, but if you could explain it in beginner terms, that would be great. Thanks!

const countTickets = (tickets) => {
let currentTickets = {red: 0, green: 0, blue: 0};
for (i = 0; i < tickets.length; i++) {
if (tickets === “red”) {currentTickets.red++}
else if (tickets === “green”) {currentTickets.green++}
else if (tickets === “blue”) {currentTickets.blue++}
}
return currentTickets;
}

Should be for(var i… In your for loop. I is not defined

My solution:

const countTickets = tickets =>
  tickets.reduce((acc, next) => ({ ...acc, [next]: acc[next] + 1 }), 
  { red: 0, green: 0, blue: 0 });

const generateMessage = color =>
  `You have the best odds of winning the ${color} raffle.`;

const bestOdds = (tickets, raffleEntries) => {
  const allCount = countTickets(tickets);
  const redCount = allCount.red / raffleEntries.red;
  const greenCount = allCount.green / raffleEntries.green;
  const blueCount = allCount.blue / raffleEntries.blue;

  if (redCount > greenCount) {
    if (redCount > blueCount) return generateMessage("red");
    return generateMessage("blue");
  } else {
    if (greenCount > blueCount) return generateMessage("green");
    return generateMessage("blue");
  }
};
2 Likes

Hello!

Try removing the curly braces {} from {currentTickets.red++} ,{currentTickets.green++} and {currentTickets.blue++}

Hope this helps :slight_smile:

Thanks for both of these tips! I implemented both of them and, while I understand why they are right, neither of them made the function run…

In your for loop, try declaring i (let i = 0) :slight_smile:

You’re checking if tickets === 'red', but tickets is the whole array, not the individual value in the loop. You need tickets[i] === 'red' :wink:

As a general note to others: while trying to help is great, it’s not always useful if you’re unsure of the answer yourself :slight_smile: A few responses have been incorrect and not relevant to the question asked, so be careful when giving out advice :wink:

1 Like

In JavaScript this doesn’t technically matter. Undeclared variables are declared automatically, though it’s always best practice to manually declare them because of their scope.

It’s because they assume your returned object contains red, green, and blue as keys. Even when they feed in an empty array.

Your code would give back an empty object.

try changing your starting object from {} to { red: 0, green: 0, blue: 0 } :wink:

Yes! That was it! Where I went wrong is by trying to reuse my code from an earlier challenge, but in that case it was referencing a single value, not an array. Thanks so much!

1 Like