i´m new to JavaScript and learning with the Help of the Website https://www.jshero.net/koans/roman1.html.
The exercise is to code a converter, that converts roman numbers from a string 'CDLXXXIII' to the arabic number.
I made a code with a "while loop" that works, but the website wants me to do it with a recursive function.
Heres my code:
function roman(roemische){
let romBuchstaben = ['I','IV','V','IX','X','XL','L','XC','C','CD','D','CM', 'M'];
let romZahlen = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000];
let summe = 0;
while (roemische.length > 0){
let suchzeichen = roemische[0] + roemische[1];
if (romBuchstaben.indexOf(suchzeichen) !== -1){
summe += romZahlen[romBuchstaben.indexOf(suchzeichen)];
roemische = roemische.substr(2,roemische.length-2);
} else {
summe += romZahlen[romBuchstaben.indexOf(roemische[0])];
roemische = roemische.substr(1, roemische.length-1);
}
}
return summe;
}
(I´m sorry that the var's are in german).
I´m not that familiar with recursion, could some1 give me an example, how to do it with one?
Greetings Marcel
You could change the storage of the values a bit by taking an object with roman signs as keys and decimal values.
For crating a recursive function, you could add an exit condition which is here just a check for an empty string and return zero in this case.
Then check if two character are in the object and if so take the value and add the result of calling the function again with the rest of the string.
If not take only the first character and the value and call the function again for getting the rest of the string.
function roman(number) {
const
values = { I: 1, IV: 4, V: 5, IX: 9, X: 10, XL: 40, L: 50, XC: 90, C: 100, CD: 400, D: 500, CM: 900, M: 1000 },
two = number.slice(0, 2);
if (!number) return 0;
return two in values
? values[two] + roman(number.slice(2))
: values[number[0]] + roman(number.slice(1));
}
console.log(roman('CDLXXXIII')); // 483
Related
why it is showing me 36 even though the minimum number is 27
var combination = [27, 36]
for (let x in combination) {
if (combination[x] < 50) {
var min = Math.min(combination[x])
}
}
console.log(min)
i tried this multiple ways like
var combination = [27, 30, 40, 44, 3, 239, 329, 2, 5, 20923, 96]
for (let x in combination) {
if (combination[x] < 50) {
var min = Math.min(combination[x])
}
}
console.log(min) //output-- 5 //it should be 2
in this third example i add (-) to 2
var combination = [27, 30, 40, 44, 3, 239, 329, -2, 5, 20923, 96]
for (let x in combination) {
if (combination[x] < 50) {
var min = Math.min(combination[x])
}
}
console.log(min) // output-- still 5 // it should be -2
again when am adding (-) to other numbers like in -96 or -5 the output was okay (-96) but when im adding (-) to 2 it is not showing me -2 in the output instead it showing me 5
not only in javascript i tried this with lua, php but output was same as js
can anyone explain me why this happen and how solve this
You're not comparing values to determine the minimum, but instead just replacing the min variable with the last number in the array that is smaller than 50. This can be fixed as follows:
let min = undefined;
for (let x in combination) {
if (combination[x] < 50) {
min = min == undefined ? combination[x] : Math.min(min, combination[x])
}
}
Using filter and reduce, this can be made a lot shorter:
combination.filter(x => x < 50).reduce((x, y) => Math.min(x, y))
So I'm using this function that's supposed to make a car change lanes. It will change lanes as long as I don't return the number plate return vehicleObject_list[i]. But when I return the number plate as the instructions ask, the car stops changing lanes return vehicleObject_list[i].Number_Plate. The details are below:
function moveLanes(target_car)
{
/*
This function should do the following:
- move target_car from one lane to the other.
- do the move in a single step without any extra animation.
- use Lane_Position_a and Lane_Position_b to effect the change.
- finally you should return target_car at the end of the function.
hint: You will need to modify the x property of target_car.
*/
if(checkCarInfront(target_car).x == Lane_Position_a ){
target_car.x = Lane_Position_b;
}
else {
target_car.x = Lane_Position_a;
}
}
function checkCarInfront( carObj )
{
/*
This function should do the following:
- determine if carObj is in the same lane and less than 200px behind any of the cars in vehicleObject_list.
- do this by traversing vehicleObject_list and comparing each car's Distance_Driven property to that of carObj.
- if you find a car that matches these requirements then return the Number_Plate property for the car. Otherwise return false.
*/
for (var i = 0; i < vehicleObject_list.length; i++)
{
if (carObj.x == vehicleObject_list[i].x && ((vehicleObject_list[i].Distance_Driven - carObj.Distance_Driven) < 200) && ((vehicleObject_list[i].Distance_Driven - carObj.Distance_Driven) > 0))
{
return vehicleObject_list[i].Number_Plate;
}
}
return false;
}
var vehicleObject_list = [
{ x: 500, y: 0, Distance_Driven: -200, Car_Type: 'greenCar', Number_Plate: 'MBH0WW', Gas_Amt: 2, exhaust: [ ]} , { x: 500, y: 0, Distance_Driven: 200, Car_Type: 'whiteCar', Number_Plate: 'RLDGCM', Gas_Amt: 2, exhaust: [ ]} , { x: 300, y: 0, Distance_Driven: 600, Car_Type: 'whiteCar', Number_Plate: '9WGXXI', Gas_Amt: 2, exhaust: [ ]} ]
Detective_CarObject =
{
x: roadLeftEdge + roadWidth/4,
y: 550,
Distance_Driven: 0,
Gas_Amt: 3,
EngineShudder_Value: 0,
Car_Type: 'detective',
Number_Plate: '5L3UTH',
exhaust: []
}
You could do something like:
if(checkCarInfront(target_car) && target_car.x == Lane_Position_a ){
target_car.x = Lane_Position_b;
} else {
target_car.x = Lane_Position_a;
}
because checkCarInfront(target_car) will return a number plate string if there is a match (which will evaluate to true as a non empty string). You can link the condition to the target_car object which has an .x property.
Be sure to manually test the data. (for example, with the current vehicleObject_list and Detective_CarObject values if you call checkCarInfront(Detective_CarObject) this will be false (due to Distance_Driven). You can however temporarily set Detective_CarObject's x to 500 and add an extra test car in the list to check your logic: { x: 500, y: 0, Distance_Driven: 199, Car_Type: 'rainbowCar', Number_Plate: 'R41NB0W', Gas_Amt: 2, exhaust: [ ]})
As a side note I recommend adhering to JS naming conventions. Here are a couple of examples: W3Schools, FreeCodeCamp, Google JavaScript Style Guide.
In the past I would've said choose one (e.g. underscores/snake_case (e.g. target_cat) or camelCase (e.g. checkCarInFront)) but not both and keep it consistent, but these days it seems the majority adhere to camelCase. Doing so will make it much easier to work in a team later and share/contribute to open source libraries and projects.
How do I return an image name based on an integer? I have an idea but it uses loads of if and else cases.
So here's the deal, I need a function which would return the name of an image based on an integer between 1 and 500. If the integer is between 1 and 30, I display image1 and from this point on I return a different image at 50, 75, 100, 125, 150, 175, 200, ...etc.
The first idea that comes to mind is using IFs and Elses like that:
if (number >=1 && number <= 29) {
Return image1
} else if (number >=30 && number <=49) {
Return image2
} else if... etc
But this function will become huge since I'll have around 20 If Else in order to cover all possible outcomes until number 500.
The other option is to create a JSON object with key: value pairs and get the image using the integer key like this:
returnImage(int) {
let images = {
30: 'image1',
50: 'image2',
75: 'image3'
}
return images[int]
}
Sadly I'm not sure how to make this work if the integer is 37 for example. I could obviously list all integers as keys but then the function would be even bigger than the if else function + there's gonna be a lot of repetition so that doesn't seem to work.
Any recommendations?
You can use a mathematical calculation for this:
function returnImage(i) {
let num = 1;
if (i > 30)
num = parseInt((parseInt(i / 25, 10) * 25 - 1) / 25, 10) + 2;
return 'image' + num;
}
console.log(returnImage(10));
console.log(returnImage(30));
console.log(returnImage(49));
console.log(returnImage(50));
console.log(returnImage(74));
console.log(returnImage(100));
console.log(returnImage(125));
console.log(returnImage(130));
console.log(returnImage(200));
console.log(returnImage(300));
console.log(returnImage(490));
Just loop through the keys in images.
returnImage(num){
let images= {
30: 'image1',
50: 'image2',
75: 'image3'
}
for(let image in images){
if(num <= image) return images[image];
}
}
EDIT: I would add some default image after the loop in the case that the number exceeds the max valued image.
What you need is a range.
const IMAGE_FOR_NUMBER = [
[0, 9, "one.jpg"],
[10, 19, "ten.jpg"],
[20, 100, "many.jpg"],
];
function getImage(n, notFound="not-found.jpg") {
for (const [min, max, image_name] of IMAGE_FOR_NUMBER) {
if ((min <= n) && (n <= max)) return image_name;
}
return notFound;
}
Note that it works for disjoint ranges, too
This might sound like a simple thing for you programmers out there but i can't seem to figure it out. I'm making a program that converts Decimal Numbers into Roman Numerals. I've got the core code working but i can't seem to think how i can display the results on the screen. I would like it so that when the user types a number into a text box the result appears in another text box at the press of a button. Thanks for your time & help.
function convertToRoman(num) {
var romans = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};
var result = '';
for (var key in romans) {
if (num >= romans[key]) {
result += key.repeat(Math.trunc(num / romans[key]));
num -= romans[key] * Math.trunc(num / romans[key]);
}
}
return result;
}
If you add a div element and give it an id like "output", you can do something like this.
document.getElementById("output").innerHTML = result;
You can use the trusty old alert function. Just do alert(convertToRoman(10)). Put this in a <script> tag or inside body onload attribute
For fancier more professional debugging, you can use console.log. Originating with an old Firefox addon called Firebug, it is now supported by all browsers. Simply type console.log(convertToRoman(10)); The result will be printed out to console, to see it, right click your browser, and open inspect document and move to Console tab, or alternatively, Ctrl+Shift+I in Chrome
You are missing the part where you attach the result to the html. See working code below as an example.
function convertToRoman(num) {
var romans = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1,
};
var result = '';
for (var key in romans) {
if (num >= romans[key]) {
result += key.repeat(Math.trunc(num / romans[key]));
num -= romans[key] * Math.trunc(num / romans[key]);
}
}
document.getElementById('output').innerHTML = result;
}
convertToRoman(12345);
<div> my result <span id="output"></span></div>
I am trying to subtract the value of object1's objectProperty from object2's object property and I keep getting NaN on the console. Here is example code:
object1.objectProperty - object2.object2Property
If this isn't enough to go off, I can post the full code from my project.
If there is another way to do this or some kind of function that can help, please let me know.
edit: Here is the code..
var myPokemon = {
health: 25,
defense: 5,
attack: 10,
speed: 5
};
var moves = {
Scratch: 5,
Bite: 5,
Slap: 5,
Growl: 1
};
var computerPokemon = {
health: 20,
defense: 5,
attack: 10,
speed: 7
};
function calcDamage(firstPokemon, secondPokemon, move) {
if(move == moves.Growl){
//starts here
var newDefense = moves.Growl - firstPokemon.defense;
console.log(newDefense);
//ends here
}else{
var newHealth = (firstPokemon.health + firstPokemon.defense) - (secondPokemon.attack + move);
console.log(newHealth);
}
}
edit: When I did
moves.Growl - firstPokemon.defense || 0; it returned -4 instead of NaN which is what I wanted it to do, but the person that answered that removed the answer so this has been answered by whoever that guy was.
The problem is that you are adding the object in the second argument. Also your if statement will never execute, I have fixed both as following
var myPokemon = {
health: 25,
defense: 5,
attack: 10,
speed: 5
};
var moves = {
Scratch: 5,
Bite: 5,
Slap: 5,
Growl: 1
};
var computerPokemon = {
health: 20,
defense: 5,
attack: 10,
speed: 7
};
function calcDamage(firstPokemon, secondPokemon, move) {
if(moves.Growl!=undefined){
//starts here
var newDefense = moves.Growl - firstPokemon.defense;
alert(newDefense);
//ends here
}else{
var newHealth = (Number(firstPokemon.health) + Number(firstPokemon.defense)) - (Number(secondPokemon.attack) + Number(move.Growl));
alert(newHealth);
}
}
calcDamage(myPokemon,computerPokemon,moves)
Usually, if you are getting NaN, you are probably working with other elements but numbers. Are you sure they both are numbers?
Just an example:
var x = {}, y = {};
x.r = 10;
y.r = 5;
x.r - y.r; // yields 5
Use parseInt to convert the values into integer and then do the math.
var value = parseInt(object1.objectProperty,10) - parseInt(object2.object2Property,10);
The Problem is here
var newHealth = (Number(firstPokemon.health) + Number(firstPokemon.defense)) - (Number(secondPokemon.attack) + Number(move.Growl));
The last one Number(move.Growl) it should be Number(moves.Growl) moves not move. In your case move is just a number and you are trying Number(move.Growl) which will be NaN and hence your getting NaN.