Find the threshold value - c#

(FF14:RR) This item can have 5 materias, 1 highlevel, 4 lowlevel.
I simplified the loops by having 3 types of materias (but i have 6, anw).
I put the materia in an item and then call Group.GetStats() to evaluate the statistics of the item then i store it in a List first checking its unicity.
Calling Group.GetStats() gives me a Dictionary with 3 caracteristics. And i want to filter the number of possibilities based on those statistics.
Example :
Stat1 - Stat2 - Stat3
(9, 7, 5)
(3, 10, 5)
(9, 7, 6)
(8, 6, 4)
(7, 6, 8)
(7, 7, 7) <-
(7, 7, 6)
(6, 6, 5)
(7, 6, 7)
All the tuples under (7, 7, 7) are useless because adding nothing more.
I already ended the algorithm to get all the possible materia combinations but i want to filter the combinations that are not useful.
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 3; j++)
{
for (int k = j; k < 3; k++)
{
for (int l = k; l < 3; l++)
{
for (int m = l; m < 3; m++)
{
ItemContainer Group = new ItemContainer(735, 400, 0, 1, 4, 864, 471, 6, new string[] { "Facet Alembic", "Facet Mortar" });
Group.AddMateria(new Materia(i >= 3 ? i-3 : i));
Group.AddMateria(new Materia(j));
Group.AddMateria(new Materia(k));
Group.AddMateria(new Materia(l));
Group.AddMateria(new Materia(m));
if (DEBUG) Console.WriteLine("{" + string.Join(",", Group.GetStats()) + "}");
string tempkey = string.Join(",", Group.GetStats());
if (i >= 3)
{
if (!unicityChecker.ContainsKey(tempkey))
{
if (isAnyBetter(Group.GetStats(),betterChecker.GetStats())) // Condition to keep it
{
ContainerList_1.Add(Group);
unicityChecker.Add(tempkey, Group.GetStats());
}
}
}
else
{
/*
find the betterChecker in order to do isAnyBetter to only get the useful items
*/
if (betterChecker == null) betterChecker = Group;
else
{
if (isAllBetter(Group.GetStats(), betterChecker.GetStats())) betterChecker = Group;
}
}
}
}
}
}
}
The i < 6 sounds weird but this way i made 2 passes on the same generation of combinations.
In output of the entire algorithm (that embricks 7 of this one) i have about 10M records. I thought by removing the useless items at the first generation i could lower the size of the ouput (1Gb in json).
EDIT :
static bool isAnyBetter(Dictionary<String, int> stats1, Dictionary<String, int> stats2)
{
return stats1["craftmanship"] > stats2["craftmanship"] || stats1["control"] > stats2["control"] || stats1["cp"] > stats2["cp"];
}

Related

Pair Sum problem - c# code doesn't produce expected output-- please assist

public static int FindMaxNumForMaxSum(int[] nums, int k)
{
int retVal = 0;
int N = nums.Length;
var counter = 1;
var map = new Dictionary<int, int>();
for (var i = 0; i < N; i++)
{
if (nums[i] == retVal)
{
counter++;
continue;
}
var complement = k - nums[i];
retVal = complement;
if (nums[i] == complement)
{
if (!map.ContainsKey(complement))
{
map.Add(complement, counter);
}
else
{
map[complement] = counter++;
}
}
else
{
map.Add(complement, counter);
}
}
return counter;
}
Above is my code.
Problem description below:
Given a list of n integers arr[0..(n-1)], determine the number of different pairs of elements within it which sum to k.
If an integer appears in the list multiple times, each copy is considered to be different; that is, two pairs are considered different if one pair includes at least one array index which the other doesn't, even if they include the same values.
The above solution doesn't see to produce expected output and also there is a problem of adding duplicate keys in a dictionary.
Example 1
n = 5
k = 6
arr = [1, 2, 3, 4, 3]
output = 2
The valid pairs are 2+4 and 3+3.
Example 2
n = 5
k = 6
arr = [1, 5, 3, 3, 3]
output = 4
Example 3
arr = [2, 3, 6, 7, 4, 5, 1]
output = 3

Fill a multidimensional array with pairs of ordered values

I have to present 16 financial products in a 4x4 matrix on a website. The matrix replaces the representation of a scatter graph, where the returns of the product are represented in the X axis and the risk in the Y (they are simply pairs of values), so the product in the lowest left place are the one with the minor risk and the minor returns and the ones in the top right are the ones with the major risk and the major return.
To reach this result, I thought of putting the products in a multidimensional 4x4 array, but I don't know how to sort the pairs of values correctly.
I tried some sorting methods but nobody gave me the required result.
Here is an Exammple of what I want to obtain:
Taking this sixteen couple of values:
(3,5)-(2,8)-(7,3)-(4,9)-(3,2)-(4,10)-(6,2)-(1,4)-(5,2)-(8,9)-(7,11)-(10,12)-(3,11)-(5,10)-(2,16)-(9,15)
I would like to show it in the matrix in this order
Y
^
|(7,3)(8,9)(10,12)(9,15)
|(5,2)(6,2)(5,10)(7,11)
|(3,2)(3,5)(4,9)(4,10)
|(1,4)(2,8)(3,11)(2,16)
|_____________________>X
I'm adding another answer because the first one and its comments are before you added an example and that answer was way off.
Your example is helpful. It looks like the first value in your pair is Y and the second is X? If so, that's opposite normal convention.
It seems your unspoken rules for arrangement are to arrange the pairs in such a way that the Y (left) values are increasing upward in each column, and the X (right) values are increasing rightward in each row. Importantly, it seems for Y values the columns are otherwise independent, and for the X values the rows are otherwise independent. Independent meaning you don't care about absolute placement from position to position. Like for Y, you don't care that a 3 in the third column is lower than the 3 in the first column.
But these rules will still produce multiple valid result sets. For example, in your example, (7,3) and (6,2) can be swapped and the rules as outlined above still apply.
If these unspoken rules are correct, try this broad approach:
(1) Put the list into a matrix, (2) sort all of the columns, (3) sort all of the rows, (4) repeat sorting columns and rows a few times.
Here is some code to illustrate this. Because this is just a 4x4 matrix, efficiency isn't important.
public static void Main()
{
Tuple<int,int>[] pairs = {
Tuple.Create(3, 5),
Tuple.Create(2, 8),
Tuple.Create(7, 3),
Tuple.Create(4, 9),
Tuple.Create(3, 2),
Tuple.Create(4, 10),
Tuple.Create(6, 2),
Tuple.Create(1, 4),
Tuple.Create(5, 2),
Tuple.Create(8, 9),
Tuple.Create(7, 11),
Tuple.Create(10, 12),
Tuple.Create(3, 11),
Tuple.Create(5, 10),
Tuple.Create(2, 16),
Tuple.Create(9, 15)
};
var matrix = load(pairs); //Put data into a 4x4 matrix, order doesn't matter
Console.WriteLine("Original input:");
print(matrix);
matrix = sort(matrix);
Console.WriteLine("Ordered output:");
print(matrix);
}
private static Tuple<int,int>[,] load(Tuple<int,int>[] pairs) {
var rv = new Tuple<int, int>[4, 4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
rv[i, j] = pairs[i * 4 + j];
}
}
return rv;
}
private static Tuple<int, int>[, ] sort(Tuple<int, int>[,] matrix) {
var rv = matrix;
for (int i = 0; i < 4; i++) {
rv = orderCols(rv);
rv = orderRows(rv);
}
return rv;
}
private static Tuple<int,int>[,] orderCols(Tuple<int,int>[,] matrix) {
for (int c = 0; c < 4; c++) {
//Convert column to 1D array, sort it, then apply it back
Tuple<int, int>[] a = new Tuple<int, int>[4];
for (int r = 0; r < 4; r++) a[r] = matrix[r, c];
a = a.OrderByDescending(t => t.Item1).ToArray();
for (int r = 0; r < 4; r++) matrix[r, c] = a[r];
}
return matrix;
}
private static Tuple<int,int>[,] orderRows(Tuple<int,int>[,] matrix) {
for (int r = 0; r < 4; r++) {
//Convert row to 1D array, sort it, then apply it back
Tuple<int, int>[] a = new Tuple<int, int>[4];
for (int c = 0; c < 4; c++) a[c] = matrix[r, c];
a = a.OrderBy(t => t.Item2).ToArray();
for (int c = 0; c < 4; c++) matrix[r, c] = a[c];
}
return matrix;
}
private static void print(Tuple<int, int>[,] matrix) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++)
Console.Write(writeTuple(matrix[i, j]));
Console.WriteLine();
}
Console.WriteLine();
}
private static string writeTuple(Tuple<int, int> t) {
var a = t.Item1.ToString().PadLeft(2, ' ');
var b = t.Item2.ToString().PadLeft(2, ' ');
return String.Format("({0}, {1}) ", a, b);
}
Output:
Original input:
( 3, 5) ( 2, 8) ( 7, 3) ( 4, 9)
( 3, 2) ( 4, 10) ( 6, 2) ( 1, 4)
( 5, 2) ( 8, 9) ( 7, 11) (10, 12)
( 3, 11) ( 5, 10) ( 2, 16) ( 9, 15)
Ordered output:
( 6, 2) ( 7, 3) ( 8, 9) (10, 12)
( 5, 2) ( 4, 9) ( 7, 11) ( 9, 15)
( 3, 2) ( 3, 5) ( 5, 10) ( 4, 10)
( 1, 4) ( 2, 8) ( 3, 11) ( 2, 16)
As you can see, the output does not match your example output exactly, but it is valid per the rules you seem to want. Depending on the ordering of the input, the output will be different because there are multiple valid result sets. If I'm wrong in any assumptions, let me know.
Unless I misunderstand your problem, it seems to me you need to sort your collection linearly (1-dimensional), and then present it (2-dimensional). There's a distinction between data storage and data presentation. Here's what I came up with:
//Sample data to work with
var products = new List<KeyValuePair<string, int>>();
products.Add(new KeyValuePair<string, int>("A", 12));
products.Add(new KeyValuePair<string, int>("B", 23));
products.Add(new KeyValuePair<string, int>("C", 62));
products.Add(new KeyValuePair<string, int>("D", 17));
products.Add(new KeyValuePair<string, int>("E", 11));
products.Add(new KeyValuePair<string, int>("F", 75));
products.Add(new KeyValuePair<string, int>("G", 95));
products.Add(new KeyValuePair<string, int>("H", 24));
products.Add(new KeyValuePair<string, int>("I", 85));
products.Add(new KeyValuePair<string, int>("J", 41));
products.Add(new KeyValuePair<string, int>("K", 76));
products.Add(new KeyValuePair<string, int>("L", 77));
products.Add(new KeyValuePair<string, int>("M", 33));
products.Add(new KeyValuePair<string, int>("N", 81));
products.Add(new KeyValuePair<string, int>("O", 34));
products.Add(new KeyValuePair<string, int>("P", 45));
//Sort the collection
List<KeyValuePair<string, int>> ordered = products.OrderBy(x => x.Value).ToList();
//Put linear results into 2D array (4x4)
var matrix = new KeyValuePair<string, int>[4,4];
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
matrix[i, j] = ordered[i * 4 + j];
//Write out results
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
var c = ordered[i * 4 + j];
Console.Write(c.Key + ": " + c.Value.ToString() + " ");
}
Console.WriteLine();
}
Output:
E: 11 A: 12 D: 17 B: 23
H: 24 M: 33 O: 34 J: 41
P: 45 C: 62 F: 75 K: 76
L: 77 N: 81 I: 85 G: 95

Add Int[] array into List<int[]>

I'm having trouble with int[] arrays and adding them to a List<>. I'd like to add the values of my int[] array to something each loop but every time I do this my "something" gets the same value for every element I add. Very annoying. I understand arrays are always reference vars. However even the "new" key word doesn't seem to help. What needs to happen is to add result to some enumerated object like a List or Array or ArrayList.
Here's the codility question:
You are given N counters, initially set to 0, and you have two possible operations on them:
increase(X) − counter X is increased by 1,
max_counter − all counters are set to the maximum value of any counter.
A non-empty zero-indexed array A of M integers is given. This array represents consecutive operations:
if A[K] = X, such that 1 ≤ X ≤ N, then operation K is increase(X),
if A[K] = N + 1 then operation K is max_counter.
For example, given integer N = 5 and array A such that:
A[0] = 3
A[1] = 4
A[2] = 4
A[3] = 6
A[4] = 1
A[5] = 4
A[6] = 4
the values of the counters after each consecutive operation will be:
(0, 0, 1, 0, 0)
(0, 0, 1, 1, 0)
(0, 0, 1, 2, 0)
(2, 2, 2, 2, 2)
(3, 2, 2, 2, 2)
(3, 2, 2, 3, 2)
(3, 2, 2, 4, 2)
The goal is to calculate the value of every counter after all operations.
I copied some code from others and the variable "result" does indeed load the data correctly. I just wanted to copy it back to the main program so I could see it. The only method that works is += add it into a string. Thus losing any efficiency I might have gained.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testarray
{
class Program
{
static void Main(string[] args)
{
int[] A = new int[7];
A[0] = 3;
A[1] = 4;
A[2] = 4;
A[3] = 6;
A[4] = 1;
A[5] = 4;
A[6] = 4;
List<int[]> finish = solution(5, A);
}
public static List<int[]> solution(int N, int[] A)
{
int[] result = new int[N];
int maximum = 0;
int resetlimit = 0;
int iter = 0;
List<int[]> collected_result = new List<int[]>;
for (int K = 0; K < A.Length; K++)
{
if (A[K] < 1 || A[K] > N + 1)
{
throw new InvalidOperationException();
}
if (A[K] >= 1 && A[K] <= N)
{
if (result[A[K] - 1] < resetlimit)
{
result[A[K] - 1] = resetlimit + 1;
}
else
{
result[A[K] - 1]++;
}
if (result[A[K] - 1] > maximum)
{
maximum = result[A[K] - 1];
}
}
else
{
resetlimit = maximum;
result = Enumerable.Repeat(maximum, result.Length).ToArray<int>();
}
collected_result.Add(result);
}
// for (int i = 0; i < result.Length; i++)
//result[i] = Math.max(resetLimit, result[i]);
return collected_result;
}
}
}
This doesn't work, the collected_result ends up like:
(0,0,1,2,0)
(0,0,1,2,0)
(0,0,1,2,0)
(3,2,2,4,2)
(3,2,2,4,2)
(3,2,2,4,2)
(3,2,2,4,2)
I know it's the line collected_result.Add(result); adding the reference each time to every instance of result in the List<>. Bother. I've tried adding "new" which is a compiler error. Finally in desperation I just added everything to a very long string. Can someone help me figure out how to properly load an object to pass back to main?
Easiest way to go:
Get a copy of your array before adding it to list:
collected_result.Add(result.ToArray());
Here is a Python solution:
def solution(A, N):
lenA = len(A)
k = 0
max_counter_value = 0
counters = [0 for x in range(0, N)]
for k in range(0, lenA):
if A[k] >= 1 and A[k] <= N:
counters[A[k] - 1] += 1
max_counter_value = max(counters)
if A[k] == N + 1:
counters = [max_counter_value for x in range(0, N)]
print counters
A = [3, 4, 4, 6, 1, 4, 4]
N = 5
solution(A, N)

Finding Consecutive repetition of Elements in C# Array and Altering the element

I was given this problem
Given an int array length 3, if there is a 2 in the array immediately followed by a 3,
set the 3 element to 0.
For Example ({1, 2, 3}) → {1, 2, 0}
({2, 3, 5}) → {2, 0, 5}
({1, 2, 1}) → {1, 2, 1}
And this is my implementation.
int[] x = { 1, 2, 1 };
for (int i = 0; i < x.Length; i++)
{
if (x[i] == 2 && x[i + 1] == 3)
{
for (int j = 0; j < x.Length; j++)
{
if (x[j]==3)
{
x[j] = 0;
}
}
}
}
foreach (int i in x)
{
Console.Write(i);
}
I got zero as result. Can you help me to find where I am at mistake. I can't figure it out because the lecturer didn't gave any explanation in details.
You do not need all these loops: with the length of 3, you need to perform only two checks, like this:
if (x[0]==2 && x[1]==3) x[1] = 0;
if (x[1]==2 && x[2]==3) x[2] = 0;
For arrays of arbitrary size, you could use a single loop:
for (var i = 0 ; i < x.Length-1 ; i++) {
if (x[i]==2 && x[i+1]==3) x[i+1] = 0;
}
In your code, you have a proper check: if (x[i] == 2 && x[i + 1] == 3) However, there are 2 things you could improve on.
1) If you're going to do x[i + 1] you need to make sure that i can never be the last element of the array, because the + 1 will overflow the array. So instead of i < x.Length in the for loop, try i < x.Length - 1. It seems like duct taping, but there isn't really a better way (none I know of).
2) If the condition is true, you then have a for that will find and replace EVERY 3 in the array with a 0, regardless of if the 3 is preceded by a 2. You already know that x[i] is 2 and x[i + 1] is 3 (as determined by the if that we know at this point must be true), so the index of the 3 to be replaced is i + 1, thus: x[i + 1] = 0; No loop needed.
You can do it with one loop.
// In the test part of the for loop, use ' i < x.Length - 1'
// so you don't evaluate the last element + 1 and get an IndexOutOfRangeException
for (int i = 0; i < x.Length - 1; i++)
{
if (x[i] == 2 && x[i + 1] == 3)
x[i + 1] = 0;
}

Printing out 3 elements in array per line

I have an array with x number of elements and want to print out three elements per line (with a for-loop).
Example:
123 343 3434
342 3455 13355
3444 534 2455
I guess i could use %, but I just can't figure out how to do it.
For loop is more suitable:
var array = Enumerable.Range(0, 11).ToArray();
for (int i = 0; i < array.Length; i++)
{
Console.Write("{0,-5}", array[i]);
if (i % 3 == 2)
Console.WriteLine();
}
Outputs:
0 1 2
3 4 5
6 7 8
9 10
Loop through the array 3 at a time and use String.Format().
This should do it...
for (int i = 0; i < array.Length; i += 3)
Console.WriteLine(String.Format("{0,6} {1,6} {2,6}", array[i], array[i + 1], array[i + 2]));
But if the number of items in the array is not divisable by 3, you'll have to add some logic to make sure you don't go out of bounds on the final loop.
You perhaps need to fix the format spacing...
for(int i=0;i<array.Length;i++)
{
Console.Write(array[i] + " ");
if((i+1)%3==0)
Console.WriteLine();
}
Long... but with comments:
List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int count = list.Count;
int numGroups = list.Count / 3 + ((list.Count % 3 == 0) ? 0 : 1); // A partially-filled group is still a group!
for (int i = 0; i < numGroups; i++)
{
int counterBase = i * 3;
string s = list[counterBase].ToString(); // if this a partially filled group, the first element must be here...
if (counterBase + 1 < count) // but the second...
s += list[counterBase + 1].ToString(", 0");
if (counterBase + 2 < count) // and third elements may not.
s += list[counterBase + 2].ToString(", 0");
Console.WriteLine(s);
}

Categories

Resources