Hi my task is to recursively create an expression tree from a List input.
ex. ("+", 2, 3)
"+"
/ \
2 3
I know my recursion is off, but I can't figure out how to make it work. I've been at it for longer than I'm proud to admit. Any insight is appreciated! This is what I have so
fun TreeBuild(input:List<Any>): Pair<Tree, List<Any>>{
var tree = Tree(input.get(0), Unit, Unit)
var list = input
System.out.println(list)
if(input.size == 1 ){
list = list.drop(1)
return Pair(Tree(input.get(0), Unit, Unit), list)
}
var flag: Boolean = (input.get(0) is Int)
if (!flag){
list = list.drop(1)
tree.left = TreeBuild(list).first
list = list.drop(1)
tree.right = TreeBuild(list).first
}
return Pair(tree, list)
}
Related
I have the following object:
local Game = {}
function Game:new(aNumberOfPlayers, aPlayer1, aPlayer2)
self.NumberOfPlayers = aNumberOfPlayers
self.Player1 = aPlayer1
self.Player2 = aPlayer2
self.Id = HttpService:GenerateGUID(true)
self.Status = "Waiting"
self.Moves = {}
self.Position = GetInitialGamePosition()
return self
end
local Square = {}
function Square:new(x, y, index, color)
self.X = x
self.Y = y
self.Index = index
self.Color = color
return self
end
That uses following function to intialize the 2d array for Position
function GetInitialGamePosition()
local mt = {} -- create the matrix
for i=1,15 do
mt[i] = {}
for j=1,15 do
mt[i][j] = Square:new(i,j,GetIndexFromRowColumn(i,j),nil)
end
end
return mt
end
Problem here is that since tables pass by reference each element of the 2d array ends up being the same. In other words when i iterate over a Position every element has same row, column, and index. Not sure what the best way to get around this is?
function Square:new(x, y, index, color)
local o = {}
o.X = x
o.Y = y
o.Index = index
o.Color = color
setmetatable(o, self)
self.__index = self
return o
end
I know that you can use tables in a similar way to pointers in lua. That being said, what would pointers to pointers look like? Would they look something like dp = {p = {}}? if so what would the equivalent to the c code below be in lua?
void InsertItem(node **head, node *newp){
node **dp = head;
while((*dp) && (*dp)->value > newp->value
{
dp = &(*dp)->next;
}
newp->next = *dp;
*dp = newp;
}
Yes, double pointer may be translated to Lua as nested table.
local function InsertItem(head, newitem)
while head.next and head.next.value > newitem.value do
head = head.next
end
newitem.next = head.next
head.next = newitem
end
-- Typical Usage:
local head = {}
InsertItem(head, {value = 3.14})
InsertItem(head, {value = 42})
InsertItem(head, {value = 1})
-- Now the data is the following:
-- head = {next = elem1}
-- elem1 = {next = elem2, value = 42 }
-- elem2 = {next = elem3, value = 3.14}
-- elem3 = { value = 1 }
The big difference between C pointers and Lua tables is that in C, you can take the address of a variable and pass it to a function to modify it. You can't do that in Lua, but the function could always return the modified value.
Would they look something like dp = {p = {}}?
Yes, that's about as close as close as you can get to a pointer to a pointer in Lua.
if so what would the equivalent to the c code below be in lua?
Linked lists tend to work more smoothly with recursion:
local function InsertItem(head, newp)
if not head or head.value <= newp.value then
newp.next = head
return newp
end
head.next = InsertItem(head.next, newp)
return head
end
What is the efficient way to convert an array of pixelValues [UInt8] into two dimensional array of pixelValues rows - [[UInt8]]
You can write something like this:
var pixels: [UInt8] = [0,1,2,3, 4,5,6,7, 8,9,10,11, 12,13,14,15]
let bytesPerRow = 4
assert(pixels.count % bytesPerRow == 0)
let pixels2d: [[UInt8]] = stride(from: 0, to: pixels.count, by: bytesPerRow).map {
Array(pixels[$0..<$0+bytesPerRow])
}
But with the value semantics of Swift Arrays, all attempt to create new nested Array requires copying the content, so may not be "efficient" enough for your purpose.
Re-consider if you really need such nested Array.
This should work
private func convert1Dto2DArray(oneDArray:[String], stringsPerRow:Int)->[[String]]?{
var target = oneDArray
var outOfIndexArray:[String] = [String]()
let reminder = oneDArray.count % stringsPerRow
if reminder > 0 && reminder <= stringsPerRow{
let suffix = oneDArray.suffix(reminder)
let list = oneDArray.prefix(oneDArray.count - reminder)
target = Array(list)
outOfIndexArray = Array(suffix)
}
var array2D: [[String]] = stride(from: 0, to: target.count, by: stringsPerRow).map {
Array(target[$0..<$0+stringsPerRow])}
if !outOfIndexArray.isEmpty{
array2D.append(outOfIndexArray)
}
return array2D
}
For example I have a list of strings like:
val list = listOf("a", "b", "c", "d")
and I want to convert it to a map, where the strings are the keys.
I know I should use the .toMap() function, but I don't know how, and I haven't seen any examples of it.
You have two choices:
The first and most performant is to use associateBy function that takes two lambdas for generating the key and value, and inlines the creation of the map:
val map = friends.associateBy({it.facebookId}, {it.points})
The second, less performant, is to use the standard map function to create a list of Pair which can be used by toMap to generate the final map:
val map = friends.map { it.facebookId to it.points }.toMap()
From List to Map with associate function
With Kotlin 1.3, List has a function called associate. associate has the following declaration:
fun <T, K, V> Iterable<T>.associate(transform: (T) -> Pair<K, V>): Map<K, V>
Returns a Map containing key-value pairs provided by transform function applied to elements of the given collection.
Usage:
class Person(val name: String, val id: Int)
fun main() {
val friends = listOf(Person("Sue Helen", 1), Person("JR", 2), Person("Pamela", 3))
val map = friends.associate({ Pair(it.id, it.name) })
//val map = friends.associate({ it.id to it.name }) // also works
println(map) // prints: {1=Sue Helen, 2=JR, 3=Pamela}
}
From List to Map with associateBy function
With Kotlin, List has a function called associateBy. associateBy has the following declaration:
fun <T, K, V> Iterable<T>.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map<K, V>
Returns a Map containing the values provided by valueTransform and indexed by keySelector functions applied to elements of the given collection.
Usage:
class Person(val name: String, val id: Int)
fun main() {
val friends = listOf(Person("Sue Helen", 1), Person("JR", 2), Person("Pamela", 3))
val map = friends.associateBy(keySelector = { person -> person.id }, valueTransform = { person -> person.name })
//val map = friends.associateBy({ it.id }, { it.name }) // also works
println(map) // prints: {1=Sue Helen, 2=JR, 3=Pamela}
}
If you have duplicates in your list that you don't want to lose, you can do this using groupBy.
Otherwise, like everyone else said, use associate/By/With (which in the case of duplicates, I believe, will only return the last value with that key).
An example grouping a list of people by age:
class Person(val name: String, val age: Int)
fun main() {
val people = listOf(Person("Sue Helen", 31), Person("JR", 25), Person("Pamela", 31))
val duplicatesKept = people.groupBy { it.age }
val duplicatesLost = people.associateBy({ it.age }, { it })
println(duplicatesKept)
println(duplicatesLost)
}
Results:
{31=[Person#41629346, Person#4eec7777], 25=[Person#3b07d329]}
{31=Person#4eec7777, 25=Person#3b07d329}
Convert a Iteratable Sequence Elements to a Map in kotlin ,
associate vs associateBy vs associateWith:
*Reference:Kotlin Documentation
1- associate (to set both Keys & Values): Build a map that can set key & value elements :
IterableSequenceElements.associate { newKey to newValue } //Output => Map {newKey : newValue ,...}
If any of two pairs would have the same key the last one gets added to the map.
The returned map preserves the entry iteration order of the original array.
2- associateBy (just set Keys by calculation): Build a map that we can set new Keys, analogous elements will be set for values
IterableSequenceElements.associateBy { newKey } //Result: => Map {newKey : 'Values will be set from analogous IterableSequenceElements' ,...}
3- associateWith (just set Values by calculation): Build a map that we can set new Values, analogous elements will be set for Keys
IterableSequenceElements.associateWith { newValue } //Result => Map { 'Keys will be set from analogous IterableSequenceElements' : newValue , ...}
Example from Kotlin tips :
You can use associate for this task:
val list = listOf("a", "b", "c", "d")
val m: Map<String, Int> = list.associate { it to it.length }
In this example, the strings from list become the keys and their corresponding lengths (as an example) become the values inside the map.
That have changed on the RC version.
I am using val map = list.groupByTo(destinationMap, {it.facebookId}, { it -> it.point })
I am trying to convert an array of strings in unityscript with values holding values like:
"Vector3(5, 3, 8)"
into an array of vectors, but Unity will not take these strings as is. Anyone have any ideas?
you cant convert all vector elements together in c# you can do it like bellow:
its psuedoCode:
position.x=convert.ToFloat("3");
position.y=....
i think there is no api to make this for you:
"Vector3(5, 3, 8)"
You didn't give us any sample code, so I'll assume the array is nicely organized, all elements right next to each other.
While I don't think there's any way that you can do this fully using UnityScript, there's ways you can process the literal string with other languages, that is, copying from your Unity script and into another program that will do the change for you.
Here's a small sample of what I would do.
Usage: Create a file array.txt with all the Vector3(x,x,x) strings, separated by line breaks and create another file array.php
Array.txt (sample)
Vector3(5, 1, 3)
Vector3(3, 3, 1)
Vector3(2, 2, 7)
Vector3(6, 6, 4)
Vector3(8, 8, 8)
Vector3(9, 3, 2)
Vector3(1, 2, 1)
Vector3(4, 3, 6)
Vector3(5, 3, 8)
Array.php
<?
$file = file('array.txt');
$text = array();
$text[] = "var vectors = new Array;";
foreach ( $file as $i )
{
$text[] = "vectors.Push(".trim($i).");";
}
echo implode("<br>", $text);
Then just run it under a PHP sandbox or a web server and copy and paste the new array into your script.
use this method to convert a single String value into a vector3 value
public static Vector3 StringToVector3(string sVector)
{
// Remove the parentheses
if (sVector.StartsWith ("(") && sVector.EndsWith (")")) {
sVector = sVector.Substring(1, sVector.Length-2);
}
// split the items
string[] sArray = sVector.Split(',');
// store as a Vector3
Vector3 result = new Vector3(
float.Parse(sArray[0]),
float.Parse(sArray[1]),
float.Parse(sArray[2]));
return result;
}
I figure someone else might find this useful later so:
if(PlayerPrefs.GetFloat("nodeNum") > 0) {
//Assemble axis value arrays
//X
var xString = PlayerPrefs.GetString("xVals");
var xValues = xString.Split(","[0]);
//Y
var yString = PlayerPrefs.GetString("yVals");
var yValues = yString.Split(","[0]);
//Z
var zString = PlayerPrefs.GetString("zVals");
var zValues = zString.Split(","[0]);
var countNode = 0;
var goal = PlayerPrefs.GetFloat("nodeNum");
var nodeVecs = new Array(Vector3.zero);
while (countNode != goal) {
var curVec = Vector3(float.Parse(xValues[countNode]), float.Parse(yValues[countNode]), float.Parse(zValues[countNode]));
nodeVecs.Push(curVec);
countNode += 1;
}
var convNodeVecs : Vector3[] = nodeVecs.ToBuiltin(Vector3) as Vector3[];
for(var nodeVec : Vector3 in convNodeVecs) {
Instantiate(nodeObj, nodeVec, Quaternion.identity);
}
}