Hello I am doing the leetcode problem in C++ called Interger to Roman and here is my following code:
class Solution {
public:
string intToRoman(int num) {
map<char,int> mp ={
{'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}
};
string roman = "";
//iterating from the bottom of the map
for(auto it= mp.rbegin(); it!= mp.rend(); it++){
char ch = it->first;
int val = it->second;
if((num/val) > 0){
//this is giving us how many times the string/char of the roman
//will be used
int count = num/val;
string to_add(count,ch);
roman = roman + to_add;
num = num%val;
}
}
return roman;
}
};
I would really appreicitate if you could tell me what is wrong with the code. It passes for the value 3 but fails for eg. 58
a better approach is to accualy emulate what roman numbers are formed:
1-3 -> add 1 (same group)
4 -> sub 1 form 5 (next group - current group)
5-8 -> add 1 at 5 and so on
try to figure out a pattern (btw its always 1 added to prev catttergory) so a recursive function will work? or make a calculator for adding 1 until the number is done
New to C++. I am looking for advise on the approach to this problem.
Given the following array:
Array A
1 21 43 54 99
Array B
1 4 5
What I want to achieve:
Array B integer is use to find the position of the value in array A. The end result, using the above two array, will be
End result
1 54 99
Where array B 1 will extract 1 from array A, array B 4 will extract out 54 from array A and so on. How should I approach this problem?
So you can iterate over arrB and get the desired values by doing the following:
#include <iostream>
int main(){
int arrA[] = {1, 21, 43, 54, 99};
int arrB[] = {1, 4, 5};
// iterating over arrB
for (int i = 0; i < 3; ++i)
std::cout << arrA[arrB[i] - 1] << ' ';
return 0;
}
Output :
1 54 99
Note :
Don't forget to add the required conditions (ensure accessing array within bounds) to escape from the undefined behavior.
I'm quite new to BLAS (using OpenBLAS with C++ and VisualStudio)
I know dgemm performs C <- alpha * op(A) * op(B) + beta * C
I was trying to save some allocation doing this: B <- 1 * op(A) * op(B) + 0 * B
In other words, putting the result in the B matrix,
BUT making beta = 0 and repeating B in the position of C, results in a zero answer.
Is there a way to make it right?
The code that I'm using:
double* A = new double [3*3]; //3 rows x 3 columns
A[0] = 8;
A[1] = 3;
A[2] = 4;
A[3] = 1;
A[4] = 5;
A[5] = 9;
A[6] = 6;
A[7] = 7;
A[8] = 2;
double* v = new double[3]; //3 rows x 1 column
v[0] = 3;
v[1] = 5;
v[2] = 2;
double* foo = new double[3]; //3 rows x 1 column
cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans,
3, 1, 3,
1,
A, 3,
v, 3,
0,
foo, 3); // makes foo = [41 ; 48 ; 61], **right**
cblas_dgemm(CblasColMajor, CblasTrans, CblasTrans,
3, 1, 3,
1,
A, 3,
v, 3,
0,
v, 3); // makes v = [0 ; 0 ; 0], **wrong**
BLAS dgemm function documentation states that only the C matrix parameter is for both input and output, being overwritten by the operation result. As B is defined just for input, BLAS implementations can assume that it shouldn't be modified.
Setting B and C to the same data pointer could be triggering some error verification on the implementation you're using, returning the zeroed result to indicate that.
I'm making a card shuffling function for the card game. I created an array of Card objects. Then I tried to rearrange the objects in the array using random_shuffle. But it doesn't work.
char faces[13] = { '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' };
char suits[4] = { char(3), char(4), char(5), char(6) };
int values[13] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11 };
Card** deck = new Card*[52];
for (int row = 0; row <= 3; row++)
{
for (int column = 0; column <= 12; column++)
{
deck[Card::getCounter()] = new Card(suits[row], faces[column], values[column], true);
}
}
int size = sizeof(deck) / sizeof(deck[0]);
random_shuffle(*deck, *deck + size);
I mean, if I check with cout, like
cout << deck[0]->getFace()<< deck[0]->getSuit() << endl;
it shows 2(heart), like it was before using random_shuffle
The problem with your code is that operator size returns the size of a pointer (8 on a 64-bit machine) rather than the size of the array it points to. As a consequence, the expression
sizeof(deck) / sizeof(deck[0])
returns 1, and you only shuffle a single value, which means you don't shuffle.
The solution can be:
use the explicit size of the array
random_shuffle(*deck, *deck + 52);
Better, define
const int NUM_OF_CARD_IN_DECK= 52
and use it anywhere you need it
Better still, use an std::vector
I'm sure this is pretty simple, but I'm stumped for a way to do this. Essentially if I have an array with P collumns and V^P rows, how can I fill in all the combinations, that is, essentially, all possible numbers in base V of P digits. For example, for P=3 and V=2:
000
001
010
011
100
101
110
111
Keep in mind that this is an 2 dimensional array, not an array of ints.
For P=4 and V=3.
0000
0001
0002
0010
0011
0012
....
Having this array generated, the rest of work for what I'm trying to devolop is trivial. So having some code/tips on how to do this would be greatly appreciated. Thanks.
Taking your example with P=3 and V=2, in the first column you need this sequence of numbers:
0, 0, 0, 0, 1, 1, 1, 1
So you essentially want four 0's followed by four 1's.
In the second column you need:
0, 0, 1, 1, 0, 0, 1, 1
So you want two 0's followed by two 1's, followed by the same again.
In general, in column number n, you need V^(P-n) of each digit, repeated V^(n-1) times.
Example when P=3 and V=2:
Column 1: We need V^(P-n) = 2^(3-1) = 4 of each digit, repeated V^(n-1) = 2^0 = 1 times:
[0, 0, 0, 0, 1, 1, 1, 1]
Column 2: We need V^(P-n) = 2^(3-2) = 2 of each digit, repeated V^(n-1) = 2^1 = 2 times:
[0, 0, 1, 1], [0, 0, 1, 1]
Column 3: We need V^(P-n) = 2^(3-3) = 1 of each digit, repeated V^(n-1) = 2^2 = 4 times:
[0, 1], [0, 1], [0, 1], [0, 1]
Some Python code that generates this sequence:
def sequence(v, p, column):
subsequence = []
for i in range(v):
subsequence += [i] * v**(p - column)
return subsequence * v**(column - 1)
Basically this is making a list of vp numbers from 0 to the largest number of digit width p in base v. numpy.base_repr can be used to do this in Python:
from numpy import base_repr
def base_of_size(base, size):
for i in range(base ** size):
yield base_repr(i, base).rjust(size, "0")
Additionally, itertools.product(range(v), repeat=p) is another Python builtin that does the job (it turns out most efficiently--see benchmark below).
Here's the algorithm from numpy.base_repr translated to C# (Convert.ToString() is very selective about bases):
using System;
using System.Collections.Generic;
class Converter
{
public static IEnumerable<string> BaseOfSize(int baseN, int size)
{
for (int i = 0; i < Math.Pow(baseN, size); i++)
{
yield return BaseRepr(i, baseN).PadLeft(size, '0');
}
}
public static string BaseRepr(int n, int baseN)
{
string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var res = new List<char>();
for (int num = Math.Abs(n); num > 0; num /= baseN)
{
res.Add(digits[num%baseN]);
}
if (n < 0) res.Add('-');
res.Reverse();
return string.Join("", res);
}
public static void Main(string[] args)
{
foreach (var n in BaseOfSize(2, 3))
{
Console.WriteLine(n);
}
Console.WriteLine();
foreach (var n in BaseOfSize(3, 4))
{
Console.WriteLine(n);
}
}
}
Output:
000
001
010
011
100
101
110
111
0000
0001
0002
0010
0011
0012
0020
...
2220
2221
2222
Although the numpy version is simple to use and iterative, it's also slow. Using a recursive DFS approach means we don't have to compute each number from scratch, but can simply increment the previous number until we reach a new leaf. These versions don't use generators, but it's an easy adjustment:
Python:
def base_of_size(base, size):
def recurse(res, row, i=0):
if i >= size:
res.append(row[:])
else:
for j in range(base):
row[i] = j
recurse(res, row, i + 1)
return res
return recurse([], [None] * size)
C#:
using System;
using System.Collections.Generic;
class Converter
{
public static List<List<int>> BaseOfSize(int v, int p)
{
var res = new List<List<int>>();
BaseOfSize(v, p, 0, new List<int>(new int[p]), res);
return res;
}
private static void BaseOfSize(int v, int p, int i, List<int> row, List<List<int>> res)
{
if (i >= p)
{
res.Add(new List<int>(row));
}
else
{
for (int j = 0; j < v; j++)
{
row[i] = j;
BaseOfSize(v, p, i + 1, row, res);
}
}
}
}
Quick benchmark (with generators):
from itertools import product
from time import time
from numpy import base_repr
def base_of_size(base, size):
def recurse(res, row, i=0):
if i >= size:
yield row[:]
else:
for j in range(base):
row[i] = j
yield from recurse(res, row, i + 1)
return res
yield from recurse([], [None] * size)
def base_of_size2(base, size):
for i in range(base ** size):
yield base_repr(i, base).rjust(size, "0")
if __name__ == "__main__":
start = time()
list(base_of_size(10, 6))
end = time()
print("dfs:", end - start)
start = time()
list(base_of_size2(10, 6))
end = time()
print("base_repr:", end - start)
start = time()
list(product(range(10), repeat=6))
end = time()
print("product:", end - start)
Output:
dfs: 4.616123676300049
base_repr: 9.795292377471924
product: 0.5925478935241699
itertools.product wins by a long shot.
If there is varying number of options in each "digit", this code can be used.
Maybe in some optimization tool there exist algorithm to do this, because it could be useful for brute force method. Code below adds a column which shows "the value of biggest digit", it can be ignored:
import numpy as np
val=np.arange(15)
options=[2,2,3]
print(val)
print(options)
opt = options + [1] # Assumes options to be a list
opt_cp = np.flip(np.cumprod(np.flip(np.array(opt))))
ret = np.floor_divide(val[:,np.newaxis], opt_cp[np.newaxis,:])
ret[:,1:] = np.remainder(ret[:,1:], np.array(opt[:-1])[np.newaxis,:])
inds = ret[:,1:]
print(inds)
You could also use numpy's N-dimensional mesh grid functions.
E.g.
np.mgrid[0:2,0:2,0:2].reshape((3, 8)).T
array([[0, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 1, 1],
[1, 0, 0],
[1, 0, 1],
[1, 1, 0],
[1, 1, 1]])
or
np.stack(np.meshgrid(range(2), range(2), range(2), indexing='ij')).reshape(3, -1).T
or in general for any P, V:
np.mgrid[[slice(0, V)]*P].reshape((P, -1)).T
or
np.stack(np.meshgrid(*[range(V)]*P, indexing='ij')).reshape((P, -1)).T
There must be a more obvious way but I can't think what.