Clarification needed for children_ attribute of sklearn's AgglomerativeClustering - d3.js
To start with, it seems to me that I am making a silly mistake somewhere. Hence, your help is much appreciated to locate this mistake.
The documentation for sklearn's AgglomerativeClustering model states this:
children_ : array-like, shape (n_nodes-1, 2)
The children of each non-leaf node. Values less than n_samples
correspond to leaves of the tree which are the original samples. A
node i greater than or equal to n_samples is a non-leaf node and has
children children_[i - n_samples]. Alternatively at the i-th
iteration, children[i][0] and children[i][1] are merged to form node
n_samples + i
Now, here is my model.children_ output, with 1093 being the biggest index, which is (n_samples-1)*2 -1):
agglo_children = [[67, 256],[13, 400],[70, 309],[15, 35],[181, 416],[391, 546],[311, 486],[420, 516],[80, 240],[75, 314],[26, 254],[76, 338],[134, 536],[258, 455],[152, 411],[481, 500],[170, 243],[24, 37],[428, 514],[8, 453],[93, 301],[163, 214],[74, 498],[206, 318],[17, 217],[121, 395],[306, 394],[12, 362],[169, 287],[16, 408],[224, 426],[61, 263],[136, 187],[0, 18],[21, 22],[89, 361],[175, 531],[105, 465],[294, 547],[31, 68],[308, 468],[417, 430],[266, 456],[278, 449],[127, 549],[36, 373],[151, 448],[213, 365],[100, 343],[180, 567],[77, 216],[220, 555],[159, 435],[146, 445],[54, 503],[57, 336],[42, 452],[399, 472],[49, 562],[564, 565],[274, 487],[235, 412],[247, 540],[162, 522],[1, 538],[207, 497],[79, 480],[125, 528],[85, 345],[478, 485],[447, 603],[160, 592],[535, 544],[303, 319],[132, 282],[55, 457],[4, 509],[479, 588],[227, 470],[2, 402],[117, 469],[95, 580],[120, 142],[401, 576],[52, 316],[591, 594],[380, 575],[339, 467],[233, 600],[48, 458],[38, 346],[246, 568],[53, 265],[221, 355],[335, 560],[196, 344],[135, 226],[201, 238],[72, 190],[239, 518],[248, 459],[150, 586],[414, 515],[520, 629],[143, 272],[58, 307],[477, 604],[543, 574],[204, 450],[328, 405],[237, 621],[164, 496],[101, 442],[323, 376],[444, 570],[495, 512],[33, 333],[464, 473],[441, 471],[398, 460],[633, 649],[418, 609],[82, 174],[103, 182],[374, 572],[577, 639],[88, 261],[25, 291],[69, 466],[6, 563],[371, 566],[385, 505],[504, 524],[492, 608],[168, 578],[474, 598],[255, 488],[558, 634],[137, 491],[228, 357],[155, 403],[192, 556],[87, 624],[610, 626],[34, 605],[147, 529],[183, 622],[178, 384],[84, 209],[45, 647],[386, 490],[130, 409],[62, 98],[312, 661],[44, 407],[203, 589],[148, 584],[140, 635],[210, 606],[527, 653],[73, 425],[363, 534],[310, 667],[358, 625],[288, 298],[599, 623],[351, 397],[297, 382],[43, 245],[10, 324],[602, 673],[99, 230],[299, 415],[23, 451],[611, 678],[561, 677],[614, 681],[277, 356],[111, 421],[499, 654],[65, 617],[259, 484],[585, 630],[40, 352],[569, 657],[131, 637],[212, 669],[454, 613],[205, 273],[50, 628],[108, 462],[5, 114],[177, 387],[59, 185],[81, 662],[521, 674],[198, 275],[331, 571],[30, 537],[341, 672],[123, 691],[3, 129],[250, 429],[315, 593],[63, 64],[251, 293],[284, 632],[119, 141],[153, 436],[194, 597],[86, 573],[636, 682],[78, 393],[173, 727],[184, 651],[262, 718],[27, 532],[195, 197],[253, 286],[66, 327],[11, 377],[381, 513],[138, 552],[139, 257],[413, 687],[71, 730],[541, 659],[313, 694],[47, 502],[369, 664],[419, 734],[28, 229],[507, 640],[236, 583],[106, 686],[551, 668],[124, 305],[724, 754],[158, 188],[218, 279],[9, 102],[582, 697],[326, 349],[354, 508],[51, 696],[545, 698],[643, 646],[41, 671],[104, 378],[260, 601],[360, 790],[711, 783],[20, 705],[422, 706],[359, 704],[292, 751],[701, 755],[332, 763],[161, 320],[431, 707],[208, 439],[383, 690],[97, 443],[501, 778],[109, 252],[716, 746],[348, 767],[234, 761],[438, 728],[122, 638],[115, 590],[539, 619],[225, 595],[631, 759],[553, 642],[302, 322],[242, 396],[94, 717],[133, 709],[771, 774],[249, 267],[530, 735],[432, 792],[364, 812],[559, 785],[641, 776],[612, 679],[476, 542],[525, 652],[660, 749],[317, 353],[695, 756],[329, 685],[368, 607],[334, 375],[46, 179],[244, 482],[116, 281],[280, 721],[379, 693],[112, 742],[410, 722],[424, 811],[342, 743],[533, 791],[390, 782],[475, 680],[714, 740],[285, 713],[773, 807],[14, 167],[202, 489],[655, 839],[437, 463],[91, 337],[92, 330],[264, 741],[32, 232],[748, 829],[616, 840],[699, 794],[145, 703],[60, 200],[189, 554],[725, 823],[423, 815],[813, 837],[366, 670],[404, 676],[29, 855],[832, 871],[627, 758],[290, 787],[579, 806],[171, 644],[154, 805],[388, 523],[268, 656],[96, 581],[90, 276],[692, 702],[193, 739],[789, 830],[506, 700],[295, 769],[596, 689],[803, 831],[289, 645],[762, 866],[283, 764],[128, 864],[325, 897],[738, 857],[493, 801],[304, 620],[118, 885],[511, 587],[367, 849],[222, 715],[144, 172],[708, 780],[744, 777],[733, 848],[615, 726],[271, 843],[215, 321],[176, 766],[223, 347],[156, 890],[186, 300],[684, 851],[269, 510],[434, 440],[820, 884],[650, 795],[149, 519],[340, 389],[19, 39],[406, 446],[658, 836],[550, 886],[860, 865],[113, 665],[56, 392],[802, 804],[881, 891],[370, 752],[816, 906],[712, 900],[548, 796],[648, 846],[427, 483],[350, 833],[107, 165],[719, 921],[231, 800],[784, 877],[683, 750],[157, 675],[720, 896],[788, 905],[710, 911],[770, 874],[557, 918],[372, 876],[850, 934],[241, 914],[879, 947],[745, 882],[461, 852],[737, 927],[817, 936],[110, 858],[270, 880],[841, 904],[166, 723],[757, 901],[7, 898],[126, 826],[663, 862],[753, 818],[736, 892],[732, 929],[875, 966],[781, 920],[747, 913],[845, 945],[731, 808],[834, 853],[868, 895],[870, 968],[935, 949],[899, 915],[219, 902],[433, 517],[211, 952],[872, 959],[526, 786],[688, 859],[296, 950],[910, 933],[838, 847],[922, 979],[775, 976],[618, 760],[199, 893],[869, 981],[797, 955],[956, 973],[842, 867],[768, 908],[765, 931],[835, 919],[827, 984],[917, 946],[793, 974],[814, 819],[948, 990],[798, 825],[729, 854],[883, 888],[930, 987],[903, 943],[856, 964],[844, 993],[83, 666],[821, 977],[809, 928],[907, 967],[822, 1004],[940, 951],[958, 971],[894, 960],[970, 978],[963, 1014],[954, 989],[828, 861],[191, 988],[972, 1012],[772, 975],[986, 1008],[941, 1013],[992, 994],[799, 1022],[938, 999],[996, 1011],[925, 942],[953, 1021],[1000, 1010],[957, 985],[494, 983],[962, 1019],[932, 1027],[1005, 1028],[889, 909],[824, 1001],[1006, 1023],[980, 1016],[923, 926],[1026, 1031],[873, 1041],[1003, 1025],[1007, 1043],[944, 1009],[937, 995],[1002, 1048],[887, 916],[998, 1018],[1020, 1038],[1047, 1053],[779, 1033],[991, 1045],[939, 961],[1040, 1042],[997, 1036],[1024, 1052],[965, 1039],[912, 1035],[1032, 1056],[982, 1051],[878, 1015],[1059, 1066],[1017, 1067],[1030, 1037],[1044, 1065],[1050, 1064],[1054, 1057],[1071, 1074],[924, 1063],[1069, 1075],[1072, 1077],[1055, 1070],[1029, 1060],[1068, 1076],[1046, 1061],[810, 969],[1078, 1083],[1062, 1084],[1080, 1082],[1073, 1079],[863, 1058],[1085, 1086],[1081, 1088],[1087, 1089],[1034, 1091],[1049, 1092],[1090, 1093]]
My problem is that I cannot map these to the original data. The end goal is to have a Newick parse of this and build a hierarchy from it. But once I do that, I have indexes in the hierarchy that are > n_samples, which makes no sense.
Here is my parsing, on the front-end:
var agglo_data = d3.stratify()
.id((d,i) => i + numSamples)
.parentId((d, i) => {
var parIndex = agglo_data.findIndex(e => e.includes && e.includes(i + numSamples));
if (parIndex < 0) {
return;
}
return parIndex + numSamples;
})(agglo_children);
Here is what I get:
As you can see, there are indexes that are bigger than n_samples, which makes no sense to me.
Can anyone spot the mistake?
Related
Breadth-first algorithm implementation
I am trying to implement a "Breadth-First" Algorithm as a variation of something I've seen in a book. My issue is that the algorithm is not adding the elements of every node into the queue. For instance, if I search for "black lab" under the name 'mariela' in the "search()" function, I will get the correct output: "simon is a black lab" However, I ought to be able to look for "black lab" in "walter", which is connected to "mariela", which is connected to "simon", who is a "black lab'. This is not working. Have I made a rookie mistake in my implementation of this algorithm, or have I set up my graph wrong? As always, any/all help is much appreciated! from collections import deque # TEST GRAPH ------------- graph = {} graph['walter'] = ['luci', 'kaiser', 'andrea', 'mariela'] graph['andrea'] = ['echo', 'dante', 'walter', 'mariela'] graph['mariela'] = ['ginger', 'simon', 'walter', 'andrea'] graph['kaiser'] = 'german shepherd' graph['luci'] = 'black cat' graph['echo'] = 'pitbull' graph['dante'] = 'pitbull' graph['ginger'] = 'orange cat' graph['simon'] = 'black lab' def condition_met(name): if graph[name] == 'black lab': return name def search(name): search_queue = deque() search_queue += graph[name] # add all elements of "name" to queue searchedAlready = [] # holding array for people already searched through while search_queue: # while queue not empty... person = search_queue.popleft() # pull 1st person from queue if person not in searchedAlready: # if person hasn't been searched through yet... if condition_met(person): print person + ' is a black labrador' return True else: search_queue += graph[person] searchedAlready.append(person) return False search('walter') #search('mariela')
You have lots of problems in your implementation - both Python and Algorithm wise. Rewrite as: # #param graph graph to search # #param start the node to start at # #param value the value to search for def search(graph, start, value): explored = [] queue = [start] while len(queue) > 0: # next node to explore node = queue.pop() # only explore if not already explored if node not in explored: # node found, search complete if node == value: return True # add children of node to queue else: explored.append(node) queue.extend(graph[node]) # extend is faster than concat (+=) return False graph = {} graph['walter'] = ['luci', 'kaiser', 'andrea', 'mariela'] graph['andrea'] = ['echo', 'dante', 'walter', 'mariela'] graph['mariela'] = ['ginger', 'simon', 'walter', 'andrea'] # children should be a list graph['kaiser'] = ['german shepherd'] graph['luci'] = ['black cat'] graph['echo'] = ['pitbull'] graph['dante'] = ['pitbull'] graph['ginger'] = ['orange cat'] graph['simon'] = ['black lab'] print search(graph, 'mariela', 'walter') Here is a demo https://repl.it/IkRA/0
How to improve running time of my binary search code in peripherical parts?
I am studying for this great Coursera course https://www.coursera.org/learn/algorithmic-toolbox . On the fourth week, we have an assignment related to binary trees. I think I did a good job. I created a binary search code that solves this problem using recursion in Python3. That's my code: #python3 data_in_sequence = list(map(int,(input().split()))) data_in_keys = list(map(int,(input()).split())) original_array = data_in_sequence[1:] data_in_sequence = data_in_sequence[1:] data_in_keys = data_in_keys[1:] def binary_search(data_in_sequence,target): answer = 0 sub_array = data_in_sequence #print("sub_array",sub_array) if not sub_array: # print("sub_array",sub_array) answer = -1 return answer #print("target",target) mid_point_index = (len(sub_array)//2) #print("mid_point", sub_array[mid_point_index]) beg_point_index = 0 #print("beg_point_index",beg_point_index) end_point_index = len(sub_array)-1 #print("end_point_index",end_point_index) if sub_array[mid_point_index]==target: #print ("final midpoint, ", sub_array[mid_point_index]) #print ("original_array",original_array) #print("sub_array[mid_point_index]",sub_array[mid_point_index]) #print ("answer",answer) answer = original_array.index(sub_array[mid_point_index]) return answer elif target>sub_array[mid_point_index]: #print("target num higher than current midpoint") beg_point_index = mid_point_index+1 sub_array=sub_array[beg_point_index:] end_point_index = len(sub_array)-1 #print("sub_array",sub_array) return binary_search(sub_array,target) elif target<sub_array[mid_point_index]: #print("target num smaller than current midpoint") sub_array = sub_array[:mid_point_index] return binary_search(sub_array,target) else: return None def bin_search_over_seq(data_in_sequence,data_in_keys): final_output = "" for key in data_in_keys: final_output = final_output + " " + str(binary_search(data_in_sequence,key)) return final_output print (bin_search_over_seq(data_in_sequence,data_in_keys)) I usually get the correct output. For instance, if I input: 5 1 5 8 12 13 5 8 1 23 1 11 I get the correct indexes of the sequences or (-1) if the term is not in sequence (first line): 2 0 -1 0 -1 However, my code does not pass on the expected running time. Failed case #4/22: time limit exceeded (Time used: 13.47/10.00, memory used: 36696064/536870912.) I think this happens not due to the implementation of my binary search (I think it is right). Actually, I think this happens due to some inneficieny in a peripheral part of the code. Like the way I am managing to output the final answer. However, the way I am presenting the final answer does not seem to be really "heavy"... I am lost. Am I not seeing something? Is there another inefficiency I am not seeing? How can I solve this? Just trying to present the final result in a faster way?
lua - How to perform transitions in sequence
i'm trying to move an object along the points of a complex curved path with a constant velocity using transitions. I have two tables to keep the coordinates of the points and another table with the respective time intervals for travelling each linear segment at the same speed (despite they have different lengths). Assuming the firts and last values of the "timeTable" are 0, i tried with something similar to this: local i = 1 local function Move() transition.to(player, {time=timeTable[i+1], x=TableX[i+1], y=TableY[i+1]}) i=i+1 end timer.performWithDelay( timeTable[i], Move, 0 ) It doesn't work although it no error is given. Thanks in advance for your helpenter code here
May be this would work local timeTable = {1, 3, 4, 1} local TableX = {100, 400, 400, 500} local TableY = {100, 100, 500, 500} local i = 0 local function onCompleteMove() i = i + 1 if timeTable[i] then transition.to(player, { time=timeTable[i], x=TableX[i], y=TableY[i], onComplete=onCompleteMove }) end end onCompleteMove() -- start moving to first point
Try Tutorial: Moving objects along a path Tutorial: Working with curved paths Method for chain of transition for the same object local function chainOfTransitions(object, params, ...) if params then function params.onComplete() chainOfTransitions(object, unpack(arg)) end transition.to(object, params) end end
Thanks to all of you! I accomplished the goal by doing so: local segmentTransition local delta = 1 local function onCompleteMove() i = i + delta if timeTable[i] then segmentTransition = transition.to(player2, { time=timeTable[i], x=tableX[i+delta], y=tableY[i+delta], onComplete=onCompleteMove }) end end onCompleteMove() -- start moving
Join tiles in Corona SDK into one word for a Breakout game grid?
I have a game project to re-implement Breakout. I want to display two words, each word on a line. They are joined by the bricks block. Inside, the top line is the first name, aligned left. The bottom line is the last name, aligned right. They are input from textboxes, and rendered as shown: Each second that passes, the screen will add a configurable number of bricks to the grid (for example, five bricks per second) until the two words appear complete. I displayed a letter of the alphabet which is created from the matrix(0,1). ...But I don’t know how to join them into one word. How can I join these letters? This is what I've gotten so far: Bricks.lua local Bricks = display.newGroup() -- static object local Events = require("Events") local Levels = require("Levels") local sound = require("Sound") local physics = require("physics") local Sprites = require("Sprites") local Func = require("Func") local brickSpriteData = { { name = "brick", frames = {Sprites.brick} }, { name = "brick2", frames = {Sprites.brick2} }, { name = "brick3", frames = {Sprites.brick3} }, } -- animation table local brickAnimations = {} Sprites:CreateAnimationTable { spriteData = brickSpriteData, animationTable = brickAnimations } -- get size from temp object for later use local tempBrick = display.newImage('red_apple_20.png',300,500) --local tempBrick = display.newImage('cheryGreen2.png',300,500) local brickSize = { width = tempBrick.width, height = tempBrick.height } --tempBrick:removeSelf( ) ---------------- -- Rubble -- needs to be moved to its own file ---------------- local rubbleSpriteData = { { name = "rubble1", frames = {Sprites.rubble1} }, { name = "rubble2", frames = {Sprites.rubble2} }, { name = "rubble3", frames = {Sprites.rubble3} }, { name = "rubble4", frames = {Sprites.rubble4} }, { name = "rubble5", frames = {Sprites.rubble5} }, } local rubbleAnimations = {} Sprites:CreateAnimationTable { spriteData = rubbleSpriteData, animationTable = rubbleAnimations } local totalBricksBroken = 0 -- used to track when level is complete local totalBricksAtStart = 0 -- contains all brick objects local bricks = {} local function CreateBrick(data) -- random brick sprite local obj = display.newImage('red_apple_20.png') local objGreen = display.newImage('cheryGreen2.png') obj.name = "brick" obj.x = data.x --or display.contentCenterX obj.y = data.y --or 1000 obj.brickType = data.brickType or 1 obj.index = data.index function obj:Break() totalBricksBroken = totalBricksBroken + 1 bricks[self.index] = nil obj:removeSelf( ) sound.play(sound.breakBrick) end function obj:Update() if(self == nil) then return end if(self.y > display.contentHeight - 20) then obj:Break() end end if(obj.brickType ==1) then physics.addBody( obj, "static", {friction=0.5, bounce=0.5 } ) elseif(obj.brickType == 2) then physics.addBody( objGreen,"static",{friction=0.2, bounce=0.5, density = 1 } ) end return obj end local currentLevel = testLevel -- create level from bricks defined in an object -- this allows for levels to be designed local function CreateBricksFromTable(level) totalBricksAtStart = 0 local activeBricksCount = 0 for yi=1, #level.bricks do for xi=1, #level.bricks[yi] do -- create brick? if(level.bricks[yi][xi] > 0) then local xPos local yPos if(level.align == "center") then --1100-((99*16)*0.5) xPos = display.contentCenterX- ((level.columns * brickSize.width) * 0.5/3) + ((xi-1) * level.xSpace)--display.contentCenterX --xPos = 300 +(xi * level.xSpace) yPos = 100 + (yi * level.ySpace)--100 else xPos = level.xStart + (xi * level.xSpace) yPos = level.yStart + (yi * level.ySpace) end local brickData = { x = xPos, y = yPos, brickType = level.bricks[yi][xi], index = activeBricksCount+1 } bricks[activeBricksCount+1] = CreateBrick(brickData) activeBricksCount = activeBricksCount + 1 end end end totalBricks = activeBricksCount totalBricksAtStart = activeBricksCount end -- create bricks for level --> set from above functions, change function to change brick build type local CreateAllBricks = CreateBricksFromTable -- called by a timer so I can pass arguments to CreateAllBricks local function CreateAllBricksTimerCall() CreateAllBricks(Levels.currentLevel) end -- remove all brick objects from memory local function ClearBricks() for i=1, #bricks do bricks[i] = nil end end -- stuff run on enterFrame event function Bricks:Update() -- update individual bricks if(totalBricksAtStart > 0) then for i=1, totalBricksAtStart do -- brick exists? if(bricks[i]) then bricks[i]:Update() end end end -- is level over? if(totalBricksBroken == totalBricks) then Events.allBricksBroken:Dispatch() end end ---------------- -- Events ---------------- function Bricks:allBricksBroken(event) -- cleanup bricks ClearBricks() local t = timer.performWithDelay( 1000, CreateAllBricksTimerCall) --CreateAllBricks() totalBricksBroken = 0 -- play happy sound for player to enjoy sound.play(sound.win) print("You Win!") end Events.allBricksBroken:AddObject(Bricks) CreateAllBricks(Levels.currentLevel) return Bricks Levels.lua local Events = require("Events") local Levels = {} local function MakeLevel(data) local level = {} level.xStart = data.xStart or 100 level.yStart = data.yStart or 100 level.xSpace = data.xSpace or 23 level.ySpace = data.ySpace or 23 level.align = data.align or "center" level.columns = data.columns or #data.bricks[1] level.bricks = data.bricks --> required return level end Levels.test4 = MakeLevel { bricks = { {0,2,0,0,2,0,0,2,0}, {0,0,2,0,2,0,2,0,0}, {0,0,0,0,2,0,0,0,0}, {1,1,2,1,1,1,2,1,1}, {0,0,0,0,1,0,0,0,0}, {0,0,0,0,1,0,0,0,0}, {0,0,0,0,1,0,0,0,0}, } } Levels.test5 = MakeLevel { bricks = { {0,0,0,1,0,0,0,0}, {0,0,1,0,1,0,0,0}, {0,0,1,0,1,0,0,0}, {0,1,0,0,0,1,0,0}, {0,1,1,1,1,1,0,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,1,0}, {1,0,0,0,0,0,1,0} } } -- Levels.test6 = MakeLevel2 -- { -- bricks = -- { ----A "a" = {{0,0,0,1,0,0,0,0}, -- {0,0,1,0,1,0,0,0}, -- {0,0,1,0,1,0,0,0}, -- {0,1,0,0,0,1,0,0}, -- {0,1,1,1,1,1,0,0}, -- {1,0,0,0,0,0,1,0}, -- {1,0,0,0,0,0,1,0}, -- {1,0,0,0,0,0,1,0}, -- {1,0,0,0,0,0,1,0}}, ----B -- "b" = {{1,1,1,1,0,0,0}, -- {1,0,0,0,1,0,0}, -- {1,0,0,0,1,0,0}, -- {1,0,0,0,1,0,0}, -- {1,1,1,1,0,0,0}, -- {1,0,0,0,1,0,0}, -- {1,0,0,0,0,1,0}, -- {1,0,0,0,0,1,0}, -- {1,1,1,1,1,0,0}}, --........... --....... --... -- --Z -- "z"= {{1,1,1,1,1,1,1,0}, -- {0,0,0,0,0,1,0,0}, -- {0,0,0,0,1,0,0,0}, -- {0,0,0,0,1,0,0,0}, -- {0,0,0,1,0,0,0,0}, -- {0,0,1,0,0,0,0,0}, -- {0,0,1,0,0,0,0,0}, -- {0,1,0,0,0,0,0,0}, -- {1,1,1,1,1,1,1,0}} -- } -- } -- stores all levels in ordered table so that one can be selected randomly by index Levels.levels = { --Levels.test4, Levels.test5 -- Levels.test6, } function Levels:GetRandomLevel() return self.levels[math.random(#Levels.levels)] end Levels.notPlayedYet = {} Levels.currentLevel = Levels:GetRandomLevel() -- Events function Levels:allBricksBroken(event) self.currentLevel = Levels:GetRandomLevel() end Events.allBricksBroken:AddObject(Levels) return Levels The work I've done thus far (same as above) as an external download: http://www.mediafire.com/download/1t89ftkbznkn184/Breakout2.rar
In the interest of actually answering the question: I'm not 100% sure what you mean by "How can I join these letters", but from poking through the code I have a guess, so please clarify on whether it is accurate, or if I am wrong about what you wanted. Scenario 1 You haven't successfully achieved the image illustrated in the screenshot - you've been able to draw one letter, but not multiple ones. In this case, you'll need to have a better understanding of what your code is doing. The CreateBricksFromTable function takes in a Level object, which is created by the MakeLevel function from a table with a bricks property, which is a table of tables that represent rows with columns in them, showing what type of brick should be at each position. In your commented-out level, you have created an table where the bricks field contains a field for each letter, but the MakeLevel function still expects a bricks field that directly contains the grid of blocks. You will have to - as it seems you attempted - create a MakeWordLevel function (or the like) that takes this letter list, and a word for each line, and constructs a larger grid by copying the appropriate letters into it. StackOverflow is not your programming tutor, and an SO question is not the right forum for having people write code for you or getting into step-by-step details of how to do this, but I'll leave you a basic outline. Your function would look something like this: local function MakeWordLevel(data, line1, line2) local level = {} ... return level end And then would have to: Populate all of the same properties that MakeLevel does Calculate how wide (level.columns) the level should be with all the letters Create a table in the same format as the bricks properties, but big enough to hold all of the letters Go through the input strings (line1 and line2), find the correct letter data from what is now the test6 array, and copy that data into the large table Assign that table as level.bricks This question already is a bit outside of what StackOverflow is intended for in that it asks about how to implement a feature rather than achieve a small, specific programming task, so any further followup should take place in a chatroom - perhaps the Hello World room would be helpful. Scenario 2: This was my original guess, but after considering and reading past edits, I doubt this is answering the right question You may want a solid "background" of, say, red blocks, surrounding your letters and making the field into a solid "wall", with the name in a different color. And you may want these bricks to slowly show up a few at a time. In that case, the main thing you need to do is keep track of what spaces are "taken" by the name bricks. There are many ways to do this, but I would start with a matrix to keep track of that - as big as the final playing field - full of 0's. Then, as you add the bricks for the name, set a 1 at the x,y location in that matrix according to that block's coordinate. When you want to fill in the background, each time you go to add a block at a coordinate, check that "taken" matrix before trying to add a block - if it's taken (1), then just skip it and move onto the next coordinate. This works if you're filling in the background blocks sequentially (say, left to right, top to bottom), or if you want to add them randomly. With random, you'd also want to keep updating the "taken" matrix so you don't try to add a block twice. The random fill-in, however, presents its own problem - it will keep taking longer to fill in as it goes, because it'll find more and more "taken" blocks and have to pick a new one. There are solutions to this, of course, but I won't go too far down that road when I don't know if that's even what you want.
I don't really understand (or read, for that matter) your code but from what I see joining them into complete words is easy. You have two possibilities. You can "render" them directly into your level/display data, simply copy them to the appropriate places, like this: -- The level data. local level = {} -- Create the level data. for row = 1, 25, 1 do local rowData = {} for column = 1, 80, 1 do rowData[column] = "." end level[row] = rowData end -- Now let us setup the letters. local letters = { A = { {".",".",".","#",".",".",".","."}, {".",".","#",".","#",".",".","."}, {".",".","#",".","#",".",".","."}, {".","#",".",".",".","#",".","."}, {".","#","#","#","#","#",".","."}, {"#",".",".",".",".",".","#","."}, {"#",".",".",".",".",".","#","."}, {"#",".",".",".",".",".","#","."}, {"#",".",".",".",".",".","#","."} }, B = { {"#","#","#","#",".",".","."}, {"#",".",".",".","#",".","."}, {"#",".",".",".","#",".","."}, {"#",".",".",".","#",".","."}, {"#","#","#","#",".",".","."}, {"#",".",".",".","#",".","."}, {"#",".",".",".",".","#","."}, {"#",".",".",".",".","#","."}, {"#","#","#","#","#",".","."} } } -- The string to print. local text = "ABBA" -- Let us insert the data into the level data. for index = 1, #text, 1 do local char = string.sub(text, index, index) local charData = letters[char] local offset = index * 7 for row = 1, 9, 1 do local rowData = charData[row] for column = 1, 7, 1 do level[row][offset + column] = rowData[column] end end end -- Print everything for row = 1, 25, 1 do local rowData = level[row] for column = 1, 80, 1 do io.write(rowData[column]) end print() end You save you letters in a lookup table and then copy them, piece by piece, to the level data. Here I replaced the numbers with dots and number signs to make it prettier on the command line. Alternately to that you can also "render" the words into a prepared buffer and then insert that into the level data by using the same logic.
Carrot2 circle chart
Anyone know how to create circle chart like the one used in carrto2?
The mbostock/d3 gallery has good visualizations for Carrot2 output. This carrot2-rb ruby client for Carrot2 returns an object with a clusters array. The scores and phrases attributes can be used in a simple doughnut chart. More dynamic visualizations like expandable dendrograms are possible with tree structures like flare.json. Here is a zoomable wheel based on Carrot2 results. This is the coffeescript code I wrote to create flare.json using the documents elements. clusters = [{"id":0,"size":3,"phrases":["Coupon"],"score":0.06441151442396735,"documents":["0","1","2"],"attributes":{"score":0.06441151442396735}},{"id":1,"size":2,"phrases":["Exclusive"],"score":0.7044284368639101,"documents":["0","1"],"attributes":{"score":0.7044284368639101}},{"id":2,"size":1,"phrases":["Other Topics"],"score":0.0,"documents":["3"],"attributes":{"other-topics":true,"score":0.0}}] flare = get_flare clusters get_children = (index, index2, clusters, documents) ->unless index == (clusters.length - 1) # If not last cluster orphans = {'name': ''} intr = _.intersection(documents, clusters[index2].documents); if intr.length > 0 # continue drilling if index2 < (clusters.length - 1) # Up until last element. # Get next layer of orphans orphan_docs = _.difference(intr, clusters[index2 + 1].documents) if orphan_docs.length > 0 orphans = {'name': orphan_docs, 'size': orphan_docs.length} if _.intersection(intr, clusters[index2 + 1].documents).length > 0 return [orphans, {'name': clusters[index2+1].phrases[0], 'children': get_children(index, (index2 + 1), clusters, intr)}] else return [orphans] else # At second to last cluster, so terminate here return [{'name': inter}] else # No intersection, so return bundle of current documents. return [{'name': documents}] return [{'name': _.intersection(clusters[index].documents, clusters[index2].documents)}] get_flare = (clusters) -> # Make root object flare = name: "root" children: [] children = flare.children _.each(clusters[0..(clusters.length - 2)], (cluster, index) -> # All clusters but the last. (It has already been compared to previous ones) #All documents for all remaining clusters in array remaining_documents = _.flatten(_.map clusters[(index + 1)..clusters.length], (c) -> c.documents ) root_child = {'name': cluster.phrases[0], 'children': []} # Get first layer of orphans orphan_docs = _.difference(cluster.documents, remaining_documents) if orphan_docs.length > 0 root_child.children.push {'name': orphan_docs, size: orphan_docs.length} for index2 in [(index + 1)..(clusters.length - 1)] by 1 if _.intersection(cluster.documents, clusters[index2].documents).length > 0 root_child.children.push {'name': clusters[index2].phrases[0], 'children': get_children(index, (index2), clusters, cluster.documents)} children.push root_child ) flare
You can buy their Circles Javascript component: http://carrotsearch.com/circles-overview